Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_usart.c
blobcaf70aa771c64ba03597dfc47b2d32de11ea0472
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 @verbatim
15 ===============================================================================
16 ##### How to use this driver #####
17 ===============================================================================
18 [..]
19 The USART HAL driver can be used as follows:
21 (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
22 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
23 (++) Enable the USARTx interface clock.
24 (++) USART pins configuration:
25 (+++) Enable the clock for the USART GPIOs.
26 (+++) Configure these USART pins as alternate function pull-up.
27 (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
28 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
29 (+++) Configure the USARTx interrupt priority.
30 (+++) Enable the NVIC USART IRQ handle.
31 (++) USART interrupts handling:
32 -@@- The specific USART interrupts (Transmission complete interrupt,
33 RXNE interrupt and Error Interrupts) will be managed using the macros
34 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
35 (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
36 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
37 (+++) Declare a DMA handle structure for the Tx/Rx channel.
38 (+++) Enable the DMAx interface clock.
39 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40 (+++) Configure the DMA Tx/Rx channel.
41 (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
42 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
44 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
45 (Receiver/Transmitter) in the husart handle Init structure.
47 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
48 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
49 by calling the customized HAL_USART_MspInit(&husart) API.
51 [..]
52 (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
53 HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
54 HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
56 ##### Callback registration #####
57 ==================================
59 [..]
60 The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
61 allows the user to configure dynamically the driver callbacks.
63 [..]
64 Use Function @ref HAL_USART_RegisterCallback() to register a user callback.
65 Function @ref HAL_USART_RegisterCallback() allows to register following callbacks:
66 (+) TxHalfCpltCallback : Tx Half Complete Callback.
67 (+) TxCpltCallback : Tx Complete Callback.
68 (+) RxHalfCpltCallback : Rx Half Complete Callback.
69 (+) RxCpltCallback : Rx Complete Callback.
70 (+) TxRxCpltCallback : Tx Rx Complete Callback.
71 (+) ErrorCallback : Error Callback.
72 (+) AbortCpltCallback : Abort Complete Callback.
73 (+) RxFifoFullCallback : Rx Fifo Full Callback.
74 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
75 (+) MspInitCallback : USART MspInit.
76 (+) MspDeInitCallback : USART MspDeInit.
77 This function takes as parameters the HAL peripheral handle, the Callback ID
78 and a pointer to the user callback function.
80 [..]
81 Use function @ref HAL_USART_UnRegisterCallback() to reset a callback to the default
82 weak (surcharged) function.
83 @ref HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
84 and the Callback ID.
85 This function allows to reset following callbacks:
86 (+) TxHalfCpltCallback : Tx Half Complete Callback.
87 (+) TxCpltCallback : Tx Complete Callback.
88 (+) RxHalfCpltCallback : Rx Half Complete Callback.
89 (+) RxCpltCallback : Rx Complete Callback.
90 (+) TxRxCpltCallback : Tx Rx Complete Callback.
91 (+) ErrorCallback : Error Callback.
92 (+) AbortCpltCallback : Abort Complete Callback.
93 (+) RxFifoFullCallback : Rx Fifo Full Callback.
94 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
95 (+) MspInitCallback : USART MspInit.
96 (+) MspDeInitCallback : USART MspDeInit.
98 [..]
99 By default, after the @ref HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
100 all callbacks are set to the corresponding weak (surcharged) functions:
101 examples @ref HAL_USART_TxCpltCallback(), @ref HAL_USART_RxHalfCpltCallback().
102 Exception done for MspInit and MspDeInit functions that are respectively
103 reset to the legacy weak (surcharged) functions in the @ref HAL_USART_Init()
104 and @ref HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
105 If not, MspInit or MspDeInit are not null, the @ref HAL_USART_Init() and @ref HAL_USART_DeInit()
106 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
108 [..]
109 Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
110 Exception done MspInit/MspDeInit that can be registered/unregistered
111 in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
112 MspInit/DeInit callbacks can be used during the Init/DeInit.
113 In that case first register the MspInit/MspDeInit user callbacks
114 using @ref HAL_USART_RegisterCallback() before calling @ref HAL_USART_DeInit()
115 or @ref HAL_USART_Init() function.
117 [..]
118 When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
119 not defined, the callback registration feature is not available
120 and weak (surcharged) callbacks are used.
123 @endverbatim
124 ******************************************************************************
125 * @attention
127 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
128 * All rights reserved.</center></h2>
130 * This software component is licensed by ST under BSD 3-Clause license,
131 * the "License"; You may not use this file except in compliance with the
132 * License. You may obtain a copy of the License at:
133 * opensource.org/licenses/BSD-3-Clause
135 ******************************************************************************
138 /* Includes ------------------------------------------------------------------*/
139 #include "stm32h7xx_hal.h"
141 /** @addtogroup STM32H7xx_HAL_Driver
142 * @{
145 /** @defgroup USART USART
146 * @brief HAL USART Synchronous module driver
147 * @{
150 #ifdef HAL_USART_MODULE_ENABLED
152 /* Private typedef -----------------------------------------------------------*/
153 /* Private define ------------------------------------------------------------*/
154 /** @defgroup USART_Private_Constants USART Private Constants
155 * @{
157 #define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
158 #define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
159 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
160 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 | \
161 USART_CR1_FIFOEN )) /*!< USART CR1 fields of parameters set by USART_SetConfig API */
163 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
164 USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \
165 USART_CR2_DIS_NSS)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
167 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */
169 #define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */
170 #define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */
172 * @}
175 /* Private macros ------------------------------------------------------------*/
176 /* Private variables ---------------------------------------------------------*/
177 /* Private function prototypes -----------------------------------------------*/
178 /** @addtogroup USART_Private_Functions
179 * @{
181 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
182 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
183 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
184 static void USART_EndTransfer(USART_HandleTypeDef *husart);
185 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
186 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
187 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
188 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
189 static void USART_DMAError(DMA_HandleTypeDef *hdma);
190 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
191 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
192 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
193 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
194 uint32_t Tickstart, uint32_t Timeout);
195 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
196 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
197 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart);
198 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart);
199 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
200 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
201 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart);
202 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart);
203 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart);
204 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
205 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
209 * @}
212 /* Exported functions --------------------------------------------------------*/
214 /** @defgroup USART_Exported_Functions USART Exported Functions
215 * @{
218 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
219 * @brief Initialization and Configuration functions
221 @verbatim
222 ===============================================================================
223 ##### Initialization and Configuration functions #####
224 ===============================================================================
225 [..]
226 This subsection provides a set of functions allowing to initialize the USART
227 in asynchronous and in synchronous modes.
228 (+) For the asynchronous mode only these parameters can be configured:
229 (++) Baud Rate
230 (++) Word Length
231 (++) Stop Bit
232 (++) Parity: If the parity is enabled, then the MSB bit of the data written
233 in the data register is transmitted but is changed by the parity bit.
234 (++) USART polarity
235 (++) USART phase
236 (++) USART LastBit
237 (++) Receiver/transmitter modes
239 [..]
240 The HAL_USART_Init() function follows the USART synchronous configuration
241 procedure (details for the procedure are available in reference manual).
243 @endverbatim
245 Depending on the frame length defined by the M1 and M0 bits (7-bit,
246 8-bit or 9-bit), the possible USART formats are listed in the
247 following table.
249 Table 1. USART frame format.
250 +-----------------------------------------------------------------------+
251 | M1 bit | M0 bit | PCE bit | USART frame |
252 |---------|---------|-----------|---------------------------------------|
253 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
254 |---------|---------|-----------|---------------------------------------|
255 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
256 |---------|---------|-----------|---------------------------------------|
257 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
258 |---------|---------|-----------|---------------------------------------|
259 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
260 |---------|---------|-----------|---------------------------------------|
261 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
262 |---------|---------|-----------|---------------------------------------|
263 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
264 +-----------------------------------------------------------------------+
266 * @{
270 * @brief Initialize the USART mode according to the specified
271 * parameters in the USART_InitTypeDef and initialize the associated handle.
272 * @param husart USART handle.
273 * @retval HAL status
275 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
277 /* Check the USART handle allocation */
278 if (husart == NULL)
280 return HAL_ERROR;
283 /* Check the parameters */
284 assert_param(IS_USART_INSTANCE(husart->Instance));
286 if (husart->State == HAL_USART_STATE_RESET)
288 /* Allocate lock resource and initialize it */
289 husart->Lock = HAL_UNLOCKED;
291 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
292 USART_InitCallbacksToDefault(husart);
294 if (husart->MspInitCallback == NULL)
296 husart->MspInitCallback = HAL_USART_MspInit;
299 /* Init the low level hardware */
300 husart->MspInitCallback(husart);
301 #else
302 /* Init the low level hardware : GPIO, CLOCK */
303 HAL_USART_MspInit(husart);
304 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
307 husart->State = HAL_USART_STATE_BUSY;
309 /* Disable the Peripheral */
310 __HAL_USART_DISABLE(husart);
312 /* Set the Usart Communication parameters */
313 if (USART_SetConfig(husart) == HAL_ERROR)
315 return HAL_ERROR;
318 /* In Synchronous mode, the following bits must be kept cleared:
319 - LINEN bit in the USART_CR2 register
320 - HDSEL, SCEN and IREN bits in the USART_CR3 register.
322 husart->Instance->CR2 &= ~USART_CR2_LINEN;
323 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
325 /* Enable the Peripheral */
326 __HAL_USART_ENABLE(husart);
328 /* TEACK and/or REACK to check before moving husart->State to Ready */
329 return (USART_CheckIdleState(husart));
333 * @brief DeInitialize the USART peripheral.
334 * @param husart USART handle.
335 * @retval HAL status
337 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
339 /* Check the USART handle allocation */
340 if (husart == NULL)
342 return HAL_ERROR;
345 /* Check the parameters */
346 assert_param(IS_USART_INSTANCE(husart->Instance));
348 husart->State = HAL_USART_STATE_BUSY;
350 husart->Instance->CR1 = 0x0U;
351 husart->Instance->CR2 = 0x0U;
352 husart->Instance->CR3 = 0x0U;
354 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
355 if (husart->MspDeInitCallback == NULL)
357 husart->MspDeInitCallback = HAL_USART_MspDeInit;
359 /* DeInit the low level hardware */
360 husart->MspDeInitCallback(husart);
361 #else
362 /* DeInit the low level hardware */
363 HAL_USART_MspDeInit(husart);
364 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
366 husart->ErrorCode = HAL_USART_ERROR_NONE;
367 husart->State = HAL_USART_STATE_RESET;
369 /* Process Unlock */
370 __HAL_UNLOCK(husart);
372 return HAL_OK;
376 * @brief Initialize the USART MSP.
377 * @param husart USART handle.
378 * @retval None
380 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
382 /* Prevent unused argument(s) compilation warning */
383 UNUSED(husart);
385 /* NOTE : This function should not be modified, when the callback is needed,
386 the HAL_USART_MspInit can be implemented in the user file
391 * @brief DeInitialize the USART MSP.
392 * @param husart USART handle.
393 * @retval None
395 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
397 /* Prevent unused argument(s) compilation warning */
398 UNUSED(husart);
400 /* NOTE : This function should not be modified, when the callback is needed,
401 the HAL_USART_MspDeInit can be implemented in the user file
405 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
407 * @brief Register a User USART Callback
408 * To be used instead of the weak predefined callback
409 * @param husart usart handle
410 * @param CallbackID ID of the callback to be registered
411 * This parameter can be one of the following values:
412 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
413 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
414 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
415 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
416 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
417 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
418 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
419 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
420 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
421 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
422 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
423 * @param pCallback pointer to the Callback function
424 * @retval HAL status
425 + */
426 HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
427 pUSART_CallbackTypeDef pCallback)
429 HAL_StatusTypeDef status = HAL_OK;
431 if (pCallback == NULL)
433 /* Update the error code */
434 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
436 return HAL_ERROR;
438 /* Process locked */
439 __HAL_LOCK(husart);
441 if (husart->State == HAL_USART_STATE_READY)
443 switch (CallbackID)
445 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
446 husart->TxHalfCpltCallback = pCallback;
447 break;
449 case HAL_USART_TX_COMPLETE_CB_ID :
450 husart->TxCpltCallback = pCallback;
451 break;
453 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
454 husart->RxHalfCpltCallback = pCallback;
455 break;
457 case HAL_USART_RX_COMPLETE_CB_ID :
458 husart->RxCpltCallback = pCallback;
459 break;
461 case HAL_USART_TX_RX_COMPLETE_CB_ID :
462 husart->TxRxCpltCallback = pCallback;
463 break;
465 case HAL_USART_ERROR_CB_ID :
466 husart->ErrorCallback = pCallback;
467 break;
469 case HAL_USART_ABORT_COMPLETE_CB_ID :
470 husart->AbortCpltCallback = pCallback;
471 break;
473 case HAL_USART_RX_FIFO_FULL_CB_ID :
474 husart->RxFifoFullCallback = pCallback;
475 break;
477 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
478 husart->TxFifoEmptyCallback = pCallback;
479 break;
481 case HAL_USART_MSPINIT_CB_ID :
482 husart->MspInitCallback = pCallback;
483 break;
485 case HAL_USART_MSPDEINIT_CB_ID :
486 husart->MspDeInitCallback = pCallback;
487 break;
489 default :
490 /* Update the error code */
491 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
493 /* Return error status */
494 status = HAL_ERROR;
495 break;
498 else if (husart->State == HAL_USART_STATE_RESET)
500 switch (CallbackID)
502 case HAL_USART_MSPINIT_CB_ID :
503 husart->MspInitCallback = pCallback;
504 break;
506 case HAL_USART_MSPDEINIT_CB_ID :
507 husart->MspDeInitCallback = pCallback;
508 break;
510 default :
511 /* Update the error code */
512 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
514 /* Return error status */
515 status = HAL_ERROR;
516 break;
519 else
521 /* Update the error code */
522 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
524 /* Return error status */
525 status = HAL_ERROR;
528 /* Release Lock */
529 __HAL_UNLOCK(husart);
531 return status;
535 * @brief Unregister an UART Callback
536 * UART callaback is redirected to the weak predefined callback
537 * @param husart uart 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 /* Process locked */
558 __HAL_LOCK(husart);
560 if (HAL_USART_STATE_READY == husart->State)
562 switch (CallbackID)
564 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
565 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
566 break;
568 case HAL_USART_TX_COMPLETE_CB_ID :
569 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
570 break;
572 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
573 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
574 break;
576 case HAL_USART_RX_COMPLETE_CB_ID :
577 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
578 break;
580 case HAL_USART_TX_RX_COMPLETE_CB_ID :
581 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
582 break;
584 case HAL_USART_ERROR_CB_ID :
585 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
586 break;
588 case HAL_USART_ABORT_COMPLETE_CB_ID :
589 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
590 break;
592 case HAL_USART_RX_FIFO_FULL_CB_ID :
593 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
594 break;
596 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
597 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
598 break;
600 case HAL_USART_MSPINIT_CB_ID :
601 husart->MspInitCallback = HAL_USART_MspInit; /* Legacy weak MspInitCallback */
602 break;
604 case HAL_USART_MSPDEINIT_CB_ID :
605 husart->MspDeInitCallback = HAL_USART_MspDeInit; /* Legacy weak MspDeInitCallback */
606 break;
608 default :
609 /* Update the error code */
610 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
612 /* Return error status */
613 status = HAL_ERROR;
614 break;
617 else if (HAL_USART_STATE_RESET == husart->State)
619 switch (CallbackID)
621 case HAL_USART_MSPINIT_CB_ID :
622 husart->MspInitCallback = HAL_USART_MspInit;
623 break;
625 case HAL_USART_MSPDEINIT_CB_ID :
626 husart->MspDeInitCallback = HAL_USART_MspDeInit;
627 break;
629 default :
630 /* Update the error code */
631 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
633 /* Return error status */
634 status = HAL_ERROR;
635 break;
638 else
640 /* Update the error code */
641 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
643 /* Return error status */
644 status = HAL_ERROR;
647 /* Release Lock */
648 __HAL_UNLOCK(husart);
650 return status;
652 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
656 * @}
659 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
660 * @brief USART Transmit and Receive functions
662 @verbatim
663 ===============================================================================
664 ##### IO operation functions #####
665 ===============================================================================
666 [..] This subsection provides a set of functions allowing to manage the USART synchronous
667 data transfers.
669 [..] The USART supports master mode only: it cannot receive or send data related to an input
670 clock (SCLK is always an output).
672 [..]
674 (#) There are two modes of transfer:
675 (++) Blocking mode: The communication is performed in polling mode.
676 The HAL status of all data processing is returned by the same function
677 after finishing transfer.
678 (++) No-Blocking mode: The communication is performed using Interrupts
679 or DMA, These API's return the HAL status.
680 The end of the data processing will be indicated through the
681 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
682 using DMA mode.
683 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
684 will be executed respectively at the end of the transmit or Receive process
685 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
687 (#) Blocking mode API's are :
688 (++) HAL_USART_Transmit() in simplex mode
689 (++) HAL_USART_Receive() in full duplex receive only
690 (++) HAL_USART_TransmitReceive() in full duplex mode
692 (#) Non-Blocking mode API's with Interrupt are :
693 (++) HAL_USART_Transmit_IT() in simplex mode
694 (++) HAL_USART_Receive_IT() in full duplex receive only
695 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
696 (++) HAL_USART_IRQHandler()
698 (#) No-Blocking mode API's with DMA are :
699 (++) HAL_USART_Transmit_DMA() in simplex mode
700 (++) HAL_USART_Receive_DMA() in full duplex receive only
701 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
702 (++) HAL_USART_DMAPause()
703 (++) HAL_USART_DMAResume()
704 (++) HAL_USART_DMAStop()
706 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
707 (++) HAL_USART_TxCpltCallback()
708 (++) HAL_USART_RxCpltCallback()
709 (++) HAL_USART_TxHalfCpltCallback()
710 (++) HAL_USART_RxHalfCpltCallback()
711 (++) HAL_USART_ErrorCallback()
712 (++) HAL_USART_TxRxCpltCallback()
714 (#) Non-Blocking mode transfers could be aborted using Abort API's :
715 (++) HAL_USART_Abort()
716 (++) HAL_USART_Abort_IT()
718 (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
719 (++) HAL_USART_AbortCpltCallback()
721 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
722 Errors are handled as follows :
723 (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
724 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
725 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
726 and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side.
727 If user wants to abort it, Abort services should be called by user.
728 (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
729 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
730 Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed.
732 @endverbatim
733 * @{
737 * @brief Simplex send an amount of data in blocking mode.
738 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
739 * the sent data is handled as a set of u16. In this case, Size must indicate the number
740 * of u16 provided through pTxData.
741 * @param husart USART handle.
742 * @param pTxData Pointer to data buffer (u8 or u16 data elements).
743 * @param Size Amount of data elements (u8 or u16) to be sent.
744 * @param Timeout Timeout duration.
745 * @retval HAL status
747 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
749 uint8_t *ptxdata8bits;
750 uint16_t *ptxdata16bits;
751 uint32_t tickstart;
753 if (husart->State == HAL_USART_STATE_READY)
755 if ((pTxData == NULL) || (Size == 0U))
757 return HAL_ERROR;
760 /* Process Locked */
761 __HAL_LOCK(husart);
763 husart->ErrorCode = HAL_USART_ERROR_NONE;
764 husart->State = HAL_USART_STATE_BUSY_TX;
766 /* Init tickstart for timeout managment*/
767 tickstart = HAL_GetTick();
769 husart->TxXferSize = Size;
770 husart->TxXferCount = Size;
772 /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
773 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
775 ptxdata8bits = NULL;
776 ptxdata16bits = (uint16_t *) pTxData;
778 else
780 ptxdata8bits = pTxData;
781 ptxdata16bits = NULL;
784 /* Check the remaining data to be sent */
785 while (husart->TxXferCount > 0U)
787 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
789 return HAL_TIMEOUT;
791 if (ptxdata8bits == NULL)
793 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
794 ptxdata16bits++;
796 else
798 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
799 ptxdata8bits++;
802 husart->TxXferCount--;
805 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
807 return HAL_TIMEOUT;
810 /* Clear Transmission Complete Flag */
811 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
813 /* Clear overrun flag and discard the received data */
814 __HAL_USART_CLEAR_OREFLAG(husart);
815 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
816 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
818 /* At end of Tx process, restore husart->State to Ready */
819 husart->State = HAL_USART_STATE_READY;
821 /* Process Unlocked */
822 __HAL_UNLOCK(husart);
824 return HAL_OK;
826 else
828 return HAL_BUSY;
833 * @brief Receive an amount of data in blocking mode.
834 * @note To receive synchronous data, dummy data are simultaneously transmitted.
835 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
836 * the received data is handled as a set of u16. In this case, Size must indicate the number
837 * of u16 available through pRxData.
838 * @param husart USART handle.
839 * @param pRxData Pointer to data buffer (u8 or u16 data elements).
840 * @param Size Amount of data elements (u8 or u16) to be received.
841 * @param Timeout Timeout duration.
842 * @retval HAL status
844 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
846 uint8_t *prxdata8bits;
847 uint16_t *prxdata16bits;
848 uint16_t uhMask;
849 uint32_t tickstart;
851 if (husart->State == HAL_USART_STATE_READY)
853 if ((pRxData == NULL) || (Size == 0U))
855 return HAL_ERROR;
858 /* Process Locked */
859 __HAL_LOCK(husart);
861 husart->ErrorCode = HAL_USART_ERROR_NONE;
862 husart->State = HAL_USART_STATE_BUSY_RX;
864 /* Init tickstart for timeout managment*/
865 tickstart = HAL_GetTick();
867 husart->RxXferSize = Size;
868 husart->RxXferCount = Size;
870 /* Computation of USART mask to apply to RDR register */
871 USART_MASK_COMPUTATION(husart);
872 uhMask = husart->Mask;
874 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
875 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
877 prxdata8bits = NULL;
878 prxdata16bits = (uint16_t *) pRxData;
880 else
882 prxdata8bits = pRxData;
883 prxdata16bits = NULL;
886 /* as long as data have to be received */
887 while (husart->RxXferCount > 0U)
889 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
891 /* Wait until TXE flag is set to send dummy byte in order to generate the
892 * clock for the slave to send data.
893 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
894 * can be written for all the cases. */
895 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
897 return HAL_TIMEOUT;
899 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
902 /* Wait for RXNE Flag */
903 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
905 return HAL_TIMEOUT;
908 if (prxdata8bits == NULL)
910 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
911 prxdata16bits++;
913 else
915 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
916 prxdata8bits++;
919 husart->RxXferCount--;
923 /* Clear SPI slave underrun flag and discard transmit data */
924 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
926 __HAL_USART_CLEAR_UDRFLAG(husart);
927 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
930 /* At end of Rx process, restore husart->State to Ready */
931 husart->State = HAL_USART_STATE_READY;
933 /* Process Unlocked */
934 __HAL_UNLOCK(husart);
936 return HAL_OK;
938 else
940 return HAL_BUSY;
945 * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
946 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
947 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
948 * of u16 available through pTxData and through pRxData.
949 * @param husart USART handle.
950 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
951 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
952 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
953 * @param Timeout Timeout duration.
954 * @retval HAL status
956 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,
957 uint16_t Size, uint32_t Timeout)
959 uint8_t *prxdata8bits;
960 uint16_t *prxdata16bits;
961 uint8_t *ptxdata8bits;
962 uint16_t *ptxdata16bits;
963 uint16_t uhMask;
964 uint16_t rxdatacount;
965 uint32_t tickstart;
967 if (husart->State == HAL_USART_STATE_READY)
969 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
971 return HAL_ERROR;
974 /* Process Locked */
975 __HAL_LOCK(husart);
977 husart->ErrorCode = HAL_USART_ERROR_NONE;
978 husart->State = HAL_USART_STATE_BUSY_RX;
980 /* Init tickstart for timeout managment*/
981 tickstart = HAL_GetTick();
983 husart->RxXferSize = Size;
984 husart->TxXferSize = Size;
985 husart->TxXferCount = Size;
986 husart->RxXferCount = Size;
988 /* Computation of USART mask to apply to RDR register */
989 USART_MASK_COMPUTATION(husart);
990 uhMask = husart->Mask;
992 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
993 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
995 prxdata8bits = NULL;
996 ptxdata8bits = NULL;
997 ptxdata16bits = (uint16_t *) pTxData;
998 prxdata16bits = (uint16_t *) pRxData;
1000 else
1002 prxdata8bits = pRxData;
1003 ptxdata8bits = pTxData;
1004 ptxdata16bits = NULL;
1005 prxdata16bits = NULL;
1008 if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE))
1010 /* Wait until TXE flag is set to send data */
1011 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1013 return HAL_TIMEOUT;
1015 if (ptxdata8bits == NULL)
1017 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1018 ptxdata16bits++;
1020 else
1022 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1023 ptxdata8bits++;
1026 husart->TxXferCount--;
1029 /* Check the remain data to be sent */
1030 /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
1031 rxdatacount = husart->RxXferCount;
1032 while ((husart->TxXferCount > 0U) || (rxdatacount > 0U))
1034 if (husart->TxXferCount > 0U)
1036 /* Wait until TXE flag is set to send data */
1037 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1039 return HAL_TIMEOUT;
1041 if (ptxdata8bits == NULL)
1043 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1044 ptxdata16bits++;
1046 else
1048 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1049 ptxdata8bits++;
1052 husart->TxXferCount--;
1055 if (husart->RxXferCount > 0U)
1057 /* Wait for RXNE Flag */
1058 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1060 return HAL_TIMEOUT;
1063 if (prxdata8bits == NULL)
1065 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
1066 prxdata16bits++;
1068 else
1070 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
1071 prxdata8bits++;
1074 husart->RxXferCount--;
1076 rxdatacount = husart->RxXferCount;
1079 /* At end of TxRx process, restore husart->State to Ready */
1080 husart->State = HAL_USART_STATE_READY;
1082 /* Process Unlocked */
1083 __HAL_UNLOCK(husart);
1085 return HAL_OK;
1087 else
1089 return HAL_BUSY;
1094 * @brief Send an amount of data in interrupt mode.
1095 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1096 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1097 * of u16 provided through pTxData.
1098 * @param husart USART handle.
1099 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1100 * @param Size amount of data elements (u8 or u16) to be sent.
1101 * @retval HAL status
1103 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
1105 if (husart->State == HAL_USART_STATE_READY)
1107 if ((pTxData == NULL) || (Size == 0U))
1109 return HAL_ERROR;
1112 /* Process Locked */
1113 __HAL_LOCK(husart);
1115 husart->pTxBuffPtr = pTxData;
1116 husart->TxXferSize = Size;
1117 husart->TxXferCount = Size;
1118 husart->TxISR = NULL;
1120 husart->ErrorCode = HAL_USART_ERROR_NONE;
1121 husart->State = HAL_USART_STATE_BUSY_TX;
1123 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1124 are not managed by the USART Transmit Process to avoid the overrun interrupt
1125 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1126 to benefit for the frame error and noise interrupts the usart mode should be
1127 configured only for transmit "USART_MODE_TX" */
1129 /* Configure Tx interrupt processing */
1130 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1132 /* Set the Tx ISR function pointer according to the data word length */
1133 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1135 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1137 else
1139 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1142 /* Process Unlocked */
1143 __HAL_UNLOCK(husart);
1145 /* Enable the TX FIFO threshold interrupt */
1146 __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT);
1148 else
1150 /* Set the Tx ISR function pointer according to the data word length */
1151 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1153 husart->TxISR = USART_TxISR_16BIT;
1155 else
1157 husart->TxISR = USART_TxISR_8BIT;
1160 /* Process Unlocked */
1161 __HAL_UNLOCK(husart);
1163 /* Enable the USART Transmit Data Register Empty Interrupt */
1164 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
1167 return HAL_OK;
1169 else
1171 return HAL_BUSY;
1176 * @brief Receive an amount of data in interrupt mode.
1177 * @note To receive synchronous data, dummy data are simultaneously transmitted.
1178 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1179 * the received data is handled as a set of u16. In this case, Size must indicate the number
1180 * of u16 available through pRxData.
1181 * @param husart USART handle.
1182 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1183 * @param Size amount of data elements (u8 or u16) to be received.
1184 * @retval HAL status
1186 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1188 uint16_t nb_dummy_data;
1190 if (husart->State == HAL_USART_STATE_READY)
1192 if ((pRxData == NULL) || (Size == 0U))
1194 return HAL_ERROR;
1197 /* Process Locked */
1198 __HAL_LOCK(husart);
1200 husart->pRxBuffPtr = pRxData;
1201 husart->RxXferSize = Size;
1202 husart->RxXferCount = Size;
1203 husart->RxISR = NULL;
1205 USART_MASK_COMPUTATION(husart);
1207 husart->ErrorCode = HAL_USART_ERROR_NONE;
1208 husart->State = HAL_USART_STATE_BUSY_RX;
1210 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1211 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1213 /* Configure Rx interrupt processing */
1214 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1216 /* Set the Rx ISR function pointer according to the data word length */
1217 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1219 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1221 else
1223 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1226 /* Process Unlocked */
1227 __HAL_UNLOCK(husart);
1229 /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
1230 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 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1252 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
1254 /* Send dummy data in order to generate the clock for the Slave to send the next data.
1255 When FIFO mode is disabled only one data must be transferred.
1256 When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold.
1258 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1260 for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--)
1262 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1265 else
1267 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1271 return HAL_OK;
1273 else
1275 return HAL_BUSY;
1280 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1281 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1282 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1283 * of u16 available through pTxData and through pRxData.
1284 * @param husart USART handle.
1285 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1286 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1287 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
1288 * @retval HAL status
1290 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,
1291 uint16_t Size)
1294 if (husart->State == HAL_USART_STATE_READY)
1296 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1298 return HAL_ERROR;
1301 /* Process Locked */
1302 __HAL_LOCK(husart);
1304 husart->pRxBuffPtr = pRxData;
1305 husart->RxXferSize = Size;
1306 husart->RxXferCount = Size;
1307 husart->pTxBuffPtr = pTxData;
1308 husart->TxXferSize = Size;
1309 husart->TxXferCount = Size;
1311 /* Computation of USART mask to apply to RDR register */
1312 USART_MASK_COMPUTATION(husart);
1314 husart->ErrorCode = HAL_USART_ERROR_NONE;
1315 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1317 /* Configure TxRx interrupt processing */
1318 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1320 /* Set the Rx ISR function pointer according to the data word length */
1321 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1323 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1324 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1326 else
1328 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1329 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1332 /* Process Locked */
1333 __HAL_UNLOCK(husart);
1335 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1336 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1338 /* Enable the USART Parity Error interrupt */
1339 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1341 /* Enable the TX and RX FIFO Threshold interrupts */
1342 SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE));
1344 else
1346 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1348 husart->TxISR = USART_TxISR_16BIT;
1349 husart->RxISR = USART_RxISR_16BIT;
1351 else
1353 husart->TxISR = USART_TxISR_8BIT;
1354 husart->RxISR = USART_RxISR_8BIT;
1357 /* Process Locked */
1358 __HAL_UNLOCK(husart);
1360 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1361 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1363 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1364 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1366 /* Enable the USART Transmit Data Register Empty Interrupt */
1367 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1370 return HAL_OK;
1372 else
1374 return HAL_BUSY;
1379 * @brief Send an amount of data in DMA mode.
1380 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1381 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1382 * of u16 provided through pTxData.
1383 * @param husart USART handle.
1384 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1385 * @param Size amount of data elements (u8 or u16) to be sent.
1386 * @retval HAL status
1388 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
1390 HAL_StatusTypeDef status = HAL_OK;
1391 uint32_t *tmp;
1393 if (husart->State == HAL_USART_STATE_READY)
1395 if ((pTxData == NULL) || (Size == 0U))
1397 return HAL_ERROR;
1400 /* Process Locked */
1401 __HAL_LOCK(husart);
1403 husart->pTxBuffPtr = pTxData;
1404 husart->TxXferSize = Size;
1405 husart->TxXferCount = Size;
1407 husart->ErrorCode = HAL_USART_ERROR_NONE;
1408 husart->State = HAL_USART_STATE_BUSY_TX;
1410 if (husart->hdmatx != NULL)
1412 /* Set the USART DMA transfer complete callback */
1413 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1415 /* Set the USART DMA Half transfer complete callback */
1416 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1418 /* Set the DMA error callback */
1419 husart->hdmatx->XferErrorCallback = USART_DMAError;
1421 /* Enable the USART transmit DMA channel */
1422 tmp = (uint32_t *)&pTxData;
1423 status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1426 if (status == HAL_OK)
1428 /* Clear the TC flag in the ICR register */
1429 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1431 /* Process Unlocked */
1432 __HAL_UNLOCK(husart);
1434 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1435 in the USART CR3 register */
1436 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1438 return HAL_OK;
1440 else
1442 /* Set error code to DMA */
1443 husart->ErrorCode = HAL_USART_ERROR_DMA;
1445 /* Process Unlocked */
1446 __HAL_UNLOCK(husart);
1448 /* Restore husart->State to ready */
1449 husart->State = HAL_USART_STATE_READY;
1451 return HAL_ERROR;
1454 else
1456 return HAL_BUSY;
1461 * @brief Receive an amount of data in DMA mode.
1462 * @note When the USART parity is enabled (PCE = 1), the received data contain
1463 * the parity bit (MSB position).
1464 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1465 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1466 * the received data is handled as a set of u16. In this case, Size must indicate the number
1467 * of u16 available through pRxData.
1468 * @param husart USART handle.
1469 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1470 * @param Size amount of data elements (u8 or u16) to be received.
1471 * @retval HAL status
1473 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1475 HAL_StatusTypeDef status = HAL_OK;
1476 uint32_t *tmp = (uint32_t *)&pRxData;
1478 /* Check that a Rx process is not already ongoing */
1479 if (husart->State == HAL_USART_STATE_READY)
1481 if ((pRxData == NULL) || (Size == 0U))
1483 return HAL_ERROR;
1486 /* Process Locked */
1487 __HAL_LOCK(husart);
1489 husart->pRxBuffPtr = pRxData;
1490 husart->RxXferSize = Size;
1491 husart->pTxBuffPtr = pRxData;
1492 husart->TxXferSize = Size;
1494 husart->ErrorCode = HAL_USART_ERROR_NONE;
1495 husart->State = HAL_USART_STATE_BUSY_RX;
1497 if (husart->hdmarx != NULL)
1499 /* Set the USART DMA Rx transfer complete callback */
1500 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1502 /* Set the USART DMA Half transfer complete callback */
1503 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1505 /* Set the USART DMA Rx transfer error callback */
1506 husart->hdmarx->XferErrorCallback = USART_DMAError;
1508 /* Enable the USART receive DMA channel */
1509 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1512 if ((status == HAL_OK) &&
1513 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
1515 /* Enable the USART transmit DMA channel: the transmit channel is used in order
1516 to generate in the non-blocking mode the clock to the slave device,
1517 this mode isn't a simplex receive mode but a full-duplex receive mode */
1519 /* Set the USART DMA Tx Complete and Error callback to Null */
1520 if (husart->hdmatx != NULL)
1522 husart->hdmatx->XferErrorCallback = NULL;
1523 husart->hdmatx->XferHalfCpltCallback = NULL;
1524 husart->hdmatx->XferCpltCallback = NULL;
1525 status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1529 if (status == HAL_OK)
1531 /* Process Unlocked */
1532 __HAL_UNLOCK(husart);
1534 /* Enable the USART Parity Error Interrupt */
1535 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1537 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1538 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1540 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1541 in the USART CR3 register */
1542 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1544 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1545 in the USART CR3 register */
1546 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1548 return HAL_OK;
1550 else
1552 if (husart->hdmarx != NULL)
1554 status = HAL_DMA_Abort(husart->hdmarx);
1557 /* No need to check on error code */
1558 UNUSED(status);
1560 /* Set error code to DMA */
1561 husart->ErrorCode = HAL_USART_ERROR_DMA;
1563 /* Process Unlocked */
1564 __HAL_UNLOCK(husart);
1566 /* Restore husart->State to ready */
1567 husart->State = HAL_USART_STATE_READY;
1569 return HAL_ERROR;
1572 else
1574 return HAL_BUSY;
1579 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1580 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1581 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1582 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1583 * of u16 available through pTxData and through pRxData.
1584 * @param husart USART handle.
1585 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1586 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1587 * @param Size amount of data elements (u8 or u16) to be received/sent.
1588 * @retval HAL status
1590 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,
1591 uint16_t Size)
1593 HAL_StatusTypeDef status;
1594 uint32_t *tmp;
1596 if (husart->State == HAL_USART_STATE_READY)
1598 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1600 return HAL_ERROR;
1603 /* Process Locked */
1604 __HAL_LOCK(husart);
1606 husart->pRxBuffPtr = pRxData;
1607 husart->RxXferSize = Size;
1608 husart->pTxBuffPtr = pTxData;
1609 husart->TxXferSize = Size;
1611 husart->ErrorCode = HAL_USART_ERROR_NONE;
1612 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1614 if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
1616 /* Set the USART DMA Rx transfer complete callback */
1617 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1619 /* Set the USART DMA Half transfer complete callback */
1620 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1622 /* Set the USART DMA Tx transfer complete callback */
1623 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1625 /* Set the USART DMA Half transfer complete callback */
1626 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1628 /* Set the USART DMA Tx transfer error callback */
1629 husart->hdmatx->XferErrorCallback = USART_DMAError;
1631 /* Set the USART DMA Rx transfer error callback */
1632 husart->hdmarx->XferErrorCallback = USART_DMAError;
1634 /* Enable the USART receive DMA channel */
1635 tmp = (uint32_t *)&pRxData;
1636 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1638 /* Enable the USART transmit DMA channel */
1639 if (status == HAL_OK)
1641 tmp = (uint32_t *)&pTxData;
1642 status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1645 else
1647 status = HAL_ERROR;
1650 if (status == HAL_OK)
1652 /* Process Unlocked */
1653 __HAL_UNLOCK(husart);
1655 /* Enable the USART Parity Error Interrupt */
1656 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1658 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1659 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1661 /* Clear the TC flag in the ICR register */
1662 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1664 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1665 in the USART CR3 register */
1666 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1668 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1669 in the USART CR3 register */
1670 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1672 return HAL_OK;
1674 else
1676 if (husart->hdmarx != NULL)
1678 status = HAL_DMA_Abort(husart->hdmarx);
1681 /* No need to check on error code */
1682 UNUSED(status);
1684 /* Set error code to DMA */
1685 husart->ErrorCode = HAL_USART_ERROR_DMA;
1687 /* Process Unlocked */
1688 __HAL_UNLOCK(husart);
1690 /* Restore husart->State to ready */
1691 husart->State = HAL_USART_STATE_READY;
1693 return HAL_ERROR;
1696 else
1698 return HAL_BUSY;
1703 * @brief Pause the DMA Transfer.
1704 * @param husart USART handle.
1705 * @retval HAL status
1707 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1709 const HAL_USART_StateTypeDef state = husart->State;
1711 /* Process Locked */
1712 __HAL_LOCK(husart);
1714 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
1715 (state == HAL_USART_STATE_BUSY_TX))
1717 /* Disable the USART DMA Tx request */
1718 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1720 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1721 (state == HAL_USART_STATE_BUSY_TX_RX))
1723 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1725 /* Disable the USART DMA Tx request */
1726 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1728 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1730 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1731 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1732 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1734 /* Disable the USART DMA Rx request */
1735 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1738 else
1740 /* Nothing to do */
1743 /* Process Unlocked */
1744 __HAL_UNLOCK(husart);
1746 return HAL_OK;
1750 * @brief Resume the DMA Transfer.
1751 * @param husart USART handle.
1752 * @retval HAL status
1754 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1756 const HAL_USART_StateTypeDef state = husart->State;
1758 /* Process Locked */
1759 __HAL_LOCK(husart);
1761 if (state == HAL_USART_STATE_BUSY_TX)
1763 /* Enable the USART DMA Tx request */
1764 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1766 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1767 (state == HAL_USART_STATE_BUSY_TX_RX))
1769 /* Clear the Overrun flag before resuming the Rx transfer*/
1770 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
1772 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1773 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1774 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1776 /* Enable the USART DMA Rx request before the DMA Tx request */
1777 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1779 /* Enable the USART DMA Tx request */
1780 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1782 else
1784 /* Nothing to do */
1787 /* Process Unlocked */
1788 __HAL_UNLOCK(husart);
1790 return HAL_OK;
1794 * @brief Stop the DMA Transfer.
1795 * @param husart USART handle.
1796 * @retval HAL status
1798 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1800 /* The Lock is not implemented on this API to allow the user application
1801 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1802 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1803 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1804 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1805 the stream and the corresponding call back is executed. */
1807 /* Disable the USART Tx/Rx DMA requests */
1808 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1809 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1811 /* Abort the USART DMA tx channel */
1812 if (husart->hdmatx != NULL)
1814 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1816 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1818 /* Set error code to DMA */
1819 husart->ErrorCode = HAL_USART_ERROR_DMA;
1821 return HAL_TIMEOUT;
1825 /* Abort the USART DMA rx channel */
1826 if (husart->hdmarx != NULL)
1828 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1830 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1832 /* Set error code to DMA */
1833 husart->ErrorCode = HAL_USART_ERROR_DMA;
1835 return HAL_TIMEOUT;
1840 USART_EndTransfer(husart);
1841 husart->State = HAL_USART_STATE_READY;
1843 return HAL_OK;
1847 * @brief Abort ongoing transfers (blocking mode).
1848 * @param husart USART handle.
1849 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1850 * This procedure performs following operations :
1851 * - Disable USART Interrupts (Tx and Rx)
1852 * - Disable the DMA transfer in the peripheral register (if enabled)
1853 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1854 * - Set handle State to READY
1855 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1856 * @retval HAL status
1858 HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
1860 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1861 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
1862 USART_CR1_TCIE));
1863 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1865 /* Disable the USART DMA Tx request if enabled */
1866 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1868 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1870 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1871 if (husart->hdmatx != NULL)
1873 /* Set the USART DMA Abort callback to Null.
1874 No call back execution at end of DMA abort procedure */
1875 husart->hdmatx->XferAbortCallback = NULL;
1877 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1879 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1881 /* Set error code to DMA */
1882 husart->ErrorCode = HAL_USART_ERROR_DMA;
1884 return HAL_TIMEOUT;
1890 /* Disable the USART DMA Rx request if enabled */
1891 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1893 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1895 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1896 if (husart->hdmarx != NULL)
1898 /* Set the USART DMA Abort callback to Null.
1899 No call back execution at end of DMA abort procedure */
1900 husart->hdmarx->XferAbortCallback = NULL;
1902 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1904 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1906 /* Set error code to DMA */
1907 husart->ErrorCode = HAL_USART_ERROR_DMA;
1909 return HAL_TIMEOUT;
1915 /* Reset Tx and Rx transfer counters */
1916 husart->TxXferCount = 0U;
1917 husart->RxXferCount = 0U;
1919 /* Clear the Error flags in the ICR register */
1920 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
1922 /* Flush the whole TX FIFO (if needed) */
1923 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1925 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
1928 /* Discard the received data */
1929 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
1931 /* Restore husart->State to Ready */
1932 husart->State = HAL_USART_STATE_READY;
1934 /* Reset Handle ErrorCode to No Error */
1935 husart->ErrorCode = HAL_USART_ERROR_NONE;
1937 return HAL_OK;
1941 * @brief Abort ongoing transfers (Interrupt mode).
1942 * @param husart USART handle.
1943 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1944 * This procedure performs following operations :
1945 * - Disable USART Interrupts (Tx and Rx)
1946 * - Disable the DMA transfer in the peripheral register (if enabled)
1947 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1948 * - Set handle State to READY
1949 * - At abort completion, call user abort complete callback
1950 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1951 * considered as completed only when user abort complete callback is executed (not when exiting function).
1952 * @retval HAL status
1954 HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
1956 uint32_t abortcplt = 1U;
1958 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1959 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
1960 USART_CR1_TCIE));
1961 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1963 /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
1964 before any call to DMA Abort functions */
1965 /* DMA Tx Handle is valid */
1966 if (husart->hdmatx != NULL)
1968 /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
1969 Otherwise, set it to NULL */
1970 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1972 husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
1974 else
1976 husart->hdmatx->XferAbortCallback = NULL;
1979 /* DMA Rx Handle is valid */
1980 if (husart->hdmarx != NULL)
1982 /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
1983 Otherwise, set it to NULL */
1984 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1986 husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
1988 else
1990 husart->hdmarx->XferAbortCallback = NULL;
1994 /* Disable the USART DMA Tx request if enabled */
1995 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1997 /* Disable DMA Tx at USART level */
1998 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2000 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2001 if (husart->hdmatx != NULL)
2003 /* USART Tx DMA Abort callback has already been initialised :
2004 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2006 /* Abort DMA TX */
2007 if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
2009 husart->hdmatx->XferAbortCallback = NULL;
2011 else
2013 abortcplt = 0U;
2018 /* Disable the USART DMA Rx request if enabled */
2019 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2021 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2023 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2024 if (husart->hdmarx != NULL)
2026 /* USART Rx DMA Abort callback has already been initialised :
2027 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2029 /* Abort DMA RX */
2030 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2032 husart->hdmarx->XferAbortCallback = NULL;
2033 abortcplt = 1U;
2035 else
2037 abortcplt = 0U;
2042 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2043 if (abortcplt == 1U)
2045 /* Reset Tx and Rx transfer counters */
2046 husart->TxXferCount = 0U;
2047 husart->RxXferCount = 0U;
2049 /* Reset errorCode */
2050 husart->ErrorCode = HAL_USART_ERROR_NONE;
2052 /* Clear the Error flags in the ICR register */
2053 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2055 /* Flush the whole TX FIFO (if needed) */
2056 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2058 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2061 /* Discard the received data */
2062 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2064 /* Restore husart->State to Ready */
2065 husart->State = HAL_USART_STATE_READY;
2067 /* As no DMA to be aborted, call directly user Abort complete callback */
2068 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2069 /* Call registered Abort Complete Callback */
2070 husart->AbortCpltCallback(husart);
2071 #else
2072 /* Call legacy weak Abort Complete Callback */
2073 HAL_USART_AbortCpltCallback(husart);
2074 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2077 return HAL_OK;
2081 * @brief Handle USART interrupt request.
2082 * @param husart USART handle.
2083 * @retval None
2085 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
2087 uint32_t isrflags = READ_REG(husart->Instance->ISR);
2088 uint32_t cr1its = READ_REG(husart->Instance->CR1);
2089 uint32_t cr3its = READ_REG(husart->Instance->CR3);
2091 uint32_t errorflags;
2092 uint32_t errorcode;
2094 /* If no error occurs */
2095 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF | USART_ISR_UDR));
2096 if (errorflags == 0U)
2098 /* USART in mode Receiver ---------------------------------------------------*/
2099 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2100 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2101 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2103 if (husart->RxISR != NULL)
2105 husart->RxISR(husart);
2107 return;
2111 /* If some errors occur */
2112 if ((errorflags != 0U)
2113 && (((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2114 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
2116 /* USART parity error interrupt occurred -------------------------------------*/
2117 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2119 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
2121 husart->ErrorCode |= HAL_USART_ERROR_PE;
2124 /* USART frame error interrupt occurred --------------------------------------*/
2125 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2127 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
2129 husart->ErrorCode |= HAL_USART_ERROR_FE;
2132 /* USART noise error interrupt occurred --------------------------------------*/
2133 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2135 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
2137 husart->ErrorCode |= HAL_USART_ERROR_NE;
2140 /* USART Over-Run interrupt occurred -----------------------------------------*/
2141 if (((isrflags & USART_ISR_ORE) != 0U)
2142 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2143 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2145 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
2147 husart->ErrorCode |= HAL_USART_ERROR_ORE;
2150 /* USART Receiver Timeout interrupt occurred ---------------------------------*/
2151 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2153 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF);
2155 husart->ErrorCode |= HAL_USART_ERROR_RTO;
2158 /* USART SPI slave underrun error interrupt occurred -------------------------*/
2159 if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2161 /* Ignore SPI slave underrun errors when reception is going on */
2162 if (husart->State == HAL_USART_STATE_BUSY_RX)
2164 __HAL_USART_CLEAR_UDRFLAG(husart);
2165 return;
2167 else
2169 __HAL_USART_CLEAR_UDRFLAG(husart);
2170 husart->ErrorCode |= HAL_USART_ERROR_UDR;
2174 /* Call USART Error Call back function if need be --------------------------*/
2175 if (husart->ErrorCode != HAL_USART_ERROR_NONE)
2177 /* USART in mode Receiver ---------------------------------------------------*/
2178 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2179 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2180 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2182 if (husart->RxISR != NULL)
2184 husart->RxISR(husart);
2188 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2189 consider error as blocking */
2190 errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE;
2191 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) ||
2192 (errorcode != 0U))
2194 /* Blocking error : transfer is aborted
2195 Set the USART state ready to be able to start again the process,
2196 Disable Interrupts, and disable DMA requests, if ongoing */
2197 USART_EndTransfer(husart);
2199 /* Disable the USART DMA Rx request if enabled */
2200 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2202 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
2204 /* Abort the USART DMA Tx channel */
2205 if (husart->hdmatx != NULL)
2207 /* Set the USART Tx DMA Abort callback to NULL : no callback
2208 executed at end of DMA abort procedure */
2209 husart->hdmatx->XferAbortCallback = NULL;
2211 /* Abort DMA TX */
2212 (void)HAL_DMA_Abort_IT(husart->hdmatx);
2215 /* Abort the USART DMA Rx channel */
2216 if (husart->hdmarx != NULL)
2218 /* Set the USART Rx DMA Abort callback :
2219 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2220 husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
2222 /* Abort DMA RX */
2223 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2225 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2226 husart->hdmarx->XferAbortCallback(husart->hdmarx);
2229 else
2231 /* Call user error callback */
2232 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2233 /* Call registered Error Callback */
2234 husart->ErrorCallback(husart);
2235 #else
2236 /* Call legacy weak Error Callback */
2237 HAL_USART_ErrorCallback(husart);
2238 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2241 else
2243 /* Call user error callback */
2244 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2245 /* Call registered Error Callback */
2246 husart->ErrorCallback(husart);
2247 #else
2248 /* Call legacy weak Error Callback */
2249 HAL_USART_ErrorCallback(husart);
2250 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2253 else
2255 /* Non Blocking error : transfer could go on.
2256 Error is notified to user through user error callback */
2257 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2258 /* Call registered Error Callback */
2259 husart->ErrorCallback(husart);
2260 #else
2261 /* Call legacy weak Error Callback */
2262 HAL_USART_ErrorCallback(husart);
2263 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2264 husart->ErrorCode = HAL_USART_ERROR_NONE;
2267 return;
2269 } /* End if some error occurs */
2272 /* USART in mode Transmitter ------------------------------------------------*/
2273 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2274 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2275 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2277 if (husart->TxISR != NULL)
2279 husart->TxISR(husart);
2281 return;
2284 /* USART in mode Transmitter (transmission end) -----------------------------*/
2285 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2287 USART_EndTransmit_IT(husart);
2288 return;
2291 /* USART TX Fifo Empty occurred ----------------------------------------------*/
2292 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2294 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2295 /* Call registered Tx Fifo Empty Callback */
2296 husart->TxFifoEmptyCallback(husart);
2297 #else
2298 /* Call legacy weak Tx Fifo Empty Callback */
2299 HAL_USARTEx_TxFifoEmptyCallback(husart);
2300 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2301 return;
2304 /* USART RX Fifo Full occurred ----------------------------------------------*/
2305 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2307 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2308 /* Call registered Rx Fifo Full Callback */
2309 husart->RxFifoFullCallback(husart);
2310 #else
2311 /* Call legacy weak Rx Fifo Full Callback */
2312 HAL_USARTEx_RxFifoFullCallback(husart);
2313 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2314 return;
2319 * @brief Tx Transfer completed callback.
2320 * @param husart USART handle.
2321 * @retval None
2323 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
2325 /* Prevent unused argument(s) compilation warning */
2326 UNUSED(husart);
2328 /* NOTE : This function should not be modified, when the callback is needed,
2329 the HAL_USART_TxCpltCallback can be implemented in the user file.
2334 * @brief Tx Half Transfer completed callback.
2335 * @param husart USART handle.
2336 * @retval None
2338 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
2340 /* Prevent unused argument(s) compilation warning */
2341 UNUSED(husart);
2343 /* NOTE: This function should not be modified, when the callback is needed,
2344 the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2349 * @brief Rx Transfer completed callback.
2350 * @param husart USART handle.
2351 * @retval None
2353 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
2355 /* Prevent unused argument(s) compilation warning */
2356 UNUSED(husart);
2358 /* NOTE: This function should not be modified, when the callback is needed,
2359 the HAL_USART_RxCpltCallback can be implemented in the user file.
2364 * @brief Rx Half Transfer completed callback.
2365 * @param husart USART handle.
2366 * @retval None
2368 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
2370 /* Prevent unused argument(s) compilation warning */
2371 UNUSED(husart);
2373 /* NOTE : This function should not be modified, when the callback is needed,
2374 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2379 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2380 * @param husart USART handle.
2381 * @retval None
2383 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
2385 /* Prevent unused argument(s) compilation warning */
2386 UNUSED(husart);
2388 /* NOTE : This function should not be modified, when the callback is needed,
2389 the HAL_USART_TxRxCpltCallback can be implemented in the user file
2394 * @brief USART error callback.
2395 * @param husart USART handle.
2396 * @retval None
2398 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
2400 /* Prevent unused argument(s) compilation warning */
2401 UNUSED(husart);
2403 /* NOTE : This function should not be modified, when the callback is needed,
2404 the HAL_USART_ErrorCallback can be implemented in the user file.
2409 * @brief USART Abort Complete callback.
2410 * @param husart USART handle.
2411 * @retval None
2413 __weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
2415 /* Prevent unused argument(s) compilation warning */
2416 UNUSED(husart);
2418 /* NOTE : This function should not be modified, when the callback is needed,
2419 the HAL_USART_AbortCpltCallback can be implemented in the user file.
2424 * @}
2427 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2428 * @brief USART Peripheral State and Error functions
2430 @verbatim
2431 ==============================================================================
2432 ##### Peripheral State and Error functions #####
2433 ==============================================================================
2434 [..]
2435 This subsection provides functions allowing to :
2436 (+) Return the USART handle state
2437 (+) Return the USART handle error code
2439 @endverbatim
2440 * @{
2445 * @brief Return the USART handle state.
2446 * @param husart pointer to a USART_HandleTypeDef structure that contains
2447 * the configuration information for the specified USART.
2448 * @retval USART handle state
2450 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
2452 return husart->State;
2456 * @brief Return the USART error code.
2457 * @param husart pointer to a USART_HandleTypeDef structure that contains
2458 * the configuration information for the specified USART.
2459 * @retval USART handle Error Code
2461 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
2463 return husart->ErrorCode;
2467 * @}
2471 * @}
2474 /** @defgroup USART_Private_Functions USART Private Functions
2475 * @{
2479 * @brief Initialize the callbacks to their default values.
2480 * @param husart USART handle.
2481 * @retval none
2483 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2484 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
2486 /* Init the USART Callback settings */
2487 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
2488 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
2489 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
2490 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
2491 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
2492 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
2493 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
2494 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
2495 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
2497 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2500 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2501 * @param husart USART handle.
2502 * @retval None
2504 static void USART_EndTransfer(USART_HandleTypeDef *husart)
2506 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2507 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2508 USART_CR1_TCIE));
2509 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2511 /* At end of process, restore husart->State to Ready */
2512 husart->State = HAL_USART_STATE_READY;
2516 * @brief DMA USART transmit process complete callback.
2517 * @param hdma DMA handle.
2518 * @retval None
2520 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2522 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2524 /* DMA Normal mode */
2525 if (hdma->Init.Mode != DMA_CIRCULAR)
2527 husart->TxXferCount = 0U;
2529 if (husart->State == HAL_USART_STATE_BUSY_TX)
2531 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2532 in the USART CR3 register */
2533 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2535 /* Enable the USART Transmit Complete Interrupt */
2536 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2539 /* DMA Circular mode */
2540 else
2542 if (husart->State == HAL_USART_STATE_BUSY_TX)
2544 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2545 /* Call registered Tx Complete Callback */
2546 husart->TxCpltCallback(husart);
2547 #else
2548 /* Call legacy weak Tx Complete Callback */
2549 HAL_USART_TxCpltCallback(husart);
2550 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2556 * @brief DMA USART transmit process half complete callback.
2557 * @param hdma DMA handle.
2558 * @retval None
2560 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2562 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2564 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2565 /* Call registered Tx Half Complete Callback */
2566 husart->TxHalfCpltCallback(husart);
2567 #else
2568 /* Call legacy weak Tx Half Complete Callback */
2569 HAL_USART_TxHalfCpltCallback(husart);
2570 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2574 * @brief DMA USART receive process complete callback.
2575 * @param hdma DMA handle.
2576 * @retval None
2578 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2580 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2582 /* DMA Normal mode */
2583 if (hdma->Init.Mode != DMA_CIRCULAR)
2585 husart->RxXferCount = 0U;
2587 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2588 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2589 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2591 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2592 in USART CR3 register */
2593 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2594 /* similarly, disable the DMA TX transfer that was started to provide the
2595 clock to the slave device */
2596 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2598 if (husart->State == HAL_USART_STATE_BUSY_RX)
2600 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2601 /* Call registered Rx Complete Callback */
2602 husart->RxCpltCallback(husart);
2603 #else
2604 /* Call legacy weak Rx Complete Callback */
2605 HAL_USART_RxCpltCallback(husart);
2606 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2608 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2609 else
2611 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2612 /* Call registered Tx Rx Complete Callback */
2613 husart->TxRxCpltCallback(husart);
2614 #else
2615 /* Call legacy weak Tx Rx Complete Callback */
2616 HAL_USART_TxRxCpltCallback(husart);
2617 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2619 husart->State = HAL_USART_STATE_READY;
2621 /* DMA circular mode */
2622 else
2624 if (husart->State == HAL_USART_STATE_BUSY_RX)
2626 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2627 /* Call registered Rx Complete Callback */
2628 husart->RxCpltCallback(husart);
2629 #else
2630 /* Call legacy weak Rx Complete Callback */
2631 HAL_USART_RxCpltCallback(husart);
2632 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2634 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2635 else
2637 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2638 /* Call registered Tx Rx Complete Callback */
2639 husart->TxRxCpltCallback(husart);
2640 #else
2641 /* Call legacy weak Tx Rx Complete Callback */
2642 HAL_USART_TxRxCpltCallback(husart);
2643 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2649 * @brief DMA USART receive process half complete callback.
2650 * @param hdma DMA handle.
2651 * @retval None
2653 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2655 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2657 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2658 /* Call registered Rx Half Complete Callback */
2659 husart->RxHalfCpltCallback(husart);
2660 #else
2661 /* Call legacy weak Rx Half Complete Callback */
2662 HAL_USART_RxHalfCpltCallback(husart);
2663 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2667 * @brief DMA USART communication error callback.
2668 * @param hdma DMA handle.
2669 * @retval None
2671 static void USART_DMAError(DMA_HandleTypeDef *hdma)
2673 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2675 husart->RxXferCount = 0U;
2676 husart->TxXferCount = 0U;
2677 USART_EndTransfer(husart);
2679 husart->ErrorCode |= HAL_USART_ERROR_DMA;
2680 husart->State = HAL_USART_STATE_READY;
2682 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2683 /* Call registered Error Callback */
2684 husart->ErrorCallback(husart);
2685 #else
2686 /* Call legacy weak Error Callback */
2687 HAL_USART_ErrorCallback(husart);
2688 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2692 * @brief DMA USART communication abort callback, when initiated by HAL services on Error
2693 * (To be called at end of DMA Abort procedure following error occurrence).
2694 * @param hdma DMA handle.
2695 * @retval None
2697 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2699 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2700 husart->RxXferCount = 0U;
2701 husart->TxXferCount = 0U;
2703 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2704 /* Call registered Error Callback */
2705 husart->ErrorCallback(husart);
2706 #else
2707 /* Call legacy weak Error Callback */
2708 HAL_USART_ErrorCallback(husart);
2709 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2713 * @brief DMA USART Tx communication abort callback, when initiated by user
2714 * (To be called at end of DMA Tx Abort procedure following user abort request).
2715 * @note When this callback is executed, User Abort complete call back is called only if no
2716 * Abort still ongoing for Rx DMA Handle.
2717 * @param hdma DMA handle.
2718 * @retval None
2720 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2722 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2724 husart->hdmatx->XferAbortCallback = NULL;
2726 /* Check if an Abort process is still ongoing */
2727 if (husart->hdmarx != NULL)
2729 if (husart->hdmarx->XferAbortCallback != NULL)
2731 return;
2735 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2736 husart->TxXferCount = 0U;
2737 husart->RxXferCount = 0U;
2739 /* Reset errorCode */
2740 husart->ErrorCode = HAL_USART_ERROR_NONE;
2742 /* Clear the Error flags in the ICR register */
2743 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2745 /* Restore husart->State to Ready */
2746 husart->State = HAL_USART_STATE_READY;
2748 /* Call user Abort complete callback */
2749 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2750 /* Call registered Abort Complete Callback */
2751 husart->AbortCpltCallback(husart);
2752 #else
2753 /* Call legacy weak Abort Complete Callback */
2754 HAL_USART_AbortCpltCallback(husart);
2755 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2761 * @brief DMA USART Rx communication abort callback, when initiated by user
2762 * (To be called at end of DMA Rx Abort procedure following user abort request).
2763 * @note When this callback is executed, User Abort complete call back is called only if no
2764 * Abort still ongoing for Tx DMA Handle.
2765 * @param hdma DMA handle.
2766 * @retval None
2768 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2770 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2772 husart->hdmarx->XferAbortCallback = NULL;
2774 /* Check if an Abort process is still ongoing */
2775 if (husart->hdmatx != NULL)
2777 if (husart->hdmatx->XferAbortCallback != NULL)
2779 return;
2783 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2784 husart->TxXferCount = 0U;
2785 husart->RxXferCount = 0U;
2787 /* Reset errorCode */
2788 husart->ErrorCode = HAL_USART_ERROR_NONE;
2790 /* Clear the Error flags in the ICR register */
2791 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2793 /* Restore husart->State to Ready */
2794 husart->State = HAL_USART_STATE_READY;
2796 /* Call user Abort complete callback */
2797 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2798 /* Call registered Abort Complete Callback */
2799 husart->AbortCpltCallback(husart);
2800 #else
2801 /* Call legacy weak Abort Complete Callback */
2802 HAL_USART_AbortCpltCallback(husart);
2803 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2808 * @brief Handle USART Communication Timeout.
2809 * @param husart USART handle.
2810 * @param Flag Specifies the USART flag to check.
2811 * @param Status the Flag status (SET or RESET).
2812 * @param Tickstart Tick start value
2813 * @param Timeout timeout duration.
2814 * @retval HAL status
2816 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
2817 uint32_t Tickstart, uint32_t Timeout)
2819 /* Wait until flag is set */
2820 while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
2822 /* Check for the Timeout */
2823 if (Timeout != HAL_MAX_DELAY)
2825 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2827 husart->State = HAL_USART_STATE_READY;
2829 /* Process Unlocked */
2830 __HAL_UNLOCK(husart);
2832 return HAL_TIMEOUT;
2836 return HAL_OK;
2840 * @brief Configure the USART peripheral.
2841 * @param husart USART handle.
2842 * @retval HAL status
2844 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
2846 uint32_t tmpreg;
2847 USART_ClockSourceTypeDef clocksource;
2848 HAL_StatusTypeDef ret = HAL_OK;
2849 uint16_t brrtemp;
2850 uint32_t usartdiv = 0x00000000;
2851 PLL2_ClocksTypeDef pll2_clocks;
2852 PLL3_ClocksTypeDef pll3_clocks;
2853 uint32_t pclk;
2855 /* Check the parameters */
2856 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
2857 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
2858 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
2859 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
2860 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
2861 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
2862 assert_param(IS_USART_PARITY(husart->Init.Parity));
2863 assert_param(IS_USART_MODE(husart->Init.Mode));
2864 assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler));
2866 /*-------------------------- USART CR1 Configuration -----------------------*/
2867 /* Clear M, PCE, PS, TE and RE bits and configure
2868 * the USART Word Length, Parity and Mode:
2869 * set the M bits according to husart->Init.WordLength value
2870 * set PCE and PS bits according to husart->Init.Parity value
2871 * set TE and RE bits according to husart->Init.Mode value
2872 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
2873 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
2874 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2876 /*---------------------------- USART CR2 Configuration ---------------------*/
2877 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
2878 * set CPOL bit according to husart->Init.CLKPolarity value
2879 * set CPHA bit according to husart->Init.CLKPhase value
2880 * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
2881 * set STOP[13:12] bits according to husart->Init.StopBits value */
2882 tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
2883 tmpreg |= (uint32_t)husart->Init.CLKLastBit;
2884 tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
2885 tmpreg |= (uint32_t)husart->Init.StopBits;
2886 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
2888 /*-------------------------- USART PRESC Configuration -----------------------*/
2889 /* Configure
2890 * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
2891 MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler);
2893 /*-------------------------- USART BRR Configuration -----------------------*/
2894 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
2895 USART_GETCLOCKSOURCE(husart, clocksource);
2897 switch (clocksource)
2899 case USART_CLOCKSOURCE_D2PCLK1:
2900 pclk = HAL_RCC_GetPCLK1Freq();
2901 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2902 break;
2903 case USART_CLOCKSOURCE_D2PCLK2:
2904 pclk = HAL_RCC_GetPCLK2Freq();
2905 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2906 break;
2907 case USART_CLOCKSOURCE_PLL2:
2908 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
2909 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pll2_clocks.PLL2_Q_Frequency, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2910 break;
2911 case USART_CLOCKSOURCE_PLL3:
2912 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
2913 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pll3_clocks.PLL3_Q_Frequency, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2914 break;
2915 case USART_CLOCKSOURCE_HSI:
2916 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2918 usartdiv = (uint32_t)(USART_DIV_SAMPLING8((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), husart->Init.BaudRate, husart->Init.ClockPrescaler));
2920 else
2922 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2924 break;
2925 case USART_CLOCKSOURCE_CSI:
2926 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(CSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2927 break;
2928 case USART_CLOCKSOURCE_LSE:
2929 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2930 break;
2931 default:
2932 ret = HAL_ERROR;
2933 break;
2936 /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
2937 if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
2939 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
2940 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
2941 husart->Instance->BRR = brrtemp;
2943 else
2945 ret = HAL_ERROR;
2948 /* Initialize the number of data to process during RX/TX ISR execution */
2949 husart->NbTxDataToProcess = 1U;
2950 husart->NbRxDataToProcess = 1U;
2952 /* Clear ISR function pointers */
2953 husart->RxISR = NULL;
2954 husart->TxISR = NULL;
2956 return ret;
2960 * @brief Check the USART Idle State.
2961 * @param husart USART handle.
2962 * @retval HAL status
2964 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
2966 uint32_t tickstart;
2968 /* Initialize the USART ErrorCode */
2969 husart->ErrorCode = HAL_USART_ERROR_NONE;
2971 /* Init tickstart for timeout managment*/
2972 tickstart = HAL_GetTick();
2974 /* Check if the Transmitter is enabled */
2975 if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2977 /* Wait until TEACK flag is set */
2978 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
2980 /* Timeout occurred */
2981 return HAL_TIMEOUT;
2984 /* Check if the Receiver is enabled */
2985 if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
2987 /* Wait until REACK flag is set */
2988 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
2990 /* Timeout occurred */
2991 return HAL_TIMEOUT;
2995 /* Initialize the USART state*/
2996 husart->State = HAL_USART_STATE_READY;
2998 /* Process Unlocked */
2999 __HAL_UNLOCK(husart);
3001 return HAL_OK;
3005 * @brief Simplex send an amount of data in non-blocking mode.
3006 * @note Function called under interruption only, once
3007 * interruptions have been enabled by HAL_USART_Transmit_IT().
3008 * @note The USART errors are not managed to avoid the overrun error.
3009 * @note ISR function executed when FIFO mode is disabled and when the
3010 * data word length is less than 9 bits long.
3011 * @param husart USART handle.
3012 * @retval None
3014 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
3016 const HAL_USART_StateTypeDef state = husart->State;
3018 /* Check that a Tx process is ongoing */
3019 if ((state == HAL_USART_STATE_BUSY_TX) ||
3020 (state == HAL_USART_STATE_BUSY_TX_RX))
3022 if (husart->TxXferCount == 0U)
3024 /* Disable the USART Transmit data register empty interrupt */
3025 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3027 /* Enable the USART Transmit Complete Interrupt */
3028 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3030 else
3032 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3033 husart->pTxBuffPtr++;
3034 husart->TxXferCount--;
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 9 bits long.
3046 * @param husart USART handle.
3047 * @retval None
3049 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
3051 const HAL_USART_StateTypeDef state = husart->State;
3052 uint16_t *tmp;
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 tmp = (uint16_t *) husart->pTxBuffPtr;
3068 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3069 husart->pTxBuffPtr += 2U;
3070 husart->TxXferCount--;
3076 * @brief Simplex send an amount of data in non-blocking mode.
3077 * @note Function called under interruption only, once
3078 * interruptions have been enabled by HAL_USART_Transmit_IT().
3079 * @note The USART errors are not managed to avoid the overrun error.
3080 * @note ISR function executed when FIFO mode is enabled and when the
3081 * data word length is less than 9 bits long.
3082 * @param husart USART handle.
3083 * @retval None
3085 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3087 const HAL_USART_StateTypeDef state = husart->State;
3088 uint16_t nb_tx_data;
3090 /* Check that a Tx process is ongoing */
3091 if ((state == HAL_USART_STATE_BUSY_TX) ||
3092 (state == HAL_USART_STATE_BUSY_TX_RX))
3094 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3096 if (husart->TxXferCount == 0U)
3098 /* Disable the TX FIFO threshold interrupt */
3099 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3101 /* Enable the USART Transmit Complete Interrupt */
3102 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3104 break; /* force exit loop */
3106 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3108 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3109 husart->pTxBuffPtr++;
3110 husart->TxXferCount--;
3112 else
3114 /* Nothing to do */
3121 * @brief Simplex send an amount of data in non-blocking mode.
3122 * @note Function called under interruption only, once
3123 * interruptions have been enabled by HAL_USART_Transmit_IT().
3124 * @note The USART errors are not managed to avoid the overrun error.
3125 * @note ISR function executed when FIFO mode is enabled and when the
3126 * data word length is 9 bits long.
3127 * @param husart USART handle.
3128 * @retval None
3130 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3132 const HAL_USART_StateTypeDef state = husart->State;
3133 uint16_t *tmp;
3134 uint16_t nb_tx_data;
3136 /* Check that a Tx process is ongoing */
3137 if ((state == HAL_USART_STATE_BUSY_TX) ||
3138 (state == HAL_USART_STATE_BUSY_TX_RX))
3140 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3142 if (husart->TxXferCount == 0U)
3144 /* Disable the TX FIFO threshold interrupt */
3145 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3147 /* Enable the USART Transmit Complete Interrupt */
3148 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3150 break; /* force exit loop */
3152 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3154 tmp = (uint16_t *) husart->pTxBuffPtr;
3155 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3156 husart->pTxBuffPtr += 2U;
3157 husart->TxXferCount--;
3159 else
3161 /* Nothing to do */
3168 * @brief Wraps up transmission in non-blocking mode.
3169 * @param husart Pointer to a USART_HandleTypeDef structure that contains
3170 * the configuration information for the specified USART module.
3171 * @retval None
3173 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3175 /* Disable the USART Transmit Complete Interrupt */
3176 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3178 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3179 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3181 /* Clear TxISR function pointer */
3182 husart->TxISR = NULL;
3184 if (husart->State == HAL_USART_STATE_BUSY_TX)
3186 /* Clear overrun flag and discard the received data */
3187 __HAL_USART_CLEAR_OREFLAG(husart);
3188 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3190 /* Tx process is completed, restore husart->State to Ready */
3191 husart->State = HAL_USART_STATE_READY;
3193 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3194 /* Call registered Tx Complete Callback */
3195 husart->TxCpltCallback(husart);
3196 #else
3197 /* Call legacy weak Tx Complete Callback */
3198 HAL_USART_TxCpltCallback(husart);
3199 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3201 else if (husart->RxXferCount == 0U)
3203 /* TxRx process is completed, restore husart->State to Ready */
3204 husart->State = HAL_USART_STATE_READY;
3206 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3207 /* Call registered Tx Rx Complete Callback */
3208 husart->TxRxCpltCallback(husart);
3209 #else
3210 /* Call legacy weak Tx Rx Complete Callback */
3211 HAL_USART_TxRxCpltCallback(husart);
3212 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3214 else
3216 /* Nothing to do */
3222 * @brief Simplex receive an amount of data in non-blocking mode.
3223 * @note Function called under interruption only, once
3224 * interruptions have been enabled by HAL_USART_Receive_IT().
3225 * @note ISR function executed when FIFO mode is disabled and when the
3226 * data word length is less than 9 bits long.
3227 * @param husart USART handle
3228 * @retval None
3230 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3232 const HAL_USART_StateTypeDef state = husart->State;
3233 uint16_t txdatacount;
3234 uint16_t uhMask = husart->Mask;
3235 uint32_t txftie;
3237 if ((state == HAL_USART_STATE_BUSY_RX) ||
3238 (state == HAL_USART_STATE_BUSY_TX_RX))
3240 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3241 husart->pRxBuffPtr++;
3242 husart->RxXferCount--;
3244 if (husart->RxXferCount == 0U)
3246 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3247 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3249 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3250 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3252 /* Clear RxISR function pointer */
3253 husart->RxISR = NULL;
3255 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3256 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3257 txdatacount = husart->TxXferCount;
3259 if (state == HAL_USART_STATE_BUSY_RX)
3261 /* Clear SPI slave underrun flag and discard transmit data */
3262 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3264 __HAL_USART_CLEAR_UDRFLAG(husart);
3265 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3268 /* Rx process is completed, restore husart->State to Ready */
3269 husart->State = HAL_USART_STATE_READY;
3271 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3272 /* Call registered Rx Complete Callback */
3273 husart->RxCpltCallback(husart);
3274 #else
3275 /* Call legacy weak Rx Complete Callback */
3276 HAL_USART_RxCpltCallback(husart);
3277 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3279 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3280 (txftie != USART_CR3_TXFTIE) &&
3281 (txdatacount == 0U))
3283 /* TxRx process is completed, restore husart->State to Ready */
3284 husart->State = HAL_USART_STATE_READY;
3286 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3287 /* Call registered Tx Rx Complete Callback */
3288 husart->TxRxCpltCallback(husart);
3289 #else
3290 /* Call legacy weak Tx Rx Complete Callback */
3291 HAL_USART_TxRxCpltCallback(husart);
3292 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3294 else
3296 /* Nothing to do */
3299 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3300 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3302 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3303 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3305 else
3307 /* Nothing to do */
3313 * @brief Simplex receive an amount of data in non-blocking mode.
3314 * @note Function called under interruption only, once
3315 * interruptions have been enabled by HAL_USART_Receive_IT().
3316 * @note ISR function executed when FIFO mode is disabled and when the
3317 * data word length is 9 bits long.
3318 * @param husart USART handle
3319 * @retval None
3321 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
3323 const HAL_USART_StateTypeDef state = husart->State;
3324 uint16_t txdatacount;
3325 uint16_t *tmp;
3326 uint16_t uhMask = husart->Mask;
3327 uint32_t txftie;
3329 if ((state == HAL_USART_STATE_BUSY_RX) ||
3330 (state == HAL_USART_STATE_BUSY_TX_RX))
3332 tmp = (uint16_t *) husart->pRxBuffPtr;
3333 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3334 husart->pRxBuffPtr += 2U;
3335 husart->RxXferCount--;
3337 if (husart->RxXferCount == 0U)
3339 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3340 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3342 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3343 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3345 /* Clear RxISR function pointer */
3346 husart->RxISR = NULL;
3348 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3349 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3350 txdatacount = husart->TxXferCount;
3352 if (state == HAL_USART_STATE_BUSY_RX)
3354 /* Clear SPI slave underrun flag and discard transmit data */
3355 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3357 __HAL_USART_CLEAR_UDRFLAG(husart);
3358 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3361 /* Rx process is completed, restore husart->State to Ready */
3362 husart->State = HAL_USART_STATE_READY;
3364 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3365 /* Call registered Rx Complete Callback */
3366 husart->RxCpltCallback(husart);
3367 #else
3368 /* Call legacy weak Rx Complete Callback */
3369 HAL_USART_RxCpltCallback(husart);
3370 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3372 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3373 (txftie != USART_CR3_TXFTIE) &&
3374 (txdatacount == 0U))
3376 /* TxRx process is completed, restore husart->State to Ready */
3377 husart->State = HAL_USART_STATE_READY;
3379 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3380 /* Call registered Tx Rx Complete Callback */
3381 husart->TxRxCpltCallback(husart);
3382 #else
3383 /* Call legacy weak Tx Rx Complete Callback */
3384 HAL_USART_TxRxCpltCallback(husart);
3385 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3387 else
3389 /* Nothing to do */
3392 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3393 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3395 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3396 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3398 else
3400 /* Nothing to do */
3406 * @brief Simplex receive an amount of data in non-blocking mode.
3407 * @note Function called under interruption only, once
3408 * interruptions have been enabled by HAL_USART_Receive_IT().
3409 * @note ISR function executed when FIFO mode is enabled and when the
3410 * data word length is less than 9 bits long.
3411 * @param husart USART handle
3412 * @retval None
3414 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3416 HAL_USART_StateTypeDef state = husart->State;
3417 uint16_t txdatacount;
3418 uint16_t rxdatacount;
3419 uint16_t uhMask = husart->Mask;
3420 uint16_t nb_rx_data;
3421 uint32_t txftie;
3423 /* Check that a Rx process is ongoing */
3424 if ((state == HAL_USART_STATE_BUSY_RX) ||
3425 (state == HAL_USART_STATE_BUSY_TX_RX))
3427 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3429 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3431 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
3432 husart->pRxBuffPtr++;
3433 husart->RxXferCount--;
3435 if (husart->RxXferCount == 0U)
3437 /* Disable the USART Parity Error Interrupt */
3438 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3440 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3441 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3443 /* Clear RxISR function pointer */
3444 husart->RxISR = NULL;
3446 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3447 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3448 txdatacount = husart->TxXferCount;
3450 if (state == HAL_USART_STATE_BUSY_RX)
3452 /* Clear SPI slave underrun flag and discard transmit data */
3453 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3455 __HAL_USART_CLEAR_UDRFLAG(husart);
3456 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3459 /* Rx process is completed, restore husart->State to Ready */
3460 husart->State = HAL_USART_STATE_READY;
3461 state = HAL_USART_STATE_READY;
3463 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3464 /* Call registered Rx Complete Callback */
3465 husart->RxCpltCallback(husart);
3466 #else
3467 /* Call legacy weak Rx Complete Callback */
3468 HAL_USART_RxCpltCallback(husart);
3469 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3471 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3472 (txftie != USART_CR3_TXFTIE) &&
3473 (txdatacount == 0U))
3475 /* TxRx process is completed, restore husart->State to Ready */
3476 husart->State = HAL_USART_STATE_READY;
3477 state = HAL_USART_STATE_READY;
3479 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3480 /* Call registered Tx Rx Complete Callback */
3481 husart->TxRxCpltCallback(husart);
3482 #else
3483 /* Call legacy weak Tx Rx Complete Callback */
3484 HAL_USART_TxRxCpltCallback(husart);
3485 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3487 else
3489 /* Nothing to do */
3492 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3493 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3495 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3496 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3498 else
3500 /* Nothing to do */
3505 /* When remaining number of bytes to receive is less than the RX FIFO
3506 threshold, next incoming frames are processed as if FIFO mode was
3507 disabled (i.e. one interrupt per received frame).
3509 rxdatacount = husart->RxXferCount;
3510 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3512 /* Disable the USART RXFT interrupt*/
3513 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3515 /* Update the RxISR function pointer */
3516 husart->RxISR = USART_RxISR_8BIT;
3518 /* Enable the USART Data Register Not Empty interrupt */
3519 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3521 if ((husart->TxXferCount == 0U) &&
3522 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3523 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3525 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3526 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3530 else
3532 /* Clear RXNE interrupt flag */
3533 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3538 * @brief Simplex receive an amount of data in non-blocking mode.
3539 * @note Function called under interruption only, once
3540 * interruptions have been enabled by HAL_USART_Receive_IT().
3541 * @note ISR function executed when FIFO mode is enabled and when the
3542 * data word length is 9 bits long.
3543 * @param husart USART handle
3544 * @retval None
3546 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3548 HAL_USART_StateTypeDef state = husart->State;
3549 uint16_t txdatacount;
3550 uint16_t rxdatacount;
3551 uint16_t *tmp;
3552 uint16_t uhMask = husart->Mask;
3553 uint16_t nb_rx_data;
3554 uint32_t txftie;
3556 /* Check that a Tx process is ongoing */
3557 if ((state == HAL_USART_STATE_BUSY_RX) ||
3558 (state == HAL_USART_STATE_BUSY_TX_RX))
3560 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3562 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3564 tmp = (uint16_t *) husart->pRxBuffPtr;
3565 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3566 husart->pRxBuffPtr += 2U;
3567 husart->RxXferCount--;
3569 if (husart->RxXferCount == 0U)
3571 /* Disable the USART Parity Error Interrupt */
3572 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3574 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3575 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3577 /* Clear RxISR function pointer */
3578 husart->RxISR = NULL;
3580 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3581 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3582 txdatacount = husart->TxXferCount;
3584 if (state == HAL_USART_STATE_BUSY_RX)
3586 /* Clear SPI slave underrun flag and discard transmit data */
3587 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3589 __HAL_USART_CLEAR_UDRFLAG(husart);
3590 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3593 /* Rx process is completed, restore husart->State to Ready */
3594 husart->State = HAL_USART_STATE_READY;
3595 state = HAL_USART_STATE_READY;
3597 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3598 /* Call registered Rx Complete Callback */
3599 husart->RxCpltCallback(husart);
3600 #else
3601 /* Call legacy weak Rx Complete Callback */
3602 HAL_USART_RxCpltCallback(husart);
3603 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3605 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3606 (txftie != USART_CR3_TXFTIE) &&
3607 (txdatacount == 0U))
3609 /* TxRx process is completed, restore husart->State to Ready */
3610 husart->State = HAL_USART_STATE_READY;
3611 state = HAL_USART_STATE_READY;
3613 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3614 /* Call registered Tx Rx Complete Callback */
3615 husart->TxRxCpltCallback(husart);
3616 #else
3617 /* Call legacy weak Tx Rx Complete Callback */
3618 HAL_USART_TxRxCpltCallback(husart);
3619 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3621 else
3623 /* Nothing to do */
3626 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3627 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3629 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3630 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3632 else
3634 /* Nothing to do */
3639 /* When remaining number of bytes to receive is less than the RX FIFO
3640 threshold, next incoming frames are processed as if FIFO mode was
3641 disabled (i.e. one interrupt per received frame).
3643 rxdatacount = husart->RxXferCount;
3644 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3646 /* Disable the USART RXFT interrupt*/
3647 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3649 /* Update the RxISR function pointer */
3650 husart->RxISR = USART_RxISR_16BIT;
3652 /* Enable the USART Data Register Not Empty interrupt */
3653 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3655 if ((husart->TxXferCount == 0U) &&
3656 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3657 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3659 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3660 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3664 else
3666 /* Clear RXNE interrupt flag */
3667 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3672 * @}
3675 #endif /* HAL_USART_MODULE_ENABLED */
3677 * @}
3681 * @}
3684 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/