1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_usart.c
4 * @author MCD Application Team
5 * @brief USART HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
8 * Peripheral (USART).
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral Control functions
12 * + Peripheral State and Error functions
13 *
14 ******************************************************************************
15 * @attention
16 *
17 * Copyright (c) 2017 STMicroelectronics.
18 * All rights reserved.
19 *
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
23 *
24 ******************************************************************************
25 @verbatim
26 ===============================================================================
27 ##### How to use this driver #####
28 ===============================================================================
29 [..]
30 The USART HAL driver can be used as follows:
31
32 (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
33 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
34 (++) Enable the USARTx interface clock.
35 (++) USART pins configuration:
36 (+++) Enable the clock for the USART GPIOs.
37 (+++) Configure these USART pins as alternate function pull-up.
38 (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
39 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
40 (+++) Configure the USARTx interrupt priority.
41 (+++) Enable the NVIC USART IRQ handle.
42 (++) USART interrupts handling:
43 -@@- The specific USART interrupts (Transmission complete interrupt,
44 RXNE interrupt and Error Interrupts) will be managed using the macros
45 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
46 (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
47 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
48 (+++) Declare a DMA handle structure for the Tx/Rx channel.
49 (+++) Enable the DMAx interface clock.
50 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
51 (+++) Configure the DMA Tx/Rx channel.
52 (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
53 (+++) Configure the priority and enable the NVIC for the transfer
54 complete interrupt on the DMA Tx/Rx channel.
55
56 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
57 (Receiver/Transmitter) in the husart handle Init structure.
58
59 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
60 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
61 by calling the customized HAL_USART_MspInit(&husart) API.
62
63 [..]
64 (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
65 HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
66 HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
67
68 ##### Callback registration #####
69 ==================================
70
71 [..]
72 The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
73 allows the user to configure dynamically the driver callbacks.
74
75 [..]
76 Use Function HAL_USART_RegisterCallback() to register a user callback.
77 Function HAL_USART_RegisterCallback() allows to register following callbacks:
78 (+) TxHalfCpltCallback : Tx Half Complete Callback.
79 (+) TxCpltCallback : Tx Complete Callback.
80 (+) RxHalfCpltCallback : Rx Half Complete Callback.
81 (+) RxCpltCallback : Rx Complete Callback.
82 (+) TxRxCpltCallback : Tx Rx Complete Callback.
83 (+) ErrorCallback : Error Callback.
84 (+) AbortCpltCallback : Abort Complete Callback.
85 (+) RxFifoFullCallback : Rx Fifo Full Callback.
86 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
87 (+) MspInitCallback : USART MspInit.
88 (+) MspDeInitCallback : USART MspDeInit.
89 This function takes as parameters the HAL peripheral handle, the Callback ID
90 and a pointer to the user callback function.
91
92 [..]
93 Use function HAL_USART_UnRegisterCallback() to reset a callback to the default
94 weak function.
95 HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
96 and the Callback ID.
97 This function allows to reset following callbacks:
98 (+) TxHalfCpltCallback : Tx Half Complete Callback.
99 (+) TxCpltCallback : Tx Complete Callback.
100 (+) RxHalfCpltCallback : Rx Half Complete Callback.
101 (+) RxCpltCallback : Rx Complete Callback.
102 (+) TxRxCpltCallback : Tx Rx Complete Callback.
103 (+) ErrorCallback : Error Callback.
104 (+) AbortCpltCallback : Abort Complete Callback.
105 (+) RxFifoFullCallback : Rx Fifo Full Callback.
106 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
107 (+) MspInitCallback : USART MspInit.
108 (+) MspDeInitCallback : USART MspDeInit.
109
110 [..]
111 By default, after the HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
112 all callbacks are set to the corresponding weak functions:
113 examples HAL_USART_TxCpltCallback(), HAL_USART_RxHalfCpltCallback().
114 Exception done for MspInit and MspDeInit functions that are respectively
115 reset to the legacy weak functions in the HAL_USART_Init()
116 and HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
117 If not, MspInit or MspDeInit are not null, the HAL_USART_Init() and HAL_USART_DeInit()
118 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
119
120 [..]
121 Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
122 Exception done MspInit/MspDeInit that can be registered/unregistered
123 in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
124 MspInit/DeInit callbacks can be used during the Init/DeInit.
125 In that case first register the MspInit/MspDeInit user callbacks
126 using HAL_USART_RegisterCallback() before calling HAL_USART_DeInit()
127 or HAL_USART_Init() function.
128
129 [..]
130 When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
131 not defined, the callback registration feature is not available
132 and weak callbacks are used.
133
134
135 @endverbatim
136 ******************************************************************************
137 */
138
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32h7xx_hal.h"
141
142 /** @addtogroup STM32H7xx_HAL_Driver
143 * @{
144 */
145
146 /** @defgroup USART USART
147 * @brief HAL USART Synchronous SPI module driver
148 * @{
149 */
150
151 #ifdef HAL_USART_MODULE_ENABLED
152
153 /* Private typedef -----------------------------------------------------------*/
154 /* Private define ------------------------------------------------------------*/
155 /** @defgroup USART_Private_Constants USART Private Constants
156 * @{
157 */
158 #define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
159 #define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
160 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
161 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 | \
162 USART_CR1_FIFOEN )) /*!< USART CR1 fields of parameters set by USART_SetConfig API */
163
164 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
165 USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \
166 USART_CR2_DIS_NSS)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
167
168 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */
169
170 #define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */
171 #define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */
172 /**
173 * @}
174 */
175
176 /* Private macros ------------------------------------------------------------*/
177 /* Private variables ---------------------------------------------------------*/
178 /* Private function prototypes -----------------------------------------------*/
179 /** @addtogroup USART_Private_Functions
180 * @{
181 */
182 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
183 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
184 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
185 static void USART_EndTransfer(USART_HandleTypeDef *husart);
186 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
187 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
188 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
189 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
190 static void USART_DMAError(DMA_HandleTypeDef *hdma);
191 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
192 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
193 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
194 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
195 uint32_t Tickstart, uint32_t Timeout);
196 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
197 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
198 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart);
199 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart);
200 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
201 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
202 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart);
203 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart);
204 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart);
205 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
206 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
207
208
209 /**
210 * @}
211 */
212
213 /* Exported functions --------------------------------------------------------*/
214
215 /** @defgroup USART_Exported_Functions USART Exported Functions
216 * @{
217 */
218
219 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
220 * @brief Initialization and Configuration functions
221 *
222 @verbatim
223 ===============================================================================
224 ##### Initialization and Configuration functions #####
225 ===============================================================================
226 [..]
227 This subsection provides a set of functions allowing to initialize the USART
228 in synchronous SPI master/slave mode.
229 (+) For the synchronous SPI mode only these parameters can be configured:
230 (++) Baud Rate
231 (++) Word Length
232 (++) Stop Bit
233 (++) Parity: If the parity is enabled, then the MSB bit of the data written
234 in the data register is transmitted but is changed by the parity bit.
235 (++) USART polarity
236 (++) USART phase
237 (++) USART LastBit
238 (++) Receiver/transmitter modes
239
240 [..]
241 The HAL_USART_Init() function follows the USART synchronous SPI configuration
242 procedure (details for the procedure are available in reference manual).
243
244 @endverbatim
245
246 Depending on the frame length defined by the M1 and M0 bits (7-bit,
247 8-bit or 9-bit), the possible USART formats are listed in the
248 following table.
249
250 Table 1. USART frame format.
251 +-----------------------------------------------------------------------+
252 | M1 bit | M0 bit | PCE bit | USART frame |
253 |---------|---------|-----------|---------------------------------------|
254 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
255 |---------|---------|-----------|---------------------------------------|
256 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
257 |---------|---------|-----------|---------------------------------------|
258 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
259 |---------|---------|-----------|---------------------------------------|
260 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
261 |---------|---------|-----------|---------------------------------------|
262 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
263 |---------|---------|-----------|---------------------------------------|
264 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
265 +-----------------------------------------------------------------------+
266
267 * @{
268 */
269
270 /**
271 * @brief Initialize the USART mode according to the specified
272 * parameters in the USART_InitTypeDef and initialize the associated handle.
273 * @param husart USART handle.
274 * @retval HAL status
275 */
HAL_USART_Init(USART_HandleTypeDef * husart)276 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
277 {
278 /* Check the USART handle allocation */
279 if (husart == NULL)
280 {
281 return HAL_ERROR;
282 }
283
284 /* Check the parameters */
285 assert_param(IS_USART_INSTANCE(husart->Instance));
286
287 if (husart->State == HAL_USART_STATE_RESET)
288 {
289 /* Allocate lock resource and initialize it */
290 husart->Lock = HAL_UNLOCKED;
291
292 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
293 USART_InitCallbacksToDefault(husart);
294
295 if (husart->MspInitCallback == NULL)
296 {
297 husart->MspInitCallback = HAL_USART_MspInit;
298 }
299
300 /* Init the low level hardware */
301 husart->MspInitCallback(husart);
302 #else
303 /* Init the low level hardware : GPIO, CLOCK */
304 HAL_USART_MspInit(husart);
305 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
306 }
307
308 husart->State = HAL_USART_STATE_BUSY;
309
310 /* Disable the Peripheral */
311 __HAL_USART_DISABLE(husart);
312
313 /* Set the Usart Communication parameters */
314 if (USART_SetConfig(husart) == HAL_ERROR)
315 {
316 return HAL_ERROR;
317 }
318
319 /* In Synchronous SPI mode, the following bits must be kept cleared:
320 - LINEN bit in the USART_CR2 register
321 - HDSEL, SCEN and IREN bits in the USART_CR3 register.
322 */
323 husart->Instance->CR2 &= ~USART_CR2_LINEN;
324 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
325
326 /* Enable the Peripheral */
327 __HAL_USART_ENABLE(husart);
328
329 /* TEACK and/or REACK to check before moving husart->State to Ready */
330 return (USART_CheckIdleState(husart));
331 }
332
333 /**
334 * @brief DeInitialize the USART peripheral.
335 * @param husart USART handle.
336 * @retval HAL status
337 */
HAL_USART_DeInit(USART_HandleTypeDef * husart)338 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
339 {
340 /* Check the USART handle allocation */
341 if (husart == NULL)
342 {
343 return HAL_ERROR;
344 }
345
346 /* Check the parameters */
347 assert_param(IS_USART_INSTANCE(husart->Instance));
348
349 husart->State = HAL_USART_STATE_BUSY;
350
351 husart->Instance->CR1 = 0x0U;
352 husart->Instance->CR2 = 0x0U;
353 husart->Instance->CR3 = 0x0U;
354
355 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
356 if (husart->MspDeInitCallback == NULL)
357 {
358 husart->MspDeInitCallback = HAL_USART_MspDeInit;
359 }
360 /* DeInit the low level hardware */
361 husart->MspDeInitCallback(husart);
362 #else
363 /* DeInit the low level hardware */
364 HAL_USART_MspDeInit(husart);
365 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
366
367 husart->ErrorCode = HAL_USART_ERROR_NONE;
368 husart->State = HAL_USART_STATE_RESET;
369
370 /* Process Unlock */
371 __HAL_UNLOCK(husart);
372
373 return HAL_OK;
374 }
375
376 /**
377 * @brief Initialize the USART MSP.
378 * @param husart USART handle.
379 * @retval None
380 */
HAL_USART_MspInit(USART_HandleTypeDef * husart)381 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
382 {
383 /* Prevent unused argument(s) compilation warning */
384 UNUSED(husart);
385
386 /* NOTE : This function should not be modified, when the callback is needed,
387 the HAL_USART_MspInit can be implemented in the user file
388 */
389 }
390
391 /**
392 * @brief DeInitialize the USART MSP.
393 * @param husart USART handle.
394 * @retval None
395 */
HAL_USART_MspDeInit(USART_HandleTypeDef * husart)396 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
397 {
398 /* Prevent unused argument(s) compilation warning */
399 UNUSED(husart);
400
401 /* NOTE : This function should not be modified, when the callback is needed,
402 the HAL_USART_MspDeInit can be implemented in the user file
403 */
404 }
405
406 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
407 /**
408 * @brief Register a User USART Callback
409 * To be used to override the weak predefined callback
410 * @note The HAL_USART_RegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET
411 * to register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID
412 * @param husart usart handle
413 * @param CallbackID ID of the callback to be registered
414 * This parameter can be one of the following values:
415 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
416 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
417 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
418 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
419 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
420 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
421 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
422 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
423 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
424 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
425 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
426 * @param pCallback pointer to the Callback function
427 * @retval HAL status
428 + */
HAL_USART_RegisterCallback(USART_HandleTypeDef * husart,HAL_USART_CallbackIDTypeDef CallbackID,pUSART_CallbackTypeDef pCallback)429 HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
430 pUSART_CallbackTypeDef pCallback)
431 {
432 HAL_StatusTypeDef status = HAL_OK;
433
434 if (pCallback == NULL)
435 {
436 /* Update the error code */
437 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
438
439 return HAL_ERROR;
440 }
441
442 if (husart->State == HAL_USART_STATE_READY)
443 {
444 switch (CallbackID)
445 {
446 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
447 husart->TxHalfCpltCallback = pCallback;
448 break;
449
450 case HAL_USART_TX_COMPLETE_CB_ID :
451 husart->TxCpltCallback = pCallback;
452 break;
453
454 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
455 husart->RxHalfCpltCallback = pCallback;
456 break;
457
458 case HAL_USART_RX_COMPLETE_CB_ID :
459 husart->RxCpltCallback = pCallback;
460 break;
461
462 case HAL_USART_TX_RX_COMPLETE_CB_ID :
463 husart->TxRxCpltCallback = pCallback;
464 break;
465
466 case HAL_USART_ERROR_CB_ID :
467 husart->ErrorCallback = pCallback;
468 break;
469
470 case HAL_USART_ABORT_COMPLETE_CB_ID :
471 husart->AbortCpltCallback = pCallback;
472 break;
473
474 case HAL_USART_RX_FIFO_FULL_CB_ID :
475 husart->RxFifoFullCallback = pCallback;
476 break;
477
478 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
479 husart->TxFifoEmptyCallback = pCallback;
480 break;
481
482 case HAL_USART_MSPINIT_CB_ID :
483 husart->MspInitCallback = pCallback;
484 break;
485
486 case HAL_USART_MSPDEINIT_CB_ID :
487 husart->MspDeInitCallback = pCallback;
488 break;
489
490 default :
491 /* Update the error code */
492 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
493
494 /* Return error status */
495 status = HAL_ERROR;
496 break;
497 }
498 }
499 else if (husart->State == HAL_USART_STATE_RESET)
500 {
501 switch (CallbackID)
502 {
503 case HAL_USART_MSPINIT_CB_ID :
504 husart->MspInitCallback = pCallback;
505 break;
506
507 case HAL_USART_MSPDEINIT_CB_ID :
508 husart->MspDeInitCallback = pCallback;
509 break;
510
511 default :
512 /* Update the error code */
513 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
514
515 /* Return error status */
516 status = HAL_ERROR;
517 break;
518 }
519 }
520 else
521 {
522 /* Update the error code */
523 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
524
525 /* Return error status */
526 status = HAL_ERROR;
527 }
528
529 return status;
530 }
531
532 /**
533 * @brief Unregister an USART Callback
534 * USART callaback is redirected to the weak predefined callback
535 * @note The HAL_USART_UnRegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET
536 * to un-register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID
537 * @param husart usart handle
538 * @param CallbackID ID of the callback to be unregistered
539 * This parameter can be one of the following values:
540 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
541 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
542 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
543 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
544 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
545 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
546 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
547 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
548 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
549 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
550 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
551 * @retval HAL status
552 */
HAL_USART_UnRegisterCallback(USART_HandleTypeDef * husart,HAL_USART_CallbackIDTypeDef CallbackID)553 HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
554 {
555 HAL_StatusTypeDef status = HAL_OK;
556
557 if (HAL_USART_STATE_READY == husart->State)
558 {
559 switch (CallbackID)
560 {
561 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
562 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
563 break;
564
565 case HAL_USART_TX_COMPLETE_CB_ID :
566 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
567 break;
568
569 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
570 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
571 break;
572
573 case HAL_USART_RX_COMPLETE_CB_ID :
574 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
575 break;
576
577 case HAL_USART_TX_RX_COMPLETE_CB_ID :
578 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
579 break;
580
581 case HAL_USART_ERROR_CB_ID :
582 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
583 break;
584
585 case HAL_USART_ABORT_COMPLETE_CB_ID :
586 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
587 break;
588
589 case HAL_USART_RX_FIFO_FULL_CB_ID :
590 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
591 break;
592
593 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
594 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
595 break;
596
597 case HAL_USART_MSPINIT_CB_ID :
598 husart->MspInitCallback = HAL_USART_MspInit; /* Legacy weak MspInitCallback */
599 break;
600
601 case HAL_USART_MSPDEINIT_CB_ID :
602 husart->MspDeInitCallback = HAL_USART_MspDeInit; /* Legacy weak MspDeInitCallback */
603 break;
604
605 default :
606 /* Update the error code */
607 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
608
609 /* Return error status */
610 status = HAL_ERROR;
611 break;
612 }
613 }
614 else if (HAL_USART_STATE_RESET == husart->State)
615 {
616 switch (CallbackID)
617 {
618 case HAL_USART_MSPINIT_CB_ID :
619 husart->MspInitCallback = HAL_USART_MspInit;
620 break;
621
622 case HAL_USART_MSPDEINIT_CB_ID :
623 husart->MspDeInitCallback = HAL_USART_MspDeInit;
624 break;
625
626 default :
627 /* Update the error code */
628 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
629
630 /* Return error status */
631 status = HAL_ERROR;
632 break;
633 }
634 }
635 else
636 {
637 /* Update the error code */
638 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
639
640 /* Return error status */
641 status = HAL_ERROR;
642 }
643
644 return status;
645 }
646 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
647
648
649 /**
650 * @}
651 */
652
653 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
654 * @brief USART Transmit and Receive functions
655 *
656 @verbatim
657 ===============================================================================
658 ##### IO operation functions #####
659 ===============================================================================
660 [..] This subsection provides a set of functions allowing to manage the USART synchronous SPI
661 data transfers.
662
663 [..] The USART Synchronous SPI supports master and slave modes (SCLK as output or input).
664
665 [..]
666
667 (#) There are two modes of transfer:
668 (++) Blocking mode: The communication is performed in polling mode.
669 The HAL status of all data processing is returned by the same function
670 after finishing transfer.
671 (++) No-Blocking mode: The communication is performed using Interrupts
672 or DMA, These API's return the HAL status.
673 The end of the data processing will be indicated through the
674 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
675 using DMA mode.
676 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
677 will be executed respectively at the end of the transmit or Receive process
678 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
679
680 (#) Blocking mode API's are :
681 (++) HAL_USART_Transmit() in simplex mode
682 (++) HAL_USART_Receive() in full duplex receive only
683 (++) HAL_USART_TransmitReceive() in full duplex mode
684
685 (#) Non-Blocking mode API's with Interrupt are :
686 (++) HAL_USART_Transmit_IT() in simplex mode
687 (++) HAL_USART_Receive_IT() in full duplex receive only
688 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
689 (++) HAL_USART_IRQHandler()
690
691 (#) No-Blocking mode API's with DMA are :
692 (++) HAL_USART_Transmit_DMA() in simplex mode
693 (++) HAL_USART_Receive_DMA() in full duplex receive only
694 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
695 (++) HAL_USART_DMAPause()
696 (++) HAL_USART_DMAResume()
697 (++) HAL_USART_DMAStop()
698
699 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
700 (++) HAL_USART_TxCpltCallback()
701 (++) HAL_USART_RxCpltCallback()
702 (++) HAL_USART_TxHalfCpltCallback()
703 (++) HAL_USART_RxHalfCpltCallback()
704 (++) HAL_USART_ErrorCallback()
705 (++) HAL_USART_TxRxCpltCallback()
706
707 (#) Non-Blocking mode transfers could be aborted using Abort API's :
708 (++) HAL_USART_Abort()
709 (++) HAL_USART_Abort_IT()
710
711 (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
712 (++) HAL_USART_AbortCpltCallback()
713
714 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
715 Errors are handled as follows :
716 (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
717 to be evaluated by user : this concerns Frame Error,
718 Parity Error or Noise Error in Interrupt mode reception .
719 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify
720 error type, and HAL_USART_ErrorCallback() user callback is executed.
721 Transfer is kept ongoing on USART side.
722 If user wants to abort it, Abort services should be called by user.
723 (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
724 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
725 Error code is set to allow user to identify error type,
726 and HAL_USART_ErrorCallback() user callback is executed.
727
728 @endverbatim
729 * @{
730 */
731
732 /**
733 * @brief Simplex send an amount of data in blocking mode.
734 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
735 * the sent data is handled as a set of u16. In this case, Size must indicate the number
736 * of u16 provided through pTxData.
737 * @param husart USART handle.
738 * @param pTxData Pointer to data buffer (u8 or u16 data elements).
739 * @param Size Amount of data elements (u8 or u16) to be sent.
740 * @param Timeout Timeout duration.
741 * @retval HAL status
742 */
HAL_USART_Transmit(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size,uint32_t Timeout)743 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size,
744 uint32_t Timeout)
745 {
746 const uint8_t *ptxdata8bits;
747 const uint16_t *ptxdata16bits;
748 uint32_t tickstart;
749
750 if (husart->State == HAL_USART_STATE_READY)
751 {
752 if ((pTxData == NULL) || (Size == 0U))
753 {
754 return HAL_ERROR;
755 }
756
757 /* Process Locked */
758 __HAL_LOCK(husart);
759
760 husart->ErrorCode = HAL_USART_ERROR_NONE;
761 husart->State = HAL_USART_STATE_BUSY_TX;
762
763 /* Init tickstart for timeout management */
764 tickstart = HAL_GetTick();
765
766 husart->TxXferSize = Size;
767 husart->TxXferCount = Size;
768
769 /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
770 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
771 {
772 ptxdata8bits = NULL;
773 ptxdata16bits = (const uint16_t *) pTxData;
774 }
775 else
776 {
777 ptxdata8bits = pTxData;
778 ptxdata16bits = NULL;
779 }
780
781 /* Check the remaining data to be sent */
782 while (husart->TxXferCount > 0U)
783 {
784 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
785 {
786 return HAL_TIMEOUT;
787 }
788 if (ptxdata8bits == NULL)
789 {
790 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
791 ptxdata16bits++;
792 }
793 else
794 {
795 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
796 ptxdata8bits++;
797 }
798
799 husart->TxXferCount--;
800 }
801
802 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
803 {
804 return HAL_TIMEOUT;
805 }
806
807 /* Clear Transmission Complete Flag */
808 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
809
810 /* Clear overrun flag and discard the received data */
811 __HAL_USART_CLEAR_OREFLAG(husart);
812 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
813 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
814
815 /* At end of Tx process, restore husart->State to Ready */
816 husart->State = HAL_USART_STATE_READY;
817
818 /* Process Unlocked */
819 __HAL_UNLOCK(husart);
820
821 return HAL_OK;
822 }
823 else
824 {
825 return HAL_BUSY;
826 }
827 }
828
829 /**
830 * @brief Receive an amount of data in blocking mode.
831 * @note To receive synchronous data, dummy data are simultaneously transmitted.
832 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
833 * the received data is handled as a set of u16. In this case, Size must indicate the number
834 * of u16 available through pRxData.
835 * @param husart USART handle.
836 * @param pRxData Pointer to data buffer (u8 or u16 data elements).
837 * @param Size Amount of data elements (u8 or u16) to be received.
838 * @param Timeout Timeout duration.
839 * @retval HAL status
840 */
HAL_USART_Receive(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)841 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
842 {
843 uint8_t *prxdata8bits;
844 uint16_t *prxdata16bits;
845 uint16_t uhMask;
846 uint32_t tickstart;
847
848 if (husart->State == HAL_USART_STATE_READY)
849 {
850 if ((pRxData == NULL) || (Size == 0U))
851 {
852 return HAL_ERROR;
853 }
854
855 /* Process Locked */
856 __HAL_LOCK(husart);
857
858 husart->ErrorCode = HAL_USART_ERROR_NONE;
859 husart->State = HAL_USART_STATE_BUSY_RX;
860
861 /* Init tickstart for timeout management */
862 tickstart = HAL_GetTick();
863
864 husart->RxXferSize = Size;
865 husart->RxXferCount = Size;
866
867 /* Computation of USART mask to apply to RDR register */
868 USART_MASK_COMPUTATION(husart);
869 uhMask = husart->Mask;
870
871 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
872 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
873 {
874 prxdata8bits = NULL;
875 prxdata16bits = (uint16_t *) pRxData;
876 }
877 else
878 {
879 prxdata8bits = pRxData;
880 prxdata16bits = NULL;
881 }
882
883 /* as long as data have to be received */
884 while (husart->RxXferCount > 0U)
885 {
886 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
887 {
888 /* Wait until TXE flag is set to send dummy byte in order to generate the
889 * clock for the slave to send data.
890 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
891 * can be written for all the cases. */
892 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
893 {
894 return HAL_TIMEOUT;
895 }
896 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
897 }
898
899 /* Wait for RXNE Flag */
900 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
901 {
902 return HAL_TIMEOUT;
903 }
904
905 if (prxdata8bits == NULL)
906 {
907 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
908 prxdata16bits++;
909 }
910 else
911 {
912 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
913 prxdata8bits++;
914 }
915
916 husart->RxXferCount--;
917
918 }
919
920 /* Clear SPI slave underrun flag and discard transmit data */
921 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
922 {
923 __HAL_USART_CLEAR_UDRFLAG(husart);
924 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
925 }
926
927 /* At end of Rx process, restore husart->State to Ready */
928 husart->State = HAL_USART_STATE_READY;
929
930 /* Process Unlocked */
931 __HAL_UNLOCK(husart);
932
933 return HAL_OK;
934 }
935 else
936 {
937 return HAL_BUSY;
938 }
939 }
940
941 /**
942 * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
943 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
944 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
945 * of u16 available through pTxData and through pRxData.
946 * @param husart USART handle.
947 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
948 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
949 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
950 * @param Timeout Timeout duration.
951 * @retval HAL status
952 */
HAL_USART_TransmitReceive(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)953 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
954 uint16_t Size, uint32_t Timeout)
955 {
956 uint8_t *prxdata8bits;
957 uint16_t *prxdata16bits;
958 const uint8_t *ptxdata8bits;
959 const uint16_t *ptxdata16bits;
960 uint16_t uhMask;
961 uint16_t rxdatacount;
962 uint32_t tickstart;
963
964 if (husart->State == HAL_USART_STATE_READY)
965 {
966 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
967 {
968 return HAL_ERROR;
969 }
970
971 /* Process Locked */
972 __HAL_LOCK(husart);
973
974 husart->ErrorCode = HAL_USART_ERROR_NONE;
975 husart->State = HAL_USART_STATE_BUSY_RX;
976
977 /* Init tickstart for timeout management */
978 tickstart = HAL_GetTick();
979
980 husart->RxXferSize = Size;
981 husart->TxXferSize = Size;
982 husart->TxXferCount = Size;
983 husart->RxXferCount = Size;
984
985 /* Computation of USART mask to apply to RDR register */
986 USART_MASK_COMPUTATION(husart);
987 uhMask = husart->Mask;
988
989 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
990 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
991 {
992 prxdata8bits = NULL;
993 ptxdata8bits = NULL;
994 ptxdata16bits = (const uint16_t *) pTxData;
995 prxdata16bits = (uint16_t *) pRxData;
996 }
997 else
998 {
999 prxdata8bits = pRxData;
1000 ptxdata8bits = pTxData;
1001 ptxdata16bits = NULL;
1002 prxdata16bits = NULL;
1003 }
1004
1005 if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE))
1006 {
1007 /* Wait until TXE flag is set to send data */
1008 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1009 {
1010 return HAL_TIMEOUT;
1011 }
1012 if (ptxdata8bits == NULL)
1013 {
1014 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1015 ptxdata16bits++;
1016 }
1017 else
1018 {
1019 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1020 ptxdata8bits++;
1021 }
1022
1023 husart->TxXferCount--;
1024 }
1025
1026 /* Check the remain data to be sent */
1027 /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
1028 rxdatacount = husart->RxXferCount;
1029 while ((husart->TxXferCount > 0U) || (rxdatacount > 0U))
1030 {
1031 if (husart->TxXferCount > 0U)
1032 {
1033 /* Wait until TXE flag is set to send data */
1034 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1035 {
1036 return HAL_TIMEOUT;
1037 }
1038 if (ptxdata8bits == NULL)
1039 {
1040 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1041 ptxdata16bits++;
1042 }
1043 else
1044 {
1045 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1046 ptxdata8bits++;
1047 }
1048
1049 husart->TxXferCount--;
1050 }
1051
1052 if (husart->RxXferCount > 0U)
1053 {
1054 /* Wait for RXNE Flag */
1055 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1056 {
1057 return HAL_TIMEOUT;
1058 }
1059
1060 if (prxdata8bits == NULL)
1061 {
1062 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
1063 prxdata16bits++;
1064 }
1065 else
1066 {
1067 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
1068 prxdata8bits++;
1069 }
1070
1071 husart->RxXferCount--;
1072 }
1073 rxdatacount = husart->RxXferCount;
1074 }
1075
1076 /* At end of TxRx process, restore husart->State to Ready */
1077 husart->State = HAL_USART_STATE_READY;
1078
1079 /* Process Unlocked */
1080 __HAL_UNLOCK(husart);
1081
1082 return HAL_OK;
1083 }
1084 else
1085 {
1086 return HAL_BUSY;
1087 }
1088 }
1089
1090 /**
1091 * @brief Send an amount of data in interrupt mode.
1092 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1093 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1094 * of u16 provided through pTxData.
1095 * @param husart USART handle.
1096 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1097 * @param Size amount of data elements (u8 or u16) to be sent.
1098 * @retval HAL status
1099 */
HAL_USART_Transmit_IT(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size)1100 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1101 {
1102 if (husart->State == HAL_USART_STATE_READY)
1103 {
1104 if ((pTxData == NULL) || (Size == 0U))
1105 {
1106 return HAL_ERROR;
1107 }
1108
1109 /* Process Locked */
1110 __HAL_LOCK(husart);
1111
1112 husart->pTxBuffPtr = pTxData;
1113 husart->TxXferSize = Size;
1114 husart->TxXferCount = Size;
1115 husart->TxISR = NULL;
1116
1117 husart->ErrorCode = HAL_USART_ERROR_NONE;
1118 husart->State = HAL_USART_STATE_BUSY_TX;
1119
1120 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1121 are not managed by the USART Transmit Process to avoid the overrun interrupt
1122 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1123 to benefit for the frame error and noise interrupts the usart mode should be
1124 configured only for transmit "USART_MODE_TX" */
1125
1126 /* Configure Tx interrupt processing */
1127 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1128 {
1129 /* Set the Tx ISR function pointer according to the data word length */
1130 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1131 {
1132 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1133 }
1134 else
1135 {
1136 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1137 }
1138
1139 /* Process Unlocked */
1140 __HAL_UNLOCK(husart);
1141
1142 /* Enable the TX FIFO threshold interrupt */
1143 __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT);
1144 }
1145 else
1146 {
1147 /* Set the Tx ISR function pointer according to the data word length */
1148 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1149 {
1150 husart->TxISR = USART_TxISR_16BIT;
1151 }
1152 else
1153 {
1154 husart->TxISR = USART_TxISR_8BIT;
1155 }
1156
1157 /* Process Unlocked */
1158 __HAL_UNLOCK(husart);
1159
1160 /* Enable the USART Transmit Data Register Empty Interrupt */
1161 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
1162 }
1163
1164 return HAL_OK;
1165 }
1166 else
1167 {
1168 return HAL_BUSY;
1169 }
1170 }
1171
1172 /**
1173 * @brief Receive an amount of data in interrupt mode.
1174 * @note To receive synchronous data, dummy data are simultaneously transmitted.
1175 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1176 * the received data is handled as a set of u16. In this case, Size must indicate the number
1177 * of u16 available through pRxData.
1178 * @param husart USART handle.
1179 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1180 * @param Size amount of data elements (u8 or u16) to be received.
1181 * @retval HAL status
1182 */
HAL_USART_Receive_IT(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size)1183 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1184 {
1185 uint16_t nb_dummy_data;
1186
1187 if (husart->State == HAL_USART_STATE_READY)
1188 {
1189 if ((pRxData == NULL) || (Size == 0U))
1190 {
1191 return HAL_ERROR;
1192 }
1193
1194 /* Process Locked */
1195 __HAL_LOCK(husart);
1196
1197 husart->pRxBuffPtr = pRxData;
1198 husart->RxXferSize = Size;
1199 husart->RxXferCount = Size;
1200 husart->RxISR = NULL;
1201
1202 USART_MASK_COMPUTATION(husart);
1203
1204 husart->ErrorCode = HAL_USART_ERROR_NONE;
1205 husart->State = HAL_USART_STATE_BUSY_RX;
1206
1207 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1208 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1209
1210 /* Configure Rx interrupt processing */
1211 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1212 {
1213 /* Set the Rx ISR function pointer according to the data word length */
1214 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1215 {
1216 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1217 }
1218 else
1219 {
1220 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1221 }
1222
1223 /* Process Unlocked */
1224 __HAL_UNLOCK(husart);
1225
1226 /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
1227 if (husart->Init.Parity != USART_PARITY_NONE)
1228 {
1229 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1230 }
1231 SET_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
1232 }
1233 else
1234 {
1235 /* Set the Rx ISR function pointer according to the data word length */
1236 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1237 {
1238 husart->RxISR = USART_RxISR_16BIT;
1239 }
1240 else
1241 {
1242 husart->RxISR = USART_RxISR_8BIT;
1243 }
1244
1245 /* Process Unlocked */
1246 __HAL_UNLOCK(husart);
1247
1248 /* Enable the USART Parity Error and Data Register not empty Interrupts */
1249 if (husart->Init.Parity != USART_PARITY_NONE)
1250 {
1251 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1252 }
1253 else
1254 {
1255 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1256 }
1257 }
1258
1259 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
1260 {
1261 /* Send dummy data in order to generate the clock for the Slave to send the next data.
1262 When FIFO mode is disabled only one data must be transferred.
1263 When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold.
1264 */
1265 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1266 {
1267 for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--)
1268 {
1269 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1270 }
1271 }
1272 else
1273 {
1274 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1275 }
1276 }
1277
1278 return HAL_OK;
1279 }
1280 else
1281 {
1282 return HAL_BUSY;
1283 }
1284 }
1285
1286 /**
1287 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1288 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1289 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1290 * of u16 available through pTxData and through pRxData.
1291 * @param husart USART handle.
1292 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1293 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1294 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
1295 * @retval HAL status
1296 */
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1297 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1298 uint16_t Size)
1299 {
1300
1301 if (husart->State == HAL_USART_STATE_READY)
1302 {
1303 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1304 {
1305 return HAL_ERROR;
1306 }
1307
1308 /* Process Locked */
1309 __HAL_LOCK(husart);
1310
1311 husart->pRxBuffPtr = pRxData;
1312 husart->RxXferSize = Size;
1313 husart->RxXferCount = Size;
1314 husart->pTxBuffPtr = pTxData;
1315 husart->TxXferSize = Size;
1316 husart->TxXferCount = Size;
1317
1318 /* Computation of USART mask to apply to RDR register */
1319 USART_MASK_COMPUTATION(husart);
1320
1321 husart->ErrorCode = HAL_USART_ERROR_NONE;
1322 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1323
1324 /* Configure TxRx interrupt processing */
1325 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1326 {
1327 /* Set the Rx ISR function pointer according to the data word length */
1328 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1329 {
1330 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1331 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1332 }
1333 else
1334 {
1335 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1336 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1337 }
1338
1339 /* Process Locked */
1340 __HAL_UNLOCK(husart);
1341
1342 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1343 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1344
1345 if (husart->Init.Parity != USART_PARITY_NONE)
1346 {
1347 /* Enable the USART Parity Error interrupt */
1348 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1349 }
1350
1351 /* Enable the TX and RX FIFO Threshold interrupts */
1352 SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE));
1353 }
1354 else
1355 {
1356 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1357 {
1358 husart->TxISR = USART_TxISR_16BIT;
1359 husart->RxISR = USART_RxISR_16BIT;
1360 }
1361 else
1362 {
1363 husart->TxISR = USART_TxISR_8BIT;
1364 husart->RxISR = USART_RxISR_8BIT;
1365 }
1366
1367 /* Process Locked */
1368 __HAL_UNLOCK(husart);
1369
1370 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1371 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1372
1373 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1374 if (husart->Init.Parity != USART_PARITY_NONE)
1375 {
1376 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1377 }
1378 else
1379 {
1380 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1381 }
1382
1383 /* Enable the USART Transmit Data Register Empty Interrupt */
1384 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1385 }
1386
1387 return HAL_OK;
1388 }
1389 else
1390 {
1391 return HAL_BUSY;
1392 }
1393 }
1394
1395 /**
1396 * @brief Send an amount of data in DMA mode.
1397 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1398 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1399 * of u16 provided through pTxData.
1400 * @param husart USART handle.
1401 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1402 * @param Size amount of data elements (u8 or u16) to be sent.
1403 * @retval HAL status
1404 */
HAL_USART_Transmit_DMA(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size)1405 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1406 {
1407 HAL_StatusTypeDef status = HAL_OK;
1408 const uint32_t *tmp;
1409
1410 if (husart->State == HAL_USART_STATE_READY)
1411 {
1412 if ((pTxData == NULL) || (Size == 0U))
1413 {
1414 return HAL_ERROR;
1415 }
1416
1417 /* Process Locked */
1418 __HAL_LOCK(husart);
1419
1420 husart->pTxBuffPtr = pTxData;
1421 husart->TxXferSize = Size;
1422 husart->TxXferCount = Size;
1423
1424 husart->ErrorCode = HAL_USART_ERROR_NONE;
1425 husart->State = HAL_USART_STATE_BUSY_TX;
1426
1427 if (husart->hdmatx != NULL)
1428 {
1429 /* Set the USART DMA transfer complete callback */
1430 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1431
1432 /* Set the USART DMA Half transfer complete callback */
1433 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1434
1435 /* Set the DMA error callback */
1436 husart->hdmatx->XferErrorCallback = USART_DMAError;
1437
1438 /* Enable the USART transmit DMA channel */
1439 tmp = (const uint32_t *)&pTxData;
1440 status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1441 }
1442
1443 if (status == HAL_OK)
1444 {
1445 /* Clear the TC flag in the ICR register */
1446 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1447
1448 /* Process Unlocked */
1449 __HAL_UNLOCK(husart);
1450
1451 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1452 in the USART CR3 register */
1453 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1454
1455 return HAL_OK;
1456 }
1457 else
1458 {
1459 /* Set error code to DMA */
1460 husart->ErrorCode = HAL_USART_ERROR_DMA;
1461
1462 /* Process Unlocked */
1463 __HAL_UNLOCK(husart);
1464
1465 /* Restore husart->State to ready */
1466 husart->State = HAL_USART_STATE_READY;
1467
1468 return HAL_ERROR;
1469 }
1470 }
1471 else
1472 {
1473 return HAL_BUSY;
1474 }
1475 }
1476
1477 /**
1478 * @brief Receive an amount of data in DMA mode.
1479 * @note When the USART parity is enabled (PCE = 1), the received data contain
1480 * the parity bit (MSB position).
1481 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1482 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1483 * the received data is handled as a set of u16. In this case, Size must indicate the number
1484 * of u16 available through pRxData.
1485 * @param husart USART handle.
1486 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1487 * @param Size amount of data elements (u8 or u16) to be received.
1488 * @retval HAL status
1489 */
HAL_USART_Receive_DMA(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size)1490 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1491 {
1492 HAL_StatusTypeDef status = HAL_OK;
1493 uint32_t *tmp = (uint32_t *)&pRxData;
1494
1495 /* Check that a Rx process is not already ongoing */
1496 if (husart->State == HAL_USART_STATE_READY)
1497 {
1498 if ((pRxData == NULL) || (Size == 0U))
1499 {
1500 return HAL_ERROR;
1501 }
1502
1503 /* Process Locked */
1504 __HAL_LOCK(husart);
1505
1506 husart->pRxBuffPtr = pRxData;
1507 husart->RxXferSize = Size;
1508 husart->pTxBuffPtr = pRxData;
1509 husart->TxXferSize = Size;
1510
1511 husart->ErrorCode = HAL_USART_ERROR_NONE;
1512 husart->State = HAL_USART_STATE_BUSY_RX;
1513
1514 if (husart->hdmarx != NULL)
1515 {
1516 /* Set the USART DMA Rx transfer complete callback */
1517 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1518
1519 /* Set the USART DMA Half transfer complete callback */
1520 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1521
1522 /* Set the USART DMA Rx transfer error callback */
1523 husart->hdmarx->XferErrorCallback = USART_DMAError;
1524
1525 /* Enable the USART receive DMA channel */
1526 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1527 }
1528
1529 if ((status == HAL_OK) &&
1530 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
1531 {
1532 /* Enable the USART transmit DMA channel: the transmit channel is used in order
1533 to generate in the non-blocking mode the clock to the slave device,
1534 this mode isn't a simplex receive mode but a full-duplex receive mode */
1535
1536 /* Set the USART DMA Tx Complete and Error callback to Null */
1537 if (husart->hdmatx != NULL)
1538 {
1539 husart->hdmatx->XferErrorCallback = NULL;
1540 husart->hdmatx->XferHalfCpltCallback = NULL;
1541 husart->hdmatx->XferCpltCallback = NULL;
1542 status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1543 }
1544 }
1545
1546 if (status == HAL_OK)
1547 {
1548 /* Process Unlocked */
1549 __HAL_UNLOCK(husart);
1550
1551 if (husart->Init.Parity != USART_PARITY_NONE)
1552 {
1553 /* Enable the USART Parity Error Interrupt */
1554 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1555 }
1556
1557 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1558 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1559
1560 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1561 in the USART CR3 register */
1562 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1563
1564 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1565 in the USART CR3 register */
1566 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1567
1568 return HAL_OK;
1569 }
1570 else
1571 {
1572 if (husart->hdmarx != NULL)
1573 {
1574 status = HAL_DMA_Abort(husart->hdmarx);
1575 }
1576
1577 /* No need to check on error code */
1578 UNUSED(status);
1579
1580 /* Set error code to DMA */
1581 husart->ErrorCode = HAL_USART_ERROR_DMA;
1582
1583 /* Process Unlocked */
1584 __HAL_UNLOCK(husart);
1585
1586 /* Restore husart->State to ready */
1587 husart->State = HAL_USART_STATE_READY;
1588
1589 return HAL_ERROR;
1590 }
1591 }
1592 else
1593 {
1594 return HAL_BUSY;
1595 }
1596 }
1597
1598 /**
1599 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1600 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1601 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1602 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1603 * of u16 available through pTxData and through pRxData.
1604 * @param husart USART handle.
1605 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1606 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1607 * @param Size amount of data elements (u8 or u16) to be received/sent.
1608 * @retval HAL status
1609 */
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1610 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1611 uint16_t Size)
1612 {
1613 HAL_StatusTypeDef status;
1614 const uint32_t *tmp;
1615
1616 if (husart->State == HAL_USART_STATE_READY)
1617 {
1618 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1619 {
1620 return HAL_ERROR;
1621 }
1622
1623 /* Process Locked */
1624 __HAL_LOCK(husart);
1625
1626 husart->pRxBuffPtr = pRxData;
1627 husart->RxXferSize = Size;
1628 husart->pTxBuffPtr = pTxData;
1629 husart->TxXferSize = Size;
1630
1631 husart->ErrorCode = HAL_USART_ERROR_NONE;
1632 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1633
1634 if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
1635 {
1636 /* Set the USART DMA Rx transfer complete callback */
1637 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1638
1639 /* Set the USART DMA Half transfer complete callback */
1640 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1641
1642 /* Set the USART DMA Tx transfer complete callback */
1643 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1644
1645 /* Set the USART DMA Half transfer complete callback */
1646 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1647
1648 /* Set the USART DMA Tx transfer error callback */
1649 husart->hdmatx->XferErrorCallback = USART_DMAError;
1650
1651 /* Set the USART DMA Rx transfer error callback */
1652 husart->hdmarx->XferErrorCallback = USART_DMAError;
1653
1654 /* Enable the USART receive DMA channel */
1655 tmp = (uint32_t *)&pRxData;
1656 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(const uint32_t *)tmp, Size);
1657
1658 /* Enable the USART transmit DMA channel */
1659 if (status == HAL_OK)
1660 {
1661 tmp = (const uint32_t *)&pTxData;
1662 status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1663 }
1664 }
1665 else
1666 {
1667 status = HAL_ERROR;
1668 }
1669
1670 if (status == HAL_OK)
1671 {
1672 /* Process Unlocked */
1673 __HAL_UNLOCK(husart);
1674
1675 if (husart->Init.Parity != USART_PARITY_NONE)
1676 {
1677 /* Enable the USART Parity Error Interrupt */
1678 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1679 }
1680
1681 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1682 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1683
1684 /* Clear the TC flag in the ICR register */
1685 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1686
1687 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1688 in the USART CR3 register */
1689 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1690
1691 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1692 in the USART CR3 register */
1693 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1694
1695 return HAL_OK;
1696 }
1697 else
1698 {
1699 if (husart->hdmarx != NULL)
1700 {
1701 status = HAL_DMA_Abort(husart->hdmarx);
1702 }
1703
1704 /* No need to check on error code */
1705 UNUSED(status);
1706
1707 /* Set error code to DMA */
1708 husart->ErrorCode = HAL_USART_ERROR_DMA;
1709
1710 /* Process Unlocked */
1711 __HAL_UNLOCK(husart);
1712
1713 /* Restore husart->State to ready */
1714 husart->State = HAL_USART_STATE_READY;
1715
1716 return HAL_ERROR;
1717 }
1718 }
1719 else
1720 {
1721 return HAL_BUSY;
1722 }
1723 }
1724
1725 /**
1726 * @brief Pause the DMA Transfer.
1727 * @param husart USART handle.
1728 * @retval HAL status
1729 */
HAL_USART_DMAPause(USART_HandleTypeDef * husart)1730 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1731 {
1732 const HAL_USART_StateTypeDef state = husart->State;
1733
1734 /* Process Locked */
1735 __HAL_LOCK(husart);
1736
1737 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
1738 (state == HAL_USART_STATE_BUSY_TX))
1739 {
1740 /* Disable the USART DMA Tx request */
1741 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1742 }
1743 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1744 (state == HAL_USART_STATE_BUSY_TX_RX))
1745 {
1746 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1747 {
1748 /* Disable the USART DMA Tx request */
1749 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1750 }
1751 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1752 {
1753 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1754 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1755 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1756
1757 /* Disable the USART DMA Rx request */
1758 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1759 }
1760 }
1761 else
1762 {
1763 /* Nothing to do */
1764 }
1765
1766 /* Process Unlocked */
1767 __HAL_UNLOCK(husart);
1768
1769 return HAL_OK;
1770 }
1771
1772 /**
1773 * @brief Resume the DMA Transfer.
1774 * @param husart USART handle.
1775 * @retval HAL status
1776 */
HAL_USART_DMAResume(USART_HandleTypeDef * husart)1777 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1778 {
1779 const HAL_USART_StateTypeDef state = husart->State;
1780
1781 /* Process Locked */
1782 __HAL_LOCK(husart);
1783
1784 if (state == HAL_USART_STATE_BUSY_TX)
1785 {
1786 /* Enable the USART DMA Tx request */
1787 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1788 }
1789 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1790 (state == HAL_USART_STATE_BUSY_TX_RX))
1791 {
1792 /* Clear the Overrun flag before resuming the Rx transfer*/
1793 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
1794
1795 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1796 if (husart->Init.Parity != USART_PARITY_NONE)
1797 {
1798 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1799 }
1800 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1801
1802 /* Enable the USART DMA Rx request before the DMA Tx request */
1803 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1804
1805 /* Enable the USART DMA Tx request */
1806 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1807 }
1808 else
1809 {
1810 /* Nothing to do */
1811 }
1812
1813 /* Process Unlocked */
1814 __HAL_UNLOCK(husart);
1815
1816 return HAL_OK;
1817 }
1818
1819 /**
1820 * @brief Stop the DMA Transfer.
1821 * @param husart USART handle.
1822 * @retval HAL status
1823 */
HAL_USART_DMAStop(USART_HandleTypeDef * husart)1824 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1825 {
1826 /* The Lock is not implemented on this API to allow the user application
1827 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1828 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1829 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1830 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1831 the stream and the corresponding call back is executed. */
1832
1833 /* Disable the USART Tx/Rx DMA requests */
1834 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1835 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1836
1837 /* Abort the USART DMA tx channel */
1838 if (husart->hdmatx != NULL)
1839 {
1840 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1841 {
1842 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1843 {
1844 /* Set error code to DMA */
1845 husart->ErrorCode = HAL_USART_ERROR_DMA;
1846
1847 return HAL_TIMEOUT;
1848 }
1849 }
1850 }
1851 /* Abort the USART DMA rx channel */
1852 if (husart->hdmarx != NULL)
1853 {
1854 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1855 {
1856 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1857 {
1858 /* Set error code to DMA */
1859 husart->ErrorCode = HAL_USART_ERROR_DMA;
1860
1861 return HAL_TIMEOUT;
1862 }
1863 }
1864 }
1865
1866 USART_EndTransfer(husart);
1867 husart->State = HAL_USART_STATE_READY;
1868
1869 return HAL_OK;
1870 }
1871
1872 /**
1873 * @brief Abort ongoing transfers (blocking mode).
1874 * @param husart USART handle.
1875 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1876 * This procedure performs following operations :
1877 * - Disable USART Interrupts (Tx and Rx)
1878 * - Disable the DMA transfer in the peripheral register (if enabled)
1879 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1880 * - Set handle State to READY
1881 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1882 * @retval HAL status
1883 */
HAL_USART_Abort(USART_HandleTypeDef * husart)1884 HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
1885 {
1886 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1887 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
1888 USART_CR1_TCIE));
1889 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1890
1891 /* Abort the USART DMA Tx channel if enabled */
1892 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1893 {
1894 /* Disable the USART DMA Tx request if enabled */
1895 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1896
1897 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1898 if (husart->hdmatx != NULL)
1899 {
1900 /* Set the USART DMA Abort callback to Null.
1901 No call back execution at end of DMA abort procedure */
1902 husart->hdmatx->XferAbortCallback = NULL;
1903
1904 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1905 {
1906 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1907 {
1908 /* Set error code to DMA */
1909 husart->ErrorCode = HAL_USART_ERROR_DMA;
1910
1911 return HAL_TIMEOUT;
1912 }
1913 }
1914 }
1915 }
1916
1917 /* Abort the USART DMA Rx channel if enabled */
1918 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1919 {
1920 /* Disable the USART DMA Rx request if enabled */
1921 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1922
1923 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1924 if (husart->hdmarx != NULL)
1925 {
1926 /* Set the USART DMA Abort callback to Null.
1927 No call back execution at end of DMA abort procedure */
1928 husart->hdmarx->XferAbortCallback = NULL;
1929
1930 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1931 {
1932 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1933 {
1934 /* Set error code to DMA */
1935 husart->ErrorCode = HAL_USART_ERROR_DMA;
1936
1937 return HAL_TIMEOUT;
1938 }
1939 }
1940 }
1941 }
1942
1943 /* Reset Tx and Rx transfer counters */
1944 husart->TxXferCount = 0U;
1945 husart->RxXferCount = 0U;
1946
1947 /* Clear the Error flags in the ICR register */
1948 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
1949
1950 /* Flush the whole TX FIFO (if needed) */
1951 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1952 {
1953 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
1954 }
1955
1956 /* Discard the received data */
1957 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
1958
1959 /* Restore husart->State to Ready */
1960 husart->State = HAL_USART_STATE_READY;
1961
1962 /* Reset Handle ErrorCode to No Error */
1963 husart->ErrorCode = HAL_USART_ERROR_NONE;
1964
1965 return HAL_OK;
1966 }
1967
1968 /**
1969 * @brief Abort ongoing transfers (Interrupt mode).
1970 * @param husart USART handle.
1971 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1972 * This procedure performs following operations :
1973 * - Disable USART Interrupts (Tx and Rx)
1974 * - Disable the DMA transfer in the peripheral register (if enabled)
1975 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1976 * - Set handle State to READY
1977 * - At abort completion, call user abort complete callback
1978 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1979 * considered as completed only when user abort complete callback is executed (not when exiting function).
1980 * @retval HAL status
1981 */
HAL_USART_Abort_IT(USART_HandleTypeDef * husart)1982 HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
1983 {
1984 uint32_t abortcplt = 1U;
1985
1986 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1987 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
1988 USART_CR1_TCIE));
1989 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1990
1991 /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
1992 before any call to DMA Abort functions */
1993 /* DMA Tx Handle is valid */
1994 if (husart->hdmatx != NULL)
1995 {
1996 /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
1997 Otherwise, set it to NULL */
1998 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1999 {
2000 husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
2001 }
2002 else
2003 {
2004 husart->hdmatx->XferAbortCallback = NULL;
2005 }
2006 }
2007 /* DMA Rx Handle is valid */
2008 if (husart->hdmarx != NULL)
2009 {
2010 /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
2011 Otherwise, set it to NULL */
2012 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2013 {
2014 husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
2015 }
2016 else
2017 {
2018 husart->hdmarx->XferAbortCallback = NULL;
2019 }
2020 }
2021
2022 /* Abort the USART DMA Tx channel if enabled */
2023 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2024 {
2025 /* Disable DMA Tx at USART level */
2026 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2027
2028 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2029 if (husart->hdmatx != NULL)
2030 {
2031 /* USART Tx DMA Abort callback has already been initialised :
2032 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2033
2034 /* Abort DMA TX */
2035 if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
2036 {
2037 husart->hdmatx->XferAbortCallback = NULL;
2038 }
2039 else
2040 {
2041 abortcplt = 0U;
2042 }
2043 }
2044 }
2045
2046 /* Abort the USART DMA Rx channel if enabled */
2047 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2048 {
2049 /* Disable the USART DMA Rx request if enabled */
2050 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2051
2052 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2053 if (husart->hdmarx != NULL)
2054 {
2055 /* USART Rx DMA Abort callback has already been initialised :
2056 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2057
2058 /* Abort DMA RX */
2059 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2060 {
2061 husart->hdmarx->XferAbortCallback = NULL;
2062 abortcplt = 1U;
2063 }
2064 else
2065 {
2066 abortcplt = 0U;
2067 }
2068 }
2069 }
2070
2071 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2072 if (abortcplt == 1U)
2073 {
2074 /* Reset Tx and Rx transfer counters */
2075 husart->TxXferCount = 0U;
2076 husart->RxXferCount = 0U;
2077
2078 /* Reset errorCode */
2079 husart->ErrorCode = HAL_USART_ERROR_NONE;
2080
2081 /* Clear the Error flags in the ICR register */
2082 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2083
2084 /* Flush the whole TX FIFO (if needed) */
2085 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2086 {
2087 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2088 }
2089
2090 /* Discard the received data */
2091 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2092
2093 /* Restore husart->State to Ready */
2094 husart->State = HAL_USART_STATE_READY;
2095
2096 /* As no DMA to be aborted, call directly user Abort complete callback */
2097 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2098 /* Call registered Abort Complete Callback */
2099 husart->AbortCpltCallback(husart);
2100 #else
2101 /* Call legacy weak Abort Complete Callback */
2102 HAL_USART_AbortCpltCallback(husart);
2103 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2104 }
2105
2106 return HAL_OK;
2107 }
2108
2109 /**
2110 * @brief Handle USART interrupt request.
2111 * @param husart USART handle.
2112 * @retval None
2113 */
HAL_USART_IRQHandler(USART_HandleTypeDef * husart)2114 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
2115 {
2116 uint32_t isrflags = READ_REG(husart->Instance->ISR);
2117 uint32_t cr1its = READ_REG(husart->Instance->CR1);
2118 uint32_t cr3its = READ_REG(husart->Instance->CR3);
2119
2120 uint32_t errorflags;
2121 uint32_t errorcode;
2122
2123 /* If no error occurs */
2124 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF |
2125 USART_ISR_UDR));
2126 if (errorflags == 0U)
2127 {
2128 /* USART in mode Receiver ---------------------------------------------------*/
2129 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2130 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2131 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2132 {
2133 if (husart->RxISR != NULL)
2134 {
2135 husart->RxISR(husart);
2136 }
2137 return;
2138 }
2139 }
2140
2141 /* If some errors occur */
2142 if ((errorflags != 0U)
2143 && (((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2144 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
2145 {
2146 /* USART parity error interrupt occurred -------------------------------------*/
2147 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2148 {
2149 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
2150
2151 husart->ErrorCode |= HAL_USART_ERROR_PE;
2152 }
2153
2154 /* USART frame error interrupt occurred --------------------------------------*/
2155 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2156 {
2157 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
2158
2159 husart->ErrorCode |= HAL_USART_ERROR_FE;
2160 }
2161
2162 /* USART noise error interrupt occurred --------------------------------------*/
2163 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2164 {
2165 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
2166
2167 husart->ErrorCode |= HAL_USART_ERROR_NE;
2168 }
2169
2170 /* USART Over-Run interrupt occurred -----------------------------------------*/
2171 if (((isrflags & USART_ISR_ORE) != 0U)
2172 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2173 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2174 {
2175 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
2176
2177 husart->ErrorCode |= HAL_USART_ERROR_ORE;
2178 }
2179
2180 /* USART Receiver Timeout interrupt occurred ---------------------------------*/
2181 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2182 {
2183 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF);
2184
2185 husart->ErrorCode |= HAL_USART_ERROR_RTO;
2186 }
2187
2188 /* USART SPI slave underrun error interrupt occurred -------------------------*/
2189 if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2190 {
2191 /* Ignore SPI slave underrun errors when reception is going on */
2192 if (husart->State == HAL_USART_STATE_BUSY_RX)
2193 {
2194 __HAL_USART_CLEAR_UDRFLAG(husart);
2195 return;
2196 }
2197 else
2198 {
2199 __HAL_USART_CLEAR_UDRFLAG(husart);
2200 husart->ErrorCode |= HAL_USART_ERROR_UDR;
2201 }
2202 }
2203
2204 /* Call USART Error Call back function if need be --------------------------*/
2205 if (husart->ErrorCode != HAL_USART_ERROR_NONE)
2206 {
2207 /* USART in mode Receiver ---------------------------------------------------*/
2208 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2209 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2210 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2211 {
2212 if (husart->RxISR != NULL)
2213 {
2214 husart->RxISR(husart);
2215 }
2216 }
2217
2218 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2219 consider error as blocking */
2220 errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE;
2221 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) ||
2222 (errorcode != 0U))
2223 {
2224 /* Blocking error : transfer is aborted
2225 Set the USART state ready to be able to start again the process,
2226 Disable Interrupts, and disable DMA requests, if ongoing */
2227 USART_EndTransfer(husart);
2228
2229 /* Abort the USART DMA Rx channel if enabled */
2230 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2231 {
2232 /* Disable the USART DMA Rx request if enabled */
2233 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
2234
2235 /* Abort the USART DMA Tx channel */
2236 if (husart->hdmatx != NULL)
2237 {
2238 /* Set the USART Tx DMA Abort callback to NULL : no callback
2239 executed at end of DMA abort procedure */
2240 husart->hdmatx->XferAbortCallback = NULL;
2241
2242 /* Abort DMA TX */
2243 (void)HAL_DMA_Abort_IT(husart->hdmatx);
2244 }
2245
2246 /* Abort the USART DMA Rx channel */
2247 if (husart->hdmarx != NULL)
2248 {
2249 /* Set the USART Rx DMA Abort callback :
2250 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2251 husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
2252
2253 /* Abort DMA RX */
2254 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2255 {
2256 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2257 husart->hdmarx->XferAbortCallback(husart->hdmarx);
2258 }
2259 }
2260 else
2261 {
2262 /* Call user error callback */
2263 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2264 /* Call registered Error Callback */
2265 husart->ErrorCallback(husart);
2266 #else
2267 /* Call legacy weak Error Callback */
2268 HAL_USART_ErrorCallback(husart);
2269 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2270 }
2271 }
2272 else
2273 {
2274 /* Call user error callback */
2275 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2276 /* Call registered Error Callback */
2277 husart->ErrorCallback(husart);
2278 #else
2279 /* Call legacy weak Error Callback */
2280 HAL_USART_ErrorCallback(husart);
2281 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2282 }
2283 }
2284 else
2285 {
2286 /* Non Blocking error : transfer could go on.
2287 Error is notified to user through user error callback */
2288 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2289 /* Call registered Error Callback */
2290 husart->ErrorCallback(husart);
2291 #else
2292 /* Call legacy weak Error Callback */
2293 HAL_USART_ErrorCallback(husart);
2294 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2295 husart->ErrorCode = HAL_USART_ERROR_NONE;
2296 }
2297 }
2298 return;
2299
2300 } /* End if some error occurs */
2301
2302
2303 /* USART in mode Transmitter ------------------------------------------------*/
2304 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2305 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2306 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2307 {
2308 if (husart->TxISR != NULL)
2309 {
2310 husart->TxISR(husart);
2311 }
2312 return;
2313 }
2314
2315 /* USART in mode Transmitter (transmission end) -----------------------------*/
2316 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2317 {
2318 USART_EndTransmit_IT(husart);
2319 return;
2320 }
2321
2322 /* USART TX Fifo Empty occurred ----------------------------------------------*/
2323 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2324 {
2325 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2326 /* Call registered Tx Fifo Empty Callback */
2327 husart->TxFifoEmptyCallback(husart);
2328 #else
2329 /* Call legacy weak Tx Fifo Empty Callback */
2330 HAL_USARTEx_TxFifoEmptyCallback(husart);
2331 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2332 return;
2333 }
2334
2335 /* USART RX Fifo Full occurred ----------------------------------------------*/
2336 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2337 {
2338 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2339 /* Call registered Rx Fifo Full Callback */
2340 husart->RxFifoFullCallback(husart);
2341 #else
2342 /* Call legacy weak Rx Fifo Full Callback */
2343 HAL_USARTEx_RxFifoFullCallback(husart);
2344 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2345 return;
2346 }
2347 }
2348
2349 /**
2350 * @brief Tx Transfer completed callback.
2351 * @param husart USART handle.
2352 * @retval None
2353 */
HAL_USART_TxCpltCallback(USART_HandleTypeDef * husart)2354 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
2355 {
2356 /* Prevent unused argument(s) compilation warning */
2357 UNUSED(husart);
2358
2359 /* NOTE : This function should not be modified, when the callback is needed,
2360 the HAL_USART_TxCpltCallback can be implemented in the user file.
2361 */
2362 }
2363
2364 /**
2365 * @brief Tx Half Transfer completed callback.
2366 * @param husart USART handle.
2367 * @retval None
2368 */
HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef * husart)2369 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
2370 {
2371 /* Prevent unused argument(s) compilation warning */
2372 UNUSED(husart);
2373
2374 /* NOTE: This function should not be modified, when the callback is needed,
2375 the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2376 */
2377 }
2378
2379 /**
2380 * @brief Rx Transfer completed callback.
2381 * @param husart USART handle.
2382 * @retval None
2383 */
HAL_USART_RxCpltCallback(USART_HandleTypeDef * husart)2384 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
2385 {
2386 /* Prevent unused argument(s) compilation warning */
2387 UNUSED(husart);
2388
2389 /* NOTE: This function should not be modified, when the callback is needed,
2390 the HAL_USART_RxCpltCallback can be implemented in the user file.
2391 */
2392 }
2393
2394 /**
2395 * @brief Rx Half Transfer completed callback.
2396 * @param husart USART handle.
2397 * @retval None
2398 */
HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef * husart)2399 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
2400 {
2401 /* Prevent unused argument(s) compilation warning */
2402 UNUSED(husart);
2403
2404 /* NOTE : This function should not be modified, when the callback is needed,
2405 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2406 */
2407 }
2408
2409 /**
2410 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2411 * @param husart USART handle.
2412 * @retval None
2413 */
HAL_USART_TxRxCpltCallback(USART_HandleTypeDef * husart)2414 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
2415 {
2416 /* Prevent unused argument(s) compilation warning */
2417 UNUSED(husart);
2418
2419 /* NOTE : This function should not be modified, when the callback is needed,
2420 the HAL_USART_TxRxCpltCallback can be implemented in the user file
2421 */
2422 }
2423
2424 /**
2425 * @brief USART error callback.
2426 * @param husart USART handle.
2427 * @retval None
2428 */
HAL_USART_ErrorCallback(USART_HandleTypeDef * husart)2429 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
2430 {
2431 /* Prevent unused argument(s) compilation warning */
2432 UNUSED(husart);
2433
2434 /* NOTE : This function should not be modified, when the callback is needed,
2435 the HAL_USART_ErrorCallback can be implemented in the user file.
2436 */
2437 }
2438
2439 /**
2440 * @brief USART Abort Complete callback.
2441 * @param husart USART handle.
2442 * @retval None
2443 */
HAL_USART_AbortCpltCallback(USART_HandleTypeDef * husart)2444 __weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
2445 {
2446 /* Prevent unused argument(s) compilation warning */
2447 UNUSED(husart);
2448
2449 /* NOTE : This function should not be modified, when the callback is needed,
2450 the HAL_USART_AbortCpltCallback can be implemented in the user file.
2451 */
2452 }
2453
2454 /**
2455 * @}
2456 */
2457
2458 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2459 * @brief USART Peripheral State and Error functions
2460 *
2461 @verbatim
2462 ==============================================================================
2463 ##### Peripheral State and Error functions #####
2464 ==============================================================================
2465 [..]
2466 This subsection provides functions allowing to :
2467 (+) Return the USART handle state
2468 (+) Return the USART handle error code
2469
2470 @endverbatim
2471 * @{
2472 */
2473
2474
2475 /**
2476 * @brief Return the USART handle state.
2477 * @param husart pointer to a USART_HandleTypeDef structure that contains
2478 * the configuration information for the specified USART.
2479 * @retval USART handle state
2480 */
HAL_USART_GetState(const USART_HandleTypeDef * husart)2481 HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart)
2482 {
2483 return husart->State;
2484 }
2485
2486 /**
2487 * @brief Return the USART error code.
2488 * @param husart pointer to a USART_HandleTypeDef structure that contains
2489 * the configuration information for the specified USART.
2490 * @retval USART handle Error Code
2491 */
HAL_USART_GetError(const USART_HandleTypeDef * husart)2492 uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart)
2493 {
2494 return husart->ErrorCode;
2495 }
2496
2497 /**
2498 * @}
2499 */
2500
2501 /**
2502 * @}
2503 */
2504
2505 /** @defgroup USART_Private_Functions USART Private Functions
2506 * @{
2507 */
2508
2509 /**
2510 * @brief Initialize the callbacks to their default values.
2511 * @param husart USART handle.
2512 * @retval none
2513 */
2514 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
USART_InitCallbacksToDefault(USART_HandleTypeDef * husart)2515 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
2516 {
2517 /* Init the USART Callback settings */
2518 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
2519 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
2520 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
2521 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
2522 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
2523 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
2524 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
2525 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
2526 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
2527 }
2528 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2529
2530 /**
2531 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2532 * @param husart USART handle.
2533 * @retval None
2534 */
USART_EndTransfer(USART_HandleTypeDef * husart)2535 static void USART_EndTransfer(USART_HandleTypeDef *husart)
2536 {
2537 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2538 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2539 USART_CR1_TCIE));
2540 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2541
2542 /* At end of process, restore husart->State to Ready */
2543 husart->State = HAL_USART_STATE_READY;
2544 }
2545
2546 /**
2547 * @brief DMA USART transmit process complete callback.
2548 * @param hdma DMA handle.
2549 * @retval None
2550 */
USART_DMATransmitCplt(DMA_HandleTypeDef * hdma)2551 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2552 {
2553 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2554
2555 /* DMA Normal mode */
2556 if (hdma->Init.Mode != DMA_CIRCULAR)
2557 {
2558 husart->TxXferCount = 0U;
2559
2560 if (husart->State == HAL_USART_STATE_BUSY_TX)
2561 {
2562 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2563 in the USART CR3 register */
2564 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2565
2566 /* Enable the USART Transmit Complete Interrupt */
2567 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2568 }
2569 }
2570 /* DMA Circular mode */
2571 else
2572 {
2573 if (husart->State == HAL_USART_STATE_BUSY_TX)
2574 {
2575 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2576 /* Call registered Tx Complete Callback */
2577 husart->TxCpltCallback(husart);
2578 #else
2579 /* Call legacy weak Tx Complete Callback */
2580 HAL_USART_TxCpltCallback(husart);
2581 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2582 }
2583 }
2584 }
2585
2586 /**
2587 * @brief DMA USART transmit process half complete callback.
2588 * @param hdma DMA handle.
2589 * @retval None
2590 */
USART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2591 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2592 {
2593 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2594
2595 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2596 /* Call registered Tx Half Complete Callback */
2597 husart->TxHalfCpltCallback(husart);
2598 #else
2599 /* Call legacy weak Tx Half Complete Callback */
2600 HAL_USART_TxHalfCpltCallback(husart);
2601 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2602 }
2603
2604 /**
2605 * @brief DMA USART receive process complete callback.
2606 * @param hdma DMA handle.
2607 * @retval None
2608 */
USART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2609 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2610 {
2611 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2612
2613 /* DMA Normal mode */
2614 if (hdma->Init.Mode != DMA_CIRCULAR)
2615 {
2616 husart->RxXferCount = 0U;
2617
2618 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2619 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2620 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2621
2622 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2623 in USART CR3 register */
2624 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2625 /* similarly, disable the DMA TX transfer that was started to provide the
2626 clock to the slave device */
2627 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2628
2629 if (husart->State == HAL_USART_STATE_BUSY_RX)
2630 {
2631 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2632 /* Call registered Rx Complete Callback */
2633 husart->RxCpltCallback(husart);
2634 #else
2635 /* Call legacy weak Rx Complete Callback */
2636 HAL_USART_RxCpltCallback(husart);
2637 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2638 }
2639 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2640 else
2641 {
2642 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2643 /* Call registered Tx Rx Complete Callback */
2644 husart->TxRxCpltCallback(husart);
2645 #else
2646 /* Call legacy weak Tx Rx Complete Callback */
2647 HAL_USART_TxRxCpltCallback(husart);
2648 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2649 }
2650 husart->State = HAL_USART_STATE_READY;
2651 }
2652 /* DMA circular mode */
2653 else
2654 {
2655 if (husart->State == HAL_USART_STATE_BUSY_RX)
2656 {
2657 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2658 /* Call registered Rx Complete Callback */
2659 husart->RxCpltCallback(husart);
2660 #else
2661 /* Call legacy weak Rx Complete Callback */
2662 HAL_USART_RxCpltCallback(husart);
2663 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2664 }
2665 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2666 else
2667 {
2668 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2669 /* Call registered Tx Rx Complete Callback */
2670 husart->TxRxCpltCallback(husart);
2671 #else
2672 /* Call legacy weak Tx Rx Complete Callback */
2673 HAL_USART_TxRxCpltCallback(husart);
2674 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2675 }
2676 }
2677 }
2678
2679 /**
2680 * @brief DMA USART receive process half complete callback.
2681 * @param hdma DMA handle.
2682 * @retval None
2683 */
USART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2684 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2685 {
2686 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2687
2688 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2689 /* Call registered Rx Half Complete Callback */
2690 husart->RxHalfCpltCallback(husart);
2691 #else
2692 /* Call legacy weak Rx Half Complete Callback */
2693 HAL_USART_RxHalfCpltCallback(husart);
2694 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2695 }
2696
2697 /**
2698 * @brief DMA USART communication error callback.
2699 * @param hdma DMA handle.
2700 * @retval None
2701 */
USART_DMAError(DMA_HandleTypeDef * hdma)2702 static void USART_DMAError(DMA_HandleTypeDef *hdma)
2703 {
2704 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2705
2706 husart->RxXferCount = 0U;
2707 husart->TxXferCount = 0U;
2708 USART_EndTransfer(husart);
2709
2710 husart->ErrorCode |= HAL_USART_ERROR_DMA;
2711 husart->State = HAL_USART_STATE_READY;
2712
2713 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2714 /* Call registered Error Callback */
2715 husart->ErrorCallback(husart);
2716 #else
2717 /* Call legacy weak Error Callback */
2718 HAL_USART_ErrorCallback(husart);
2719 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2720 }
2721
2722 /**
2723 * @brief DMA USART communication abort callback, when initiated by HAL services on Error
2724 * (To be called at end of DMA Abort procedure following error occurrence).
2725 * @param hdma DMA handle.
2726 * @retval None
2727 */
USART_DMAAbortOnError(DMA_HandleTypeDef * hdma)2728 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2729 {
2730 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2731 husart->RxXferCount = 0U;
2732 husart->TxXferCount = 0U;
2733
2734 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2735 /* Call registered Error Callback */
2736 husart->ErrorCallback(husart);
2737 #else
2738 /* Call legacy weak Error Callback */
2739 HAL_USART_ErrorCallback(husart);
2740 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2741 }
2742
2743 /**
2744 * @brief DMA USART Tx communication abort callback, when initiated by user
2745 * (To be called at end of DMA Tx Abort procedure following user abort request).
2746 * @note When this callback is executed, User Abort complete call back is called only if no
2747 * Abort still ongoing for Rx DMA Handle.
2748 * @param hdma DMA handle.
2749 * @retval None
2750 */
USART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2751 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2752 {
2753 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2754
2755 husart->hdmatx->XferAbortCallback = NULL;
2756
2757 /* Check if an Abort process is still ongoing */
2758 if (husart->hdmarx != NULL)
2759 {
2760 if (husart->hdmarx->XferAbortCallback != NULL)
2761 {
2762 return;
2763 }
2764 }
2765
2766 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2767 husart->TxXferCount = 0U;
2768 husart->RxXferCount = 0U;
2769
2770 /* Reset errorCode */
2771 husart->ErrorCode = HAL_USART_ERROR_NONE;
2772
2773 /* Clear the Error flags in the ICR register */
2774 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2775
2776 /* Restore husart->State to Ready */
2777 husart->State = HAL_USART_STATE_READY;
2778
2779 /* Call user Abort complete callback */
2780 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2781 /* Call registered Abort Complete Callback */
2782 husart->AbortCpltCallback(husart);
2783 #else
2784 /* Call legacy weak Abort Complete Callback */
2785 HAL_USART_AbortCpltCallback(husart);
2786 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2787
2788 }
2789
2790
2791 /**
2792 * @brief DMA USART Rx communication abort callback, when initiated by user
2793 * (To be called at end of DMA Rx Abort procedure following user abort request).
2794 * @note When this callback is executed, User Abort complete call back is called only if no
2795 * Abort still ongoing for Tx DMA Handle.
2796 * @param hdma DMA handle.
2797 * @retval None
2798 */
USART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)2799 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2800 {
2801 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2802
2803 husart->hdmarx->XferAbortCallback = NULL;
2804
2805 /* Check if an Abort process is still ongoing */
2806 if (husart->hdmatx != NULL)
2807 {
2808 if (husart->hdmatx->XferAbortCallback != NULL)
2809 {
2810 return;
2811 }
2812 }
2813
2814 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2815 husart->TxXferCount = 0U;
2816 husart->RxXferCount = 0U;
2817
2818 /* Reset errorCode */
2819 husart->ErrorCode = HAL_USART_ERROR_NONE;
2820
2821 /* Clear the Error flags in the ICR register */
2822 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2823
2824 /* Restore husart->State to Ready */
2825 husart->State = HAL_USART_STATE_READY;
2826
2827 /* Call user Abort complete callback */
2828 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2829 /* Call registered Abort Complete Callback */
2830 husart->AbortCpltCallback(husart);
2831 #else
2832 /* Call legacy weak Abort Complete Callback */
2833 HAL_USART_AbortCpltCallback(husart);
2834 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2835 }
2836
2837
2838 /**
2839 * @brief Handle USART Communication Timeout. It waits
2840 * until a flag is no longer in the specified status.
2841 * @param husart USART handle.
2842 * @param Flag Specifies the USART flag to check.
2843 * @param Status the actual Flag status (SET or RESET).
2844 * @param Tickstart Tick start value
2845 * @param Timeout timeout duration.
2846 * @retval HAL status
2847 */
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef * husart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)2848 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
2849 uint32_t Tickstart, uint32_t Timeout)
2850 {
2851 /* Wait until flag is set */
2852 while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
2853 {
2854 /* Check for the Timeout */
2855 if (Timeout != HAL_MAX_DELAY)
2856 {
2857 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2858 {
2859 husart->State = HAL_USART_STATE_READY;
2860
2861 /* Process Unlocked */
2862 __HAL_UNLOCK(husart);
2863
2864 return HAL_TIMEOUT;
2865 }
2866 }
2867 }
2868 return HAL_OK;
2869 }
2870
2871 /**
2872 * @brief Configure the USART peripheral.
2873 * @param husart USART handle.
2874 * @retval HAL status
2875 */
USART_SetConfig(USART_HandleTypeDef * husart)2876 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
2877 {
2878 uint32_t tmpreg;
2879 USART_ClockSourceTypeDef clocksource;
2880 HAL_StatusTypeDef ret = HAL_OK;
2881 uint16_t brrtemp;
2882 uint32_t usartdiv = 0x00000000;
2883 PLL2_ClocksTypeDef pll2_clocks;
2884 PLL3_ClocksTypeDef pll3_clocks;
2885 uint32_t pclk;
2886
2887 /* Check the parameters */
2888 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
2889 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
2890 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
2891 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
2892 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
2893 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
2894 assert_param(IS_USART_PARITY(husart->Init.Parity));
2895 assert_param(IS_USART_MODE(husart->Init.Mode));
2896 assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler));
2897
2898 /*-------------------------- USART CR1 Configuration -----------------------*/
2899 /* Clear M, PCE, PS, TE and RE bits and configure
2900 * the USART Word Length, Parity and Mode:
2901 * set the M bits according to husart->Init.WordLength value
2902 * set PCE and PS bits according to husart->Init.Parity value
2903 * set TE and RE bits according to husart->Init.Mode value
2904 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
2905 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
2906 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2907
2908 /*---------------------------- USART CR2 Configuration ---------------------*/
2909 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
2910 * set CPOL bit according to husart->Init.CLKPolarity value
2911 * set CPHA bit according to husart->Init.CLKPhase value
2912 * set LBCL bit according to husart->Init.CLKLastBit value (used in USART Synchronous SPI master mode only)
2913 * set STOP[13:12] bits according to husart->Init.StopBits value */
2914 tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
2915 tmpreg |= (uint32_t)husart->Init.CLKLastBit;
2916 tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
2917 tmpreg |= (uint32_t)husart->Init.StopBits;
2918 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
2919
2920 /*-------------------------- USART PRESC Configuration -----------------------*/
2921 /* Configure
2922 * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
2923 MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler);
2924
2925 /*-------------------------- USART BRR Configuration -----------------------*/
2926 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
2927 USART_GETCLOCKSOURCE(husart, clocksource);
2928
2929 switch (clocksource)
2930 {
2931 case USART_CLOCKSOURCE_D2PCLK1:
2932 pclk = HAL_RCC_GetPCLK1Freq();
2933 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2934 break;
2935 case USART_CLOCKSOURCE_D2PCLK2:
2936 pclk = HAL_RCC_GetPCLK2Freq();
2937 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2938 break;
2939 case USART_CLOCKSOURCE_PLL2:
2940 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
2941 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pll2_clocks.PLL2_Q_Frequency, husart->Init.BaudRate,
2942 husart->Init.ClockPrescaler));
2943 break;
2944 case USART_CLOCKSOURCE_PLL3:
2945 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
2946 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pll3_clocks.PLL3_Q_Frequency, husart->Init.BaudRate,
2947 husart->Init.ClockPrescaler));
2948 break;
2949 case USART_CLOCKSOURCE_HSI:
2950 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2951 {
2952 usartdiv = (uint32_t)(USART_DIV_SAMPLING8((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)),
2953 husart->Init.BaudRate, husart->Init.ClockPrescaler));
2954 }
2955 else
2956 {
2957 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2958 }
2959 break;
2960 case USART_CLOCKSOURCE_CSI:
2961 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(CSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2962 break;
2963 case USART_CLOCKSOURCE_LSE:
2964 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2965 break;
2966 default:
2967 ret = HAL_ERROR;
2968 break;
2969 }
2970
2971 /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
2972 if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
2973 {
2974 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
2975 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
2976 husart->Instance->BRR = brrtemp;
2977 }
2978 else
2979 {
2980 ret = HAL_ERROR;
2981 }
2982
2983 /* Initialize the number of data to process during RX/TX ISR execution */
2984 husart->NbTxDataToProcess = 1U;
2985 husart->NbRxDataToProcess = 1U;
2986
2987 /* Clear ISR function pointers */
2988 husart->RxISR = NULL;
2989 husart->TxISR = NULL;
2990
2991 return ret;
2992 }
2993
2994 /**
2995 * @brief Check the USART Idle State.
2996 * @param husart USART handle.
2997 * @retval HAL status
2998 */
USART_CheckIdleState(USART_HandleTypeDef * husart)2999 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
3000 {
3001 uint32_t tickstart;
3002
3003 /* Initialize the USART ErrorCode */
3004 husart->ErrorCode = HAL_USART_ERROR_NONE;
3005
3006 /* Init tickstart for timeout management */
3007 tickstart = HAL_GetTick();
3008
3009 /* Check if the Transmitter is enabled */
3010 if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3011 {
3012 /* Wait until TEACK flag is set */
3013 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3014 {
3015 /* Timeout occurred */
3016 return HAL_TIMEOUT;
3017 }
3018 }
3019 /* Check if the Receiver is enabled */
3020 if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3021 {
3022 /* Wait until REACK flag is set */
3023 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3024 {
3025 /* Timeout occurred */
3026 return HAL_TIMEOUT;
3027 }
3028 }
3029
3030 /* Initialize the USART state*/
3031 husart->State = HAL_USART_STATE_READY;
3032
3033 /* Process Unlocked */
3034 __HAL_UNLOCK(husart);
3035
3036 return HAL_OK;
3037 }
3038
3039 /**
3040 * @brief Simplex send an amount of data in non-blocking mode.
3041 * @note Function called under interruption only, once
3042 * interruptions have been enabled by HAL_USART_Transmit_IT().
3043 * @note The USART errors are not managed to avoid the overrun error.
3044 * @note ISR function executed when FIFO mode is disabled and when the
3045 * data word length is less than 9 bits long.
3046 * @param husart USART handle.
3047 * @retval None
3048 */
USART_TxISR_8BIT(USART_HandleTypeDef * husart)3049 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
3050 {
3051 const HAL_USART_StateTypeDef state = husart->State;
3052
3053 /* Check that a Tx process is ongoing */
3054 if ((state == HAL_USART_STATE_BUSY_TX) ||
3055 (state == HAL_USART_STATE_BUSY_TX_RX))
3056 {
3057 if (husart->TxXferCount == 0U)
3058 {
3059 /* Disable the USART Transmit data register empty interrupt */
3060 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3061
3062 /* Enable the USART Transmit Complete Interrupt */
3063 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3064 }
3065 else
3066 {
3067 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3068 husart->pTxBuffPtr++;
3069 husart->TxXferCount--;
3070 }
3071 }
3072 }
3073
3074 /**
3075 * @brief Simplex send an amount of data in non-blocking mode.
3076 * @note Function called under interruption only, once
3077 * interruptions have been enabled by HAL_USART_Transmit_IT().
3078 * @note The USART errors are not managed to avoid the overrun error.
3079 * @note ISR function executed when FIFO mode is disabled and when the
3080 * data word length is 9 bits long.
3081 * @param husart USART handle.
3082 * @retval None
3083 */
USART_TxISR_16BIT(USART_HandleTypeDef * husart)3084 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
3085 {
3086 const HAL_USART_StateTypeDef state = husart->State;
3087 const uint16_t *tmp;
3088
3089 if ((state == HAL_USART_STATE_BUSY_TX) ||
3090 (state == HAL_USART_STATE_BUSY_TX_RX))
3091 {
3092 if (husart->TxXferCount == 0U)
3093 {
3094 /* Disable the USART Transmit data register empty interrupt */
3095 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3096
3097 /* Enable the USART Transmit Complete Interrupt */
3098 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3099 }
3100 else
3101 {
3102 tmp = (const uint16_t *) husart->pTxBuffPtr;
3103 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3104 husart->pTxBuffPtr += 2U;
3105 husart->TxXferCount--;
3106 }
3107 }
3108 }
3109
3110 /**
3111 * @brief Simplex send an amount of data in non-blocking mode.
3112 * @note Function called under interruption only, once
3113 * interruptions have been enabled by HAL_USART_Transmit_IT().
3114 * @note The USART errors are not managed to avoid the overrun error.
3115 * @note ISR function executed when FIFO mode is enabled and when the
3116 * data word length is less than 9 bits long.
3117 * @param husart USART handle.
3118 * @retval None
3119 */
USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3120 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3121 {
3122 const HAL_USART_StateTypeDef state = husart->State;
3123 uint16_t nb_tx_data;
3124
3125 /* Check that a Tx process is ongoing */
3126 if ((state == HAL_USART_STATE_BUSY_TX) ||
3127 (state == HAL_USART_STATE_BUSY_TX_RX))
3128 {
3129 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3130 {
3131 if (husart->TxXferCount == 0U)
3132 {
3133 /* Disable the TX FIFO threshold interrupt */
3134 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3135
3136 /* Enable the USART Transmit Complete Interrupt */
3137 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3138
3139 break; /* force exit loop */
3140 }
3141 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3142 {
3143 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3144 husart->pTxBuffPtr++;
3145 husart->TxXferCount--;
3146 }
3147 else
3148 {
3149 /* Nothing to do */
3150 }
3151 }
3152 }
3153 }
3154
3155 /**
3156 * @brief Simplex send an amount of data in non-blocking mode.
3157 * @note Function called under interruption only, once
3158 * interruptions have been enabled by HAL_USART_Transmit_IT().
3159 * @note The USART errors are not managed to avoid the overrun error.
3160 * @note ISR function executed when FIFO mode is enabled and when the
3161 * data word length is 9 bits long.
3162 * @param husart USART handle.
3163 * @retval None
3164 */
USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3165 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3166 {
3167 const HAL_USART_StateTypeDef state = husart->State;
3168 const uint16_t *tmp;
3169 uint16_t nb_tx_data;
3170
3171 /* Check that a Tx process is ongoing */
3172 if ((state == HAL_USART_STATE_BUSY_TX) ||
3173 (state == HAL_USART_STATE_BUSY_TX_RX))
3174 {
3175 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3176 {
3177 if (husart->TxXferCount == 0U)
3178 {
3179 /* Disable the TX FIFO threshold interrupt */
3180 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3181
3182 /* Enable the USART Transmit Complete Interrupt */
3183 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3184
3185 break; /* force exit loop */
3186 }
3187 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3188 {
3189 tmp = (const uint16_t *) husart->pTxBuffPtr;
3190 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3191 husart->pTxBuffPtr += 2U;
3192 husart->TxXferCount--;
3193 }
3194 else
3195 {
3196 /* Nothing to do */
3197 }
3198 }
3199 }
3200 }
3201
3202 /**
3203 * @brief Wraps up transmission in non-blocking mode.
3204 * @param husart Pointer to a USART_HandleTypeDef structure that contains
3205 * the configuration information for the specified USART module.
3206 * @retval None
3207 */
USART_EndTransmit_IT(USART_HandleTypeDef * husart)3208 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3209 {
3210 /* Disable the USART Transmit Complete Interrupt */
3211 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3212
3213 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3214 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3215
3216 /* Clear TxISR function pointer */
3217 husart->TxISR = NULL;
3218
3219 if (husart->State == HAL_USART_STATE_BUSY_TX)
3220 {
3221 /* Clear overrun flag and discard the received data */
3222 __HAL_USART_CLEAR_OREFLAG(husart);
3223 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3224
3225 /* Tx process is completed, restore husart->State to Ready */
3226 husart->State = HAL_USART_STATE_READY;
3227
3228 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3229 /* Call registered Tx Complete Callback */
3230 husart->TxCpltCallback(husart);
3231 #else
3232 /* Call legacy weak Tx Complete Callback */
3233 HAL_USART_TxCpltCallback(husart);
3234 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3235 }
3236 else if (husart->RxXferCount == 0U)
3237 {
3238 /* TxRx process is completed, restore husart->State to Ready */
3239 husart->State = HAL_USART_STATE_READY;
3240
3241 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3242 /* Call registered Tx Rx Complete Callback */
3243 husart->TxRxCpltCallback(husart);
3244 #else
3245 /* Call legacy weak Tx Rx Complete Callback */
3246 HAL_USART_TxRxCpltCallback(husart);
3247 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3248 }
3249 else
3250 {
3251 /* Nothing to do */
3252 }
3253 }
3254
3255
3256 /**
3257 * @brief Simplex receive an amount of data in non-blocking mode.
3258 * @note Function called under interruption only, once
3259 * interruptions have been enabled by HAL_USART_Receive_IT().
3260 * @note ISR function executed when FIFO mode is disabled and when the
3261 * data word length is less than 9 bits long.
3262 * @param husart USART handle
3263 * @retval None
3264 */
USART_RxISR_8BIT(USART_HandleTypeDef * husart)3265 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3266 {
3267 const HAL_USART_StateTypeDef state = husart->State;
3268 uint16_t txdatacount;
3269 uint16_t uhMask = husart->Mask;
3270 uint32_t txftie;
3271
3272 if ((state == HAL_USART_STATE_BUSY_RX) ||
3273 (state == HAL_USART_STATE_BUSY_TX_RX))
3274 {
3275 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3276 husart->pRxBuffPtr++;
3277 husart->RxXferCount--;
3278
3279 if (husart->RxXferCount == 0U)
3280 {
3281 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3282 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3283
3284 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3285 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3286
3287 /* Clear RxISR function pointer */
3288 husart->RxISR = NULL;
3289
3290 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3291 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3292 txdatacount = husart->TxXferCount;
3293
3294 if (state == HAL_USART_STATE_BUSY_RX)
3295 {
3296 /* Clear SPI slave underrun flag and discard transmit data */
3297 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3298 {
3299 __HAL_USART_CLEAR_UDRFLAG(husart);
3300 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3301 }
3302
3303 /* Rx process is completed, restore husart->State to Ready */
3304 husart->State = HAL_USART_STATE_READY;
3305
3306 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3307 /* Call registered Rx Complete Callback */
3308 husart->RxCpltCallback(husart);
3309 #else
3310 /* Call legacy weak Rx Complete Callback */
3311 HAL_USART_RxCpltCallback(husart);
3312 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3313 }
3314 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3315 (txftie != USART_CR3_TXFTIE) &&
3316 (txdatacount == 0U))
3317 {
3318 /* TxRx process is completed, restore husart->State to Ready */
3319 husart->State = HAL_USART_STATE_READY;
3320
3321 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3322 /* Call registered Tx Rx Complete Callback */
3323 husart->TxRxCpltCallback(husart);
3324 #else
3325 /* Call legacy weak Tx Rx Complete Callback */
3326 HAL_USART_TxRxCpltCallback(husart);
3327 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3328 }
3329 else
3330 {
3331 /* Nothing to do */
3332 }
3333 }
3334 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3335 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3336 {
3337 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3338 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3339 }
3340 else
3341 {
3342 /* Nothing to do */
3343 }
3344 }
3345 }
3346
3347 /**
3348 * @brief Simplex receive an amount of data in non-blocking mode.
3349 * @note Function called under interruption only, once
3350 * interruptions have been enabled by HAL_USART_Receive_IT().
3351 * @note ISR function executed when FIFO mode is disabled and when the
3352 * data word length is 9 bits long.
3353 * @param husart USART handle
3354 * @retval None
3355 */
USART_RxISR_16BIT(USART_HandleTypeDef * husart)3356 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
3357 {
3358 const HAL_USART_StateTypeDef state = husart->State;
3359 uint16_t txdatacount;
3360 uint16_t *tmp;
3361 uint16_t uhMask = husart->Mask;
3362 uint32_t txftie;
3363
3364 if ((state == HAL_USART_STATE_BUSY_RX) ||
3365 (state == HAL_USART_STATE_BUSY_TX_RX))
3366 {
3367 tmp = (uint16_t *) husart->pRxBuffPtr;
3368 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3369 husart->pRxBuffPtr += 2U;
3370 husart->RxXferCount--;
3371
3372 if (husart->RxXferCount == 0U)
3373 {
3374 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3375 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3376
3377 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3378 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3379
3380 /* Clear RxISR function pointer */
3381 husart->RxISR = NULL;
3382
3383 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3384 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3385 txdatacount = husart->TxXferCount;
3386
3387 if (state == HAL_USART_STATE_BUSY_RX)
3388 {
3389 /* Clear SPI slave underrun flag and discard transmit data */
3390 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3391 {
3392 __HAL_USART_CLEAR_UDRFLAG(husart);
3393 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3394 }
3395
3396 /* Rx process is completed, restore husart->State to Ready */
3397 husart->State = HAL_USART_STATE_READY;
3398
3399 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3400 /* Call registered Rx Complete Callback */
3401 husart->RxCpltCallback(husart);
3402 #else
3403 /* Call legacy weak Rx Complete Callback */
3404 HAL_USART_RxCpltCallback(husart);
3405 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3406 }
3407 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3408 (txftie != USART_CR3_TXFTIE) &&
3409 (txdatacount == 0U))
3410 {
3411 /* TxRx process is completed, restore husart->State to Ready */
3412 husart->State = HAL_USART_STATE_READY;
3413
3414 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3415 /* Call registered Tx Rx Complete Callback */
3416 husart->TxRxCpltCallback(husart);
3417 #else
3418 /* Call legacy weak Tx Rx Complete Callback */
3419 HAL_USART_TxRxCpltCallback(husart);
3420 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3421 }
3422 else
3423 {
3424 /* Nothing to do */
3425 }
3426 }
3427 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3428 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3429 {
3430 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3431 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3432 }
3433 else
3434 {
3435 /* Nothing to do */
3436 }
3437 }
3438 }
3439
3440 /**
3441 * @brief Simplex receive an amount of data in non-blocking mode.
3442 * @note Function called under interruption only, once
3443 * interruptions have been enabled by HAL_USART_Receive_IT().
3444 * @note ISR function executed when FIFO mode is enabled and when the
3445 * data word length is less than 9 bits long.
3446 * @param husart USART handle
3447 * @retval None
3448 */
USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3449 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3450 {
3451 HAL_USART_StateTypeDef state = husart->State;
3452 uint16_t txdatacount;
3453 uint16_t rxdatacount;
3454 uint16_t uhMask = husart->Mask;
3455 uint16_t nb_rx_data;
3456 uint32_t txftie;
3457
3458 /* Check that a Rx process is ongoing */
3459 if ((state == HAL_USART_STATE_BUSY_RX) ||
3460 (state == HAL_USART_STATE_BUSY_TX_RX))
3461 {
3462 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3463 {
3464 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3465 {
3466 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
3467 husart->pRxBuffPtr++;
3468 husart->RxXferCount--;
3469
3470 if (husart->RxXferCount == 0U)
3471 {
3472 /* Disable the USART Parity Error Interrupt */
3473 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3474
3475 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3476 and RX FIFO Threshold interrupt */
3477 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3478
3479 /* Clear RxISR function pointer */
3480 husart->RxISR = NULL;
3481
3482 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3483 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3484 txdatacount = husart->TxXferCount;
3485
3486 if (state == HAL_USART_STATE_BUSY_RX)
3487 {
3488 /* Clear SPI slave underrun flag and discard transmit data */
3489 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3490 {
3491 __HAL_USART_CLEAR_UDRFLAG(husart);
3492 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3493 }
3494
3495 /* Rx process is completed, restore husart->State to Ready */
3496 husart->State = HAL_USART_STATE_READY;
3497 state = HAL_USART_STATE_READY;
3498
3499 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3500 /* Call registered Rx Complete Callback */
3501 husart->RxCpltCallback(husart);
3502 #else
3503 /* Call legacy weak Rx Complete Callback */
3504 HAL_USART_RxCpltCallback(husart);
3505 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3506 }
3507 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3508 (txftie != USART_CR3_TXFTIE) &&
3509 (txdatacount == 0U))
3510 {
3511 /* TxRx process is completed, restore husart->State to Ready */
3512 husart->State = HAL_USART_STATE_READY;
3513 state = HAL_USART_STATE_READY;
3514
3515 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3516 /* Call registered Tx Rx Complete Callback */
3517 husart->TxRxCpltCallback(husart);
3518 #else
3519 /* Call legacy weak Tx Rx Complete Callback */
3520 HAL_USART_TxRxCpltCallback(husart);
3521 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3522 }
3523 else
3524 {
3525 /* Nothing to do */
3526 }
3527 }
3528 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3529 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3530 {
3531 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3532 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3533 }
3534 else
3535 {
3536 /* Nothing to do */
3537 }
3538 }
3539 }
3540
3541 /* When remaining number of bytes to receive is less than the RX FIFO
3542 threshold, next incoming frames are processed as if FIFO mode was
3543 disabled (i.e. one interrupt per received frame).
3544 */
3545 rxdatacount = husart->RxXferCount;
3546 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3547 {
3548 /* Disable the USART RXFT interrupt*/
3549 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3550
3551 /* Update the RxISR function pointer */
3552 husart->RxISR = USART_RxISR_8BIT;
3553
3554 /* Enable the USART Data Register Not Empty interrupt */
3555 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3556
3557 if ((husart->TxXferCount == 0U) &&
3558 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3559 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3560 {
3561 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3562 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3563 }
3564 }
3565 }
3566 else
3567 {
3568 /* Clear RXNE interrupt flag */
3569 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3570 }
3571 }
3572
3573 /**
3574 * @brief Simplex receive an amount of data in non-blocking mode.
3575 * @note Function called under interruption only, once
3576 * interruptions have been enabled by HAL_USART_Receive_IT().
3577 * @note ISR function executed when FIFO mode is enabled and when the
3578 * data word length is 9 bits long.
3579 * @param husart USART handle
3580 * @retval None
3581 */
USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3582 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3583 {
3584 HAL_USART_StateTypeDef state = husart->State;
3585 uint16_t txdatacount;
3586 uint16_t rxdatacount;
3587 uint16_t *tmp;
3588 uint16_t uhMask = husart->Mask;
3589 uint16_t nb_rx_data;
3590 uint32_t txftie;
3591
3592 /* Check that a Tx process is ongoing */
3593 if ((state == HAL_USART_STATE_BUSY_RX) ||
3594 (state == HAL_USART_STATE_BUSY_TX_RX))
3595 {
3596 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3597 {
3598 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3599 {
3600 tmp = (uint16_t *) husart->pRxBuffPtr;
3601 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3602 husart->pRxBuffPtr += 2U;
3603 husart->RxXferCount--;
3604
3605 if (husart->RxXferCount == 0U)
3606 {
3607 /* Disable the USART Parity Error Interrupt */
3608 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3609
3610 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3611 and RX FIFO Threshold interrupt */
3612 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3613
3614 /* Clear RxISR function pointer */
3615 husart->RxISR = NULL;
3616
3617 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3618 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3619 txdatacount = husart->TxXferCount;
3620
3621 if (state == HAL_USART_STATE_BUSY_RX)
3622 {
3623 /* Clear SPI slave underrun flag and discard transmit data */
3624 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3625 {
3626 __HAL_USART_CLEAR_UDRFLAG(husart);
3627 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3628 }
3629
3630 /* Rx process is completed, restore husart->State to Ready */
3631 husart->State = HAL_USART_STATE_READY;
3632 state = HAL_USART_STATE_READY;
3633
3634 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3635 /* Call registered Rx Complete Callback */
3636 husart->RxCpltCallback(husart);
3637 #else
3638 /* Call legacy weak Rx Complete Callback */
3639 HAL_USART_RxCpltCallback(husart);
3640 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3641 }
3642 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3643 (txftie != USART_CR3_TXFTIE) &&
3644 (txdatacount == 0U))
3645 {
3646 /* TxRx process is completed, restore husart->State to Ready */
3647 husart->State = HAL_USART_STATE_READY;
3648 state = HAL_USART_STATE_READY;
3649
3650 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3651 /* Call registered Tx Rx Complete Callback */
3652 husart->TxRxCpltCallback(husart);
3653 #else
3654 /* Call legacy weak Tx Rx Complete Callback */
3655 HAL_USART_TxRxCpltCallback(husart);
3656 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3657 }
3658 else
3659 {
3660 /* Nothing to do */
3661 }
3662 }
3663 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3664 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3665 {
3666 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3667 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3668 }
3669 else
3670 {
3671 /* Nothing to do */
3672 }
3673 }
3674 }
3675
3676 /* When remaining number of bytes to receive is less than the RX FIFO
3677 threshold, next incoming frames are processed as if FIFO mode was
3678 disabled (i.e. one interrupt per received frame).
3679 */
3680 rxdatacount = husart->RxXferCount;
3681 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3682 {
3683 /* Disable the USART RXFT interrupt*/
3684 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3685
3686 /* Update the RxISR function pointer */
3687 husart->RxISR = USART_RxISR_16BIT;
3688
3689 /* Enable the USART Data Register Not Empty interrupt */
3690 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3691
3692 if ((husart->TxXferCount == 0U) &&
3693 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3694 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3695 {
3696 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3697 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3698 }
3699 }
3700 }
3701 else
3702 {
3703 /* Clear RXNE interrupt flag */
3704 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3705 }
3706 }
3707
3708 /**
3709 * @}
3710 */
3711
3712 #endif /* HAL_USART_MODULE_ENABLED */
3713 /**
3714 * @}
3715 */
3716
3717 /**
3718 * @}
3719 */
3720
3721