Merge maintenance-8.x.x fixes into master
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_usart.c
blob6c77f25fad3dd384ed865024201ff5f3fc024c13
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
14 ******************************************************************************
15 * @attention
17 * Copyright (c) 2017 STMicroelectronics.
18 * All rights reserved.
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.
24 ******************************************************************************
25 @verbatim
26 ===============================================================================
27 ##### How to use this driver #####
28 ===============================================================================
29 [..]
30 The USART HAL driver can be used as follows:
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.
56 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
57 (Receiver/Transmitter) in the husart handle Init structure.
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.
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.
68 ##### Callback registration #####
69 ==================================
71 [..]
72 The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
73 allows the user to configure dynamically the driver callbacks.
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.
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.
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).
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.
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.
135 @endverbatim
136 ******************************************************************************
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32h7xx_hal.h"
142 /** @addtogroup STM32H7xx_HAL_Driver
143 * @{
146 /** @defgroup USART USART
147 * @brief HAL USART Synchronous SPI module driver
148 * @{
151 #ifdef HAL_USART_MODULE_ENABLED
153 /* Private typedef -----------------------------------------------------------*/
154 /* Private define ------------------------------------------------------------*/
155 /** @defgroup USART_Private_Constants USART Private Constants
156 * @{
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 */
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 */
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 */
170 #define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */
171 #define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */
173 * @}
176 /* Private macros ------------------------------------------------------------*/
177 /* Private variables ---------------------------------------------------------*/
178 /* Private function prototypes -----------------------------------------------*/
179 /** @addtogroup USART_Private_Functions
180 * @{
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);
210 * @}
213 /* Exported functions --------------------------------------------------------*/
215 /** @defgroup USART_Exported_Functions USART Exported Functions
216 * @{
219 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
220 * @brief Initialization and Configuration functions
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
240 [..]
241 The HAL_USART_Init() function follows the USART synchronous SPI configuration
242 procedure (details for the procedure are available in reference manual).
244 @endverbatim
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.
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 +-----------------------------------------------------------------------+
267 * @{
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
276 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
278 /* Check the USART handle allocation */
279 if (husart == NULL)
281 return HAL_ERROR;
284 /* Check the parameters */
285 assert_param(IS_USART_INSTANCE(husart->Instance));
287 if (husart->State == HAL_USART_STATE_RESET)
289 /* Allocate lock resource and initialize it */
290 husart->Lock = HAL_UNLOCKED;
292 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
293 USART_InitCallbacksToDefault(husart);
295 if (husart->MspInitCallback == NULL)
297 husart->MspInitCallback = HAL_USART_MspInit;
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 */
308 husart->State = HAL_USART_STATE_BUSY;
310 /* Disable the Peripheral */
311 __HAL_USART_DISABLE(husart);
313 /* Set the Usart Communication parameters */
314 if (USART_SetConfig(husart) == HAL_ERROR)
316 return HAL_ERROR;
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.
323 husart->Instance->CR2 &= ~USART_CR2_LINEN;
324 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
326 /* Enable the Peripheral */
327 __HAL_USART_ENABLE(husart);
329 /* TEACK and/or REACK to check before moving husart->State to Ready */
330 return (USART_CheckIdleState(husart));
334 * @brief DeInitialize the USART peripheral.
335 * @param husart USART handle.
336 * @retval HAL status
338 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
340 /* Check the USART handle allocation */
341 if (husart == NULL)
343 return HAL_ERROR;
346 /* Check the parameters */
347 assert_param(IS_USART_INSTANCE(husart->Instance));
349 husart->State = HAL_USART_STATE_BUSY;
351 husart->Instance->CR1 = 0x0U;
352 husart->Instance->CR2 = 0x0U;
353 husart->Instance->CR3 = 0x0U;
355 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
356 if (husart->MspDeInitCallback == NULL)
358 husart->MspDeInitCallback = HAL_USART_MspDeInit;
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 */
367 husart->ErrorCode = HAL_USART_ERROR_NONE;
368 husart->State = HAL_USART_STATE_RESET;
370 /* Process Unlock */
371 __HAL_UNLOCK(husart);
373 return HAL_OK;
377 * @brief Initialize the USART MSP.
378 * @param husart USART handle.
379 * @retval None
381 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
383 /* Prevent unused argument(s) compilation warning */
384 UNUSED(husart);
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
392 * @brief DeInitialize the USART MSP.
393 * @param husart USART handle.
394 * @retval None
396 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
398 /* Prevent unused argument(s) compilation warning */
399 UNUSED(husart);
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
406 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
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 + */
429 HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
430 pUSART_CallbackTypeDef pCallback)
432 HAL_StatusTypeDef status = HAL_OK;
434 if (pCallback == NULL)
436 /* Update the error code */
437 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
439 return HAL_ERROR;
442 if (husart->State == HAL_USART_STATE_READY)
444 switch (CallbackID)
446 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
447 husart->TxHalfCpltCallback = pCallback;
448 break;
450 case HAL_USART_TX_COMPLETE_CB_ID :
451 husart->TxCpltCallback = pCallback;
452 break;
454 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
455 husart->RxHalfCpltCallback = pCallback;
456 break;
458 case HAL_USART_RX_COMPLETE_CB_ID :
459 husart->RxCpltCallback = pCallback;
460 break;
462 case HAL_USART_TX_RX_COMPLETE_CB_ID :
463 husart->TxRxCpltCallback = pCallback;
464 break;
466 case HAL_USART_ERROR_CB_ID :
467 husart->ErrorCallback = pCallback;
468 break;
470 case HAL_USART_ABORT_COMPLETE_CB_ID :
471 husart->AbortCpltCallback = pCallback;
472 break;
474 case HAL_USART_RX_FIFO_FULL_CB_ID :
475 husart->RxFifoFullCallback = pCallback;
476 break;
478 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
479 husart->TxFifoEmptyCallback = pCallback;
480 break;
482 case HAL_USART_MSPINIT_CB_ID :
483 husart->MspInitCallback = pCallback;
484 break;
486 case HAL_USART_MSPDEINIT_CB_ID :
487 husart->MspDeInitCallback = pCallback;
488 break;
490 default :
491 /* Update the error code */
492 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
494 /* Return error status */
495 status = HAL_ERROR;
496 break;
499 else if (husart->State == HAL_USART_STATE_RESET)
501 switch (CallbackID)
503 case HAL_USART_MSPINIT_CB_ID :
504 husart->MspInitCallback = pCallback;
505 break;
507 case HAL_USART_MSPDEINIT_CB_ID :
508 husart->MspDeInitCallback = pCallback;
509 break;
511 default :
512 /* Update the error code */
513 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
515 /* Return error status */
516 status = HAL_ERROR;
517 break;
520 else
522 /* Update the error code */
523 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
525 /* Return error status */
526 status = HAL_ERROR;
529 return status;
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
553 HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
555 HAL_StatusTypeDef status = HAL_OK;
557 if (HAL_USART_STATE_READY == husart->State)
559 switch (CallbackID)
561 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
562 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
563 break;
565 case HAL_USART_TX_COMPLETE_CB_ID :
566 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
567 break;
569 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
570 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
571 break;
573 case HAL_USART_RX_COMPLETE_CB_ID :
574 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
575 break;
577 case HAL_USART_TX_RX_COMPLETE_CB_ID :
578 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
579 break;
581 case HAL_USART_ERROR_CB_ID :
582 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
583 break;
585 case HAL_USART_ABORT_COMPLETE_CB_ID :
586 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
587 break;
589 case HAL_USART_RX_FIFO_FULL_CB_ID :
590 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
591 break;
593 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
594 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
595 break;
597 case HAL_USART_MSPINIT_CB_ID :
598 husart->MspInitCallback = HAL_USART_MspInit; /* Legacy weak MspInitCallback */
599 break;
601 case HAL_USART_MSPDEINIT_CB_ID :
602 husart->MspDeInitCallback = HAL_USART_MspDeInit; /* Legacy weak MspDeInitCallback */
603 break;
605 default :
606 /* Update the error code */
607 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
609 /* Return error status */
610 status = HAL_ERROR;
611 break;
614 else if (HAL_USART_STATE_RESET == husart->State)
616 switch (CallbackID)
618 case HAL_USART_MSPINIT_CB_ID :
619 husart->MspInitCallback = HAL_USART_MspInit;
620 break;
622 case HAL_USART_MSPDEINIT_CB_ID :
623 husart->MspDeInitCallback = HAL_USART_MspDeInit;
624 break;
626 default :
627 /* Update the error code */
628 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
630 /* Return error status */
631 status = HAL_ERROR;
632 break;
635 else
637 /* Update the error code */
638 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
640 /* Return error status */
641 status = HAL_ERROR;
644 return status;
646 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
650 * @}
653 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
654 * @brief USART Transmit and Receive functions
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.
663 [..] The USART Synchronous SPI supports master and slave modes (SCLK as output or input).
665 [..]
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
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
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()
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()
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()
707 (#) Non-Blocking mode transfers could be aborted using Abort API's :
708 (++) HAL_USART_Abort()
709 (++) HAL_USART_Abort_IT()
711 (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
712 (++) HAL_USART_AbortCpltCallback()
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.
728 @endverbatim
729 * @{
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
743 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size,
744 uint32_t Timeout)
746 const uint8_t *ptxdata8bits;
747 const uint16_t *ptxdata16bits;
748 uint32_t tickstart;
750 if (husart->State == HAL_USART_STATE_READY)
752 if ((pTxData == NULL) || (Size == 0U))
754 return HAL_ERROR;
757 /* Process Locked */
758 __HAL_LOCK(husart);
760 husart->ErrorCode = HAL_USART_ERROR_NONE;
761 husart->State = HAL_USART_STATE_BUSY_TX;
763 /* Init tickstart for timeout management */
764 tickstart = HAL_GetTick();
766 husart->TxXferSize = Size;
767 husart->TxXferCount = Size;
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))
772 ptxdata8bits = NULL;
773 ptxdata16bits = (const uint16_t *) pTxData;
775 else
777 ptxdata8bits = pTxData;
778 ptxdata16bits = NULL;
781 /* Check the remaining data to be sent */
782 while (husart->TxXferCount > 0U)
784 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
786 return HAL_TIMEOUT;
788 if (ptxdata8bits == NULL)
790 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
791 ptxdata16bits++;
793 else
795 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
796 ptxdata8bits++;
799 husart->TxXferCount--;
802 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
804 return HAL_TIMEOUT;
807 /* Clear Transmission Complete Flag */
808 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
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);
815 /* At end of Tx process, restore husart->State to Ready */
816 husart->State = HAL_USART_STATE_READY;
818 /* Process Unlocked */
819 __HAL_UNLOCK(husart);
821 return HAL_OK;
823 else
825 return HAL_BUSY;
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
841 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
843 uint8_t *prxdata8bits;
844 uint16_t *prxdata16bits;
845 uint16_t uhMask;
846 uint32_t tickstart;
848 if (husart->State == HAL_USART_STATE_READY)
850 if ((pRxData == NULL) || (Size == 0U))
852 return HAL_ERROR;
855 /* Process Locked */
856 __HAL_LOCK(husart);
858 husart->ErrorCode = HAL_USART_ERROR_NONE;
859 husart->State = HAL_USART_STATE_BUSY_RX;
861 /* Init tickstart for timeout management */
862 tickstart = HAL_GetTick();
864 husart->RxXferSize = Size;
865 husart->RxXferCount = Size;
867 /* Computation of USART mask to apply to RDR register */
868 USART_MASK_COMPUTATION(husart);
869 uhMask = husart->Mask;
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))
874 prxdata8bits = NULL;
875 prxdata16bits = (uint16_t *) pRxData;
877 else
879 prxdata8bits = pRxData;
880 prxdata16bits = NULL;
883 /* as long as data have to be received */
884 while (husart->RxXferCount > 0U)
886 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
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)
894 return HAL_TIMEOUT;
896 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
899 /* Wait for RXNE Flag */
900 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
902 return HAL_TIMEOUT;
905 if (prxdata8bits == NULL)
907 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
908 prxdata16bits++;
910 else
912 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
913 prxdata8bits++;
916 husart->RxXferCount--;
920 /* Clear SPI slave underrun flag and discard transmit data */
921 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
923 __HAL_USART_CLEAR_UDRFLAG(husart);
924 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
927 /* At end of Rx process, restore husart->State to Ready */
928 husart->State = HAL_USART_STATE_READY;
930 /* Process Unlocked */
931 __HAL_UNLOCK(husart);
933 return HAL_OK;
935 else
937 return HAL_BUSY;
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
953 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
954 uint16_t Size, uint32_t Timeout)
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;
964 if (husart->State == HAL_USART_STATE_READY)
966 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
968 return HAL_ERROR;
971 /* Process Locked */
972 __HAL_LOCK(husart);
974 husart->ErrorCode = HAL_USART_ERROR_NONE;
975 husart->State = HAL_USART_STATE_BUSY_RX;
977 /* Init tickstart for timeout management */
978 tickstart = HAL_GetTick();
980 husart->RxXferSize = Size;
981 husart->TxXferSize = Size;
982 husart->TxXferCount = Size;
983 husart->RxXferCount = Size;
985 /* Computation of USART mask to apply to RDR register */
986 USART_MASK_COMPUTATION(husart);
987 uhMask = husart->Mask;
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))
992 prxdata8bits = NULL;
993 ptxdata8bits = NULL;
994 ptxdata16bits = (const uint16_t *) pTxData;
995 prxdata16bits = (uint16_t *) pRxData;
997 else
999 prxdata8bits = pRxData;
1000 ptxdata8bits = pTxData;
1001 ptxdata16bits = NULL;
1002 prxdata16bits = NULL;
1005 if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE))
1007 /* Wait until TXE flag is set to send data */
1008 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1010 return HAL_TIMEOUT;
1012 if (ptxdata8bits == NULL)
1014 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1015 ptxdata16bits++;
1017 else
1019 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1020 ptxdata8bits++;
1023 husart->TxXferCount--;
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))
1031 if (husart->TxXferCount > 0U)
1033 /* Wait until TXE flag is set to send data */
1034 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1036 return HAL_TIMEOUT;
1038 if (ptxdata8bits == NULL)
1040 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1041 ptxdata16bits++;
1043 else
1045 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1046 ptxdata8bits++;
1049 husart->TxXferCount--;
1052 if (husart->RxXferCount > 0U)
1054 /* Wait for RXNE Flag */
1055 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1057 return HAL_TIMEOUT;
1060 if (prxdata8bits == NULL)
1062 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
1063 prxdata16bits++;
1065 else
1067 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
1068 prxdata8bits++;
1071 husart->RxXferCount--;
1073 rxdatacount = husart->RxXferCount;
1076 /* At end of TxRx process, restore husart->State to Ready */
1077 husart->State = HAL_USART_STATE_READY;
1079 /* Process Unlocked */
1080 __HAL_UNLOCK(husart);
1082 return HAL_OK;
1084 else
1086 return HAL_BUSY;
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
1100 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1102 if (husart->State == HAL_USART_STATE_READY)
1104 if ((pTxData == NULL) || (Size == 0U))
1106 return HAL_ERROR;
1109 /* Process Locked */
1110 __HAL_LOCK(husart);
1112 husart->pTxBuffPtr = pTxData;
1113 husart->TxXferSize = Size;
1114 husart->TxXferCount = Size;
1115 husart->TxISR = NULL;
1117 husart->ErrorCode = HAL_USART_ERROR_NONE;
1118 husart->State = HAL_USART_STATE_BUSY_TX;
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" */
1126 /* Configure Tx interrupt processing */
1127 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
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))
1132 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1134 else
1136 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1139 /* Process Unlocked */
1140 __HAL_UNLOCK(husart);
1142 /* Enable the TX FIFO threshold interrupt */
1143 __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT);
1145 else
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))
1150 husart->TxISR = USART_TxISR_16BIT;
1152 else
1154 husart->TxISR = USART_TxISR_8BIT;
1157 /* Process Unlocked */
1158 __HAL_UNLOCK(husart);
1160 /* Enable the USART Transmit Data Register Empty Interrupt */
1161 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
1164 return HAL_OK;
1166 else
1168 return HAL_BUSY;
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
1183 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1185 uint16_t nb_dummy_data;
1187 if (husart->State == HAL_USART_STATE_READY)
1189 if ((pRxData == NULL) || (Size == 0U))
1191 return HAL_ERROR;
1194 /* Process Locked */
1195 __HAL_LOCK(husart);
1197 husart->pRxBuffPtr = pRxData;
1198 husart->RxXferSize = Size;
1199 husart->RxXferCount = Size;
1200 husart->RxISR = NULL;
1202 USART_MASK_COMPUTATION(husart);
1204 husart->ErrorCode = HAL_USART_ERROR_NONE;
1205 husart->State = HAL_USART_STATE_BUSY_RX;
1207 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1208 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1210 /* Configure Rx interrupt processing */
1211 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
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))
1216 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1218 else
1220 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1223 /* Process Unlocked */
1224 __HAL_UNLOCK(husart);
1226 /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
1227 if (husart->Init.Parity != USART_PARITY_NONE)
1229 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1231 SET_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
1233 else
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))
1238 husart->RxISR = USART_RxISR_16BIT;
1240 else
1242 husart->RxISR = USART_RxISR_8BIT;
1245 /* Process Unlocked */
1246 __HAL_UNLOCK(husart);
1248 /* Enable the USART Parity Error and Data Register not empty Interrupts */
1249 if (husart->Init.Parity != USART_PARITY_NONE)
1251 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1253 else
1255 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1259 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
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.
1265 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1267 for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--)
1269 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1272 else
1274 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1278 return HAL_OK;
1280 else
1282 return HAL_BUSY;
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
1297 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1298 uint16_t Size)
1301 if (husart->State == HAL_USART_STATE_READY)
1303 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1305 return HAL_ERROR;
1308 /* Process Locked */
1309 __HAL_LOCK(husart);
1311 husart->pRxBuffPtr = pRxData;
1312 husart->RxXferSize = Size;
1313 husart->RxXferCount = Size;
1314 husart->pTxBuffPtr = pTxData;
1315 husart->TxXferSize = Size;
1316 husart->TxXferCount = Size;
1318 /* Computation of USART mask to apply to RDR register */
1319 USART_MASK_COMPUTATION(husart);
1321 husart->ErrorCode = HAL_USART_ERROR_NONE;
1322 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1324 /* Configure TxRx interrupt processing */
1325 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
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))
1330 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1331 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1333 else
1335 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1336 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1339 /* Process Locked */
1340 __HAL_UNLOCK(husart);
1342 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1343 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1345 if (husart->Init.Parity != USART_PARITY_NONE)
1347 /* Enable the USART Parity Error interrupt */
1348 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1351 /* Enable the TX and RX FIFO Threshold interrupts */
1352 SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE));
1354 else
1356 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1358 husart->TxISR = USART_TxISR_16BIT;
1359 husart->RxISR = USART_RxISR_16BIT;
1361 else
1363 husart->TxISR = USART_TxISR_8BIT;
1364 husart->RxISR = USART_RxISR_8BIT;
1367 /* Process Locked */
1368 __HAL_UNLOCK(husart);
1370 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1371 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1373 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1374 if (husart->Init.Parity != USART_PARITY_NONE)
1376 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1378 else
1380 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1383 /* Enable the USART Transmit Data Register Empty Interrupt */
1384 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1387 return HAL_OK;
1389 else
1391 return HAL_BUSY;
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
1405 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1407 HAL_StatusTypeDef status = HAL_OK;
1408 const uint32_t *tmp;
1410 if (husart->State == HAL_USART_STATE_READY)
1412 if ((pTxData == NULL) || (Size == 0U))
1414 return HAL_ERROR;
1417 /* Process Locked */
1418 __HAL_LOCK(husart);
1420 husart->pTxBuffPtr = pTxData;
1421 husart->TxXferSize = Size;
1422 husart->TxXferCount = Size;
1424 husart->ErrorCode = HAL_USART_ERROR_NONE;
1425 husart->State = HAL_USART_STATE_BUSY_TX;
1427 if (husart->hdmatx != NULL)
1429 /* Set the USART DMA transfer complete callback */
1430 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1432 /* Set the USART DMA Half transfer complete callback */
1433 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1435 /* Set the DMA error callback */
1436 husart->hdmatx->XferErrorCallback = USART_DMAError;
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);
1443 if (status == HAL_OK)
1445 /* Clear the TC flag in the ICR register */
1446 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1448 /* Process Unlocked */
1449 __HAL_UNLOCK(husart);
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);
1455 return HAL_OK;
1457 else
1459 /* Set error code to DMA */
1460 husart->ErrorCode = HAL_USART_ERROR_DMA;
1462 /* Process Unlocked */
1463 __HAL_UNLOCK(husart);
1465 /* Restore husart->State to ready */
1466 husart->State = HAL_USART_STATE_READY;
1468 return HAL_ERROR;
1471 else
1473 return HAL_BUSY;
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
1490 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1492 HAL_StatusTypeDef status = HAL_OK;
1493 uint32_t *tmp = (uint32_t *)&pRxData;
1495 /* Check that a Rx process is not already ongoing */
1496 if (husart->State == HAL_USART_STATE_READY)
1498 if ((pRxData == NULL) || (Size == 0U))
1500 return HAL_ERROR;
1503 /* Process Locked */
1504 __HAL_LOCK(husart);
1506 husart->pRxBuffPtr = pRxData;
1507 husart->RxXferSize = Size;
1508 husart->pTxBuffPtr = pRxData;
1509 husart->TxXferSize = Size;
1511 husart->ErrorCode = HAL_USART_ERROR_NONE;
1512 husart->State = HAL_USART_STATE_BUSY_RX;
1514 if (husart->hdmarx != NULL)
1516 /* Set the USART DMA Rx transfer complete callback */
1517 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1519 /* Set the USART DMA Half transfer complete callback */
1520 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1522 /* Set the USART DMA Rx transfer error callback */
1523 husart->hdmarx->XferErrorCallback = USART_DMAError;
1525 /* Enable the USART receive DMA channel */
1526 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1529 if ((status == HAL_OK) &&
1530 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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 */
1536 /* Set the USART DMA Tx Complete and Error callback to Null */
1537 if (husart->hdmatx != NULL)
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);
1546 if (status == HAL_OK)
1548 /* Process Unlocked */
1549 __HAL_UNLOCK(husart);
1551 if (husart->Init.Parity != USART_PARITY_NONE)
1553 /* Enable the USART Parity Error Interrupt */
1554 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1557 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1558 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
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);
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);
1568 return HAL_OK;
1570 else
1572 if (husart->hdmarx != NULL)
1574 status = HAL_DMA_Abort(husart->hdmarx);
1577 /* No need to check on error code */
1578 UNUSED(status);
1580 /* Set error code to DMA */
1581 husart->ErrorCode = HAL_USART_ERROR_DMA;
1583 /* Process Unlocked */
1584 __HAL_UNLOCK(husart);
1586 /* Restore husart->State to ready */
1587 husart->State = HAL_USART_STATE_READY;
1589 return HAL_ERROR;
1592 else
1594 return HAL_BUSY;
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
1610 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1611 uint16_t Size)
1613 HAL_StatusTypeDef status;
1614 const uint32_t *tmp;
1616 if (husart->State == HAL_USART_STATE_READY)
1618 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1620 return HAL_ERROR;
1623 /* Process Locked */
1624 __HAL_LOCK(husart);
1626 husart->pRxBuffPtr = pRxData;
1627 husart->RxXferSize = Size;
1628 husart->pTxBuffPtr = pTxData;
1629 husart->TxXferSize = Size;
1631 husart->ErrorCode = HAL_USART_ERROR_NONE;
1632 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1634 if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
1636 /* Set the USART DMA Rx transfer complete callback */
1637 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1639 /* Set the USART DMA Half transfer complete callback */
1640 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1642 /* Set the USART DMA Tx transfer complete callback */
1643 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1645 /* Set the USART DMA Half transfer complete callback */
1646 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1648 /* Set the USART DMA Tx transfer error callback */
1649 husart->hdmatx->XferErrorCallback = USART_DMAError;
1651 /* Set the USART DMA Rx transfer error callback */
1652 husart->hdmarx->XferErrorCallback = USART_DMAError;
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);
1658 /* Enable the USART transmit DMA channel */
1659 if (status == HAL_OK)
1661 tmp = (const uint32_t *)&pTxData;
1662 status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1665 else
1667 status = HAL_ERROR;
1670 if (status == HAL_OK)
1672 /* Process Unlocked */
1673 __HAL_UNLOCK(husart);
1675 if (husart->Init.Parity != USART_PARITY_NONE)
1677 /* Enable the USART Parity Error Interrupt */
1678 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1681 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1682 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1684 /* Clear the TC flag in the ICR register */
1685 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
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);
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);
1695 return HAL_OK;
1697 else
1699 if (husart->hdmarx != NULL)
1701 status = HAL_DMA_Abort(husart->hdmarx);
1704 /* No need to check on error code */
1705 UNUSED(status);
1707 /* Set error code to DMA */
1708 husart->ErrorCode = HAL_USART_ERROR_DMA;
1710 /* Process Unlocked */
1711 __HAL_UNLOCK(husart);
1713 /* Restore husart->State to ready */
1714 husart->State = HAL_USART_STATE_READY;
1716 return HAL_ERROR;
1719 else
1721 return HAL_BUSY;
1726 * @brief Pause the DMA Transfer.
1727 * @param husart USART handle.
1728 * @retval HAL status
1730 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1732 const HAL_USART_StateTypeDef state = husart->State;
1734 /* Process Locked */
1735 __HAL_LOCK(husart);
1737 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
1738 (state == HAL_USART_STATE_BUSY_TX))
1740 /* Disable the USART DMA Tx request */
1741 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1743 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1744 (state == HAL_USART_STATE_BUSY_TX_RX))
1746 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1748 /* Disable the USART DMA Tx request */
1749 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1751 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
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);
1757 /* Disable the USART DMA Rx request */
1758 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1761 else
1763 /* Nothing to do */
1766 /* Process Unlocked */
1767 __HAL_UNLOCK(husart);
1769 return HAL_OK;
1773 * @brief Resume the DMA Transfer.
1774 * @param husart USART handle.
1775 * @retval HAL status
1777 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1779 const HAL_USART_StateTypeDef state = husart->State;
1781 /* Process Locked */
1782 __HAL_LOCK(husart);
1784 if (state == HAL_USART_STATE_BUSY_TX)
1786 /* Enable the USART DMA Tx request */
1787 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1789 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1790 (state == HAL_USART_STATE_BUSY_TX_RX))
1792 /* Clear the Overrun flag before resuming the Rx transfer*/
1793 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
1795 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1796 if (husart->Init.Parity != USART_PARITY_NONE)
1798 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1800 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1802 /* Enable the USART DMA Rx request before the DMA Tx request */
1803 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1805 /* Enable the USART DMA Tx request */
1806 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1808 else
1810 /* Nothing to do */
1813 /* Process Unlocked */
1814 __HAL_UNLOCK(husart);
1816 return HAL_OK;
1820 * @brief Stop the DMA Transfer.
1821 * @param husart USART handle.
1822 * @retval HAL status
1824 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
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. */
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);
1837 /* Abort the USART DMA tx channel */
1838 if (husart->hdmatx != NULL)
1840 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1842 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1844 /* Set error code to DMA */
1845 husart->ErrorCode = HAL_USART_ERROR_DMA;
1847 return HAL_TIMEOUT;
1851 /* Abort the USART DMA rx channel */
1852 if (husart->hdmarx != NULL)
1854 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1856 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1858 /* Set error code to DMA */
1859 husart->ErrorCode = HAL_USART_ERROR_DMA;
1861 return HAL_TIMEOUT;
1866 USART_EndTransfer(husart);
1867 husart->State = HAL_USART_STATE_READY;
1869 return HAL_OK;
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
1884 HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
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));
1891 /* Abort the USART DMA Tx channel if enabled */
1892 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1894 /* Disable the USART DMA Tx request if enabled */
1895 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1897 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1898 if (husart->hdmatx != NULL)
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;
1904 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1906 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1908 /* Set error code to DMA */
1909 husart->ErrorCode = HAL_USART_ERROR_DMA;
1911 return HAL_TIMEOUT;
1917 /* Abort the USART DMA Rx channel if enabled */
1918 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1920 /* Disable the USART DMA Rx request if enabled */
1921 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1923 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1924 if (husart->hdmarx != NULL)
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;
1930 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1932 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1934 /* Set error code to DMA */
1935 husart->ErrorCode = HAL_USART_ERROR_DMA;
1937 return HAL_TIMEOUT;
1943 /* Reset Tx and Rx transfer counters */
1944 husart->TxXferCount = 0U;
1945 husart->RxXferCount = 0U;
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);
1950 /* Flush the whole TX FIFO (if needed) */
1951 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1953 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
1956 /* Discard the received data */
1957 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
1959 /* Restore husart->State to Ready */
1960 husart->State = HAL_USART_STATE_READY;
1962 /* Reset Handle ErrorCode to No Error */
1963 husart->ErrorCode = HAL_USART_ERROR_NONE;
1965 return HAL_OK;
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
1982 HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
1984 uint32_t abortcplt = 1U;
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));
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)
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))
2000 husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
2002 else
2004 husart->hdmatx->XferAbortCallback = NULL;
2007 /* DMA Rx Handle is valid */
2008 if (husart->hdmarx != NULL)
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))
2014 husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
2016 else
2018 husart->hdmarx->XferAbortCallback = NULL;
2022 /* Abort the USART DMA Tx channel if enabled */
2023 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2025 /* Disable DMA Tx at USART level */
2026 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2028 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2029 if (husart->hdmatx != NULL)
2031 /* USART Tx DMA Abort callback has already been initialised :
2032 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2034 /* Abort DMA TX */
2035 if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
2037 husart->hdmatx->XferAbortCallback = NULL;
2039 else
2041 abortcplt = 0U;
2046 /* Abort the USART DMA Rx channel if enabled */
2047 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2049 /* Disable the USART DMA Rx request if enabled */
2050 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2052 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2053 if (husart->hdmarx != NULL)
2055 /* USART Rx DMA Abort callback has already been initialised :
2056 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2058 /* Abort DMA RX */
2059 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2061 husart->hdmarx->XferAbortCallback = NULL;
2062 abortcplt = 1U;
2064 else
2066 abortcplt = 0U;
2071 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2072 if (abortcplt == 1U)
2074 /* Reset Tx and Rx transfer counters */
2075 husart->TxXferCount = 0U;
2076 husart->RxXferCount = 0U;
2078 /* Reset errorCode */
2079 husart->ErrorCode = HAL_USART_ERROR_NONE;
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);
2084 /* Flush the whole TX FIFO (if needed) */
2085 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2087 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2090 /* Discard the received data */
2091 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2093 /* Restore husart->State to Ready */
2094 husart->State = HAL_USART_STATE_READY;
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 */
2106 return HAL_OK;
2110 * @brief Handle USART interrupt request.
2111 * @param husart USART handle.
2112 * @retval None
2114 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
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);
2120 uint32_t errorflags;
2121 uint32_t errorcode;
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)
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)))
2133 if (husart->RxISR != NULL)
2135 husart->RxISR(husart);
2137 return;
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)))
2146 /* USART parity error interrupt occurred -------------------------------------*/
2147 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2149 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
2151 husart->ErrorCode |= HAL_USART_ERROR_PE;
2154 /* USART frame error interrupt occurred --------------------------------------*/
2155 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2157 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
2159 husart->ErrorCode |= HAL_USART_ERROR_FE;
2162 /* USART noise error interrupt occurred --------------------------------------*/
2163 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2165 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
2167 husart->ErrorCode |= HAL_USART_ERROR_NE;
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)))
2175 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
2177 husart->ErrorCode |= HAL_USART_ERROR_ORE;
2180 /* USART Receiver Timeout interrupt occurred ---------------------------------*/
2181 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2183 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF);
2185 husart->ErrorCode |= HAL_USART_ERROR_RTO;
2188 /* USART SPI slave underrun error interrupt occurred -------------------------*/
2189 if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2191 /* Ignore SPI slave underrun errors when reception is going on */
2192 if (husart->State == HAL_USART_STATE_BUSY_RX)
2194 __HAL_USART_CLEAR_UDRFLAG(husart);
2195 return;
2197 else
2199 __HAL_USART_CLEAR_UDRFLAG(husart);
2200 husart->ErrorCode |= HAL_USART_ERROR_UDR;
2204 /* Call USART Error Call back function if need be --------------------------*/
2205 if (husart->ErrorCode != HAL_USART_ERROR_NONE)
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)))
2212 if (husart->RxISR != NULL)
2214 husart->RxISR(husart);
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))
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);
2229 /* Abort the USART DMA Rx channel if enabled */
2230 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2232 /* Disable the USART DMA Rx request if enabled */
2233 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
2235 /* Abort the USART DMA Tx channel */
2236 if (husart->hdmatx != NULL)
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;
2242 /* Abort DMA TX */
2243 (void)HAL_DMA_Abort_IT(husart->hdmatx);
2246 /* Abort the USART DMA Rx channel */
2247 if (husart->hdmarx != NULL)
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;
2253 /* Abort DMA RX */
2254 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2256 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2257 husart->hdmarx->XferAbortCallback(husart->hdmarx);
2260 else
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 */
2272 else
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 */
2284 else
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;
2298 return;
2300 } /* End if some error occurs */
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)))
2308 if (husart->TxISR != NULL)
2310 husart->TxISR(husart);
2312 return;
2315 /* USART in mode Transmitter (transmission end) -----------------------------*/
2316 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2318 USART_EndTransmit_IT(husart);
2319 return;
2322 /* USART TX Fifo Empty occurred ----------------------------------------------*/
2323 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
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;
2335 /* USART RX Fifo Full occurred ----------------------------------------------*/
2336 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
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;
2350 * @brief Tx Transfer completed callback.
2351 * @param husart USART handle.
2352 * @retval None
2354 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
2356 /* Prevent unused argument(s) compilation warning */
2357 UNUSED(husart);
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.
2365 * @brief Tx Half Transfer completed callback.
2366 * @param husart USART handle.
2367 * @retval None
2369 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
2371 /* Prevent unused argument(s) compilation warning */
2372 UNUSED(husart);
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.
2380 * @brief Rx Transfer completed callback.
2381 * @param husart USART handle.
2382 * @retval None
2384 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
2386 /* Prevent unused argument(s) compilation warning */
2387 UNUSED(husart);
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.
2395 * @brief Rx Half Transfer completed callback.
2396 * @param husart USART handle.
2397 * @retval None
2399 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
2401 /* Prevent unused argument(s) compilation warning */
2402 UNUSED(husart);
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
2410 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2411 * @param husart USART handle.
2412 * @retval None
2414 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
2416 /* Prevent unused argument(s) compilation warning */
2417 UNUSED(husart);
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
2425 * @brief USART error callback.
2426 * @param husart USART handle.
2427 * @retval None
2429 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
2431 /* Prevent unused argument(s) compilation warning */
2432 UNUSED(husart);
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.
2440 * @brief USART Abort Complete callback.
2441 * @param husart USART handle.
2442 * @retval None
2444 __weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
2446 /* Prevent unused argument(s) compilation warning */
2447 UNUSED(husart);
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.
2455 * @}
2458 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2459 * @brief USART Peripheral State and Error functions
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
2470 @endverbatim
2471 * @{
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
2481 HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart)
2483 return husart->State;
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
2492 uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart)
2494 return husart->ErrorCode;
2498 * @}
2502 * @}
2505 /** @defgroup USART_Private_Functions USART Private Functions
2506 * @{
2510 * @brief Initialize the callbacks to their default values.
2511 * @param husart USART handle.
2512 * @retval none
2514 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2515 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
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 */
2528 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2531 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2532 * @param husart USART handle.
2533 * @retval None
2535 static void USART_EndTransfer(USART_HandleTypeDef *husart)
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));
2542 /* At end of process, restore husart->State to Ready */
2543 husart->State = HAL_USART_STATE_READY;
2547 * @brief DMA USART transmit process complete callback.
2548 * @param hdma DMA handle.
2549 * @retval None
2551 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2553 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2555 /* DMA Normal mode */
2556 if (hdma->Init.Mode != DMA_CIRCULAR)
2558 husart->TxXferCount = 0U;
2560 if (husart->State == HAL_USART_STATE_BUSY_TX)
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);
2566 /* Enable the USART Transmit Complete Interrupt */
2567 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2570 /* DMA Circular mode */
2571 else
2573 if (husart->State == HAL_USART_STATE_BUSY_TX)
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 */
2587 * @brief DMA USART transmit process half complete callback.
2588 * @param hdma DMA handle.
2589 * @retval None
2591 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2593 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
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 */
2605 * @brief DMA USART receive process complete callback.
2606 * @param hdma DMA handle.
2607 * @retval None
2609 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2611 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2613 /* DMA Normal mode */
2614 if (hdma->Init.Mode != DMA_CIRCULAR)
2616 husart->RxXferCount = 0U;
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);
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);
2629 if (husart->State == HAL_USART_STATE_BUSY_RX)
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 */
2639 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2640 else
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 */
2650 husart->State = HAL_USART_STATE_READY;
2652 /* DMA circular mode */
2653 else
2655 if (husart->State == HAL_USART_STATE_BUSY_RX)
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 */
2665 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2666 else
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 */
2680 * @brief DMA USART receive process half complete callback.
2681 * @param hdma DMA handle.
2682 * @retval None
2684 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2686 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
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 */
2698 * @brief DMA USART communication error callback.
2699 * @param hdma DMA handle.
2700 * @retval None
2702 static void USART_DMAError(DMA_HandleTypeDef *hdma)
2704 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2706 husart->RxXferCount = 0U;
2707 husart->TxXferCount = 0U;
2708 USART_EndTransfer(husart);
2710 husart->ErrorCode |= HAL_USART_ERROR_DMA;
2711 husart->State = HAL_USART_STATE_READY;
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 */
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
2728 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2730 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2731 husart->RxXferCount = 0U;
2732 husart->TxXferCount = 0U;
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 */
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
2751 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2753 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2755 husart->hdmatx->XferAbortCallback = NULL;
2757 /* Check if an Abort process is still ongoing */
2758 if (husart->hdmarx != NULL)
2760 if (husart->hdmarx->XferAbortCallback != NULL)
2762 return;
2766 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2767 husart->TxXferCount = 0U;
2768 husart->RxXferCount = 0U;
2770 /* Reset errorCode */
2771 husart->ErrorCode = HAL_USART_ERROR_NONE;
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);
2776 /* Restore husart->State to Ready */
2777 husart->State = HAL_USART_STATE_READY;
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 */
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
2799 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2801 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2803 husart->hdmarx->XferAbortCallback = NULL;
2805 /* Check if an Abort process is still ongoing */
2806 if (husart->hdmatx != NULL)
2808 if (husart->hdmatx->XferAbortCallback != NULL)
2810 return;
2814 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2815 husart->TxXferCount = 0U;
2816 husart->RxXferCount = 0U;
2818 /* Reset errorCode */
2819 husart->ErrorCode = HAL_USART_ERROR_NONE;
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);
2824 /* Restore husart->State to Ready */
2825 husart->State = HAL_USART_STATE_READY;
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 */
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
2848 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
2849 uint32_t Tickstart, uint32_t Timeout)
2851 /* Wait until flag is set */
2852 while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
2854 /* Check for the Timeout */
2855 if (Timeout != HAL_MAX_DELAY)
2857 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2859 husart->State = HAL_USART_STATE_READY;
2861 /* Process Unlocked */
2862 __HAL_UNLOCK(husart);
2864 return HAL_TIMEOUT;
2868 return HAL_OK;
2872 * @brief Configure the USART peripheral.
2873 * @param husart USART handle.
2874 * @retval HAL status
2876 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
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;
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));
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);
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);
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);
2925 /*-------------------------- USART BRR Configuration -----------------------*/
2926 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
2927 USART_GETCLOCKSOURCE(husart, clocksource);
2929 switch (clocksource)
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)
2952 usartdiv = (uint32_t)(USART_DIV_SAMPLING8((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)),
2953 husart->Init.BaudRate, husart->Init.ClockPrescaler));
2955 else
2957 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
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;
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))
2974 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
2975 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
2976 husart->Instance->BRR = brrtemp;
2978 else
2980 ret = HAL_ERROR;
2983 /* Initialize the number of data to process during RX/TX ISR execution */
2984 husart->NbTxDataToProcess = 1U;
2985 husart->NbRxDataToProcess = 1U;
2987 /* Clear ISR function pointers */
2988 husart->RxISR = NULL;
2989 husart->TxISR = NULL;
2991 return ret;
2995 * @brief Check the USART Idle State.
2996 * @param husart USART handle.
2997 * @retval HAL status
2999 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
3001 uint32_t tickstart;
3003 /* Initialize the USART ErrorCode */
3004 husart->ErrorCode = HAL_USART_ERROR_NONE;
3006 /* Init tickstart for timeout management */
3007 tickstart = HAL_GetTick();
3009 /* Check if the Transmitter is enabled */
3010 if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3012 /* Wait until TEACK flag is set */
3013 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3015 /* Timeout occurred */
3016 return HAL_TIMEOUT;
3019 /* Check if the Receiver is enabled */
3020 if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3022 /* Wait until REACK flag is set */
3023 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3025 /* Timeout occurred */
3026 return HAL_TIMEOUT;
3030 /* Initialize the USART state*/
3031 husart->State = HAL_USART_STATE_READY;
3033 /* Process Unlocked */
3034 __HAL_UNLOCK(husart);
3036 return HAL_OK;
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
3049 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
3051 const HAL_USART_StateTypeDef state = husart->State;
3053 /* Check that a Tx process is ongoing */
3054 if ((state == HAL_USART_STATE_BUSY_TX) ||
3055 (state == HAL_USART_STATE_BUSY_TX_RX))
3057 if (husart->TxXferCount == 0U)
3059 /* Disable the USART Transmit data register empty interrupt */
3060 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3062 /* Enable the USART Transmit Complete Interrupt */
3063 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3065 else
3067 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3068 husart->pTxBuffPtr++;
3069 husart->TxXferCount--;
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
3084 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
3086 const HAL_USART_StateTypeDef state = husart->State;
3087 const uint16_t *tmp;
3089 if ((state == HAL_USART_STATE_BUSY_TX) ||
3090 (state == HAL_USART_STATE_BUSY_TX_RX))
3092 if (husart->TxXferCount == 0U)
3094 /* Disable the USART Transmit data register empty interrupt */
3095 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3097 /* Enable the USART Transmit Complete Interrupt */
3098 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3100 else
3102 tmp = (const uint16_t *) husart->pTxBuffPtr;
3103 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3104 husart->pTxBuffPtr += 2U;
3105 husart->TxXferCount--;
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
3120 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3122 const HAL_USART_StateTypeDef state = husart->State;
3123 uint16_t nb_tx_data;
3125 /* Check that a Tx process is ongoing */
3126 if ((state == HAL_USART_STATE_BUSY_TX) ||
3127 (state == HAL_USART_STATE_BUSY_TX_RX))
3129 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3131 if (husart->TxXferCount == 0U)
3133 /* Disable the TX FIFO threshold interrupt */
3134 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3136 /* Enable the USART Transmit Complete Interrupt */
3137 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3139 break; /* force exit loop */
3141 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3143 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3144 husart->pTxBuffPtr++;
3145 husart->TxXferCount--;
3147 else
3149 /* Nothing to do */
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
3165 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3167 const HAL_USART_StateTypeDef state = husart->State;
3168 const uint16_t *tmp;
3169 uint16_t nb_tx_data;
3171 /* Check that a Tx process is ongoing */
3172 if ((state == HAL_USART_STATE_BUSY_TX) ||
3173 (state == HAL_USART_STATE_BUSY_TX_RX))
3175 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3177 if (husart->TxXferCount == 0U)
3179 /* Disable the TX FIFO threshold interrupt */
3180 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3182 /* Enable the USART Transmit Complete Interrupt */
3183 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3185 break; /* force exit loop */
3187 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3189 tmp = (const uint16_t *) husart->pTxBuffPtr;
3190 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3191 husart->pTxBuffPtr += 2U;
3192 husart->TxXferCount--;
3194 else
3196 /* Nothing to do */
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
3208 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3210 /* Disable the USART Transmit Complete Interrupt */
3211 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3213 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3214 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3216 /* Clear TxISR function pointer */
3217 husart->TxISR = NULL;
3219 if (husart->State == HAL_USART_STATE_BUSY_TX)
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);
3225 /* Tx process is completed, restore husart->State to Ready */
3226 husart->State = HAL_USART_STATE_READY;
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 */
3236 else if (husart->RxXferCount == 0U)
3238 /* TxRx process is completed, restore husart->State to Ready */
3239 husart->State = HAL_USART_STATE_READY;
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 */
3249 else
3251 /* Nothing to do */
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
3265 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3267 const HAL_USART_StateTypeDef state = husart->State;
3268 uint16_t txdatacount;
3269 uint16_t uhMask = husart->Mask;
3270 uint32_t txftie;
3272 if ((state == HAL_USART_STATE_BUSY_RX) ||
3273 (state == HAL_USART_STATE_BUSY_TX_RX))
3275 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3276 husart->pRxBuffPtr++;
3277 husart->RxXferCount--;
3279 if (husart->RxXferCount == 0U)
3281 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3282 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3284 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3285 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3287 /* Clear RxISR function pointer */
3288 husart->RxISR = NULL;
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;
3294 if (state == HAL_USART_STATE_BUSY_RX)
3296 /* Clear SPI slave underrun flag and discard transmit data */
3297 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3299 __HAL_USART_CLEAR_UDRFLAG(husart);
3300 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3303 /* Rx process is completed, restore husart->State to Ready */
3304 husart->State = HAL_USART_STATE_READY;
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 */
3314 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3315 (txftie != USART_CR3_TXFTIE) &&
3316 (txdatacount == 0U))
3318 /* TxRx process is completed, restore husart->State to Ready */
3319 husart->State = HAL_USART_STATE_READY;
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 */
3329 else
3331 /* Nothing to do */
3334 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3335 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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);
3340 else
3342 /* Nothing to do */
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
3356 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
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;
3364 if ((state == HAL_USART_STATE_BUSY_RX) ||
3365 (state == HAL_USART_STATE_BUSY_TX_RX))
3367 tmp = (uint16_t *) husart->pRxBuffPtr;
3368 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3369 husart->pRxBuffPtr += 2U;
3370 husart->RxXferCount--;
3372 if (husart->RxXferCount == 0U)
3374 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3375 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3377 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3378 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3380 /* Clear RxISR function pointer */
3381 husart->RxISR = NULL;
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;
3387 if (state == HAL_USART_STATE_BUSY_RX)
3389 /* Clear SPI slave underrun flag and discard transmit data */
3390 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3392 __HAL_USART_CLEAR_UDRFLAG(husart);
3393 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3396 /* Rx process is completed, restore husart->State to Ready */
3397 husart->State = HAL_USART_STATE_READY;
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 */
3407 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3408 (txftie != USART_CR3_TXFTIE) &&
3409 (txdatacount == 0U))
3411 /* TxRx process is completed, restore husart->State to Ready */
3412 husart->State = HAL_USART_STATE_READY;
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 */
3422 else
3424 /* Nothing to do */
3427 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3428 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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);
3433 else
3435 /* Nothing to do */
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
3449 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
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;
3458 /* Check that a Rx process is ongoing */
3459 if ((state == HAL_USART_STATE_BUSY_RX) ||
3460 (state == HAL_USART_STATE_BUSY_TX_RX))
3462 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3464 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3466 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
3467 husart->pRxBuffPtr++;
3468 husart->RxXferCount--;
3470 if (husart->RxXferCount == 0U)
3472 /* Disable the USART Parity Error Interrupt */
3473 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
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));
3479 /* Clear RxISR function pointer */
3480 husart->RxISR = NULL;
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;
3486 if (state == HAL_USART_STATE_BUSY_RX)
3488 /* Clear SPI slave underrun flag and discard transmit data */
3489 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3491 __HAL_USART_CLEAR_UDRFLAG(husart);
3492 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3495 /* Rx process is completed, restore husart->State to Ready */
3496 husart->State = HAL_USART_STATE_READY;
3497 state = HAL_USART_STATE_READY;
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 */
3507 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3508 (txftie != USART_CR3_TXFTIE) &&
3509 (txdatacount == 0U))
3511 /* TxRx process is completed, restore husart->State to Ready */
3512 husart->State = HAL_USART_STATE_READY;
3513 state = HAL_USART_STATE_READY;
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 */
3523 else
3525 /* Nothing to do */
3528 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3529 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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);
3534 else
3536 /* Nothing to do */
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).
3545 rxdatacount = husart->RxXferCount;
3546 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3548 /* Disable the USART RXFT interrupt*/
3549 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3551 /* Update the RxISR function pointer */
3552 husart->RxISR = USART_RxISR_8BIT;
3554 /* Enable the USART Data Register Not Empty interrupt */
3555 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3557 if ((husart->TxXferCount == 0U) &&
3558 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3559 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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);
3566 else
3568 /* Clear RXNE interrupt flag */
3569 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
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
3582 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
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;
3592 /* Check that a Tx process is ongoing */
3593 if ((state == HAL_USART_STATE_BUSY_RX) ||
3594 (state == HAL_USART_STATE_BUSY_TX_RX))
3596 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3598 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3600 tmp = (uint16_t *) husart->pRxBuffPtr;
3601 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3602 husart->pRxBuffPtr += 2U;
3603 husart->RxXferCount--;
3605 if (husart->RxXferCount == 0U)
3607 /* Disable the USART Parity Error Interrupt */
3608 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
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));
3614 /* Clear RxISR function pointer */
3615 husart->RxISR = NULL;
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;
3621 if (state == HAL_USART_STATE_BUSY_RX)
3623 /* Clear SPI slave underrun flag and discard transmit data */
3624 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3626 __HAL_USART_CLEAR_UDRFLAG(husart);
3627 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3630 /* Rx process is completed, restore husart->State to Ready */
3631 husart->State = HAL_USART_STATE_READY;
3632 state = HAL_USART_STATE_READY;
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 */
3642 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3643 (txftie != USART_CR3_TXFTIE) &&
3644 (txdatacount == 0U))
3646 /* TxRx process is completed, restore husart->State to Ready */
3647 husart->State = HAL_USART_STATE_READY;
3648 state = HAL_USART_STATE_READY;
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 */
3658 else
3660 /* Nothing to do */
3663 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3664 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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);
3669 else
3671 /* Nothing to do */
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).
3680 rxdatacount = husart->RxXferCount;
3681 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3683 /* Disable the USART RXFT interrupt*/
3684 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3686 /* Update the RxISR function pointer */
3687 husart->RxISR = USART_RxISR_16BIT;
3689 /* Enable the USART Data Register Not Empty interrupt */
3690 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3692 if ((husart->TxXferCount == 0U) &&
3693 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3694 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
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);
3701 else
3703 /* Clear RXNE interrupt flag */
3704 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3709 * @}
3712 #endif /* HAL_USART_MODULE_ENABLED */
3714 * @}
3718 * @}