Merge pull request #10592 from iNavFlight/MrD_Update-parameter-description
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_uart.c
blob2e0a4c66e7dbdad0a15f1e9746942e01a4578982
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_uart.c
4 * @author MCD Application Team
5 * @brief UART HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
13 @verbatim
14 ===============================================================================
15 ##### How to use this driver #####
16 ===============================================================================
17 [..]
18 The UART HAL driver can be used as follows:
20 (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
21 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
22 (++) Enable the USARTx interface clock.
23 (++) UART pins configuration:
24 (+++) Enable the clock for the UART GPIOs.
25 (+++) Configure these UART pins as alternate function pull-up.
26 (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
27 and HAL_UART_Receive_IT() APIs):
28 (+++) Configure the USARTx interrupt priority.
29 (+++) Enable the NVIC USART IRQ handle.
30 (++) UART interrupts handling:
31 -@@- The specific UART interrupts (Transmission complete interrupt,
32 RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts)
33 are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
34 inside the transmit and receive processes.
35 (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
36 and HAL_UART_Receive_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 UART 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, Prescaler value , Hardware
45 flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
47 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
48 in the huart handle AdvancedInit structure.
50 (#) For the UART asynchronous mode, initialize the UART registers by calling
51 the HAL_UART_Init() API.
53 (#) For the UART Half duplex mode, initialize the UART registers by calling
54 the HAL_HalfDuplex_Init() API.
56 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
57 by calling the HAL_LIN_Init() API.
59 (#) For the UART Multiprocessor mode, initialize the UART registers
60 by calling the HAL_MultiProcessor_Init() API.
62 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
63 by calling the HAL_RS485Ex_Init() API.
65 [..]
66 (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
67 also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
68 calling the customized HAL_UART_MspInit() API.
70 ##### Callback registration #####
71 ==================================
73 [..]
74 The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
75 allows the user to configure dynamically the driver callbacks.
77 [..]
78 Use Function @ref HAL_UART_RegisterCallback() to register a user callback.
79 Function @ref HAL_UART_RegisterCallback() allows to register following callbacks:
80 (+) TxHalfCpltCallback : Tx Half Complete Callback.
81 (+) TxCpltCallback : Tx Complete Callback.
82 (+) RxHalfCpltCallback : Rx Half Complete Callback.
83 (+) RxCpltCallback : Rx Complete Callback.
84 (+) ErrorCallback : Error Callback.
85 (+) AbortCpltCallback : Abort Complete Callback.
86 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
87 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
88 (+) WakeupCallback : Wakeup Callback.
89 (+) RxFifoFullCallback : Rx Fifo Full Callback.
90 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
91 (+) MspInitCallback : UART MspInit.
92 (+) MspDeInitCallback : UART MspDeInit.
93 This function takes as parameters the HAL peripheral handle, the Callback ID
94 and a pointer to the user callback function.
96 [..]
97 Use function @ref HAL_UART_UnRegisterCallback() to reset a callback to the default
98 weak (surcharged) function.
99 @ref HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
100 and the Callback ID.
101 This function allows to reset following callbacks:
102 (+) TxHalfCpltCallback : Tx Half Complete Callback.
103 (+) TxCpltCallback : Tx Complete Callback.
104 (+) RxHalfCpltCallback : Rx Half Complete Callback.
105 (+) RxCpltCallback : Rx Complete Callback.
106 (+) ErrorCallback : Error Callback.
107 (+) AbortCpltCallback : Abort Complete Callback.
108 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
109 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
110 (+) WakeupCallback : Wakeup Callback.
111 (+) RxFifoFullCallback : Rx Fifo Full Callback.
112 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
113 (+) MspInitCallback : UART MspInit.
114 (+) MspDeInitCallback : UART MspDeInit.
116 [..]
117 By default, after the @ref HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
118 all callbacks are set to the corresponding weak (surcharged) functions:
119 examples @ref HAL_UART_TxCpltCallback(), @ref HAL_UART_RxHalfCpltCallback().
120 Exception done for MspInit and MspDeInit functions that are respectively
121 reset to the legacy weak (surcharged) functions in the @ref HAL_UART_Init()
122 and @ref HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
123 If not, MspInit or MspDeInit are not null, the @ref HAL_UART_Init() and @ref HAL_UART_DeInit()
124 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
126 [..]
127 Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
128 Exception done MspInit/MspDeInit that can be registered/unregistered
129 in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
130 MspInit/DeInit callbacks can be used during the Init/DeInit.
131 In that case first register the MspInit/MspDeInit user callbacks
132 using @ref HAL_UART_RegisterCallback() before calling @ref HAL_UART_DeInit()
133 or @ref HAL_UART_Init() function.
135 [..]
136 When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
137 not defined, the callback registration feature is not available
138 and weak (surcharged) callbacks are used.
141 @endverbatim
142 ******************************************************************************
143 * @attention
145 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
146 * All rights reserved.</center></h2>
148 * This software component is licensed by ST under BSD 3-Clause license,
149 * the "License"; You may not use this file except in compliance with the
150 * License. You may obtain a copy of the License at:
151 * opensource.org/licenses/BSD-3-Clause
153 ******************************************************************************
156 /* Includes ------------------------------------------------------------------*/
157 #include "stm32h7xx_hal.h"
159 /** @addtogroup STM32H7xx_HAL_Driver
160 * @{
163 /** @defgroup UART UART
164 * @brief HAL UART module driver
165 * @{
168 #ifdef HAL_UART_MODULE_ENABLED
170 /* Private typedef -----------------------------------------------------------*/
171 /* Private define ------------------------------------------------------------*/
172 /** @defgroup UART_Private_Constants UART Private Constants
173 * @{
175 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
176 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8| \
177 USART_CR1_FIFOEN )) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
179 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT| \
180 USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
182 #define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */
183 #define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */
185 #define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */
186 #define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */
189 * @}
192 /* Private macros ------------------------------------------------------------*/
193 /* Private variables ---------------------------------------------------------*/
194 /* Private function prototypes -----------------------------------------------*/
195 /** @addtogroup UART_Private_Functions
196 * @{
198 static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
199 static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
200 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
201 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
202 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
203 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
204 static void UART_DMAError(DMA_HandleTypeDef *hdma);
205 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
206 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
207 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
208 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
209 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
210 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
211 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
212 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
213 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
214 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
215 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
216 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
217 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
218 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
220 * @}
223 /* Exported functions --------------------------------------------------------*/
225 /** @defgroup UART_Exported_Functions UART Exported Functions
226 * @{
229 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
230 * @brief Initialization and Configuration functions
232 @verbatim
233 ===============================================================================
234 ##### Initialization and Configuration functions #####
235 ===============================================================================
236 [..]
237 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
238 in asynchronous mode.
239 (+) For the asynchronous mode the parameters below can be configured:
240 (++) Baud Rate
241 (++) Word Length
242 (++) Stop Bit
243 (++) Parity: If the parity is enabled, then the MSB bit of the data written
244 in the data register is transmitted but is changed by the parity bit.
245 (++) Hardware flow control
246 (++) Receiver/transmitter modes
247 (++) Over Sampling Method
248 (++) One-Bit Sampling Method
249 (+) For the asynchronous mode, the following advanced features can be configured as well:
250 (++) TX and/or RX pin level inversion
251 (++) data logical level inversion
252 (++) RX and TX pins swap
253 (++) RX overrun detection disabling
254 (++) DMA disabling on RX error
255 (++) MSB first on communication line
256 (++) auto Baud rate detection
257 [..]
258 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
259 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
260 and UART multiprocessor mode configuration procedures (details for the procedures
261 are available in reference manual).
263 @endverbatim
265 Depending on the frame length defined by the M1 and M0 bits (7-bit,
266 8-bit or 9-bit), the possible UART formats are listed in the
267 following table.
269 Table 1. UART frame format.
270 +-----------------------------------------------------------------------+
271 | M1 bit | M0 bit | PCE bit | UART frame |
272 |---------|---------|-----------|---------------------------------------|
273 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
274 |---------|---------|-----------|---------------------------------------|
275 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
276 |---------|---------|-----------|---------------------------------------|
277 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
278 |---------|---------|-----------|---------------------------------------|
279 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
280 |---------|---------|-----------|---------------------------------------|
281 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
282 |---------|---------|-----------|---------------------------------------|
283 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
284 +-----------------------------------------------------------------------+
286 * @{
290 * @brief Initialize the UART mode according to the specified
291 * parameters in the UART_InitTypeDef and initialize the associated handle.
292 * @param huart UART handle.
293 * @retval HAL status
295 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
297 /* Check the UART handle allocation */
298 if (huart == NULL)
300 return HAL_ERROR;
303 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
305 /* Check the parameters */
306 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
308 else
310 /* Check the parameters */
311 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
314 if (huart->gState == HAL_UART_STATE_RESET)
316 /* Allocate lock resource and initialize it */
317 huart->Lock = HAL_UNLOCKED;
319 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
320 UART_InitCallbacksToDefault(huart);
322 if (huart->MspInitCallback == NULL)
324 huart->MspInitCallback = HAL_UART_MspInit;
327 /* Init the low level hardware */
328 huart->MspInitCallback(huart);
329 #else
330 /* Init the low level hardware : GPIO, CLOCK */
331 HAL_UART_MspInit(huart);
332 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
335 huart->gState = HAL_UART_STATE_BUSY;
337 __HAL_UART_DISABLE(huart);
339 /* Set the UART Communication parameters */
340 if (UART_SetConfig(huart) == HAL_ERROR)
342 return HAL_ERROR;
345 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
347 UART_AdvFeatureConfig(huart);
350 /* In asynchronous mode, the following bits must be kept cleared:
351 - LINEN and CLKEN bits in the USART_CR2 register,
352 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
353 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
354 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
356 __HAL_UART_ENABLE(huart);
358 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
359 return (UART_CheckIdleState(huart));
363 * @brief Initialize the half-duplex mode according to the specified
364 * parameters in the UART_InitTypeDef and creates the associated handle.
365 * @param huart UART handle.
366 * @retval HAL status
368 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
370 /* Check the UART handle allocation */
371 if (huart == NULL)
373 return HAL_ERROR;
376 /* Check UART instance */
377 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
379 if (huart->gState == HAL_UART_STATE_RESET)
381 /* Allocate lock resource and initialize it */
382 huart->Lock = HAL_UNLOCKED;
384 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
385 UART_InitCallbacksToDefault(huart);
387 if (huart->MspInitCallback == NULL)
389 huart->MspInitCallback = HAL_UART_MspInit;
392 /* Init the low level hardware */
393 huart->MspInitCallback(huart);
394 #else
395 /* Init the low level hardware : GPIO, CLOCK */
396 HAL_UART_MspInit(huart);
397 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
400 huart->gState = HAL_UART_STATE_BUSY;
402 __HAL_UART_DISABLE(huart);
404 /* Set the UART Communication parameters */
405 if (UART_SetConfig(huart) == HAL_ERROR)
407 return HAL_ERROR;
410 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
412 UART_AdvFeatureConfig(huart);
415 /* In half-duplex mode, the following bits must be kept cleared:
416 - LINEN and CLKEN bits in the USART_CR2 register,
417 - SCEN and IREN bits in the USART_CR3 register.*/
418 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
419 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
421 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
422 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
424 __HAL_UART_ENABLE(huart);
426 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
427 return (UART_CheckIdleState(huart));
432 * @brief Initialize the LIN mode according to the specified
433 * parameters in the UART_InitTypeDef and creates the associated handle.
434 * @param huart UART handle.
435 * @param BreakDetectLength Specifies the LIN break detection length.
436 * This parameter can be one of the following values:
437 * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
438 * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
439 * @retval HAL status
441 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
443 /* Check the UART handle allocation */
444 if (huart == NULL)
446 return HAL_ERROR;
449 /* Check the LIN UART instance */
450 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
451 /* Check the Break detection length parameter */
452 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
454 /* LIN mode limited to 16-bit oversampling only */
455 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
457 return HAL_ERROR;
459 /* LIN mode limited to 8-bit data length */
460 if (huart->Init.WordLength != UART_WORDLENGTH_8B)
462 return HAL_ERROR;
465 if (huart->gState == HAL_UART_STATE_RESET)
467 /* Allocate lock resource and initialize it */
468 huart->Lock = HAL_UNLOCKED;
470 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
471 UART_InitCallbacksToDefault(huart);
473 if (huart->MspInitCallback == NULL)
475 huart->MspInitCallback = HAL_UART_MspInit;
478 /* Init the low level hardware */
479 huart->MspInitCallback(huart);
480 #else
481 /* Init the low level hardware : GPIO, CLOCK */
482 HAL_UART_MspInit(huart);
483 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
486 huart->gState = HAL_UART_STATE_BUSY;
488 __HAL_UART_DISABLE(huart);
490 /* Set the UART Communication parameters */
491 if (UART_SetConfig(huart) == HAL_ERROR)
493 return HAL_ERROR;
496 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
498 UART_AdvFeatureConfig(huart);
501 /* In LIN mode, the following bits must be kept cleared:
502 - LINEN and CLKEN bits in the USART_CR2 register,
503 - SCEN and IREN bits in the USART_CR3 register.*/
504 CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
505 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
507 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
508 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
510 /* Set the USART LIN Break detection length. */
511 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
513 __HAL_UART_ENABLE(huart);
515 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
516 return (UART_CheckIdleState(huart));
521 * @brief Initialize the multiprocessor mode according to the specified
522 * parameters in the UART_InitTypeDef and initialize the associated handle.
523 * @param huart UART handle.
524 * @param Address UART node address (4-, 6-, 7- or 8-bit long).
525 * @param WakeUpMethod Specifies the UART wakeup method.
526 * This parameter can be one of the following values:
527 * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
528 * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
529 * @note If the user resorts to idle line detection wake up, the Address parameter
530 * is useless and ignored by the initialization function.
531 * @note If the user resorts to address mark wake up, the address length detection
532 * is configured by default to 4 bits only. For the UART to be able to
533 * manage 6-, 7- or 8-bit long addresses detection, the API
534 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
535 * HAL_MultiProcessor_Init().
536 * @retval HAL status
538 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
540 /* Check the UART handle allocation */
541 if (huart == NULL)
543 return HAL_ERROR;
546 /* Check the wake up method parameter */
547 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
549 if (huart->gState == HAL_UART_STATE_RESET)
551 /* Allocate lock resource and initialize it */
552 huart->Lock = HAL_UNLOCKED;
554 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
555 UART_InitCallbacksToDefault(huart);
557 if (huart->MspInitCallback == NULL)
559 huart->MspInitCallback = HAL_UART_MspInit;
562 /* Init the low level hardware */
563 huart->MspInitCallback(huart);
564 #else
565 /* Init the low level hardware : GPIO, CLOCK */
566 HAL_UART_MspInit(huart);
567 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
570 huart->gState = HAL_UART_STATE_BUSY;
572 __HAL_UART_DISABLE(huart);
574 /* Set the UART Communication parameters */
575 if (UART_SetConfig(huart) == HAL_ERROR)
577 return HAL_ERROR;
580 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
582 UART_AdvFeatureConfig(huart);
585 /* In multiprocessor mode, the following bits must be kept cleared:
586 - LINEN and CLKEN bits in the USART_CR2 register,
587 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
588 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
589 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
591 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
593 /* If address mark wake up method is chosen, set the USART address node */
594 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
597 /* Set the wake up method by setting the WAKE bit in the CR1 register */
598 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
600 __HAL_UART_ENABLE(huart);
602 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
603 return (UART_CheckIdleState(huart));
608 * @brief DeInitialize the UART peripheral.
609 * @param huart UART handle.
610 * @retval HAL status
612 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
614 /* Check the UART handle allocation */
615 if (huart == NULL)
617 return HAL_ERROR;
620 /* Check the parameters */
621 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
623 huart->gState = HAL_UART_STATE_BUSY;
625 __HAL_UART_DISABLE(huart);
627 huart->Instance->CR1 = 0x0U;
628 huart->Instance->CR2 = 0x0U;
629 huart->Instance->CR3 = 0x0U;
631 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
632 if (huart->MspDeInitCallback == NULL)
634 huart->MspDeInitCallback = HAL_UART_MspDeInit;
636 /* DeInit the low level hardware */
637 huart->MspDeInitCallback(huart);
638 #else
639 /* DeInit the low level hardware */
640 HAL_UART_MspDeInit(huart);
641 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
643 huart->ErrorCode = HAL_UART_ERROR_NONE;
644 huart->gState = HAL_UART_STATE_RESET;
645 huart->RxState = HAL_UART_STATE_RESET;
647 __HAL_UNLOCK(huart);
649 return HAL_OK;
653 * @brief Initialize the UART MSP.
654 * @param huart UART handle.
655 * @retval None
657 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
659 /* Prevent unused argument(s) compilation warning */
660 UNUSED(huart);
662 /* NOTE : This function should not be modified, when the callback is needed,
663 the HAL_UART_MspInit can be implemented in the user file
668 * @brief DeInitialize the UART MSP.
669 * @param huart UART handle.
670 * @retval None
672 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
674 /* Prevent unused argument(s) compilation warning */
675 UNUSED(huart);
677 /* NOTE : This function should not be modified, when the callback is needed,
678 the HAL_UART_MspDeInit can be implemented in the user file
682 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
684 * @brief Register a User UART Callback
685 * To be used instead of the weak predefined callback
686 * @param huart uart handle
687 * @param CallbackID ID of the callback to be registered
688 * This parameter can be one of the following values:
689 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
690 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
691 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
692 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
693 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
694 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
695 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
696 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
697 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
698 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
699 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
700 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
701 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
702 * @param pCallback pointer to the Callback function
703 * @retval HAL status
705 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
706 pUART_CallbackTypeDef pCallback)
708 HAL_StatusTypeDef status = HAL_OK;
710 if (pCallback == NULL)
712 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
714 return HAL_ERROR;
717 __HAL_LOCK(huart);
719 if (huart->gState == HAL_UART_STATE_READY)
721 switch (CallbackID)
723 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
724 huart->TxHalfCpltCallback = pCallback;
725 break;
727 case HAL_UART_TX_COMPLETE_CB_ID :
728 huart->TxCpltCallback = pCallback;
729 break;
731 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
732 huart->RxHalfCpltCallback = pCallback;
733 break;
735 case HAL_UART_RX_COMPLETE_CB_ID :
736 huart->RxCpltCallback = pCallback;
737 break;
739 case HAL_UART_ERROR_CB_ID :
740 huart->ErrorCallback = pCallback;
741 break;
743 case HAL_UART_ABORT_COMPLETE_CB_ID :
744 huart->AbortCpltCallback = pCallback;
745 break;
747 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
748 huart->AbortTransmitCpltCallback = pCallback;
749 break;
751 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
752 huart->AbortReceiveCpltCallback = pCallback;
753 break;
755 case HAL_UART_WAKEUP_CB_ID :
756 huart->WakeupCallback = pCallback;
757 break;
759 case HAL_UART_RX_FIFO_FULL_CB_ID :
760 huart->RxFifoFullCallback = pCallback;
761 break;
763 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
764 huart->TxFifoEmptyCallback = pCallback;
765 break;
767 case HAL_UART_MSPINIT_CB_ID :
768 huart->MspInitCallback = pCallback;
769 break;
771 case HAL_UART_MSPDEINIT_CB_ID :
772 huart->MspDeInitCallback = pCallback;
773 break;
775 default :
776 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
778 status = HAL_ERROR;
779 break;
782 else if (huart->gState == HAL_UART_STATE_RESET)
784 switch (CallbackID)
786 case HAL_UART_MSPINIT_CB_ID :
787 huart->MspInitCallback = pCallback;
788 break;
790 case HAL_UART_MSPDEINIT_CB_ID :
791 huart->MspDeInitCallback = pCallback;
792 break;
794 default :
795 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
797 status = HAL_ERROR;
798 break;
801 else
803 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
805 status = HAL_ERROR;
808 __HAL_UNLOCK(huart);
810 return status;
814 * @brief Unregister an UART Callback
815 * UART callaback is redirected to the weak predefined callback
816 * @param huart uart handle
817 * @param CallbackID ID of the callback to be unregistered
818 * This parameter can be one of the following values:
819 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
820 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
821 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
822 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
823 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
824 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
825 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
826 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
827 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
828 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
829 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
830 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
831 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
832 * @retval HAL status
834 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
836 HAL_StatusTypeDef status = HAL_OK;
838 __HAL_LOCK(huart);
840 if (HAL_UART_STATE_READY == huart->gState)
842 switch (CallbackID)
844 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
845 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
846 break;
848 case HAL_UART_TX_COMPLETE_CB_ID :
849 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
850 break;
852 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
853 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
854 break;
856 case HAL_UART_RX_COMPLETE_CB_ID :
857 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
858 break;
860 case HAL_UART_ERROR_CB_ID :
861 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
862 break;
864 case HAL_UART_ABORT_COMPLETE_CB_ID :
865 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
866 break;
868 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
869 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
870 break;
872 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
873 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
874 break;
876 case HAL_UART_WAKEUP_CB_ID :
877 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
878 break;
880 case HAL_UART_RX_FIFO_FULL_CB_ID :
881 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
882 break;
884 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
885 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
886 break;
888 case HAL_UART_MSPINIT_CB_ID :
889 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
890 break;
892 case HAL_UART_MSPDEINIT_CB_ID :
893 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
894 break;
896 default :
897 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
899 status = HAL_ERROR;
900 break;
903 else if (HAL_UART_STATE_RESET == huart->gState)
905 switch (CallbackID)
907 case HAL_UART_MSPINIT_CB_ID :
908 huart->MspInitCallback = HAL_UART_MspInit;
909 break;
911 case HAL_UART_MSPDEINIT_CB_ID :
912 huart->MspDeInitCallback = HAL_UART_MspDeInit;
913 break;
915 default :
916 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
918 status = HAL_ERROR;
919 break;
922 else
924 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
926 status = HAL_ERROR;
929 __HAL_UNLOCK(huart);
931 return status;
933 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
936 * @}
939 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
940 * @brief UART Transmit/Receive functions
942 @verbatim
943 ===============================================================================
944 ##### IO operation functions #####
945 ===============================================================================
946 This subsection provides a set of functions allowing to manage the UART asynchronous
947 and Half duplex data transfers.
949 (#) There are two mode of transfer:
950 (+) Blocking mode: The communication is performed in polling mode.
951 The HAL status of all data processing is returned by the same function
952 after finishing transfer.
953 (+) Non-Blocking mode: The communication is performed using Interrupts
954 or DMA, These API's return the HAL status.
955 The end of the data processing will be indicated through the
956 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
957 using DMA mode.
958 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
959 will be executed respectively at the end of the transmit or Receive process
960 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
962 (#) Blocking mode API's are :
963 (+) HAL_UART_Transmit()
964 (+) HAL_UART_Receive()
966 (#) Non-Blocking mode API's with Interrupt are :
967 (+) HAL_UART_Transmit_IT()
968 (+) HAL_UART_Receive_IT()
969 (+) HAL_UART_IRQHandler()
971 (#) Non-Blocking mode API's with DMA are :
972 (+) HAL_UART_Transmit_DMA()
973 (+) HAL_UART_Receive_DMA()
974 (+) HAL_UART_DMAPause()
975 (+) HAL_UART_DMAResume()
976 (+) HAL_UART_DMAStop()
978 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
979 (+) HAL_UART_TxHalfCpltCallback()
980 (+) HAL_UART_TxCpltCallback()
981 (+) HAL_UART_RxHalfCpltCallback()
982 (+) HAL_UART_RxCpltCallback()
983 (+) HAL_UART_ErrorCallback()
985 (#) Non-Blocking mode transfers could be aborted using Abort API's :
986 (+) HAL_UART_Abort()
987 (+) HAL_UART_AbortTransmit()
988 (+) HAL_UART_AbortReceive()
989 (+) HAL_UART_Abort_IT()
990 (+) HAL_UART_AbortTransmit_IT()
991 (+) HAL_UART_AbortReceive_IT()
993 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
994 (+) HAL_UART_AbortCpltCallback()
995 (+) HAL_UART_AbortTransmitCpltCallback()
996 (+) HAL_UART_AbortReceiveCpltCallback()
998 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
999 Errors are handled as follows :
1000 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1001 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
1002 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
1003 and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
1004 If user wants to abort it, Abort services should be called by user.
1005 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1006 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1007 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1009 -@- In the Half duplex communication, it is forbidden to run the transmit
1010 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1012 @endverbatim
1013 * @{
1017 * @brief Send an amount of data in blocking mode.
1018 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1019 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1020 * of u16 provided through pData.
1021 * @note When FIFO mode is enabled, writing a data in the TDR register adds one
1022 * data to the TXFIFO. Write operations to the TDR register are performed
1023 * when TXFNF flag is set. From hardware perspective, TXFNF flag and
1024 * TXE are mapped on the same bit-field.
1025 * @param huart UART handle.
1026 * @param pData Pointer to data buffer (u8 or u16 data elements).
1027 * @param Size Amount of data elements (u8 or u16) to be sent.
1028 * @param Timeout Timeout duration.
1029 * @retval HAL status
1031 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1033 uint8_t *pdata8bits;
1034 uint16_t *pdata16bits;
1035 uint32_t tickstart;
1037 /* Check that a Tx process is not already ongoing */
1038 if (huart->gState == HAL_UART_STATE_READY)
1040 if ((pData == NULL) || (Size == 0U))
1042 return HAL_ERROR;
1045 __HAL_LOCK(huart);
1047 huart->ErrorCode = HAL_UART_ERROR_NONE;
1048 huart->gState = HAL_UART_STATE_BUSY_TX;
1050 /* Init tickstart for timeout managment*/
1051 tickstart = HAL_GetTick();
1053 huart->TxXferSize = Size;
1054 huart->TxXferCount = Size;
1056 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1057 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1059 pdata8bits = NULL;
1060 pdata16bits = (uint16_t *) pData;
1062 else
1064 pdata8bits = pData;
1065 pdata16bits = NULL;
1068 while (huart->TxXferCount > 0U)
1070 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1072 return HAL_TIMEOUT;
1074 if (pdata8bits == NULL)
1076 huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
1077 pdata16bits++;
1079 else
1081 huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
1082 pdata8bits++;
1084 huart->TxXferCount--;
1087 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1089 return HAL_TIMEOUT;
1092 /* At end of Tx process, restore huart->gState to Ready */
1093 huart->gState = HAL_UART_STATE_READY;
1095 __HAL_UNLOCK(huart);
1097 return HAL_OK;
1099 else
1101 return HAL_BUSY;
1106 * @brief Receive an amount of data in blocking mode.
1107 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1108 * the received data is handled as a set of u16. In this case, Size must indicate the number
1109 * of u16 available through pData.
1110 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
1111 * is not empty. Read operations from the RDR register are performed when
1112 * RXFNE flag is set. From hardware perspective, RXFNE flag and
1113 * RXNE are mapped on the same bit-field.
1114 * @param huart UART handle.
1115 * @param pData Pointer to data buffer (u8 or u16 data elements).
1116 * @param Size Amount of data elements (u8 or u16) to be received.
1117 * @param Timeout Timeout duration.
1118 * @retval HAL status
1120 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1122 uint8_t *pdata8bits;
1123 uint16_t *pdata16bits;
1124 uint16_t uhMask;
1125 uint32_t tickstart;
1127 /* Check that a Rx process is not already ongoing */
1128 if (huart->RxState == HAL_UART_STATE_READY)
1130 if ((pData == NULL) || (Size == 0U))
1132 return HAL_ERROR;
1135 __HAL_LOCK(huart);
1137 huart->ErrorCode = HAL_UART_ERROR_NONE;
1138 huart->RxState = HAL_UART_STATE_BUSY_RX;
1140 /* Init tickstart for timeout managment*/
1141 tickstart = HAL_GetTick();
1143 huart->RxXferSize = Size;
1144 huart->RxXferCount = Size;
1146 /* Computation of UART mask to apply to RDR register */
1147 UART_MASK_COMPUTATION(huart);
1148 uhMask = huart->Mask;
1150 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1151 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1153 pdata8bits = NULL;
1154 pdata16bits = (uint16_t *) pData;
1156 else
1158 pdata8bits = pData;
1159 pdata16bits = NULL;
1162 /* as long as data have to be received */
1163 while (huart->RxXferCount > 0U)
1165 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1167 return HAL_TIMEOUT;
1169 if (pdata8bits == NULL)
1171 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
1172 pdata16bits++;
1174 else
1176 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1177 pdata8bits++;
1179 huart->RxXferCount--;
1182 /* At end of Rx process, restore huart->RxState to Ready */
1183 huart->RxState = HAL_UART_STATE_READY;
1185 __HAL_UNLOCK(huart);
1187 return HAL_OK;
1189 else
1191 return HAL_BUSY;
1196 * @brief Send an amount of data in interrupt mode.
1197 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1198 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1199 * of u16 provided through pData.
1200 * @param huart UART handle.
1201 * @param pData Pointer to data buffer (u8 or u16 data elements).
1202 * @param Size Amount of data elements (u8 or u16) to be sent.
1203 * @retval HAL status
1205 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1207 /* Check that a Tx process is not already ongoing */
1208 if (huart->gState == HAL_UART_STATE_READY)
1210 if ((pData == NULL) || (Size == 0U))
1212 return HAL_ERROR;
1215 __HAL_LOCK(huart);
1217 huart->pTxBuffPtr = pData;
1218 huart->TxXferSize = Size;
1219 huart->TxXferCount = Size;
1220 huart->TxISR = NULL;
1222 huart->ErrorCode = HAL_UART_ERROR_NONE;
1223 huart->gState = HAL_UART_STATE_BUSY_TX;
1225 /* Configure Tx interrupt processing */
1226 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1228 /* Set the Tx ISR function pointer according to the data word length */
1229 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1231 huart->TxISR = UART_TxISR_16BIT_FIFOEN;
1233 else
1235 huart->TxISR = UART_TxISR_8BIT_FIFOEN;
1238 __HAL_UNLOCK(huart);
1240 /* Enable the TX FIFO threshold interrupt */
1241 SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1243 else
1245 /* Set the Tx ISR function pointer according to the data word length */
1246 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1248 huart->TxISR = UART_TxISR_16BIT;
1250 else
1252 huart->TxISR = UART_TxISR_8BIT;
1255 __HAL_UNLOCK(huart);
1257 /* Enable the Transmit Data Register Empty interrupt */
1258 SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1261 return HAL_OK;
1263 else
1265 return HAL_BUSY;
1270 * @brief Receive an amount of data in interrupt mode.
1271 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1272 * the received data is handled as a set of u16. In this case, Size must indicate the number
1273 * of u16 available through pData.
1274 * @param huart UART handle.
1275 * @param pData Pointer to data buffer (u8 or u16 data elements).
1276 * @param Size Amount of data elements (u8 or u16) to be received.
1277 * @retval HAL status
1279 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1281 /* Check that a Rx process is not already ongoing */
1282 if (huart->RxState == HAL_UART_STATE_READY)
1284 if ((pData == NULL) || (Size == 0U))
1286 return HAL_ERROR;
1289 __HAL_LOCK(huart);
1291 huart->pRxBuffPtr = pData;
1292 huart->RxXferSize = Size;
1293 huart->RxXferCount = Size;
1294 huart->RxISR = NULL;
1296 /* Computation of UART mask to apply to RDR register */
1297 UART_MASK_COMPUTATION(huart);
1299 huart->ErrorCode = HAL_UART_ERROR_NONE;
1300 huart->RxState = HAL_UART_STATE_BUSY_RX;
1302 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1303 SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1305 /* Configure Rx interrupt processing*/
1306 if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
1308 /* Set the Rx ISR function pointer according to the data word length */
1309 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1311 huart->RxISR = UART_RxISR_16BIT_FIFOEN;
1313 else
1315 huart->RxISR = UART_RxISR_8BIT_FIFOEN;
1318 __HAL_UNLOCK(huart);
1320 /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
1321 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1322 SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
1324 else
1326 /* Set the Rx ISR function pointer according to the data word length */
1327 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1329 huart->RxISR = UART_RxISR_16BIT;
1331 else
1333 huart->RxISR = UART_RxISR_8BIT;
1336 __HAL_UNLOCK(huart);
1338 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
1339 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1342 return HAL_OK;
1344 else
1346 return HAL_BUSY;
1351 * @brief Send an amount of data in DMA mode.
1352 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1353 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1354 * of u16 provided through pData.
1355 * @param huart UART handle.
1356 * @param pData Pointer to data buffer (u8 or u16 data elements).
1357 * @param Size Amount of data elements (u8 or u16) to be sent.
1358 * @retval HAL status
1360 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1362 /* Check that a Tx process is not already ongoing */
1363 if (huart->gState == HAL_UART_STATE_READY)
1365 if ((pData == NULL) || (Size == 0U))
1367 return HAL_ERROR;
1370 __HAL_LOCK(huart);
1372 huart->pTxBuffPtr = pData;
1373 huart->TxXferSize = Size;
1374 huart->TxXferCount = Size;
1376 huart->ErrorCode = HAL_UART_ERROR_NONE;
1377 huart->gState = HAL_UART_STATE_BUSY_TX;
1379 if (huart->hdmatx != NULL)
1381 /* Set the UART DMA transfer complete callback */
1382 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1384 /* Set the UART DMA Half transfer complete callback */
1385 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1387 /* Set the DMA error callback */
1388 huart->hdmatx->XferErrorCallback = UART_DMAError;
1390 /* Set the DMA abort callback */
1391 huart->hdmatx->XferAbortCallback = NULL;
1393 /* Enable the UART transmit DMA channel */
1394 if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK)
1396 /* Set error code to DMA */
1397 huart->ErrorCode = HAL_UART_ERROR_DMA;
1399 __HAL_UNLOCK(huart);
1401 /* Restore huart->gState to ready */
1402 huart->gState = HAL_UART_STATE_READY;
1404 return HAL_ERROR;
1407 /* Clear the TC flag in the ICR register */
1408 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1410 __HAL_UNLOCK(huart);
1412 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1413 in the UART CR3 register */
1414 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1416 return HAL_OK;
1418 else
1420 return HAL_BUSY;
1425 * @brief Receive an amount of data in DMA mode.
1426 * @note When the UART parity is enabled (PCE = 1), the received data contain
1427 * the parity bit (MSB position).
1428 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1429 * the received data is handled as a set of u16. In this case, Size must indicate the number
1430 * of u16 available through pData.
1431 * @param huart UART handle.
1432 * @param pData Pointer to data buffer (u8 or u16 data elements).
1433 * @param Size Amount of data elements (u8 or u16) to be received.
1434 * @retval HAL status
1436 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1438 /* Check that a Rx process is not already ongoing */
1439 if (huart->RxState == HAL_UART_STATE_READY)
1441 if ((pData == NULL) || (Size == 0U))
1443 return HAL_ERROR;
1446 __HAL_LOCK(huart);
1448 huart->pRxBuffPtr = pData;
1449 huart->RxXferSize = Size;
1451 huart->ErrorCode = HAL_UART_ERROR_NONE;
1452 huart->RxState = HAL_UART_STATE_BUSY_RX;
1454 if (huart->hdmarx != NULL)
1456 /* Set the UART DMA transfer complete callback */
1457 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
1459 /* Set the UART DMA Half transfer complete callback */
1460 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
1462 /* Set the DMA error callback */
1463 huart->hdmarx->XferErrorCallback = UART_DMAError;
1465 /* Set the DMA abort callback */
1466 huart->hdmarx->XferAbortCallback = NULL;
1468 /* Enable the DMA channel */
1469 if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
1471 /* Set error code to DMA */
1472 huart->ErrorCode = HAL_UART_ERROR_DMA;
1474 __HAL_UNLOCK(huart);
1476 /* Restore huart->gState to ready */
1477 huart->gState = HAL_UART_STATE_READY;
1479 return HAL_ERROR;
1482 __HAL_UNLOCK(huart);
1484 /* Enable the UART Parity Error Interrupt */
1485 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1487 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1488 SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1490 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1491 in the UART CR3 register */
1492 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1494 return HAL_OK;
1496 else
1498 return HAL_BUSY;
1503 * @brief Pause the DMA Transfer.
1504 * @param huart UART handle.
1505 * @retval HAL status
1507 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1509 const HAL_UART_StateTypeDef gstate = huart->gState;
1510 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1512 __HAL_LOCK(huart);
1514 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1515 (gstate == HAL_UART_STATE_BUSY_TX))
1517 /* Disable the UART DMA Tx request */
1518 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1520 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1521 (rxstate == HAL_UART_STATE_BUSY_RX))
1523 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1524 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1525 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1527 /* Disable the UART DMA Rx request */
1528 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1531 __HAL_UNLOCK(huart);
1533 return HAL_OK;
1537 * @brief Resume the DMA Transfer.
1538 * @param huart UART handle.
1539 * @retval HAL status
1541 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1543 __HAL_LOCK(huart);
1545 if (huart->gState == HAL_UART_STATE_BUSY_TX)
1547 /* Enable the UART DMA Tx request */
1548 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1550 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1552 /* Clear the Overrun flag before resuming the Rx transfer */
1553 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1555 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1556 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1557 SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1559 /* Enable the UART DMA Rx request */
1560 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1563 __HAL_UNLOCK(huart);
1565 return HAL_OK;
1569 * @brief Stop the DMA Transfer.
1570 * @param huart UART handle.
1571 * @retval HAL status
1573 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1575 /* The Lock is not implemented on this API to allow the user application
1576 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1577 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1578 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1579 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1580 the stream and the corresponding call back is executed. */
1582 const HAL_UART_StateTypeDef gstate = huart->gState;
1583 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1585 /* Stop UART DMA Tx request if ongoing */
1586 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1587 (gstate == HAL_UART_STATE_BUSY_TX))
1589 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1591 /* Abort the UART DMA Tx channel */
1592 if (huart->hdmatx != NULL)
1594 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1596 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1598 /* Set error code to DMA */
1599 huart->ErrorCode = HAL_UART_ERROR_DMA;
1601 return HAL_TIMEOUT;
1606 UART_EndTxTransfer(huart);
1609 /* Stop UART DMA Rx request if ongoing */
1610 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1611 (rxstate == HAL_UART_STATE_BUSY_RX))
1613 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1615 /* Abort the UART DMA Rx channel */
1616 if (huart->hdmarx != NULL)
1618 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1620 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1622 /* Set error code to DMA */
1623 huart->ErrorCode = HAL_UART_ERROR_DMA;
1625 return HAL_TIMEOUT;
1630 UART_EndRxTransfer(huart);
1633 return HAL_OK;
1637 * @brief Abort ongoing transfers (blocking mode).
1638 * @param huart UART handle.
1639 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1640 * This procedure performs following operations :
1641 * - Disable UART Interrupts (Tx and Rx)
1642 * - Disable the DMA transfer in the peripheral register (if enabled)
1643 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1644 * - Set handle State to READY
1645 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1646 * @retval HAL status
1648 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1650 /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
1651 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1652 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
1654 /* Disable the UART DMA Tx request if enabled */
1655 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1657 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1659 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1660 if (huart->hdmatx != NULL)
1662 /* Set the UART DMA Abort callback to Null.
1663 No call back execution at end of DMA abort procedure */
1664 huart->hdmatx->XferAbortCallback = NULL;
1666 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1668 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1670 /* Set error code to DMA */
1671 huart->ErrorCode = HAL_UART_ERROR_DMA;
1673 return HAL_TIMEOUT;
1679 /* Disable the UART DMA Rx request if enabled */
1680 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1682 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1684 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1685 if (huart->hdmarx != NULL)
1687 /* Set the UART DMA Abort callback to Null.
1688 No call back execution at end of DMA abort procedure */
1689 huart->hdmarx->XferAbortCallback = NULL;
1691 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1693 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1695 /* Set error code to DMA */
1696 huart->ErrorCode = HAL_UART_ERROR_DMA;
1698 return HAL_TIMEOUT;
1704 /* Reset Tx and Rx transfer counters */
1705 huart->TxXferCount = 0U;
1706 huart->RxXferCount = 0U;
1708 /* Clear the Error flags in the ICR register */
1709 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1711 /* Flush the whole TX FIFO (if needed) */
1712 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1714 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1717 /* Discard the received data */
1718 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1720 /* Restore huart->gState and huart->RxState to Ready */
1721 huart->gState = HAL_UART_STATE_READY;
1722 huart->RxState = HAL_UART_STATE_READY;
1724 huart->ErrorCode = HAL_UART_ERROR_NONE;
1726 return HAL_OK;
1730 * @brief Abort ongoing Transmit transfer (blocking mode).
1731 * @param huart UART handle.
1732 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1733 * This procedure performs following operations :
1734 * - Disable UART Interrupts (Tx)
1735 * - Disable the DMA transfer in the peripheral register (if enabled)
1736 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1737 * - Set handle State to READY
1738 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1739 * @retval HAL status
1741 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1743 /* Disable TCIE, TXEIE and TXFTIE interrupts */
1744 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1745 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1747 /* Disable the UART DMA Tx request if enabled */
1748 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1750 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1752 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1753 if (huart->hdmatx != NULL)
1755 /* Set the UART DMA Abort callback to Null.
1756 No call back execution at end of DMA abort procedure */
1757 huart->hdmatx->XferAbortCallback = NULL;
1759 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1761 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1763 /* Set error code to DMA */
1764 huart->ErrorCode = HAL_UART_ERROR_DMA;
1766 return HAL_TIMEOUT;
1772 /* Reset Tx transfer counter */
1773 huart->TxXferCount = 0U;
1775 /* Flush the whole TX FIFO (if needed) */
1776 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1778 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1781 /* Restore huart->gState to Ready */
1782 huart->gState = HAL_UART_STATE_READY;
1784 return HAL_OK;
1788 * @brief Abort ongoing Receive transfer (blocking mode).
1789 * @param huart UART handle.
1790 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1791 * This procedure performs following operations :
1792 * - Disable UART Interrupts (Rx)
1793 * - Disable the DMA transfer in the peripheral register (if enabled)
1794 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1795 * - Set handle State to READY
1796 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1797 * @retval HAL status
1799 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1801 /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
1802 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
1803 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
1805 /* Disable the UART DMA Rx request if enabled */
1806 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1808 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1810 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1811 if (huart->hdmarx != NULL)
1813 /* Set the UART DMA Abort callback to Null.
1814 No call back execution at end of DMA abort procedure */
1815 huart->hdmarx->XferAbortCallback = NULL;
1817 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1819 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1821 /* Set error code to DMA */
1822 huart->ErrorCode = HAL_UART_ERROR_DMA;
1824 return HAL_TIMEOUT;
1830 /* Reset Rx transfer counter */
1831 huart->RxXferCount = 0U;
1833 /* Clear the Error flags in the ICR register */
1834 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1836 /* Discard the received data */
1837 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1839 /* Restore huart->RxState to Ready */
1840 huart->RxState = HAL_UART_STATE_READY;
1842 return HAL_OK;
1846 * @brief Abort ongoing transfers (Interrupt mode).
1847 * @param huart UART handle.
1848 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1849 * This procedure performs following operations :
1850 * - Disable UART Interrupts (Tx and Rx)
1851 * - Disable the DMA transfer in the peripheral register (if enabled)
1852 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1853 * - Set handle State to READY
1854 * - At abort completion, call user abort complete callback
1855 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1856 * considered as completed only when user abort complete callback is executed (not when exiting function).
1857 * @retval HAL status
1859 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1861 uint32_t abortcplt = 1U;
1863 /* Disable interrupts */
1864 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_TXEIE_TXFNFIE));
1865 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1867 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
1868 before any call to DMA Abort functions */
1869 /* DMA Tx Handle is valid */
1870 if (huart->hdmatx != NULL)
1872 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
1873 Otherwise, set it to NULL */
1874 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1876 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
1878 else
1880 huart->hdmatx->XferAbortCallback = NULL;
1883 /* DMA Rx Handle is valid */
1884 if (huart->hdmarx != NULL)
1886 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
1887 Otherwise, set it to NULL */
1888 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1890 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
1892 else
1894 huart->hdmarx->XferAbortCallback = NULL;
1898 /* Disable the UART DMA Tx request if enabled */
1899 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1901 /* Disable DMA Tx at UART level */
1902 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1904 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
1905 if (huart->hdmatx != NULL)
1907 /* UART Tx DMA Abort callback has already been initialised :
1908 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
1910 /* Abort DMA TX */
1911 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
1913 huart->hdmatx->XferAbortCallback = NULL;
1915 else
1917 abortcplt = 0U;
1922 /* Disable the UART DMA Rx request if enabled */
1923 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1925 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1927 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
1928 if (huart->hdmarx != NULL)
1930 /* UART Rx DMA Abort callback has already been initialised :
1931 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
1933 /* Abort DMA RX */
1934 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
1936 huart->hdmarx->XferAbortCallback = NULL;
1937 abortcplt = 1U;
1939 else
1941 abortcplt = 0U;
1946 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1947 if (abortcplt == 1U)
1949 /* Reset Tx and Rx transfer counters */
1950 huart->TxXferCount = 0U;
1951 huart->RxXferCount = 0U;
1953 /* Clear ISR function pointers */
1954 huart->RxISR = NULL;
1955 huart->TxISR = NULL;
1957 /* Reset errorCode */
1958 huart->ErrorCode = HAL_UART_ERROR_NONE;
1960 /* Clear the Error flags in the ICR register */
1961 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1963 /* Flush the whole TX FIFO (if needed) */
1964 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1966 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1969 /* Discard the received data */
1970 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1972 /* Restore huart->gState and huart->RxState to Ready */
1973 huart->gState = HAL_UART_STATE_READY;
1974 huart->RxState = HAL_UART_STATE_READY;
1976 /* As no DMA to be aborted, call directly user Abort complete callback */
1977 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
1978 /* Call registered Abort complete callback */
1979 huart->AbortCpltCallback(huart);
1980 #else
1981 /* Call legacy weak Abort complete callback */
1982 HAL_UART_AbortCpltCallback(huart);
1983 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1986 return HAL_OK;
1990 * @brief Abort ongoing Transmit transfer (Interrupt mode).
1991 * @param huart UART handle.
1992 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1993 * This procedure performs following operations :
1994 * - Disable UART Interrupts (Tx)
1995 * - Disable the DMA transfer in the peripheral register (if enabled)
1996 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1997 * - Set handle State to READY
1998 * - At abort completion, call user abort complete callback
1999 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2000 * considered as completed only when user abort complete callback is executed (not when exiting function).
2001 * @retval HAL status
2003 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
2005 /* Disable interrupts */
2006 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
2007 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
2009 /* Disable the UART DMA Tx request if enabled */
2010 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2012 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2014 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2015 if (huart->hdmatx != NULL)
2017 /* Set the UART DMA Abort callback :
2018 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2019 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2021 /* Abort DMA TX */
2022 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2024 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2025 huart->hdmatx->XferAbortCallback(huart->hdmatx);
2028 else
2030 /* Reset Tx transfer counter */
2031 huart->TxXferCount = 0U;
2033 /* Clear TxISR function pointers */
2034 huart->TxISR = NULL;
2036 /* Restore huart->gState to Ready */
2037 huart->gState = HAL_UART_STATE_READY;
2039 /* As no DMA to be aborted, call directly user Abort complete callback */
2040 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2041 /* Call registered Abort Transmit Complete Callback */
2042 huart->AbortTransmitCpltCallback(huart);
2043 #else
2044 /* Call legacy weak Abort Transmit Complete Callback */
2045 HAL_UART_AbortTransmitCpltCallback(huart);
2046 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2049 else
2051 /* Reset Tx transfer counter */
2052 huart->TxXferCount = 0U;
2054 /* Clear TxISR function pointers */
2055 huart->TxISR = NULL;
2057 /* Flush the whole TX FIFO (if needed) */
2058 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2060 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2063 /* Restore huart->gState to Ready */
2064 huart->gState = HAL_UART_STATE_READY;
2066 /* As no DMA to be aborted, call directly user Abort complete callback */
2067 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2068 /* Call registered Abort Transmit Complete Callback */
2069 huart->AbortTransmitCpltCallback(huart);
2070 #else
2071 /* Call legacy weak Abort Transmit Complete Callback */
2072 HAL_UART_AbortTransmitCpltCallback(huart);
2073 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2076 return HAL_OK;
2080 * @brief Abort ongoing Receive transfer (Interrupt mode).
2081 * @param huart UART handle.
2082 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2083 * This procedure performs following operations :
2084 * - Disable UART Interrupts (Rx)
2085 * - Disable the DMA transfer in the peripheral register (if enabled)
2086 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2087 * - Set handle State to READY
2088 * - At abort completion, call user abort complete callback
2089 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2090 * considered as completed only when user abort complete callback is executed (not when exiting function).
2091 * @retval HAL status
2093 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2095 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2096 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
2097 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2099 /* Disable the UART DMA Rx request if enabled */
2100 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2102 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2104 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2105 if (huart->hdmarx != NULL)
2107 /* Set the UART DMA Abort callback :
2108 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2109 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2111 /* Abort DMA RX */
2112 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2114 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2115 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2118 else
2120 /* Reset Rx transfer counter */
2121 huart->RxXferCount = 0U;
2123 /* Clear RxISR function pointer */
2124 huart->pRxBuffPtr = NULL;
2126 /* Clear the Error flags in the ICR register */
2127 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2129 /* Discard the received data */
2130 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2132 /* Restore huart->RxState to Ready */
2133 huart->RxState = HAL_UART_STATE_READY;
2135 /* As no DMA to be aborted, call directly user Abort complete callback */
2136 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2137 /* Call registered Abort Receive Complete Callback */
2138 huart->AbortReceiveCpltCallback(huart);
2139 #else
2140 /* Call legacy weak Abort Receive Complete Callback */
2141 HAL_UART_AbortReceiveCpltCallback(huart);
2142 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2145 else
2147 /* Reset Rx transfer counter */
2148 huart->RxXferCount = 0U;
2150 /* Clear RxISR function pointer */
2151 huart->pRxBuffPtr = NULL;
2153 /* Clear the Error flags in the ICR register */
2154 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2156 /* Restore huart->RxState to Ready */
2157 huart->RxState = HAL_UART_STATE_READY;
2159 /* As no DMA to be aborted, call directly user Abort complete callback */
2160 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2161 /* Call registered Abort Receive Complete Callback */
2162 huart->AbortReceiveCpltCallback(huart);
2163 #else
2164 /* Call legacy weak Abort Receive Complete Callback */
2165 HAL_UART_AbortReceiveCpltCallback(huart);
2166 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2169 return HAL_OK;
2173 * @brief Handle UART interrupt request.
2174 * @param huart UART handle.
2175 * @retval None
2177 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2179 uint32_t isrflags = READ_REG(huart->Instance->ISR);
2180 uint32_t cr1its = READ_REG(huart->Instance->CR1);
2181 uint32_t cr3its = READ_REG(huart->Instance->CR3);
2183 uint32_t errorflags;
2184 uint32_t errorcode;
2186 /* If no error occurs */
2187 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2188 if (errorflags == 0U)
2190 /* UART in mode Receiver ---------------------------------------------------*/
2191 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2192 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2193 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2195 if (huart->RxISR != NULL)
2197 huart->RxISR(huart);
2199 return;
2203 /* If some errors occur */
2204 if ((errorflags != 0U)
2205 && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2206 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
2208 /* UART parity error interrupt occurred -------------------------------------*/
2209 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2211 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2213 huart->ErrorCode |= HAL_UART_ERROR_PE;
2216 /* UART frame error interrupt occurred --------------------------------------*/
2217 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2219 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2221 huart->ErrorCode |= HAL_UART_ERROR_FE;
2224 /* UART noise error interrupt occurred --------------------------------------*/
2225 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2227 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2229 huart->ErrorCode |= HAL_UART_ERROR_NE;
2232 /* UART Over-Run interrupt occurred -----------------------------------------*/
2233 if (((isrflags & USART_ISR_ORE) != 0U)
2234 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2235 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2237 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2239 huart->ErrorCode |= HAL_UART_ERROR_ORE;
2242 /* UART Receiver Timeout interrupt occurred ---------------------------------*/
2243 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2245 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
2247 huart->ErrorCode |= HAL_UART_ERROR_RTO;
2250 /* Call UART Error Call back function if need be ----------------------------*/
2251 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2253 /* UART in mode Receiver --------------------------------------------------*/
2254 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2255 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2256 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2258 if (huart->RxISR != NULL)
2260 huart->RxISR(huart);
2264 /* If Error is to be considered as blocking :
2265 - Receiver Timeout error in Reception
2266 - Overrun error in Reception
2267 - any error occurs in DMA mode reception
2269 errorcode = huart->ErrorCode;
2270 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
2271 ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
2273 /* Blocking error : transfer is aborted
2274 Set the UART state ready to be able to start again the process,
2275 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2276 UART_EndRxTransfer(huart);
2278 /* Disable the UART DMA Rx request if enabled */
2279 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2281 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2283 /* Abort the UART DMA Rx channel */
2284 if (huart->hdmarx != NULL)
2286 /* Set the UART DMA Abort callback :
2287 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2288 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2290 /* Abort DMA RX */
2291 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2293 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2294 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2297 else
2299 /* Call user error callback */
2300 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2301 /*Call registered error callback*/
2302 huart->ErrorCallback(huart);
2303 #else
2304 /*Call legacy weak error callback*/
2305 HAL_UART_ErrorCallback(huart);
2306 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2310 else
2312 /* Call user error callback */
2313 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2314 /*Call registered error callback*/
2315 huart->ErrorCallback(huart);
2316 #else
2317 /*Call legacy weak error callback*/
2318 HAL_UART_ErrorCallback(huart);
2319 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2322 else
2324 /* Non Blocking error : transfer could go on.
2325 Error is notified to user through user error callback */
2326 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2327 /*Call registered error callback*/
2328 huart->ErrorCallback(huart);
2329 #else
2330 /*Call legacy weak error callback*/
2331 HAL_UART_ErrorCallback(huart);
2332 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2333 huart->ErrorCode = HAL_UART_ERROR_NONE;
2336 return;
2338 } /* End if some error occurs */
2340 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2341 if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2343 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2345 /* UART Rx state is not reset as a reception process might be ongoing.
2346 If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2348 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2349 /* Call registered Wakeup Callback */
2350 huart->WakeupCallback(huart);
2351 #else
2352 /* Call legacy weak Wakeup Callback */
2353 HAL_UARTEx_WakeupCallback(huart);
2354 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2355 return;
2358 /* UART in mode Transmitter ------------------------------------------------*/
2359 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2360 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2361 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2363 if (huart->TxISR != NULL)
2365 huart->TxISR(huart);
2367 return;
2370 /* UART in mode Transmitter (transmission end) -----------------------------*/
2371 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2373 UART_EndTransmit_IT(huart);
2374 return;
2377 /* UART TX Fifo Empty occurred ----------------------------------------------*/
2378 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2380 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2381 /* Call registered Tx Fifo Empty Callback */
2382 huart->TxFifoEmptyCallback(huart);
2383 #else
2384 /* Call legacy weak Tx Fifo Empty Callback */
2385 HAL_UARTEx_TxFifoEmptyCallback(huart);
2386 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2387 return;
2390 /* UART RX Fifo Full occurred ----------------------------------------------*/
2391 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2393 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2394 /* Call registered Rx Fifo Full Callback */
2395 huart->RxFifoFullCallback(huart);
2396 #else
2397 /* Call legacy weak Rx Fifo Full Callback */
2398 HAL_UARTEx_RxFifoFullCallback(huart);
2399 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2400 return;
2405 * @brief Tx Transfer completed callback.
2406 * @param huart UART handle.
2407 * @retval None
2409 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2411 /* Prevent unused argument(s) compilation warning */
2412 UNUSED(huart);
2414 /* NOTE : This function should not be modified, when the callback is needed,
2415 the HAL_UART_TxCpltCallback can be implemented in the user file.
2420 * @brief Tx Half Transfer completed callback.
2421 * @param huart UART handle.
2422 * @retval None
2424 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2426 /* Prevent unused argument(s) compilation warning */
2427 UNUSED(huart);
2429 /* NOTE: This function should not be modified, when the callback is needed,
2430 the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2435 * @brief Rx Transfer completed callback.
2436 * @param huart UART handle.
2437 * @retval None
2439 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2441 /* Prevent unused argument(s) compilation warning */
2442 UNUSED(huart);
2444 /* NOTE : This function should not be modified, when the callback is needed,
2445 the HAL_UART_RxCpltCallback can be implemented in the user file.
2450 * @brief Rx Half Transfer completed callback.
2451 * @param huart UART handle.
2452 * @retval None
2454 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2456 /* Prevent unused argument(s) compilation warning */
2457 UNUSED(huart);
2459 /* NOTE: This function should not be modified, when the callback is needed,
2460 the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2465 * @brief UART error callback.
2466 * @param huart UART handle.
2467 * @retval None
2469 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2471 /* Prevent unused argument(s) compilation warning */
2472 UNUSED(huart);
2474 /* NOTE : This function should not be modified, when the callback is needed,
2475 the HAL_UART_ErrorCallback can be implemented in the user file.
2480 * @brief UART Abort Complete callback.
2481 * @param huart UART handle.
2482 * @retval None
2484 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2486 /* Prevent unused argument(s) compilation warning */
2487 UNUSED(huart);
2489 /* NOTE : This function should not be modified, when the callback is needed,
2490 the HAL_UART_AbortCpltCallback can be implemented in the user file.
2495 * @brief UART Abort Complete callback.
2496 * @param huart UART handle.
2497 * @retval None
2499 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2501 /* Prevent unused argument(s) compilation warning */
2502 UNUSED(huart);
2504 /* NOTE : This function should not be modified, when the callback is needed,
2505 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2510 * @brief UART Abort Receive Complete callback.
2511 * @param huart UART handle.
2512 * @retval None
2514 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2516 /* Prevent unused argument(s) compilation warning */
2517 UNUSED(huart);
2519 /* NOTE : This function should not be modified, when the callback is needed,
2520 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2525 * @}
2528 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2529 * @brief UART control functions
2531 @verbatim
2532 ===============================================================================
2533 ##### Peripheral Control functions #####
2534 ===============================================================================
2535 [..]
2536 This subsection provides a set of functions allowing to control the UART.
2537 (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2538 (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2539 (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2540 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2541 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2542 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2543 (+) UART_SetConfig() API configures the UART peripheral
2544 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2545 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2546 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2547 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2548 (+) HAL_LIN_SendBreak() API transmits the break characters
2549 @endverbatim
2550 * @{
2554 * @brief Update on the fly the receiver timeout value in RTOR register.
2555 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2556 * the configuration information for the specified UART module.
2557 * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout
2558 * value must be less or equal to 0x0FFFFFFFF.
2559 * @retval None
2561 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2563 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2565 assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2566 MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2571 * @brief Enable the UART receiver timeout feature.
2572 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2573 * the configuration information for the specified UART module.
2574 * @retval HAL status
2576 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2578 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2580 if (huart->gState == HAL_UART_STATE_READY)
2582 /* Process Locked */
2583 __HAL_LOCK(huart);
2585 huart->gState = HAL_UART_STATE_BUSY;
2587 /* Set the USART RTOEN bit */
2588 SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2590 huart->gState = HAL_UART_STATE_READY;
2592 /* Process Unlocked */
2593 __HAL_UNLOCK(huart);
2595 return HAL_OK;
2597 else
2599 return HAL_BUSY;
2602 else
2604 return HAL_ERROR;
2609 * @brief Disable the UART receiver timeout feature.
2610 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2611 * the configuration information for the specified UART module.
2612 * @retval HAL status
2614 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2616 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2618 if (huart->gState == HAL_UART_STATE_READY)
2620 /* Process Locked */
2621 __HAL_LOCK(huart);
2623 huart->gState = HAL_UART_STATE_BUSY;
2625 /* Clear the USART RTOEN bit */
2626 CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2628 huart->gState = HAL_UART_STATE_READY;
2630 /* Process Unlocked */
2631 __HAL_UNLOCK(huart);
2633 return HAL_OK;
2635 else
2637 return HAL_BUSY;
2640 else
2642 return HAL_ERROR;
2647 * @brief Enable UART in mute mode (does not mean UART enters mute mode;
2648 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2649 * @param huart UART handle.
2650 * @retval HAL status
2652 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2654 __HAL_LOCK(huart);
2656 huart->gState = HAL_UART_STATE_BUSY;
2658 /* Enable USART mute mode by setting the MME bit in the CR1 register */
2659 SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2661 huart->gState = HAL_UART_STATE_READY;
2663 return (UART_CheckIdleState(huart));
2667 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode
2668 * as it may not have been in mute mode at this very moment).
2669 * @param huart UART handle.
2670 * @retval HAL status
2672 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2674 __HAL_LOCK(huart);
2676 huart->gState = HAL_UART_STATE_BUSY;
2678 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2679 CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2681 huart->gState = HAL_UART_STATE_READY;
2683 return (UART_CheckIdleState(huart));
2687 * @brief Enter UART mute mode (means UART actually enters mute mode).
2688 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2689 * @param huart UART handle.
2690 * @retval None
2692 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2694 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2698 * @brief Enable the UART transmitter and disable the UART receiver.
2699 * @param huart UART handle.
2700 * @retval HAL status
2702 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2704 __HAL_LOCK(huart);
2705 huart->gState = HAL_UART_STATE_BUSY;
2707 /* Clear TE and RE bits */
2708 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2710 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2711 SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2713 huart->gState = HAL_UART_STATE_READY;
2715 __HAL_UNLOCK(huart);
2717 return HAL_OK;
2721 * @brief Enable the UART receiver and disable the UART transmitter.
2722 * @param huart UART handle.
2723 * @retval HAL status.
2725 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2727 __HAL_LOCK(huart);
2728 huart->gState = HAL_UART_STATE_BUSY;
2730 /* Clear TE and RE bits */
2731 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2733 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2734 SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2736 huart->gState = HAL_UART_STATE_READY;
2738 __HAL_UNLOCK(huart);
2740 return HAL_OK;
2745 * @brief Transmit break characters.
2746 * @param huart UART handle.
2747 * @retval HAL status
2749 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
2751 /* Check the parameters */
2752 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
2754 __HAL_LOCK(huart);
2756 huart->gState = HAL_UART_STATE_BUSY;
2758 /* Send break characters */
2759 __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
2761 huart->gState = HAL_UART_STATE_READY;
2763 __HAL_UNLOCK(huart);
2765 return HAL_OK;
2769 * @}
2772 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
2773 * @brief UART Peripheral State functions
2775 @verbatim
2776 ==============================================================================
2777 ##### Peripheral State and Error functions #####
2778 ==============================================================================
2779 [..]
2780 This subsection provides functions allowing to :
2781 (+) Return the UART handle state.
2782 (+) Return the UART handle error code
2784 @endverbatim
2785 * @{
2789 * @brief Return the UART handle state.
2790 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2791 * the configuration information for the specified UART.
2792 * @retval HAL state
2794 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
2796 uint32_t temp1;
2797 uint32_t temp2;
2798 temp1 = huart->gState;
2799 temp2 = huart->RxState;
2801 return (HAL_UART_StateTypeDef)(temp1 | temp2);
2805 * @brief Return the UART handle error code.
2806 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2807 * the configuration information for the specified UART.
2808 * @retval UART Error Code
2810 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
2812 return huart->ErrorCode;
2815 * @}
2819 * @}
2822 /** @defgroup UART_Private_Functions UART Private Functions
2823 * @{
2827 * @brief Initialize the callbacks to their default values.
2828 * @param huart UART handle.
2829 * @retval none
2831 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2832 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
2834 /* Init the UART Callback settings */
2835 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
2836 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
2837 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
2838 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
2839 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
2840 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
2841 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2842 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
2843 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
2844 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
2845 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
2848 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2851 * @brief Configure the UART peripheral.
2852 * @param huart UART handle.
2853 * @retval HAL status
2855 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
2857 uint32_t tmpreg;
2858 uint16_t brrtemp;
2859 UART_ClockSourceTypeDef clocksource;
2860 uint32_t usartdiv = 0x00000000U;
2861 HAL_StatusTypeDef ret = HAL_OK;
2862 uint32_t lpuart_ker_ck_pres = 0x00000000U;
2863 PLL2_ClocksTypeDef pll2_clocks;
2864 PLL3_ClocksTypeDef pll3_clocks;
2865 uint32_t pclk;
2867 /* Check the parameters */
2868 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
2869 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
2870 if (UART_INSTANCE_LOWPOWER(huart))
2872 assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
2874 else
2876 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
2877 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
2880 assert_param(IS_UART_PARITY(huart->Init.Parity));
2881 assert_param(IS_UART_MODE(huart->Init.Mode));
2882 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
2883 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
2884 assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
2886 /*-------------------------- USART CR1 Configuration -----------------------*/
2887 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
2888 * the UART Word Length, Parity, Mode and oversampling:
2889 * set the M bits according to huart->Init.WordLength value
2890 * set PCE and PS bits according to huart->Init.Parity value
2891 * set TE and RE bits according to huart->Init.Mode value
2892 * set OVER8 bit according to huart->Init.OverSampling value */
2893 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
2894 tmpreg |= (uint32_t)huart->FifoMode;
2895 MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2897 /*-------------------------- USART CR2 Configuration -----------------------*/
2898 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
2899 * to huart->Init.StopBits value */
2900 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
2902 /*-------------------------- USART CR3 Configuration -----------------------*/
2903 /* Configure
2904 * - UART HardWare Flow Control: set CTSE and RTSE bits according
2905 * to huart->Init.HwFlowCtl value
2906 * - one-bit sampling method versus three samples' majority rule according
2907 * to huart->Init.OneBitSampling (not applicable to LPUART) */
2908 tmpreg = (uint32_t)huart->Init.HwFlowCtl;
2910 if (!(UART_INSTANCE_LOWPOWER(huart)))
2912 tmpreg |= huart->Init.OneBitSampling;
2914 MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
2916 /*-------------------------- USART PRESC Configuration -----------------------*/
2917 /* Configure
2918 * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
2919 MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
2921 /*-------------------------- USART BRR Configuration -----------------------*/
2922 UART_GETCLOCKSOURCE(huart, clocksource);
2924 /* Check LPUART instance */
2925 if (UART_INSTANCE_LOWPOWER(huart))
2927 /* Retrieve frequency clock */
2928 switch (clocksource)
2930 case UART_CLOCKSOURCE_D3PCLK1:
2931 lpuart_ker_ck_pres = (HAL_RCCEx_GetD3PCLK1Freq() / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2932 break;
2933 case UART_CLOCKSOURCE_PLL2:
2934 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
2935 lpuart_ker_ck_pres = (pll2_clocks.PLL2_Q_Frequency / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2936 break;
2937 case UART_CLOCKSOURCE_PLL3:
2938 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
2939 lpuart_ker_ck_pres = (pll3_clocks.PLL3_Q_Frequency / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2940 break;
2941 case UART_CLOCKSOURCE_HSI:
2942 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2944 lpuart_ker_ck_pres = ((uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)) / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2946 else
2948 lpuart_ker_ck_pres = ((uint32_t) HSI_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2950 break;
2951 case UART_CLOCKSOURCE_CSI:
2952 lpuart_ker_ck_pres = ((uint32_t)CSI_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2953 break;
2954 case UART_CLOCKSOURCE_LSE:
2955 lpuart_ker_ck_pres = ((uint32_t)LSE_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2956 break;
2957 default:
2958 ret = HAL_ERROR;
2959 break;
2962 /* if proper clock source reported */
2963 if (lpuart_ker_ck_pres != 0U)
2965 /* ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
2966 if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
2967 (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
2969 ret = HAL_ERROR;
2971 else
2973 switch (clocksource)
2975 case UART_CLOCKSOURCE_D3PCLK1:
2976 pclk = HAL_RCCEx_GetD3PCLK1Freq();
2977 usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2978 break;
2979 case UART_CLOCKSOURCE_PLL2:
2980 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
2981 usartdiv = (uint32_t)(UART_DIV_LPUART(pll2_clocks.PLL2_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2982 break;
2983 case UART_CLOCKSOURCE_PLL3:
2984 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
2985 usartdiv = (uint32_t)(UART_DIV_LPUART(pll3_clocks.PLL3_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2986 break;
2987 case UART_CLOCKSOURCE_HSI:
2988 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2990 usartdiv = (uint32_t)(UART_DIV_LPUART((uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), huart->Init.BaudRate, huart->Init.ClockPrescaler));
2992 else
2994 usartdiv = (uint32_t)(UART_DIV_LPUART(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2996 break;
2997 case UART_CLOCKSOURCE_CSI:
2998 usartdiv = (uint32_t)(UART_DIV_LPUART(CSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2999 break;
3000 case UART_CLOCKSOURCE_LSE:
3001 usartdiv = (uint32_t)(UART_DIV_LPUART(LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3002 break;
3003 default:
3004 ret = HAL_ERROR;
3005 break;
3008 /* It is forbidden to write values lower than 0x300 in the LPUART_BRR register */
3009 if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
3011 huart->Instance->BRR = usartdiv;
3013 else
3015 ret = HAL_ERROR;
3017 } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
3018 } /* if (lpuart_ker_ck_pres != 0) */
3020 /* Check UART Over Sampling to set Baud Rate Register */
3021 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3023 switch (clocksource)
3025 case UART_CLOCKSOURCE_D2PCLK1:
3026 pclk = HAL_RCC_GetPCLK1Freq();
3027 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3028 break;
3029 case UART_CLOCKSOURCE_D2PCLK2:
3030 pclk = HAL_RCC_GetPCLK2Freq();
3031 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3032 break;
3033 case UART_CLOCKSOURCE_PLL2:
3034 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
3035 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pll2_clocks.PLL2_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3036 break;
3037 case UART_CLOCKSOURCE_PLL3:
3038 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
3039 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pll3_clocks.PLL3_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3040 break;
3041 case UART_CLOCKSOURCE_HSI:
3042 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
3044 usartdiv = (uint16_t)(UART_DIV_SAMPLING8((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), huart->Init.BaudRate, huart->Init.ClockPrescaler));
3046 else
3048 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3050 break;
3051 case UART_CLOCKSOURCE_CSI:
3052 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(CSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3053 break;
3054 case UART_CLOCKSOURCE_LSE:
3055 usartdiv = (uint16_t)(UART_DIV_SAMPLING8((uint32_t)LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3056 break;
3057 default:
3058 ret = HAL_ERROR;
3059 break;
3062 /* USARTDIV must be greater than or equal to 0d16 */
3063 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3065 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3066 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3067 huart->Instance->BRR = brrtemp;
3069 else
3071 ret = HAL_ERROR;
3074 else
3076 switch (clocksource)
3078 case UART_CLOCKSOURCE_D2PCLK1:
3079 pclk = HAL_RCC_GetPCLK1Freq();
3080 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3081 break;
3082 case UART_CLOCKSOURCE_D2PCLK2:
3083 pclk = HAL_RCC_GetPCLK2Freq();
3084 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3085 break;
3086 case UART_CLOCKSOURCE_PLL2:
3087 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
3088 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pll2_clocks.PLL2_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3089 break;
3090 case UART_CLOCKSOURCE_PLL3:
3091 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
3092 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pll3_clocks.PLL3_Q_Frequency, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3093 break;
3094 case UART_CLOCKSOURCE_HSI:
3095 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
3097 usartdiv = (uint16_t)(UART_DIV_SAMPLING16((HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), huart->Init.BaudRate, huart->Init.ClockPrescaler));
3099 else
3101 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3103 break;
3104 case UART_CLOCKSOURCE_CSI:
3105 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(CSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3106 break;
3107 case UART_CLOCKSOURCE_LSE:
3108 usartdiv = (uint16_t)(UART_DIV_SAMPLING16((uint32_t)LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3109 break;
3110 default:
3111 ret = HAL_ERROR;
3112 break;
3115 /* USARTDIV must be greater than or equal to 0d16 */
3116 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3118 huart->Instance->BRR = usartdiv;
3120 else
3122 ret = HAL_ERROR;
3126 /* Initialize the number of data to process during RX/TX ISR execution */
3127 huart->NbTxDataToProcess = 1;
3128 huart->NbRxDataToProcess = 1;
3130 /* Clear ISR function pointers */
3131 huart->RxISR = NULL;
3132 huart->TxISR = NULL;
3134 return ret;
3138 * @brief Configure the UART peripheral advanced features.
3139 * @param huart UART handle.
3140 * @retval None
3142 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3144 /* Check whether the set of advanced features to configure is properly set */
3145 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3147 /* if required, configure TX pin active level inversion */
3148 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3150 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3151 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3154 /* if required, configure RX pin active level inversion */
3155 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3157 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3158 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3161 /* if required, configure data inversion */
3162 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3164 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3165 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3168 /* if required, configure RX/TX pins swap */
3169 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3171 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3172 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3175 /* if required, configure RX overrun detection disabling */
3176 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3178 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3179 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3182 /* if required, configure DMA disabling on reception error */
3183 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3185 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3186 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3189 /* if required, configure auto Baud rate detection scheme */
3190 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3192 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3193 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3194 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3195 /* set auto Baudrate detection parameters if detection is enabled */
3196 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3198 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3199 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3203 /* if required, configure MSB first on communication line */
3204 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3206 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3207 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3212 * @brief Check the UART Idle State.
3213 * @param huart UART handle.
3214 * @retval HAL status
3216 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3218 uint32_t tickstart;
3220 /* Initialize the UART ErrorCode */
3221 huart->ErrorCode = HAL_UART_ERROR_NONE;
3223 /* Init tickstart for timeout managment*/
3224 tickstart = HAL_GetTick();
3226 /* Check if the Transmitter is enabled */
3227 if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3229 /* Wait until TEACK flag is set */
3230 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3232 /* Timeout occurred */
3233 return HAL_TIMEOUT;
3237 /* Check if the Receiver is enabled */
3238 if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3240 /* Wait until REACK flag is set */
3241 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3243 /* Timeout occurred */
3244 return HAL_TIMEOUT;
3248 /* Initialize the UART State */
3249 huart->gState = HAL_UART_STATE_READY;
3250 huart->RxState = HAL_UART_STATE_READY;
3252 __HAL_UNLOCK(huart);
3254 return HAL_OK;
3258 * @brief Handle UART Communication Timeout.
3259 * @param huart UART handle.
3260 * @param Flag Specifies the UART flag to check
3261 * @param Status Flag status (SET or RESET)
3262 * @param Tickstart Tick start value
3263 * @param Timeout Timeout duration
3264 * @retval HAL status
3266 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3267 uint32_t Tickstart, uint32_t Timeout)
3269 /* Wait until flag is set */
3270 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3272 /* Check for the Timeout */
3273 if (Timeout != HAL_MAX_DELAY)
3275 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3277 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
3278 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
3279 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3281 huart->gState = HAL_UART_STATE_READY;
3282 huart->RxState = HAL_UART_STATE_READY;
3284 __HAL_UNLOCK(huart);
3286 return HAL_TIMEOUT;
3289 if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U)
3291 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3293 /* Clear Receiver Timeout flag*/
3294 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3296 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
3297 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
3298 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3300 huart->gState = HAL_UART_STATE_READY;
3301 huart->RxState = HAL_UART_STATE_READY;
3302 huart->ErrorCode = HAL_UART_ERROR_RTO;
3304 /* Process Unlocked */
3305 __HAL_UNLOCK(huart);
3307 return HAL_TIMEOUT;
3312 return HAL_OK;
3317 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3318 * @param huart UART handle.
3319 * @retval None
3321 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3323 /* Disable TXEIE, TCIE, TXFT interrupts */
3324 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3325 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3327 /* At end of Tx process, restore huart->gState to Ready */
3328 huart->gState = HAL_UART_STATE_READY;
3333 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3334 * @param huart UART handle.
3335 * @retval None
3337 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3339 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3340 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3341 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3343 /* At end of Rx process, restore huart->RxState to Ready */
3344 huart->RxState = HAL_UART_STATE_READY;
3346 /* Reset RxIsr function pointer */
3347 huart->RxISR = NULL;
3352 * @brief DMA UART transmit process complete callback.
3353 * @param hdma DMA handle.
3354 * @retval None
3356 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3358 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3360 /* DMA Normal mode */
3361 if (hdma->Init.Mode != DMA_CIRCULAR)
3363 huart->TxXferCount = 0U;
3365 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3366 in the UART CR3 register */
3367 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
3369 /* Enable the UART Transmit Complete Interrupt */
3370 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3372 /* DMA Circular mode */
3373 else
3375 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3376 /*Call registered Tx complete callback*/
3377 huart->TxCpltCallback(huart);
3378 #else
3379 /*Call legacy weak Tx complete callback*/
3380 HAL_UART_TxCpltCallback(huart);
3381 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3386 * @brief DMA UART transmit process half complete callback.
3387 * @param hdma DMA handle.
3388 * @retval None
3390 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3392 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3394 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3395 /*Call registered Tx Half complete callback*/
3396 huart->TxHalfCpltCallback(huart);
3397 #else
3398 /*Call legacy weak Tx Half complete callback*/
3399 HAL_UART_TxHalfCpltCallback(huart);
3400 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3404 * @brief DMA UART receive process complete callback.
3405 * @param hdma DMA handle.
3406 * @retval None
3408 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3410 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3412 /* DMA Normal mode */
3413 if (hdma->Init.Mode != DMA_CIRCULAR)
3415 huart->RxXferCount = 0U;
3417 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3418 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3419 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3421 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3422 in the UART CR3 register */
3423 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3425 /* At end of Rx process, restore huart->RxState to Ready */
3426 huart->RxState = HAL_UART_STATE_READY;
3429 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3430 /*Call registered Rx complete callback*/
3431 huart->RxCpltCallback(huart);
3432 #else
3433 /*Call legacy weak Rx complete callback*/
3434 HAL_UART_RxCpltCallback(huart);
3435 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3439 * @brief DMA UART receive process half complete callback.
3440 * @param hdma DMA handle.
3441 * @retval None
3443 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3445 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3447 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3448 /*Call registered Rx Half complete callback*/
3449 huart->RxHalfCpltCallback(huart);
3450 #else
3451 /*Call legacy weak Rx Half complete callback*/
3452 HAL_UART_RxHalfCpltCallback(huart);
3453 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3457 * @brief DMA UART communication error callback.
3458 * @param hdma DMA handle.
3459 * @retval None
3461 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3463 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3465 const HAL_UART_StateTypeDef gstate = huart->gState;
3466 const HAL_UART_StateTypeDef rxstate = huart->RxState;
3468 /* Stop UART DMA Tx request if ongoing */
3469 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3470 (gstate == HAL_UART_STATE_BUSY_TX))
3472 huart->TxXferCount = 0U;
3473 UART_EndTxTransfer(huart);
3476 /* Stop UART DMA Rx request if ongoing */
3477 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3478 (rxstate == HAL_UART_STATE_BUSY_RX))
3480 huart->RxXferCount = 0U;
3481 UART_EndRxTransfer(huart);
3484 huart->ErrorCode |= HAL_UART_ERROR_DMA;
3486 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3487 /*Call registered error callback*/
3488 huart->ErrorCallback(huart);
3489 #else
3490 /*Call legacy weak error callback*/
3491 HAL_UART_ErrorCallback(huart);
3492 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3496 * @brief DMA UART communication abort callback, when initiated by HAL services on Error
3497 * (To be called at end of DMA Abort procedure following error occurrence).
3498 * @param hdma DMA handle.
3499 * @retval None
3501 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3503 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3504 huart->RxXferCount = 0U;
3505 huart->TxXferCount = 0U;
3507 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3508 /*Call registered error callback*/
3509 huart->ErrorCallback(huart);
3510 #else
3511 /*Call legacy weak error callback*/
3512 HAL_UART_ErrorCallback(huart);
3513 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3517 * @brief DMA UART Tx communication abort callback, when initiated by user
3518 * (To be called at end of DMA Tx Abort procedure following user abort request).
3519 * @note When this callback is executed, User Abort complete call back is called only if no
3520 * Abort still ongoing for Rx DMA Handle.
3521 * @param hdma DMA handle.
3522 * @retval None
3524 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3526 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3528 huart->hdmatx->XferAbortCallback = NULL;
3530 /* Check if an Abort process is still ongoing */
3531 if (huart->hdmarx != NULL)
3533 if (huart->hdmarx->XferAbortCallback != NULL)
3535 return;
3539 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3540 huart->TxXferCount = 0U;
3541 huart->RxXferCount = 0U;
3543 /* Reset errorCode */
3544 huart->ErrorCode = HAL_UART_ERROR_NONE;
3546 /* Clear the Error flags in the ICR register */
3547 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3549 /* Flush the whole TX FIFO (if needed) */
3550 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3552 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3555 /* Restore huart->gState and huart->RxState to Ready */
3556 huart->gState = HAL_UART_STATE_READY;
3557 huart->RxState = HAL_UART_STATE_READY;
3559 /* Call user Abort complete callback */
3560 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3561 /* Call registered Abort complete callback */
3562 huart->AbortCpltCallback(huart);
3563 #else
3564 /* Call legacy weak Abort complete callback */
3565 HAL_UART_AbortCpltCallback(huart);
3566 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3571 * @brief DMA UART Rx communication abort callback, when initiated by user
3572 * (To be called at end of DMA Rx Abort procedure following user abort request).
3573 * @note When this callback is executed, User Abort complete call back is called only if no
3574 * Abort still ongoing for Tx DMA Handle.
3575 * @param hdma DMA handle.
3576 * @retval None
3578 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3580 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3582 huart->hdmarx->XferAbortCallback = NULL;
3584 /* Check if an Abort process is still ongoing */
3585 if (huart->hdmatx != NULL)
3587 if (huart->hdmatx->XferAbortCallback != NULL)
3589 return;
3593 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3594 huart->TxXferCount = 0U;
3595 huart->RxXferCount = 0U;
3597 /* Reset errorCode */
3598 huart->ErrorCode = HAL_UART_ERROR_NONE;
3600 /* Clear the Error flags in the ICR register */
3601 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3603 /* Discard the received data */
3604 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3606 /* Restore huart->gState and huart->RxState to Ready */
3607 huart->gState = HAL_UART_STATE_READY;
3608 huart->RxState = HAL_UART_STATE_READY;
3610 /* Call user Abort complete callback */
3611 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3612 /* Call registered Abort complete callback */
3613 huart->AbortCpltCallback(huart);
3614 #else
3615 /* Call legacy weak Abort complete callback */
3616 HAL_UART_AbortCpltCallback(huart);
3617 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3622 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
3623 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
3624 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
3625 * and leads to user Tx Abort Complete callback execution).
3626 * @param hdma DMA handle.
3627 * @retval None
3629 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3631 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3633 huart->TxXferCount = 0U;
3635 /* Flush the whole TX FIFO (if needed) */
3636 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3638 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3641 /* Restore huart->gState to Ready */
3642 huart->gState = HAL_UART_STATE_READY;
3644 /* Call user Abort complete callback */
3645 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3646 /* Call registered Abort Transmit Complete Callback */
3647 huart->AbortTransmitCpltCallback(huart);
3648 #else
3649 /* Call legacy weak Abort Transmit Complete Callback */
3650 HAL_UART_AbortTransmitCpltCallback(huart);
3651 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3655 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
3656 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
3657 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
3658 * and leads to user Rx Abort Complete callback execution).
3659 * @param hdma DMA handle.
3660 * @retval None
3662 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3664 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3666 huart->RxXferCount = 0U;
3668 /* Clear the Error flags in the ICR register */
3669 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3671 /* Discard the received data */
3672 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3674 /* Restore huart->RxState to Ready */
3675 huart->RxState = HAL_UART_STATE_READY;
3677 /* Call user Abort complete callback */
3678 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3679 /* Call registered Abort Receive Complete Callback */
3680 huart->AbortReceiveCpltCallback(huart);
3681 #else
3682 /* Call legacy weak Abort Receive Complete Callback */
3683 HAL_UART_AbortReceiveCpltCallback(huart);
3684 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3688 * @brief TX interrrupt handler for 7 or 8 bits data word length .
3689 * @note Function is called under interruption only, once
3690 * interruptions have been enabled by HAL_UART_Transmit_IT().
3691 * @param huart UART handle.
3692 * @retval None
3694 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
3696 /* Check that a Tx process is ongoing */
3697 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3699 if (huart->TxXferCount == 0U)
3701 /* Disable the UART Transmit Data Register Empty Interrupt */
3702 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
3704 /* Enable the UART Transmit Complete Interrupt */
3705 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3707 else
3709 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
3710 huart->pTxBuffPtr++;
3711 huart->TxXferCount--;
3717 * @brief TX interrrupt handler for 9 bits data word length.
3718 * @note Function is called under interruption only, once
3719 * interruptions have been enabled by HAL_UART_Transmit_IT().
3720 * @param huart UART handle.
3721 * @retval None
3723 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
3725 uint16_t *tmp;
3727 /* Check that a Tx process is ongoing */
3728 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3730 if (huart->TxXferCount == 0U)
3732 /* Disable the UART Transmit Data Register Empty Interrupt */
3733 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
3735 /* Enable the UART Transmit Complete Interrupt */
3736 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3738 else
3740 tmp = (uint16_t *) huart->pTxBuffPtr;
3741 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
3742 huart->pTxBuffPtr += 2U;
3743 huart->TxXferCount--;
3749 * @brief TX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
3750 * @note Function is called under interruption only, once
3751 * interruptions have been enabled by HAL_UART_Transmit_IT().
3752 * @param huart UART handle.
3753 * @retval None
3755 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
3757 uint16_t nb_tx_data;
3759 /* Check that a Tx process is ongoing */
3760 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3762 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3764 if (huart->TxXferCount == 0U)
3766 /* Disable the TX FIFO threshold interrupt */
3767 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
3769 /* Enable the UART Transmit Complete Interrupt */
3770 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3772 break; /* force exit loop */
3774 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
3776 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
3777 huart->pTxBuffPtr++;
3778 huart->TxXferCount--;
3780 else
3782 /* Nothing to do */
3789 * @brief TX interrrupt handler for 9 bits data word length and FIFO mode is enabled.
3790 * @note Function is called under interruption only, once
3791 * interruptions have been enabled by HAL_UART_Transmit_IT().
3792 * @param huart UART handle.
3793 * @retval None
3795 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
3797 uint16_t *tmp;
3798 uint16_t nb_tx_data;
3800 /* Check that a Tx process is ongoing */
3801 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3803 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3805 if (huart->TxXferCount == 0U)
3807 /* Disable the TX FIFO threshold interrupt */
3808 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
3810 /* Enable the UART Transmit Complete Interrupt */
3811 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3813 break; /* force exit loop */
3815 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
3817 tmp = (uint16_t *) huart->pTxBuffPtr;
3818 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
3819 huart->pTxBuffPtr += 2U;
3820 huart->TxXferCount--;
3822 else
3824 /* Nothing to do */
3831 * @brief Wrap up transmission in non-blocking mode.
3832 * @param huart pointer to a UART_HandleTypeDef structure that contains
3833 * the configuration information for the specified UART module.
3834 * @retval None
3836 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
3838 /* Disable the UART Transmit Complete Interrupt */
3839 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3841 /* Tx process is ended, restore huart->gState to Ready */
3842 huart->gState = HAL_UART_STATE_READY;
3844 /* Cleat TxISR function pointer */
3845 huart->TxISR = NULL;
3847 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3848 /*Call registered Tx complete callback*/
3849 huart->TxCpltCallback(huart);
3850 #else
3851 /*Call legacy weak Tx complete callback*/
3852 HAL_UART_TxCpltCallback(huart);
3853 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3857 * @brief RX interrrupt handler for 7 or 8 bits data word length .
3858 * @param huart UART handle.
3859 * @retval None
3861 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
3863 uint16_t uhMask = huart->Mask;
3864 uint16_t uhdata;
3866 /* Check that a Rx process is ongoing */
3867 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3869 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3870 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
3871 huart->pRxBuffPtr++;
3872 huart->RxXferCount--;
3874 if (huart->RxXferCount == 0U)
3876 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
3877 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3879 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3880 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3882 /* Rx process is completed, restore huart->RxState to Ready */
3883 huart->RxState = HAL_UART_STATE_READY;
3885 /* Clear RxISR function pointer */
3886 huart->RxISR = NULL;
3888 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3889 /*Call registered Rx complete callback*/
3890 huart->RxCpltCallback(huart);
3891 #else
3892 /*Call legacy weak Rx complete callback*/
3893 HAL_UART_RxCpltCallback(huart);
3894 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3897 else
3899 /* Clear RXNE interrupt flag */
3900 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3905 * @brief RX interrrupt handler for 9 bits data word length .
3906 * @note Function is called under interruption only, once
3907 * interruptions have been enabled by HAL_UART_Receive_IT()
3908 * @param huart UART handle.
3909 * @retval None
3911 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
3913 uint16_t *tmp;
3914 uint16_t uhMask = huart->Mask;
3915 uint16_t uhdata;
3917 /* Check that a Rx process is ongoing */
3918 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3920 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3921 tmp = (uint16_t *) huart->pRxBuffPtr ;
3922 *tmp = (uint16_t)(uhdata & uhMask);
3923 huart->pRxBuffPtr += 2U;
3924 huart->RxXferCount--;
3926 if (huart->RxXferCount == 0U)
3928 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
3929 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3931 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3932 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3934 /* Rx process is completed, restore huart->RxState to Ready */
3935 huart->RxState = HAL_UART_STATE_READY;
3937 /* Clear RxISR function pointer */
3938 huart->RxISR = NULL;
3940 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3941 /*Call registered Rx complete callback*/
3942 huart->RxCpltCallback(huart);
3943 #else
3944 /*Call legacy weak Rx complete callback*/
3945 HAL_UART_RxCpltCallback(huart);
3946 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3949 else
3951 /* Clear RXNE interrupt flag */
3952 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3957 * @brief RX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
3958 * @note Function is called under interruption only, once
3959 * interruptions have been enabled by HAL_UART_Receive_IT()
3960 * @param huart UART handle.
3961 * @retval None
3963 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
3965 uint16_t uhMask = huart->Mask;
3966 uint16_t uhdata;
3967 uint16_t nb_rx_data;
3968 uint16_t rxdatacount;
3970 /* Check that a Rx process is ongoing */
3971 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3973 for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3975 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3976 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
3977 huart->pRxBuffPtr++;
3978 huart->RxXferCount--;
3980 if (huart->RxXferCount == 0U)
3982 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
3983 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3985 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3986 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3988 /* Rx process is completed, restore huart->RxState to Ready */
3989 huart->RxState = HAL_UART_STATE_READY;
3991 /* Clear RxISR function pointer */
3992 huart->RxISR = NULL;
3994 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3995 /*Call registered Rx complete callback*/
3996 huart->RxCpltCallback(huart);
3997 #else
3998 /*Call legacy weak Rx complete callback*/
3999 HAL_UART_RxCpltCallback(huart);
4000 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4004 /* When remaining number of bytes to receive is less than the RX FIFO
4005 threshold, next incoming frames are processed as if FIFO mode was
4006 disabled (i.e. one interrupt per received frame).
4008 rxdatacount = huart->RxXferCount;
4009 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4011 /* Disable the UART RXFT interrupt*/
4012 CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4014 /* Update the RxISR function pointer */
4015 huart->RxISR = UART_RxISR_8BIT;
4017 /* Enable the UART Data Register Not Empty interrupt */
4018 SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4021 else
4023 /* Clear RXNE interrupt flag */
4024 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4029 * @brief RX interrrupt handler for 9 bits data word length and FIFO mode is enabled.
4030 * @note Function is called under interruption only, once
4031 * interruptions have been enabled by HAL_UART_Receive_IT()
4032 * @param huart UART handle.
4033 * @retval None
4035 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4037 uint16_t *tmp;
4038 uint16_t uhMask = huart->Mask;
4039 uint16_t uhdata;
4040 uint16_t nb_rx_data;
4041 uint16_t rxdatacount;
4043 /* Check that a Rx process is ongoing */
4044 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4046 for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
4048 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4049 tmp = (uint16_t *) huart->pRxBuffPtr ;
4050 *tmp = (uint16_t)(uhdata & uhMask);
4051 huart->pRxBuffPtr += 2U;
4052 huart->RxXferCount--;
4054 if (huart->RxXferCount == 0U)
4056 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4057 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4059 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
4060 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4062 /* Rx process is completed, restore huart->RxState to Ready */
4063 huart->RxState = HAL_UART_STATE_READY;
4065 /* Clear RxISR function pointer */
4066 huart->RxISR = NULL;
4068 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4069 /*Call registered Rx complete callback*/
4070 huart->RxCpltCallback(huart);
4071 #else
4072 /*Call legacy weak Rx complete callback*/
4073 HAL_UART_RxCpltCallback(huart);
4074 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4078 /* When remaining number of bytes to receive is less than the RX FIFO
4079 threshold, next incoming frames are processed as if FIFO mode was
4080 disabled (i.e. one interrupt per received frame).
4082 rxdatacount = huart->RxXferCount;
4083 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4085 /* Disable the UART RXFT interrupt*/
4086 CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4088 /* Update the RxISR function pointer */
4089 huart->RxISR = UART_RxISR_16BIT;
4091 /* Enable the UART Data Register Not Empty interrupt */
4092 SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4095 else
4097 /* Clear RXNE interrupt flag */
4098 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4103 * @}
4106 #endif /* HAL_UART_MODULE_ENABLED */
4108 * @}
4112 * @}
4115 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/