1 | /** |
---|
2 | ****************************************************************************** |
---|
3 | * @file stm32f7xx_hal_usart.c |
---|
4 | * @author MCD Application Team |
---|
5 | * @version V1.0.1 |
---|
6 | * @date 25-June-2015 |
---|
7 | * @brief USART HAL module driver. |
---|
8 | * This file provides firmware functions to manage the following |
---|
9 | * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter |
---|
10 | * Peripheral (USART). |
---|
11 | * + Initialization and de-initialization functions |
---|
12 | * + IO operation functions |
---|
13 | * + Peripheral Control functions |
---|
14 | * |
---|
15 | @verbatim |
---|
16 | =============================================================================== |
---|
17 | ##### How to use this driver ##### |
---|
18 | =============================================================================== |
---|
19 | [..] |
---|
20 | The USART HAL driver can be used as follows: |
---|
21 | |
---|
22 | (#) Declare a USART_HandleTypeDef handle structure. |
---|
23 | (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API: |
---|
24 | (##) Enable the USARTx interface clock. |
---|
25 | (##) USART pins configuration: |
---|
26 | (+++) Enable the clock for the USART GPIOs. |
---|
27 | (+++) Configure these USART pins as alternate function pull-up. |
---|
28 | (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(), |
---|
29 | HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): |
---|
30 | (+++) Configure the USARTx interrupt priority. |
---|
31 | (+++) Enable the NVIC USART IRQ handle. |
---|
32 | (+++) The specific USART interrupts (Transmission complete interrupt, |
---|
33 | RXNE interrupt and Error Interrupts) will be managed using the macros |
---|
34 | __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process. |
---|
35 | (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA() |
---|
36 | HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): |
---|
37 | (+++) Declare a DMA handle structure for the Tx/Rx stream. |
---|
38 | (+++) Enable the DMAx interface clock. |
---|
39 | (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. |
---|
40 | (+++) Configure the DMA Tx/Rx Stream. |
---|
41 | (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle. |
---|
42 | (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream. |
---|
43 | |
---|
44 | (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware |
---|
45 | flow control and Mode(Receiver/Transmitter) in the husart Init structure. |
---|
46 | |
---|
47 | (#) Initialize the USART registers by calling the HAL_USART_Init() API: |
---|
48 | (++) These API's configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc) |
---|
49 | by calling the customed HAL_USART_MspInit(&husart) API. |
---|
50 | |
---|
51 | @endverbatim |
---|
52 | ****************************************************************************** |
---|
53 | * @attention |
---|
54 | * |
---|
55 | * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> |
---|
56 | * |
---|
57 | * Redistribution and use in source and binary forms, with or without modification, |
---|
58 | * are permitted provided that the following conditions are met: |
---|
59 | * 1. Redistributions of source code must retain the above copyright notice, |
---|
60 | * this list of conditions and the following disclaimer. |
---|
61 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
---|
62 | * this list of conditions and the following disclaimer in the documentation |
---|
63 | * and/or other materials provided with the distribution. |
---|
64 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
---|
65 | * may be used to endorse or promote products derived from this software |
---|
66 | * without specific prior written permission. |
---|
67 | * |
---|
68 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
69 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
70 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
---|
71 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
---|
72 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
73 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
---|
74 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
---|
75 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
---|
76 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
---|
77 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
78 | * |
---|
79 | ****************************************************************************** |
---|
80 | */ |
---|
81 | |
---|
82 | /* Includes ------------------------------------------------------------------*/ |
---|
83 | #include "stm32f7xx_hal.h" |
---|
84 | |
---|
85 | /** @addtogroup STM32F7xx_HAL_Driver |
---|
86 | * @{ |
---|
87 | */ |
---|
88 | |
---|
89 | /** @defgroup USART USART |
---|
90 | * @brief HAL USART Synchronous module driver |
---|
91 | * @{ |
---|
92 | */ |
---|
93 | |
---|
94 | #ifdef HAL_USART_MODULE_ENABLED |
---|
95 | |
---|
96 | /* Private typedef -----------------------------------------------------------*/ |
---|
97 | /* Private define ------------------------------------------------------------*/ |
---|
98 | /** @addtogroup USART_Private_Constants |
---|
99 | * @{ |
---|
100 | */ |
---|
101 | #define DUMMY_DATA ((uint16_t) 0xFFFF) |
---|
102 | #define TEACK_REACK_TIMEOUT ((uint32_t) 1000) |
---|
103 | #define USART_TXDMA_TIMEOUTVALUE 22000 |
---|
104 | #define USART_TIMEOUT_VALUE 22000 |
---|
105 | #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ |
---|
106 | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) |
---|
107 | #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \ |
---|
108 | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) |
---|
109 | /** |
---|
110 | * @} |
---|
111 | */ |
---|
112 | /* Private macro -------------------------------------------------------------*/ |
---|
113 | /* Private variables ---------------------------------------------------------*/ |
---|
114 | /* Private function prototypes -----------------------------------------------*/ |
---|
115 | /* Private functions ---------------------------------------------------------*/ |
---|
116 | /** @addtogroup USART_Private_Functions |
---|
117 | * @{ |
---|
118 | */ |
---|
119 | static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma); |
---|
120 | static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); |
---|
121 | static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); |
---|
122 | static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); |
---|
123 | static void USART_DMAError(DMA_HandleTypeDef *hdma); |
---|
124 | static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout); |
---|
125 | static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart); |
---|
126 | static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart); |
---|
127 | static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart); |
---|
128 | static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart); |
---|
129 | static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart); |
---|
130 | static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart); |
---|
131 | /** |
---|
132 | * @} |
---|
133 | */ |
---|
134 | |
---|
135 | /* Exported functions --------------------------------------------------------*/ |
---|
136 | |
---|
137 | /** @defgroup USART_Exported_Functions USART Exported Functions |
---|
138 | * @{ |
---|
139 | */ |
---|
140 | |
---|
141 | /** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions |
---|
142 | * @brief Initialization and Configuration functions |
---|
143 | * |
---|
144 | @verbatim |
---|
145 | =============================================================================== |
---|
146 | ##### Initialization and Configuration functions ##### |
---|
147 | =============================================================================== |
---|
148 | [..] |
---|
149 | This subsection provides a set of functions allowing to initialize the USART |
---|
150 | in asynchronous and in synchronous modes. |
---|
151 | (+) For the asynchronous mode only these parameters can be configured: |
---|
152 | (++) Baud Rate |
---|
153 | (++) Word Length |
---|
154 | (++) Stop Bit |
---|
155 | (++) Parity: If the parity is enabled, then the MSB bit of the data written |
---|
156 | in the data register is transmitted but is changed by the parity bit. |
---|
157 | Depending on the frame length defined by the M1 and M0 bits (7-bit, |
---|
158 | 8-bit or 9-bit), the possible USART frame formats are as listed in the |
---|
159 | following table: |
---|
160 | |
---|
161 | (+++) +---------------------------------------------------------------+ |
---|
162 | (+++) | M1M0 bits | PCE bit | USART frame | |
---|
163 | (+++) |-----------------------|---------------------------------------| |
---|
164 | (+++) | 10 | 0 | | SB | 7-bit data | STB | | |
---|
165 | (+++) |-----------|-----------|---------------------------------------| |
---|
166 | (+++) | 10 | 1 | | SB | 6-bit data | PB | STB | | |
---|
167 | (+++) +---------------------------------------------------------------+ |
---|
168 | |
---|
169 | (++) USART polarity |
---|
170 | (++) USART phase |
---|
171 | (++) USART LastBit |
---|
172 | (++) Receiver/transmitter modes |
---|
173 | |
---|
174 | [..] |
---|
175 | The HAL_USART_Init() function follows the USART synchronous configuration |
---|
176 | procedure (details for the procedure are available in reference manual). |
---|
177 | |
---|
178 | @endverbatim |
---|
179 | * @{ |
---|
180 | */ |
---|
181 | |
---|
182 | /** |
---|
183 | * @brief Initializes the USART mode according to the specified |
---|
184 | * parameters in the USART_InitTypeDef and create the associated handle. |
---|
185 | * @param husart: USART handle |
---|
186 | * @retval HAL status |
---|
187 | */ |
---|
188 | HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) |
---|
189 | { |
---|
190 | /* Check the USART handle allocation */ |
---|
191 | if(husart == NULL) |
---|
192 | { |
---|
193 | return HAL_ERROR; |
---|
194 | } |
---|
195 | |
---|
196 | /* Check the parameters */ |
---|
197 | assert_param(IS_USART_INSTANCE(husart->Instance)); |
---|
198 | |
---|
199 | if(husart->State == HAL_USART_STATE_RESET) |
---|
200 | { |
---|
201 | /* Allocate lock resource and initialize it */ |
---|
202 | husart->Lock = HAL_UNLOCKED; |
---|
203 | /* Init the low level hardware : GPIO, CLOCK */ |
---|
204 | HAL_USART_MspInit(husart); |
---|
205 | } |
---|
206 | |
---|
207 | husart->State = HAL_USART_STATE_BUSY; |
---|
208 | |
---|
209 | /* Disable the Peripheral */ |
---|
210 | __HAL_USART_DISABLE(husart); |
---|
211 | |
---|
212 | /* Set the Usart Communication parameters */ |
---|
213 | if (USART_SetConfig(husart) == HAL_ERROR) |
---|
214 | { |
---|
215 | return HAL_ERROR; |
---|
216 | } |
---|
217 | |
---|
218 | /* In Synchronous mode, the following bits must be kept cleared: |
---|
219 | - LINEN bit in the USART_CR2 register |
---|
220 | - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/ |
---|
221 | husart->Instance->CR2 &= ~USART_CR2_LINEN; |
---|
222 | husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); |
---|
223 | |
---|
224 | /* Enable the Peripheral */ |
---|
225 | __HAL_USART_ENABLE(husart); |
---|
226 | |
---|
227 | /* TEACK and/or REACK to check before moving husart->State to Ready */ |
---|
228 | return (USART_CheckIdleState(husart)); |
---|
229 | } |
---|
230 | |
---|
231 | /** |
---|
232 | * @brief DeInitializes the USART peripheral |
---|
233 | * @param husart: USART handle |
---|
234 | * @retval HAL status |
---|
235 | */ |
---|
236 | HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) |
---|
237 | { |
---|
238 | /* Check the USART handle allocation */ |
---|
239 | if(husart == NULL) |
---|
240 | { |
---|
241 | return HAL_ERROR; |
---|
242 | } |
---|
243 | |
---|
244 | /* Check the parameters */ |
---|
245 | assert_param(IS_USART_INSTANCE(husart->Instance)); |
---|
246 | |
---|
247 | husart->State = HAL_USART_STATE_BUSY; |
---|
248 | |
---|
249 | husart->Instance->CR1 = 0x0; |
---|
250 | husart->Instance->CR2 = 0x0; |
---|
251 | husart->Instance->CR3 = 0x0; |
---|
252 | |
---|
253 | /* DeInit the low level hardware */ |
---|
254 | HAL_USART_MspDeInit(husart); |
---|
255 | |
---|
256 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
257 | husart->State = HAL_USART_STATE_RESET; |
---|
258 | |
---|
259 | /* Process Unlock */ |
---|
260 | __HAL_UNLOCK(husart); |
---|
261 | |
---|
262 | return HAL_OK; |
---|
263 | } |
---|
264 | |
---|
265 | /** |
---|
266 | * @brief USART MSP Init |
---|
267 | * @param husart: USART handle |
---|
268 | * @retval None |
---|
269 | */ |
---|
270 | __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart) |
---|
271 | { |
---|
272 | /* NOTE : This function should not be modified, when the callback is needed, |
---|
273 | the HAL_USART_MspInit can be implemented in the user file |
---|
274 | */ |
---|
275 | } |
---|
276 | |
---|
277 | /** |
---|
278 | * @brief USART MSP DeInit |
---|
279 | * @param husart: USART handle |
---|
280 | * @retval None |
---|
281 | */ |
---|
282 | __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart) |
---|
283 | { |
---|
284 | /* NOTE : This function should not be modified, when the callback is needed, |
---|
285 | the HAL_USART_MspDeInit can be implemented in the user file |
---|
286 | */ |
---|
287 | } |
---|
288 | |
---|
289 | /** |
---|
290 | * @} |
---|
291 | */ |
---|
292 | |
---|
293 | /** @defgroup USART_Exported_Functions_Group2 IO operation functions |
---|
294 | * @brief USART Transmit and Receive functions |
---|
295 | * |
---|
296 | @verbatim |
---|
297 | =============================================================================== |
---|
298 | ##### IO operation functions ##### |
---|
299 | =============================================================================== |
---|
300 | This subsection provides a set of functions allowing to manage the USART synchronous |
---|
301 | data transfers. |
---|
302 | |
---|
303 | [..] The USART supports master mode only: it cannot receive or send data related to an input |
---|
304 | clock (SCLK is always an output). |
---|
305 | |
---|
306 | (#) There are two mode of transfer: |
---|
307 | (++) Blocking mode: The communication is performed in polling mode. |
---|
308 | The HAL status of all data processing is returned by the same function |
---|
309 | after finishing transfer. |
---|
310 | (++) No-Blocking mode: The communication is performed using Interrupts |
---|
311 | or DMA, These API's return the HAL status. |
---|
312 | The end of the data processing will be indicated through the |
---|
313 | dedicated USART IRQ when using Interrupt mode or the DMA IRQ when |
---|
314 | using DMA mode. |
---|
315 | The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks |
---|
316 | will be executed respectively at the end of the transmit or Receive process |
---|
317 | The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected |
---|
318 | |
---|
319 | (#) Blocking mode API's are : |
---|
320 | (++) HAL_USART_Transmit()in simplex mode |
---|
321 | (++) HAL_USART_Receive() in full duplex receive only |
---|
322 | (++) HAL_USART_TransmitReceive() in full duplex mode |
---|
323 | |
---|
324 | (#) Non-Blocking mode API's with Interrupt are : |
---|
325 | (++) HAL_USART_Transmit_IT()in simplex mode |
---|
326 | (++) HAL_USART_Receive_IT() in full duplex receive only |
---|
327 | (++) HAL_USART_TransmitReceive_IT()in full duplex mode |
---|
328 | (++) HAL_USART_IRQHandler() |
---|
329 | |
---|
330 | (#) No-Blocking mode functions with DMA are : |
---|
331 | (++) HAL_USART_Transmit_DMA()in simplex mode |
---|
332 | (++) HAL_USART_Receive_DMA() in full duplex receive only |
---|
333 | (++) HAL_USART_TransmitReceive_DMA() in full duplex mode |
---|
334 | (++) HAL_USART_DMAPause() |
---|
335 | (++) HAL_USART_DMAResume() |
---|
336 | (++) HAL_USART_DMAStop() |
---|
337 | |
---|
338 | (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: |
---|
339 | (++) HAL_USART_TxCpltCallback() |
---|
340 | (++) HAL_USART_RxCpltCallback() |
---|
341 | (++) HAL_USART_TxHalfCpltCallback() |
---|
342 | (++) HAL_USART_RxHalfCpltCallback() |
---|
343 | (++) HAL_USART_ErrorCallback() |
---|
344 | (++) HAL_USART_TxRxCpltCallback() |
---|
345 | |
---|
346 | @endverbatim |
---|
347 | * @{ |
---|
348 | */ |
---|
349 | |
---|
350 | /** |
---|
351 | * @brief Simplex Send an amount of data in blocking mode |
---|
352 | * @param husart: USART handle |
---|
353 | * @param pTxData: pointer to data buffer |
---|
354 | * @param Size: amount of data to be sent |
---|
355 | * @param Timeout : Timeout duration |
---|
356 | * @retval HAL status |
---|
357 | */ |
---|
358 | HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout) |
---|
359 | { |
---|
360 | uint16_t* tmp; |
---|
361 | |
---|
362 | if(husart->State == HAL_USART_STATE_READY) |
---|
363 | { |
---|
364 | if((pTxData == NULL) || (Size == 0)) |
---|
365 | { |
---|
366 | return HAL_ERROR; |
---|
367 | } |
---|
368 | |
---|
369 | /* Process Locked */ |
---|
370 | __HAL_LOCK(husart); |
---|
371 | |
---|
372 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
373 | husart->State = HAL_USART_STATE_BUSY_TX; |
---|
374 | |
---|
375 | husart->TxXferSize = Size; |
---|
376 | husart->TxXferCount = Size; |
---|
377 | |
---|
378 | /* Check the remaining data to be sent */ |
---|
379 | while(husart->TxXferCount > 0) |
---|
380 | { |
---|
381 | husart->TxXferCount--; |
---|
382 | if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK) |
---|
383 | { |
---|
384 | return HAL_TIMEOUT; |
---|
385 | } |
---|
386 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
387 | { |
---|
388 | tmp = (uint16_t*) pTxData; |
---|
389 | husart->Instance->TDR = (*tmp & (uint16_t)0x01FF); |
---|
390 | pTxData += 2; |
---|
391 | } |
---|
392 | else |
---|
393 | { |
---|
394 | husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF); |
---|
395 | } |
---|
396 | } |
---|
397 | |
---|
398 | if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK) |
---|
399 | { |
---|
400 | return HAL_TIMEOUT; |
---|
401 | } |
---|
402 | |
---|
403 | husart->State = HAL_USART_STATE_READY; |
---|
404 | |
---|
405 | /* Process Unlocked */ |
---|
406 | __HAL_UNLOCK(husart); |
---|
407 | |
---|
408 | return HAL_OK; |
---|
409 | } |
---|
410 | else |
---|
411 | { |
---|
412 | return HAL_BUSY; |
---|
413 | } |
---|
414 | } |
---|
415 | |
---|
416 | /** |
---|
417 | * @brief Receive an amount of data in blocking mode |
---|
418 | * @note To receive synchronous data, dummy data are simultaneously transmitted |
---|
419 | * @param husart: USART handle |
---|
420 | * @param pRxData: pointer to data buffer |
---|
421 | * @param Size: amount of data to be received |
---|
422 | * @param Timeout : Timeout duration |
---|
423 | * @retval HAL status |
---|
424 | */ |
---|
425 | HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) |
---|
426 | { |
---|
427 | uint16_t* tmp; |
---|
428 | uint16_t uhMask; |
---|
429 | |
---|
430 | if(husart->State == HAL_USART_STATE_READY) |
---|
431 | { |
---|
432 | if((pRxData == NULL) || (Size == 0)) |
---|
433 | { |
---|
434 | return HAL_ERROR; |
---|
435 | } |
---|
436 | /* Process Locked */ |
---|
437 | __HAL_LOCK(husart); |
---|
438 | |
---|
439 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
440 | husart->State = HAL_USART_STATE_BUSY_RX; |
---|
441 | |
---|
442 | husart->RxXferSize = Size; |
---|
443 | husart->RxXferCount = Size; |
---|
444 | |
---|
445 | /* Computation of USART mask to apply to RDR register */ |
---|
446 | __HAL_USART_MASK_COMPUTATION(husart); |
---|
447 | uhMask = husart->Mask; |
---|
448 | |
---|
449 | /* as long as data have to be received */ |
---|
450 | while(husart->RxXferCount > 0) |
---|
451 | { |
---|
452 | husart->RxXferCount--; |
---|
453 | |
---|
454 | /* Wait until TC flag is set to send dummy byte in order to generate the |
---|
455 | * clock for the slave to send data. |
---|
456 | * Whatever the frame length (7, 8 or 9-bit long), the same dummy value |
---|
457 | * can be written for all the cases. */ |
---|
458 | if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK) |
---|
459 | { |
---|
460 | return HAL_TIMEOUT; |
---|
461 | } |
---|
462 | husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FF); |
---|
463 | |
---|
464 | /* Wait for RXNE Flag */ |
---|
465 | if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) |
---|
466 | { |
---|
467 | return HAL_TIMEOUT; |
---|
468 | } |
---|
469 | |
---|
470 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
471 | { |
---|
472 | tmp = (uint16_t*) pRxData ; |
---|
473 | *tmp = (uint16_t)(husart->Instance->RDR & uhMask); |
---|
474 | pRxData +=2; |
---|
475 | } |
---|
476 | else |
---|
477 | { |
---|
478 | *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); |
---|
479 | } |
---|
480 | } |
---|
481 | |
---|
482 | husart->State = HAL_USART_STATE_READY; |
---|
483 | |
---|
484 | /* Process Unlocked */ |
---|
485 | __HAL_UNLOCK(husart); |
---|
486 | |
---|
487 | return HAL_OK; |
---|
488 | } |
---|
489 | else |
---|
490 | { |
---|
491 | return HAL_BUSY; |
---|
492 | } |
---|
493 | } |
---|
494 | |
---|
495 | /** |
---|
496 | * @brief Full-Duplex Send and Receive an amount of data in blocking mode |
---|
497 | * @param husart: USART handle |
---|
498 | * @param pTxData: pointer to TX data buffer |
---|
499 | * @param pRxData: pointer to RX data buffer |
---|
500 | * @param Size: amount of data to be sent (same amount to be received) |
---|
501 | * @param Timeout : Timeout duration |
---|
502 | * @retval HAL status |
---|
503 | */ |
---|
504 | HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) |
---|
505 | { |
---|
506 | uint16_t* tmp; |
---|
507 | uint16_t uhMask; |
---|
508 | |
---|
509 | if(husart->State == HAL_USART_STATE_READY) |
---|
510 | { |
---|
511 | if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) |
---|
512 | { |
---|
513 | return HAL_ERROR; |
---|
514 | } |
---|
515 | /* Process Locked */ |
---|
516 | __HAL_LOCK(husart); |
---|
517 | |
---|
518 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
519 | husart->State = HAL_USART_STATE_BUSY_RX; |
---|
520 | |
---|
521 | husart->RxXferSize = Size; |
---|
522 | husart->TxXferSize = Size; |
---|
523 | husart->TxXferCount = Size; |
---|
524 | husart->RxXferCount = Size; |
---|
525 | |
---|
526 | /* Computation of USART mask to apply to RDR register */ |
---|
527 | __HAL_USART_MASK_COMPUTATION(husart); |
---|
528 | uhMask = husart->Mask; |
---|
529 | |
---|
530 | /* Check the remain data to be sent */ |
---|
531 | while(husart->TxXferCount > 0) |
---|
532 | { |
---|
533 | husart->TxXferCount--; |
---|
534 | husart->RxXferCount--; |
---|
535 | |
---|
536 | /* Wait until TC flag is set to send data */ |
---|
537 | if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK) |
---|
538 | { |
---|
539 | return HAL_TIMEOUT; |
---|
540 | } |
---|
541 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
542 | { |
---|
543 | tmp = (uint16_t*) pTxData; |
---|
544 | husart->Instance->TDR = (*tmp & uhMask); |
---|
545 | pTxData += 2; |
---|
546 | } |
---|
547 | else |
---|
548 | { |
---|
549 | husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask); |
---|
550 | } |
---|
551 | |
---|
552 | /* Wait for RXNE Flag */ |
---|
553 | if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) |
---|
554 | { |
---|
555 | return HAL_TIMEOUT; |
---|
556 | } |
---|
557 | |
---|
558 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
559 | { |
---|
560 | tmp = (uint16_t*) pRxData ; |
---|
561 | *tmp = (uint16_t)(husart->Instance->RDR & uhMask); |
---|
562 | pRxData +=2; |
---|
563 | } |
---|
564 | else |
---|
565 | { |
---|
566 | *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); |
---|
567 | } |
---|
568 | } |
---|
569 | |
---|
570 | husart->State = HAL_USART_STATE_READY; |
---|
571 | |
---|
572 | /* Process Unlocked */ |
---|
573 | __HAL_UNLOCK(husart); |
---|
574 | |
---|
575 | return HAL_OK; |
---|
576 | } |
---|
577 | else |
---|
578 | { |
---|
579 | return HAL_BUSY; |
---|
580 | } |
---|
581 | } |
---|
582 | |
---|
583 | /** |
---|
584 | * @brief Send an amount of data in interrupt mode |
---|
585 | * @param husart: USART handle |
---|
586 | * @param pTxData: pointer to data buffer |
---|
587 | * @param Size: amount of data to be sent |
---|
588 | * @retval HAL status |
---|
589 | */ |
---|
590 | HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) |
---|
591 | { |
---|
592 | if(husart->State == HAL_USART_STATE_READY) |
---|
593 | { |
---|
594 | if((pTxData == NULL ) || (Size == 0)) |
---|
595 | { |
---|
596 | return HAL_ERROR; |
---|
597 | } |
---|
598 | |
---|
599 | /* Process Locked */ |
---|
600 | __HAL_LOCK(husart); |
---|
601 | |
---|
602 | husart->pTxBuffPtr = pTxData; |
---|
603 | husart->TxXferSize = Size; |
---|
604 | husart->TxXferCount = Size; |
---|
605 | |
---|
606 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
607 | husart->State = HAL_USART_STATE_BUSY_TX; |
---|
608 | |
---|
609 | /* The USART Error Interrupts: (Frame error, noise error, overrun error) |
---|
610 | are not managed by the USART Transmit Process to avoid the overrun interrupt |
---|
611 | when the usart mode is configured for transmit and receive "USART_MODE_TX_RX" |
---|
612 | to benefit for the frame error and noise interrupts the usart mode should be |
---|
613 | configured only for transmit "USART_MODE_TX" */ |
---|
614 | |
---|
615 | /* Process Unlocked */ |
---|
616 | __HAL_UNLOCK(husart); |
---|
617 | |
---|
618 | /* Enable the USART Transmit Data Register Empty Interrupt */ |
---|
619 | __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); |
---|
620 | |
---|
621 | return HAL_OK; |
---|
622 | } |
---|
623 | else |
---|
624 | { |
---|
625 | return HAL_BUSY; |
---|
626 | } |
---|
627 | } |
---|
628 | |
---|
629 | /** |
---|
630 | * @brief Receive an amount of data in blocking mode |
---|
631 | * To receive synchronous data, dummy data are simultaneously transmitted |
---|
632 | * @param husart: USART handle |
---|
633 | * @param pRxData: pointer to data buffer |
---|
634 | * @param Size: amount of data to be received |
---|
635 | * @retval HAL status |
---|
636 | */ |
---|
637 | HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) |
---|
638 | { |
---|
639 | if(husart->State == HAL_USART_STATE_READY) |
---|
640 | { |
---|
641 | if((pRxData == NULL ) || (Size == 0)) |
---|
642 | { |
---|
643 | return HAL_ERROR; |
---|
644 | } |
---|
645 | /* Process Locked */ |
---|
646 | __HAL_LOCK(husart); |
---|
647 | |
---|
648 | husart->pRxBuffPtr = pRxData; |
---|
649 | husart->RxXferSize = Size; |
---|
650 | husart->RxXferCount = Size; |
---|
651 | |
---|
652 | __HAL_USART_MASK_COMPUTATION(husart); |
---|
653 | |
---|
654 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
655 | husart->State = HAL_USART_STATE_BUSY_RX; |
---|
656 | |
---|
657 | /* Enable the USART Parity Error Interrupt */ |
---|
658 | __HAL_USART_ENABLE_IT(husart, USART_IT_PE); |
---|
659 | |
---|
660 | /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ |
---|
661 | __HAL_USART_ENABLE_IT(husart, USART_IT_ERR); |
---|
662 | |
---|
663 | /* Enable the USART Data Register not empty Interrupt */ |
---|
664 | __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); |
---|
665 | |
---|
666 | /* Process Unlocked */ |
---|
667 | __HAL_UNLOCK(husart); |
---|
668 | |
---|
669 | |
---|
670 | /* Send dummy byte in order to generate the clock for the Slave to send the next data */ |
---|
671 | if(husart->Init.WordLength == USART_WORDLENGTH_9B) |
---|
672 | { |
---|
673 | husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FF); |
---|
674 | } |
---|
675 | else |
---|
676 | { |
---|
677 | husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF); |
---|
678 | } |
---|
679 | |
---|
680 | return HAL_OK; |
---|
681 | } |
---|
682 | else |
---|
683 | { |
---|
684 | return HAL_BUSY; |
---|
685 | } |
---|
686 | } |
---|
687 | |
---|
688 | /** |
---|
689 | * @brief Full-Duplex Send and Receive an amount of data in interrupt mode |
---|
690 | * @param husart: USART handle |
---|
691 | * @param pTxData: pointer to TX data buffer |
---|
692 | * @param pRxData: pointer to RX data buffer |
---|
693 | * @param Size: amount of data to be sent (same amount to be received) |
---|
694 | * @retval HAL status |
---|
695 | */ |
---|
696 | HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) |
---|
697 | { |
---|
698 | |
---|
699 | if(husart->State == HAL_USART_STATE_READY) |
---|
700 | { |
---|
701 | if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) |
---|
702 | { |
---|
703 | return HAL_ERROR; |
---|
704 | } |
---|
705 | /* Process Locked */ |
---|
706 | __HAL_LOCK(husart); |
---|
707 | |
---|
708 | husart->pRxBuffPtr = pRxData; |
---|
709 | husart->RxXferSize = Size; |
---|
710 | husart->RxXferCount = Size; |
---|
711 | husart->pTxBuffPtr = pTxData; |
---|
712 | husart->TxXferSize = Size; |
---|
713 | husart->TxXferCount = Size; |
---|
714 | |
---|
715 | /* Computation of USART mask to apply to RDR register */ |
---|
716 | __HAL_USART_MASK_COMPUTATION(husart); |
---|
717 | |
---|
718 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
719 | husart->State = HAL_USART_STATE_BUSY_TX_RX; |
---|
720 | |
---|
721 | /* Enable the USART Data Register not empty Interrupt */ |
---|
722 | __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); |
---|
723 | |
---|
724 | /* Enable the USART Parity Error Interrupt */ |
---|
725 | __HAL_USART_ENABLE_IT(husart, USART_IT_PE); |
---|
726 | |
---|
727 | /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ |
---|
728 | __HAL_USART_ENABLE_IT(husart, USART_IT_ERR); |
---|
729 | |
---|
730 | /* Process Unlocked */ |
---|
731 | __HAL_UNLOCK(husart); |
---|
732 | |
---|
733 | /* Enable the USART Transmit Data Register Empty Interrupt */ |
---|
734 | __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); |
---|
735 | |
---|
736 | return HAL_OK; |
---|
737 | } |
---|
738 | else |
---|
739 | { |
---|
740 | return HAL_BUSY; |
---|
741 | } |
---|
742 | |
---|
743 | } |
---|
744 | |
---|
745 | /** |
---|
746 | * @brief Send an amount of data in DMA mode |
---|
747 | * @param husart: USART handle |
---|
748 | * @param pTxData: pointer to data buffer |
---|
749 | * @param Size: amount of data to be sent |
---|
750 | * @retval HAL status |
---|
751 | */ |
---|
752 | HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) |
---|
753 | { |
---|
754 | uint32_t *tmp; |
---|
755 | |
---|
756 | if(husart->State == HAL_USART_STATE_READY) |
---|
757 | { |
---|
758 | if((pTxData == NULL ) || (Size == 0)) |
---|
759 | { |
---|
760 | return HAL_ERROR; |
---|
761 | } |
---|
762 | /* Process Locked */ |
---|
763 | __HAL_LOCK(husart); |
---|
764 | |
---|
765 | husart->pTxBuffPtr = pTxData; |
---|
766 | husart->TxXferSize = Size; |
---|
767 | husart->TxXferCount = Size; |
---|
768 | |
---|
769 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
770 | husart->State = HAL_USART_STATE_BUSY_TX; |
---|
771 | |
---|
772 | /* Set the USART DMA transfer complete callback */ |
---|
773 | husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; |
---|
774 | |
---|
775 | /* Set the USART DMA Half transfer complete callback */ |
---|
776 | husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; |
---|
777 | |
---|
778 | /* Set the DMA error callback */ |
---|
779 | husart->hdmatx->XferErrorCallback = USART_DMAError; |
---|
780 | |
---|
781 | /* Enable the USART transmit DMA channel */ |
---|
782 | tmp = (uint32_t*)&pTxData; |
---|
783 | HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); |
---|
784 | |
---|
785 | |
---|
786 | /* Clear the TC flag in the SR register by writing 0 to it */ |
---|
787 | __HAL_USART_CLEAR_IT(husart, USART_FLAG_TC); |
---|
788 | |
---|
789 | /* Enable the DMA transfer for transmit request by setting the DMAT bit |
---|
790 | in the USART CR3 register */ |
---|
791 | husart->Instance->CR3 |= USART_CR3_DMAT; |
---|
792 | |
---|
793 | /* Process Unlocked */ |
---|
794 | __HAL_UNLOCK(husart); |
---|
795 | |
---|
796 | return HAL_OK; |
---|
797 | } |
---|
798 | else |
---|
799 | { |
---|
800 | return HAL_BUSY; |
---|
801 | } |
---|
802 | } |
---|
803 | |
---|
804 | /** |
---|
805 | * @brief Receive an amount of data in DMA mode |
---|
806 | * @param husart: USART handle |
---|
807 | * @param pRxData: pointer to data buffer |
---|
808 | * @param Size: amount of data to be received |
---|
809 | * @note When the USART parity is enabled (PCE = 1), the received data contain |
---|
810 | * the parity bit (MSB position) |
---|
811 | * @retval HAL status |
---|
812 | * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave. |
---|
813 | */ |
---|
814 | HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) |
---|
815 | { |
---|
816 | uint32_t *tmp; |
---|
817 | |
---|
818 | if(husart->State == HAL_USART_STATE_READY) |
---|
819 | { |
---|
820 | if((pRxData == NULL ) || (Size == 0)) |
---|
821 | { |
---|
822 | return HAL_ERROR; |
---|
823 | } |
---|
824 | |
---|
825 | /* Process Locked */ |
---|
826 | __HAL_LOCK(husart); |
---|
827 | |
---|
828 | husart->pRxBuffPtr = pRxData; |
---|
829 | husart->RxXferSize = Size; |
---|
830 | husart->pTxBuffPtr = pRxData; |
---|
831 | husart->TxXferSize = Size; |
---|
832 | |
---|
833 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
834 | husart->State = HAL_USART_STATE_BUSY_RX; |
---|
835 | |
---|
836 | /* Set the USART DMA Rx transfer complete callback */ |
---|
837 | husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; |
---|
838 | |
---|
839 | /* Set the USART DMA Half transfer complete callback */ |
---|
840 | husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; |
---|
841 | |
---|
842 | /* Set the USART DMA Rx transfer error callback */ |
---|
843 | husart->hdmarx->XferErrorCallback = USART_DMAError; |
---|
844 | |
---|
845 | /* Enable the USART receive DMA channel */ |
---|
846 | tmp = (uint32_t*)&pRxData; |
---|
847 | HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size); |
---|
848 | |
---|
849 | /* Enable the USART transmit DMA channel: the transmit stream is used in order |
---|
850 | to generate in the non-blocking mode the clock to the slave device, |
---|
851 | this mode isn't a simplex receive mode but a full-duplex receive mode */ |
---|
852 | tmp = (uint32_t*)&pRxData; |
---|
853 | HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); |
---|
854 | |
---|
855 | /* Enable the DMA transfer for the receiver request by setting the DMAR bit |
---|
856 | in the USART CR3 register */ |
---|
857 | husart->Instance->CR3 |= USART_CR3_DMAR; |
---|
858 | |
---|
859 | /* Enable the DMA transfer for transmit request by setting the DMAT bit |
---|
860 | in the USART CR3 register */ |
---|
861 | husart->Instance->CR3 |= USART_CR3_DMAT; |
---|
862 | |
---|
863 | /* Process Unlocked */ |
---|
864 | __HAL_UNLOCK(husart); |
---|
865 | |
---|
866 | return HAL_OK; |
---|
867 | } |
---|
868 | else |
---|
869 | { |
---|
870 | return HAL_BUSY; |
---|
871 | } |
---|
872 | } |
---|
873 | |
---|
874 | /** |
---|
875 | * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode |
---|
876 | * @param husart: USART handle |
---|
877 | * @param pTxData: pointer to TX data buffer |
---|
878 | * @param pRxData: pointer to RX data buffer |
---|
879 | * @param Size: amount of data to be received/sent |
---|
880 | * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. |
---|
881 | * @retval HAL status |
---|
882 | */ |
---|
883 | HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) |
---|
884 | { |
---|
885 | uint32_t *tmp; |
---|
886 | |
---|
887 | if(husart->State == HAL_USART_STATE_READY) |
---|
888 | { |
---|
889 | if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) |
---|
890 | { |
---|
891 | return HAL_ERROR; |
---|
892 | } |
---|
893 | /* Process Locked */ |
---|
894 | __HAL_LOCK(husart); |
---|
895 | |
---|
896 | husart->pRxBuffPtr = pRxData; |
---|
897 | husart->RxXferSize = Size; |
---|
898 | husart->pTxBuffPtr = pTxData; |
---|
899 | husart->TxXferSize = Size; |
---|
900 | |
---|
901 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
902 | husart->State = HAL_USART_STATE_BUSY_TX_RX; |
---|
903 | |
---|
904 | /* Set the USART DMA Rx transfer complete callback */ |
---|
905 | husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; |
---|
906 | |
---|
907 | /* Set the USART DMA Half transfer complete callback */ |
---|
908 | husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; |
---|
909 | |
---|
910 | /* Set the USART DMA Tx transfer complete callback */ |
---|
911 | husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; |
---|
912 | |
---|
913 | /* Set the USART DMA Half transfer complete callback */ |
---|
914 | husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; |
---|
915 | |
---|
916 | /* Set the USART DMA Tx transfer error callback */ |
---|
917 | husart->hdmatx->XferErrorCallback = USART_DMAError; |
---|
918 | |
---|
919 | /* Set the USART DMA Rx transfer error callback */ |
---|
920 | husart->hdmarx->XferErrorCallback = USART_DMAError; |
---|
921 | |
---|
922 | /* Enable the USART receive DMA channel */ |
---|
923 | tmp = (uint32_t*)&pRxData; |
---|
924 | HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size); |
---|
925 | |
---|
926 | /* Enable the USART transmit DMA channel */ |
---|
927 | tmp = (uint32_t*)&pTxData; |
---|
928 | HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); |
---|
929 | |
---|
930 | /* Clear the TC flag in the SR register by writing 0 to it */ |
---|
931 | __HAL_USART_CLEAR_IT(husart, USART_FLAG_TC); |
---|
932 | |
---|
933 | /* Enable the DMA transfer for the receiver request by setting the DMAR bit |
---|
934 | in the USART CR3 register */ |
---|
935 | husart->Instance->CR3 |= USART_CR3_DMAR; |
---|
936 | |
---|
937 | /* Enable the DMA transfer for transmit request by setting the DMAT bit |
---|
938 | in the USART CR3 register */ |
---|
939 | husart->Instance->CR3 |= USART_CR3_DMAT; |
---|
940 | |
---|
941 | /* Process Unlocked */ |
---|
942 | __HAL_UNLOCK(husart); |
---|
943 | |
---|
944 | return HAL_OK; |
---|
945 | } |
---|
946 | else |
---|
947 | { |
---|
948 | return HAL_BUSY; |
---|
949 | } |
---|
950 | } |
---|
951 | |
---|
952 | /** |
---|
953 | * @brief Pauses the DMA Transfer. |
---|
954 | * @param husart: USART handle |
---|
955 | * @retval None |
---|
956 | */ |
---|
957 | HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart) |
---|
958 | { |
---|
959 | /* Process Locked */ |
---|
960 | __HAL_LOCK(husart); |
---|
961 | |
---|
962 | if(husart->State == HAL_USART_STATE_BUSY_TX) |
---|
963 | { |
---|
964 | /* Disable the USART DMA Tx request */ |
---|
965 | husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); |
---|
966 | } |
---|
967 | else if(husart->State == HAL_USART_STATE_BUSY_RX) |
---|
968 | { |
---|
969 | /* Disable the USART DMA Rx request */ |
---|
970 | husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); |
---|
971 | } |
---|
972 | else if(husart->State == HAL_USART_STATE_BUSY_TX_RX) |
---|
973 | { |
---|
974 | /* Disable the USART DMA Tx request */ |
---|
975 | husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); |
---|
976 | /* Disable the USART DMA Rx request */ |
---|
977 | husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); |
---|
978 | } |
---|
979 | |
---|
980 | /* Process Unlocked */ |
---|
981 | __HAL_UNLOCK(husart); |
---|
982 | |
---|
983 | return HAL_OK; |
---|
984 | } |
---|
985 | |
---|
986 | /** |
---|
987 | * @brief Resumes the DMA Transfer. |
---|
988 | * @param husart: USART handle |
---|
989 | * @retval None |
---|
990 | */ |
---|
991 | HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) |
---|
992 | { |
---|
993 | /* Process Locked */ |
---|
994 | __HAL_LOCK(husart); |
---|
995 | |
---|
996 | if(husart->State == HAL_USART_STATE_BUSY_TX) |
---|
997 | { |
---|
998 | /* Enable the USART DMA Tx request */ |
---|
999 | husart->Instance->CR3 |= USART_CR3_DMAT; |
---|
1000 | } |
---|
1001 | else if(husart->State == HAL_USART_STATE_BUSY_RX) |
---|
1002 | { |
---|
1003 | /* Clear the Overrun flag before resuming the Rx transfer*/ |
---|
1004 | __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); |
---|
1005 | |
---|
1006 | /* Enable the USART DMA Rx request */ |
---|
1007 | husart->Instance->CR3 |= USART_CR3_DMAR; |
---|
1008 | } |
---|
1009 | else if(husart->State == HAL_USART_STATE_BUSY_TX_RX) |
---|
1010 | { |
---|
1011 | /* Clear the Overrun flag before resuming the Rx transfer*/ |
---|
1012 | __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); |
---|
1013 | |
---|
1014 | /* Enable the USART DMA Rx request before the DMA Tx request */ |
---|
1015 | husart->Instance->CR3 |= USART_CR3_DMAR; |
---|
1016 | |
---|
1017 | /* Enable the USART DMA Tx request */ |
---|
1018 | husart->Instance->CR3 |= USART_CR3_DMAT; |
---|
1019 | } |
---|
1020 | |
---|
1021 | /* Process Unlocked */ |
---|
1022 | __HAL_UNLOCK(husart); |
---|
1023 | |
---|
1024 | return HAL_OK; |
---|
1025 | } |
---|
1026 | |
---|
1027 | /** |
---|
1028 | * @brief Stops the DMA Transfer. |
---|
1029 | * @param husart: USART handle |
---|
1030 | * @retval None |
---|
1031 | */ |
---|
1032 | HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart) |
---|
1033 | { |
---|
1034 | /* The Lock is not implemented on this API to allow the user application |
---|
1035 | to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() / |
---|
1036 | HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback: |
---|
1037 | indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete |
---|
1038 | interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of |
---|
1039 | the stream and the corresponding call back is executed. */ |
---|
1040 | |
---|
1041 | /* Disable the USART Tx/Rx DMA requests */ |
---|
1042 | husart->Instance->CR3 &= ~USART_CR3_DMAT; |
---|
1043 | husart->Instance->CR3 &= ~USART_CR3_DMAR; |
---|
1044 | |
---|
1045 | /* Abort the USART DMA tx Stream */ |
---|
1046 | if(husart->hdmatx != NULL) |
---|
1047 | { |
---|
1048 | HAL_DMA_Abort(husart->hdmatx); |
---|
1049 | } |
---|
1050 | /* Abort the USART DMA rx Stream */ |
---|
1051 | if(husart->hdmarx != NULL) |
---|
1052 | { |
---|
1053 | HAL_DMA_Abort(husart->hdmarx); |
---|
1054 | } |
---|
1055 | |
---|
1056 | husart->State = HAL_USART_STATE_READY; |
---|
1057 | |
---|
1058 | return HAL_OK; |
---|
1059 | } |
---|
1060 | |
---|
1061 | /** |
---|
1062 | * @brief This function handles USART interrupt request. |
---|
1063 | * @param husart: USART handle |
---|
1064 | * @retval None |
---|
1065 | */ |
---|
1066 | void HAL_USART_IRQHandler(USART_HandleTypeDef *husart) |
---|
1067 | { |
---|
1068 | |
---|
1069 | /* USART parity error interrupt occurred ------------------------------------*/ |
---|
1070 | if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET)) |
---|
1071 | { |
---|
1072 | __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF); |
---|
1073 | husart->ErrorCode |= HAL_USART_ERROR_PE; |
---|
1074 | /* Set the USART state ready to be able to start again the process */ |
---|
1075 | husart->State = HAL_USART_STATE_READY; |
---|
1076 | } |
---|
1077 | |
---|
1078 | /* USART frame error interrupt occurred -------------------------------------*/ |
---|
1079 | if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET)) |
---|
1080 | { |
---|
1081 | __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF); |
---|
1082 | husart->ErrorCode |= HAL_USART_ERROR_FE; |
---|
1083 | /* Set the USART state ready to be able to start again the process */ |
---|
1084 | husart->State = HAL_USART_STATE_READY; |
---|
1085 | } |
---|
1086 | |
---|
1087 | /* USART noise error interrupt occurred -------------------------------------*/ |
---|
1088 | if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET)) |
---|
1089 | { |
---|
1090 | __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF); |
---|
1091 | husart->ErrorCode |= HAL_USART_ERROR_NE; |
---|
1092 | /* Set the USART state ready to be able to start again the process */ |
---|
1093 | husart->State = HAL_USART_STATE_READY; |
---|
1094 | } |
---|
1095 | |
---|
1096 | /* USART Over-Run interrupt occurred ----------------------------------------*/ |
---|
1097 | if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET)) |
---|
1098 | { |
---|
1099 | __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); |
---|
1100 | husart->ErrorCode |= HAL_USART_ERROR_ORE; |
---|
1101 | /* Set the USART state ready to be able to start again the process */ |
---|
1102 | husart->State = HAL_USART_STATE_READY; |
---|
1103 | } |
---|
1104 | |
---|
1105 | /* Call USART Error Call back function if need be --------------------------*/ |
---|
1106 | if(husart->ErrorCode != HAL_USART_ERROR_NONE) |
---|
1107 | { |
---|
1108 | HAL_USART_ErrorCallback(husart); |
---|
1109 | } |
---|
1110 | |
---|
1111 | /* USART in mode Receiver --------------------------------------------------*/ |
---|
1112 | if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET)) |
---|
1113 | { |
---|
1114 | if(husart->State == HAL_USART_STATE_BUSY_RX) |
---|
1115 | { |
---|
1116 | USART_Receive_IT(husart); |
---|
1117 | } |
---|
1118 | else |
---|
1119 | { |
---|
1120 | USART_TransmitReceive_IT(husart); |
---|
1121 | } |
---|
1122 | } |
---|
1123 | |
---|
1124 | /* USART in mode Transmitter -----------------------------------------------*/ |
---|
1125 | if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET)) |
---|
1126 | { |
---|
1127 | if(husart->State == HAL_USART_STATE_BUSY_TX) |
---|
1128 | { |
---|
1129 | USART_Transmit_IT(husart); |
---|
1130 | } |
---|
1131 | else |
---|
1132 | { |
---|
1133 | USART_TransmitReceive_IT(husart); |
---|
1134 | } |
---|
1135 | } |
---|
1136 | |
---|
1137 | /* USART in mode Transmitter (transmission end) -----------------------------*/ |
---|
1138 | if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET)) |
---|
1139 | { |
---|
1140 | USART_EndTransmit_IT(husart); |
---|
1141 | } |
---|
1142 | |
---|
1143 | } |
---|
1144 | |
---|
1145 | /** |
---|
1146 | * @brief Tx Transfer completed callbacks |
---|
1147 | * @param husart: USART handle |
---|
1148 | * @retval None |
---|
1149 | */ |
---|
1150 | __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) |
---|
1151 | { |
---|
1152 | /* NOTE : This function should not be modified, when the callback is needed, |
---|
1153 | the HAL_USART_TxCpltCallback can be implemented in the user file |
---|
1154 | */ |
---|
1155 | } |
---|
1156 | |
---|
1157 | /** |
---|
1158 | * @brief Tx Half Transfer completed callbacks. |
---|
1159 | * @param husart: USART handle |
---|
1160 | * @retval None |
---|
1161 | */ |
---|
1162 | __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart) |
---|
1163 | { |
---|
1164 | /* NOTE: This function should not be modified, when the callback is needed, |
---|
1165 | the HAL_USART_TxHalfCpltCallback can be implemented in the user file |
---|
1166 | */ |
---|
1167 | } |
---|
1168 | |
---|
1169 | /** |
---|
1170 | * @brief Rx Transfer completed callbacks. |
---|
1171 | * @param husart: USART handle |
---|
1172 | * @retval None |
---|
1173 | */ |
---|
1174 | __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) |
---|
1175 | { |
---|
1176 | /* NOTE: This function should not be modified, when the callback is needed, |
---|
1177 | the HAL_USART_RxCpltCallback can be implemented in the user file |
---|
1178 | */ |
---|
1179 | } |
---|
1180 | |
---|
1181 | /** |
---|
1182 | * @brief Rx Half Transfer completed callbacks |
---|
1183 | * @param husart: usart handle |
---|
1184 | * @retval None |
---|
1185 | */ |
---|
1186 | __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart) |
---|
1187 | { |
---|
1188 | /* NOTE : This function should not be modified, when the callback is needed, |
---|
1189 | the HAL_USART_RxHalfCpltCallback can be implemented in the user file |
---|
1190 | */ |
---|
1191 | } |
---|
1192 | |
---|
1193 | /** |
---|
1194 | * @brief Tx/Rx Transfers completed callback for the non-blocking process |
---|
1195 | * @param husart: USART handle |
---|
1196 | * @retval None |
---|
1197 | */ |
---|
1198 | __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart) |
---|
1199 | { |
---|
1200 | /* NOTE : This function should not be modified, when the callback is needed, |
---|
1201 | the HAL_USART_TxRxCpltCallback can be implemented in the user file |
---|
1202 | */ |
---|
1203 | } |
---|
1204 | |
---|
1205 | /** |
---|
1206 | * @brief USART error callbacks |
---|
1207 | * @param husart: USART handle |
---|
1208 | * @retval None |
---|
1209 | */ |
---|
1210 | __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart) |
---|
1211 | { |
---|
1212 | /* NOTE : This function should not be modified, when the callback is needed, |
---|
1213 | the HAL_USART_ErrorCallback can be implemented in the user file |
---|
1214 | */ |
---|
1215 | } |
---|
1216 | |
---|
1217 | /** |
---|
1218 | * @} |
---|
1219 | */ |
---|
1220 | |
---|
1221 | /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions |
---|
1222 | * @brief USART State and Errors functions |
---|
1223 | * |
---|
1224 | @verbatim |
---|
1225 | ============================================================================== |
---|
1226 | ##### Peripheral State and Errors functions ##### |
---|
1227 | ============================================================================== |
---|
1228 | [..] |
---|
1229 | This subsection provides a set of functions allowing to return the State of |
---|
1230 | USART communication |
---|
1231 | process, return Peripheral Errors occurred during communication process |
---|
1232 | (+) HAL_USART_GetState() API can be helpful to check in run-time the state |
---|
1233 | of the USART peripheral. |
---|
1234 | (+) HAL_USART_GetError() check in run-time errors that could be occurred during |
---|
1235 | communication. |
---|
1236 | @endverbatim |
---|
1237 | * @{ |
---|
1238 | */ |
---|
1239 | |
---|
1240 | /** |
---|
1241 | * @brief return the USART state |
---|
1242 | * @param husart: USART handle |
---|
1243 | * @retval HAL state |
---|
1244 | */ |
---|
1245 | HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart) |
---|
1246 | { |
---|
1247 | return husart->State; |
---|
1248 | } |
---|
1249 | |
---|
1250 | /** |
---|
1251 | * @brief Return the USART error code |
---|
1252 | * @param husart : pointer to a USART_HandleTypeDef structure that contains |
---|
1253 | * the configuration information for the specified USART. |
---|
1254 | * @retval USART Error Code |
---|
1255 | */ |
---|
1256 | uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart) |
---|
1257 | { |
---|
1258 | return husart->ErrorCode; |
---|
1259 | } |
---|
1260 | |
---|
1261 | /** |
---|
1262 | * @} |
---|
1263 | */ |
---|
1264 | |
---|
1265 | |
---|
1266 | /** |
---|
1267 | * @brief Simplex Send an amount of data in non-blocking mode. |
---|
1268 | * @note Function called under interruption only, once |
---|
1269 | * interruptions have been enabled by HAL_USART_Transmit_IT(). |
---|
1270 | * @param husart: USART handle |
---|
1271 | * @retval HAL status |
---|
1272 | * @note The USART errors are not managed to avoid the overrun error. |
---|
1273 | */ |
---|
1274 | static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart) |
---|
1275 | { |
---|
1276 | uint16_t* tmp; |
---|
1277 | |
---|
1278 | if(husart->State == HAL_USART_STATE_BUSY_TX) |
---|
1279 | { |
---|
1280 | |
---|
1281 | if(husart->TxXferCount == 0) |
---|
1282 | { |
---|
1283 | /* Disable the USART Transmit Complete Interrupt */ |
---|
1284 | __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); |
---|
1285 | |
---|
1286 | /* Enable the USART Transmit Complete Interrupt */ |
---|
1287 | __HAL_USART_ENABLE_IT(husart, USART_IT_TC); |
---|
1288 | |
---|
1289 | return HAL_OK; |
---|
1290 | } |
---|
1291 | else |
---|
1292 | { |
---|
1293 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
1294 | { |
---|
1295 | tmp = (uint16_t*) husart->pTxBuffPtr; |
---|
1296 | husart->Instance->TDR = (*tmp & (uint16_t)0x01FF); |
---|
1297 | husart->pTxBuffPtr += 2; |
---|
1298 | } |
---|
1299 | else |
---|
1300 | { |
---|
1301 | husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF); |
---|
1302 | } |
---|
1303 | |
---|
1304 | husart->TxXferCount--; |
---|
1305 | |
---|
1306 | return HAL_OK; |
---|
1307 | } |
---|
1308 | } |
---|
1309 | else |
---|
1310 | { |
---|
1311 | return HAL_BUSY; |
---|
1312 | } |
---|
1313 | } |
---|
1314 | |
---|
1315 | /** |
---|
1316 | * @brief Wraps up transmission in non-blocking mode. |
---|
1317 | * @param husart: pointer to a USART_HandleTypeDef structure that contains |
---|
1318 | * the configuration information for the specified USART module. |
---|
1319 | * @retval HAL status |
---|
1320 | */ |
---|
1321 | static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart) |
---|
1322 | { |
---|
1323 | /* Disable the USART Transmit Complete Interrupt */ |
---|
1324 | __HAL_USART_DISABLE_IT(husart, USART_IT_TC); |
---|
1325 | |
---|
1326 | /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ |
---|
1327 | __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); |
---|
1328 | |
---|
1329 | husart->State = HAL_USART_STATE_READY; |
---|
1330 | |
---|
1331 | HAL_USART_TxCpltCallback(husart); |
---|
1332 | |
---|
1333 | return HAL_OK; |
---|
1334 | } |
---|
1335 | |
---|
1336 | /** |
---|
1337 | * @brief Simplex Receive an amount of data in non-blocking mode. |
---|
1338 | * Function called under interruption only, once |
---|
1339 | * interruptions have been enabled by HAL_USART_Receive_IT() |
---|
1340 | * @param husart: USART handle |
---|
1341 | * @retval HAL status |
---|
1342 | */ |
---|
1343 | static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart) |
---|
1344 | { |
---|
1345 | uint16_t* tmp; |
---|
1346 | uint16_t uhMask = husart->Mask; |
---|
1347 | |
---|
1348 | if(husart->State == HAL_USART_STATE_BUSY_RX) |
---|
1349 | { |
---|
1350 | |
---|
1351 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
1352 | { |
---|
1353 | tmp = (uint16_t*) husart->pRxBuffPtr; |
---|
1354 | *tmp = (uint16_t)(husart->Instance->RDR & uhMask); |
---|
1355 | husart->pRxBuffPtr += 2; |
---|
1356 | } |
---|
1357 | else |
---|
1358 | { |
---|
1359 | *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); |
---|
1360 | } |
---|
1361 | /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ |
---|
1362 | husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF); |
---|
1363 | |
---|
1364 | if(--husart->RxXferCount == 0) |
---|
1365 | { |
---|
1366 | __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); |
---|
1367 | |
---|
1368 | /* Disable the USART Parity Error Interrupt */ |
---|
1369 | __HAL_USART_DISABLE_IT(husart, USART_IT_PE); |
---|
1370 | |
---|
1371 | /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ |
---|
1372 | __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); |
---|
1373 | |
---|
1374 | husart->State = HAL_USART_STATE_READY; |
---|
1375 | |
---|
1376 | HAL_USART_RxCpltCallback(husart); |
---|
1377 | |
---|
1378 | return HAL_OK; |
---|
1379 | } |
---|
1380 | |
---|
1381 | return HAL_OK; |
---|
1382 | } |
---|
1383 | else |
---|
1384 | { |
---|
1385 | return HAL_BUSY; |
---|
1386 | } |
---|
1387 | } |
---|
1388 | |
---|
1389 | /** |
---|
1390 | * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking). |
---|
1391 | * Function called under interruption only, once |
---|
1392 | * interruptions have been enabled by HAL_USART_TransmitReceive_IT() |
---|
1393 | * @param husart: USART handle |
---|
1394 | * @retval HAL status |
---|
1395 | */ |
---|
1396 | static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart) |
---|
1397 | { |
---|
1398 | uint16_t* tmp; |
---|
1399 | uint16_t uhMask = husart->Mask; |
---|
1400 | |
---|
1401 | if(husart->State == HAL_USART_STATE_BUSY_TX_RX) |
---|
1402 | { |
---|
1403 | if(husart->TxXferCount != 0x00) |
---|
1404 | { |
---|
1405 | if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET) |
---|
1406 | { |
---|
1407 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
1408 | { |
---|
1409 | tmp = (uint16_t*) husart->pTxBuffPtr; |
---|
1410 | husart->Instance->TDR = (uint16_t)(*tmp & uhMask); |
---|
1411 | husart->pTxBuffPtr += 2; |
---|
1412 | } |
---|
1413 | else |
---|
1414 | { |
---|
1415 | husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask); |
---|
1416 | } |
---|
1417 | husart->TxXferCount--; |
---|
1418 | |
---|
1419 | /* Check the latest data transmitted */ |
---|
1420 | if(husart->TxXferCount == 0) |
---|
1421 | { |
---|
1422 | __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); |
---|
1423 | } |
---|
1424 | } |
---|
1425 | } |
---|
1426 | |
---|
1427 | if(husart->RxXferCount != 0x00) |
---|
1428 | { |
---|
1429 | if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET) |
---|
1430 | { |
---|
1431 | if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) |
---|
1432 | { |
---|
1433 | tmp = (uint16_t*) husart->pRxBuffPtr; |
---|
1434 | *tmp = (uint16_t)(husart->Instance->RDR & uhMask); |
---|
1435 | husart->pRxBuffPtr += 2; |
---|
1436 | } |
---|
1437 | else |
---|
1438 | { |
---|
1439 | *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); |
---|
1440 | } |
---|
1441 | husart->RxXferCount--; |
---|
1442 | } |
---|
1443 | } |
---|
1444 | |
---|
1445 | /* Check the latest data received */ |
---|
1446 | if(husart->RxXferCount == 0) |
---|
1447 | { |
---|
1448 | __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); |
---|
1449 | |
---|
1450 | /* Disable the USART Parity Error Interrupt */ |
---|
1451 | __HAL_USART_DISABLE_IT(husart, USART_IT_PE); |
---|
1452 | |
---|
1453 | /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ |
---|
1454 | __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); |
---|
1455 | |
---|
1456 | husart->State = HAL_USART_STATE_READY; |
---|
1457 | |
---|
1458 | HAL_USART_TxRxCpltCallback(husart); |
---|
1459 | |
---|
1460 | return HAL_OK; |
---|
1461 | } |
---|
1462 | |
---|
1463 | return HAL_OK; |
---|
1464 | } |
---|
1465 | else |
---|
1466 | { |
---|
1467 | return HAL_BUSY; |
---|
1468 | } |
---|
1469 | } |
---|
1470 | |
---|
1471 | /** |
---|
1472 | * @brief This function handles USART Communication Timeout. |
---|
1473 | * @param husart: USART handle |
---|
1474 | * @param Flag: specifies the USART flag to check. |
---|
1475 | * @param Status: The new Flag status (SET or RESET). |
---|
1476 | * @param Timeout: Timeout duration |
---|
1477 | * @retval HAL status |
---|
1478 | */ |
---|
1479 | static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) |
---|
1480 | { |
---|
1481 | uint32_t tickstart = HAL_GetTick(); |
---|
1482 | |
---|
1483 | /* Wait until flag is set */ |
---|
1484 | if(Status == RESET) |
---|
1485 | { |
---|
1486 | while(__HAL_USART_GET_FLAG(husart, Flag) == RESET) |
---|
1487 | { |
---|
1488 | /* Check for the Timeout */ |
---|
1489 | if(Timeout != HAL_MAX_DELAY) |
---|
1490 | { |
---|
1491 | if((Timeout == 0)||((HAL_GetTick()-tickstart) >= Timeout)) |
---|
1492 | { |
---|
1493 | /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ |
---|
1494 | __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); |
---|
1495 | __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); |
---|
1496 | __HAL_USART_DISABLE_IT(husart, USART_IT_PE); |
---|
1497 | __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); |
---|
1498 | |
---|
1499 | husart->State= HAL_USART_STATE_READY; |
---|
1500 | |
---|
1501 | /* Process Unlocked */ |
---|
1502 | __HAL_UNLOCK(husart); |
---|
1503 | |
---|
1504 | return HAL_TIMEOUT; |
---|
1505 | } |
---|
1506 | } |
---|
1507 | } |
---|
1508 | } |
---|
1509 | else |
---|
1510 | { |
---|
1511 | while(__HAL_USART_GET_FLAG(husart, Flag) != RESET) |
---|
1512 | { |
---|
1513 | /* Check for the Timeout */ |
---|
1514 | if(Timeout != HAL_MAX_DELAY) |
---|
1515 | { |
---|
1516 | if((Timeout == 0)||((HAL_GetTick()-tickstart) >= Timeout)) |
---|
1517 | { |
---|
1518 | /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ |
---|
1519 | __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); |
---|
1520 | __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); |
---|
1521 | __HAL_USART_DISABLE_IT(husart, USART_IT_PE); |
---|
1522 | __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); |
---|
1523 | |
---|
1524 | husart->State= HAL_USART_STATE_READY; |
---|
1525 | |
---|
1526 | /* Process Unlocked */ |
---|
1527 | __HAL_UNLOCK(husart); |
---|
1528 | |
---|
1529 | return HAL_TIMEOUT; |
---|
1530 | } |
---|
1531 | } |
---|
1532 | } |
---|
1533 | } |
---|
1534 | return HAL_OK; |
---|
1535 | } |
---|
1536 | |
---|
1537 | |
---|
1538 | /** |
---|
1539 | * @brief DMA USART transmit process complete callback |
---|
1540 | * @param hdma: DMA handle |
---|
1541 | * @retval None |
---|
1542 | */ |
---|
1543 | static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) |
---|
1544 | { |
---|
1545 | USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
---|
1546 | |
---|
1547 | /* DMA Normal mode */ |
---|
1548 | if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) |
---|
1549 | { |
---|
1550 | husart->TxXferCount = 0; |
---|
1551 | |
---|
1552 | if(husart->State == HAL_USART_STATE_BUSY_TX) |
---|
1553 | { |
---|
1554 | /* Disable the DMA transfer for transmit request by resetting the DMAT bit |
---|
1555 | in the USART CR3 register */ |
---|
1556 | husart->Instance->CR3 &= ~(USART_CR3_DMAT); |
---|
1557 | |
---|
1558 | /* Enable the USART Transmit Complete Interrupt */ |
---|
1559 | __HAL_USART_ENABLE_IT(husart, USART_IT_TC); |
---|
1560 | } |
---|
1561 | } |
---|
1562 | /* DMA Circular mode */ |
---|
1563 | else |
---|
1564 | { |
---|
1565 | if(husart->State == HAL_USART_STATE_BUSY_TX) |
---|
1566 | { |
---|
1567 | HAL_USART_TxCpltCallback(husart); |
---|
1568 | } |
---|
1569 | } |
---|
1570 | } |
---|
1571 | |
---|
1572 | |
---|
1573 | /** |
---|
1574 | * @brief DMA USART transmit process half complete callback |
---|
1575 | * @param hdma : DMA handle |
---|
1576 | * @retval None |
---|
1577 | */ |
---|
1578 | static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) |
---|
1579 | { |
---|
1580 | USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; |
---|
1581 | |
---|
1582 | HAL_USART_TxHalfCpltCallback(husart); |
---|
1583 | } |
---|
1584 | |
---|
1585 | /** |
---|
1586 | * @brief DMA USART receive process complete callback |
---|
1587 | * @param hdma: DMA handle |
---|
1588 | * @retval None |
---|
1589 | */ |
---|
1590 | static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) |
---|
1591 | { |
---|
1592 | USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
---|
1593 | |
---|
1594 | /* DMA Normal mode */ |
---|
1595 | if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) |
---|
1596 | { |
---|
1597 | husart->RxXferCount = 0; |
---|
1598 | |
---|
1599 | /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit |
---|
1600 | in USART CR3 register */ |
---|
1601 | husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); |
---|
1602 | /* similarly, disable the DMA TX transfer that was started to provide the |
---|
1603 | clock to the slave device */ |
---|
1604 | husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); |
---|
1605 | |
---|
1606 | if(husart->State == HAL_USART_STATE_BUSY_RX) |
---|
1607 | { |
---|
1608 | HAL_USART_RxCpltCallback(husart); |
---|
1609 | } |
---|
1610 | /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ |
---|
1611 | else |
---|
1612 | { |
---|
1613 | HAL_USART_TxRxCpltCallback(husart); |
---|
1614 | } |
---|
1615 | husart->State= HAL_USART_STATE_READY; |
---|
1616 | } |
---|
1617 | /* DMA circular mode */ |
---|
1618 | else |
---|
1619 | { |
---|
1620 | if(husart->State == HAL_USART_STATE_BUSY_RX) |
---|
1621 | { |
---|
1622 | HAL_USART_RxCpltCallback(husart); |
---|
1623 | } |
---|
1624 | /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ |
---|
1625 | else |
---|
1626 | { |
---|
1627 | HAL_USART_TxRxCpltCallback(husart); |
---|
1628 | } |
---|
1629 | } |
---|
1630 | } |
---|
1631 | |
---|
1632 | /** |
---|
1633 | * @brief DMA USART receive process half complete callback |
---|
1634 | * @param hdma : DMA handle |
---|
1635 | * @retval None |
---|
1636 | */ |
---|
1637 | static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) |
---|
1638 | { |
---|
1639 | USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; |
---|
1640 | |
---|
1641 | HAL_USART_RxHalfCpltCallback(husart); |
---|
1642 | } |
---|
1643 | |
---|
1644 | /** |
---|
1645 | * @brief DMA USART communication error callback |
---|
1646 | * @param hdma: DMA handle |
---|
1647 | * @retval None |
---|
1648 | */ |
---|
1649 | static void USART_DMAError(DMA_HandleTypeDef *hdma) |
---|
1650 | { |
---|
1651 | USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
---|
1652 | |
---|
1653 | husart->RxXferCount = 0; |
---|
1654 | husart->TxXferCount = 0; |
---|
1655 | husart->ErrorCode |= HAL_USART_ERROR_DMA; |
---|
1656 | husart->State= HAL_USART_STATE_READY; |
---|
1657 | |
---|
1658 | HAL_USART_ErrorCallback(husart); |
---|
1659 | } |
---|
1660 | |
---|
1661 | /** |
---|
1662 | * @brief Configure the USART peripheral |
---|
1663 | * @param husart: USART handle |
---|
1664 | * @retval None |
---|
1665 | */ |
---|
1666 | static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart) |
---|
1667 | { |
---|
1668 | uint32_t tmpreg = 0x0; |
---|
1669 | USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED; |
---|
1670 | HAL_StatusTypeDef ret = HAL_OK; |
---|
1671 | uint16_t brrtemp = 0x0000; |
---|
1672 | uint16_t usartdiv = 0x0000; |
---|
1673 | |
---|
1674 | /* Check the parameters */ |
---|
1675 | assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity)); |
---|
1676 | assert_param(IS_USART_PHASE(husart->Init.CLKPhase)); |
---|
1677 | assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit)); |
---|
1678 | assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate)); |
---|
1679 | assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength)); |
---|
1680 | assert_param(IS_USART_STOPBITS(husart->Init.StopBits)); |
---|
1681 | assert_param(IS_USART_PARITY(husart->Init.Parity)); |
---|
1682 | assert_param(IS_USART_MODE(husart->Init.Mode)); |
---|
1683 | assert_param(IS_USART_OVERSAMPLING(husart->Init.OverSampling)); |
---|
1684 | |
---|
1685 | |
---|
1686 | /*-------------------------- USART CR1 Configuration -----------------------*/ |
---|
1687 | /* Clear M, PCE, PS, TE and RE bits and configure |
---|
1688 | * the USART Word Length, Parity, Mode and OverSampling: |
---|
1689 | * set the M bits according to husart->Init.WordLength value |
---|
1690 | * set PCE and PS bits according to husart->Init.Parity value |
---|
1691 | * set TE and RE bits according to husart->Init.Mode value |
---|
1692 | * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */ |
---|
1693 | tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; |
---|
1694 | MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); |
---|
1695 | |
---|
1696 | /*---------------------------- USART CR2 Configuration ---------------------*/ |
---|
1697 | /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits: |
---|
1698 | * set CPOL bit according to husart->Init.CLKPolarity value |
---|
1699 | * set CPHA bit according to husart->Init.CLKPhase value |
---|
1700 | * set LBCL bit according to husart->Init.CLKLastBit value |
---|
1701 | * set STOP[13:12] bits according to husart->Init.StopBits value */ |
---|
1702 | tmpreg = (uint32_t)(USART_CLOCK_ENABLE); |
---|
1703 | tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase); |
---|
1704 | tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits); |
---|
1705 | MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); |
---|
1706 | |
---|
1707 | /*-------------------------- USART CR3 Configuration -----------------------*/ |
---|
1708 | /* no CR3 register configuration */ |
---|
1709 | |
---|
1710 | /*-------------------------- USART BRR Configuration -----------------------*/ |
---|
1711 | /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */ |
---|
1712 | USART_GETCLOCKSOURCE(husart, clocksource); |
---|
1713 | switch (clocksource) |
---|
1714 | { |
---|
1715 | case USART_CLOCKSOURCE_PCLK1: |
---|
1716 | usartdiv = (uint16_t)((2*HAL_RCC_GetPCLK1Freq()) / husart->Init.BaudRate); |
---|
1717 | break; |
---|
1718 | case USART_CLOCKSOURCE_PCLK2: |
---|
1719 | usartdiv = (uint16_t)((2*HAL_RCC_GetPCLK2Freq()) / husart->Init.BaudRate); |
---|
1720 | break; |
---|
1721 | case USART_CLOCKSOURCE_HSI: |
---|
1722 | usartdiv = (uint16_t)((2*HSI_VALUE) / husart->Init.BaudRate); |
---|
1723 | break; |
---|
1724 | case USART_CLOCKSOURCE_SYSCLK: |
---|
1725 | usartdiv = (uint16_t)((2*HAL_RCC_GetSysClockFreq()) / husart->Init.BaudRate); |
---|
1726 | break; |
---|
1727 | case USART_CLOCKSOURCE_LSE: |
---|
1728 | usartdiv = (uint16_t)((2*LSE_VALUE) / husart->Init.BaudRate); |
---|
1729 | break; |
---|
1730 | case USART_CLOCKSOURCE_UNDEFINED: |
---|
1731 | default: |
---|
1732 | ret = HAL_ERROR; |
---|
1733 | break; |
---|
1734 | } |
---|
1735 | |
---|
1736 | brrtemp = usartdiv & 0xFFF0; |
---|
1737 | brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U); |
---|
1738 | husart->Instance->BRR = brrtemp; |
---|
1739 | |
---|
1740 | return ret; |
---|
1741 | } |
---|
1742 | |
---|
1743 | /** |
---|
1744 | * @brief Check the USART Idle State |
---|
1745 | * @param husart: USART handle |
---|
1746 | * @retval HAL status |
---|
1747 | */ |
---|
1748 | static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart) |
---|
1749 | { |
---|
1750 | /* Initialize the USART ErrorCode */ |
---|
1751 | husart->ErrorCode = HAL_USART_ERROR_NONE; |
---|
1752 | |
---|
1753 | /* Check if the Transmitter is enabled */ |
---|
1754 | if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) |
---|
1755 | { |
---|
1756 | /* Wait until TEACK flag is set */ |
---|
1757 | if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) |
---|
1758 | { |
---|
1759 | husart->State= HAL_USART_STATE_TIMEOUT; |
---|
1760 | return HAL_TIMEOUT; |
---|
1761 | } |
---|
1762 | } |
---|
1763 | /* Check if the Receiver is enabled */ |
---|
1764 | if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) |
---|
1765 | { |
---|
1766 | /* Wait until REACK flag is set */ |
---|
1767 | if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) |
---|
1768 | { |
---|
1769 | husart->State= HAL_USART_STATE_TIMEOUT; |
---|
1770 | return HAL_TIMEOUT; |
---|
1771 | } |
---|
1772 | } |
---|
1773 | |
---|
1774 | /* Initialize the USART state*/ |
---|
1775 | husart->State= HAL_USART_STATE_READY; |
---|
1776 | |
---|
1777 | /* Process Unlocked */ |
---|
1778 | __HAL_UNLOCK(husart); |
---|
1779 | |
---|
1780 | return HAL_OK; |
---|
1781 | } |
---|
1782 | |
---|
1783 | /** |
---|
1784 | * @} |
---|
1785 | */ |
---|
1786 | |
---|
1787 | #endif /* HAL_USART_MODULE_ENABLED */ |
---|
1788 | /** |
---|
1789 | * @} |
---|
1790 | */ |
---|
1791 | |
---|
1792 | /** |
---|
1793 | * @} |
---|
1794 | */ |
---|
1795 | |
---|
1796 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
---|