1 /**
2 ******************************************************************************
3 * @file stm32h5xx_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
11 *
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2022 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ===============================================================================
26 ##### How to use this driver #####
27 ===============================================================================
28 [..]
29 The UART HAL driver can be used as follows:
30
31 (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
32 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
33 (++) Enable the USARTx interface clock.
34 (++) UART pins configuration:
35 (+++) Enable the clock for the UART GPIOs.
36 (+++) Configure these UART pins as alternate function pull-up.
37 (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
38 and HAL_UART_Receive_IT() APIs):
39 (+++) Configure the USARTx interrupt priority.
40 (+++) Enable the NVIC USART IRQ handle.
41 (++) UART interrupts handling:
42 -@@- The specific UART interrupts (Transmission complete interrupt,
43 RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts)
44 are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
45 inside the transmit and receive processes.
46 (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
47 and HAL_UART_Receive_DMA() APIs):
48 (+++) Declare a DMA handle structure for the Tx/Rx channel.
49 (+++) Enable the DMAx interface clock.
50 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
51 (+++) Configure the DMA Tx/Rx channel.
52 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
53 (+++) Configure the priority and enable the NVIC for the transfer complete
54 interrupt on the DMA Tx/Rx channel.
55
56 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware
57 flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
58
59 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
60 in the huart handle AdvancedInit structure.
61
62 (#) For the UART asynchronous mode, initialize the UART registers by calling
63 the HAL_UART_Init() API.
64
65 (#) For the UART Half duplex mode, initialize the UART registers by calling
66 the HAL_HalfDuplex_Init() API.
67
68 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
69 by calling the HAL_LIN_Init() API.
70
71 (#) For the UART Multiprocessor mode, initialize the UART registers
72 by calling the HAL_MultiProcessor_Init() API.
73
74 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
75 by calling the HAL_RS485Ex_Init() API.
76
77 [..]
78 (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
79 also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
80 calling the customized HAL_UART_MspInit() API.
81
82 ##### Callback registration #####
83 ==================================
84
85 [..]
86 The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
87 allows the user to configure dynamically the driver callbacks.
88
89 [..]
90 Use Function HAL_UART_RegisterCallback() to register a user callback.
91 Function HAL_UART_RegisterCallback() allows to register following callbacks:
92 (+) TxHalfCpltCallback : Tx Half Complete Callback.
93 (+) TxCpltCallback : Tx Complete Callback.
94 (+) RxHalfCpltCallback : Rx Half Complete Callback.
95 (+) RxCpltCallback : Rx Complete Callback.
96 (+) ErrorCallback : Error Callback.
97 (+) AbortCpltCallback : Abort Complete Callback.
98 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
99 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
100 (+) WakeupCallback : Wakeup Callback.
101 (+) RxFifoFullCallback : Rx Fifo Full Callback.
102 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
103 (+) MspInitCallback : UART MspInit.
104 (+) MspDeInitCallback : UART MspDeInit.
105 This function takes as parameters the HAL peripheral handle, the Callback ID
106 and a pointer to the user callback function.
107
108 [..]
109 Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
110 weak function.
111 HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
112 and the Callback ID.
113 This function allows to reset following callbacks:
114 (+) TxHalfCpltCallback : Tx Half Complete Callback.
115 (+) TxCpltCallback : Tx Complete Callback.
116 (+) RxHalfCpltCallback : Rx Half Complete Callback.
117 (+) RxCpltCallback : Rx Complete Callback.
118 (+) ErrorCallback : Error Callback.
119 (+) AbortCpltCallback : Abort Complete Callback.
120 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
121 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
122 (+) WakeupCallback : Wakeup Callback.
123 (+) RxFifoFullCallback : Rx Fifo Full Callback.
124 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
125 (+) MspInitCallback : UART MspInit.
126 (+) MspDeInitCallback : UART MspDeInit.
127
128 [..]
129 For specific callback RxEventCallback, use dedicated registration/reset functions:
130 respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
131
132 [..]
133 By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
134 all callbacks are set to the corresponding weak functions:
135 examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
136 Exception done for MspInit and MspDeInit functions that are respectively
137 reset to the legacy weak functions in the HAL_UART_Init()
138 and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
139 If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
140 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
141
142 [..]
143 Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
144 Exception done MspInit/MspDeInit that can be registered/unregistered
145 in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
146 MspInit/DeInit callbacks can be used during the Init/DeInit.
147 In that case first register the MspInit/MspDeInit user callbacks
148 using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
149 or HAL_UART_Init() function.
150
151 [..]
152 When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
153 not defined, the callback registration feature is not available
154 and weak callbacks are used.
155
156
157 @endverbatim
158 ******************************************************************************
159 */
160
161 /* Includes ------------------------------------------------------------------*/
162 #include "stm32h5xx_hal.h"
163
164 /** @addtogroup STM32H5xx_HAL_Driver
165 * @{
166 */
167
168 /** @defgroup UART UART
169 * @brief HAL UART module driver
170 * @{
171 */
172
173 #ifdef HAL_UART_MODULE_ENABLED
174
175 /* Private typedef -----------------------------------------------------------*/
176 /* Private define ------------------------------------------------------------*/
177 /** @defgroup UART_Private_Constants UART Private Constants
178 * @{
179 */
180 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \
181 USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
182
183 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \
184 USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
185
186 #define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */
187 #define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */
188
189 #define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */
190 #define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */
191 /**
192 * @}
193 */
194
195 /* Private macros ------------------------------------------------------------*/
196 /* Private function prototypes -----------------------------------------------*/
197 /** @addtogroup UART_Private_Functions
198 * @{
199 */
200 static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
201 #ifdef HAL_DMA_MODULE_ENABLED
202 static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
203 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
204 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
205 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
206 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
207 static void UART_DMAError(DMA_HandleTypeDef *hdma);
208 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
209 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
210 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
211 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
212 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
213 #endif /* HAL_DMA_MODULE_ENABLED */
214 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
215 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
216 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
217 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
218 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
219 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
220 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
221 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
222 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
223 /**
224 * @}
225 */
226
227 /* Private variables ---------------------------------------------------------*/
228 /** @addtogroup UART_Private_variables
229 * @{
230 */
231 const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U};
232 /**
233 * @}
234 */
235
236 /* Exported Constants --------------------------------------------------------*/
237 /* Exported functions --------------------------------------------------------*/
238
239 /** @defgroup UART_Exported_Functions UART Exported Functions
240 * @{
241 */
242
243 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
244 * @brief Initialization and Configuration functions
245 *
246 @verbatim
247 ===============================================================================
248 ##### Initialization and Configuration functions #####
249 ===============================================================================
250 [..]
251 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
252 in asynchronous mode.
253 (+) For the asynchronous mode the parameters below can be configured:
254 (++) Baud Rate
255 (++) Word Length
256 (++) Stop Bit
257 (++) Parity: If the parity is enabled, then the MSB bit of the data written
258 in the data register is transmitted but is changed by the parity bit.
259 (++) Hardware flow control
260 (++) Receiver/transmitter modes
261 (++) Over Sampling Method
262 (++) One-Bit Sampling Method
263 (+) For the asynchronous mode, the following advanced features can be configured as well:
264 (++) TX and/or RX pin level inversion
265 (++) data logical level inversion
266 (++) RX and TX pins swap
267 (++) RX overrun detection disabling
268 (++) DMA disabling on RX error
269 (++) MSB first on communication line
270 (++) auto Baud rate detection
271 [..]
272 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
273 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
274 and UART multiprocessor mode configuration procedures (details for the procedures
275 are available in reference manual).
276
277 @endverbatim
278
279 Depending on the frame length defined by the M1 and M0 bits (7-bit,
280 8-bit or 9-bit), the possible UART formats are listed in the
281 following table.
282
283 Table 1. UART frame format.
284 +-----------------------------------------------------------------------+
285 | M1 bit | M0 bit | PCE bit | UART frame |
286 |---------|---------|-----------|---------------------------------------|
287 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
288 |---------|---------|-----------|---------------------------------------|
289 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
290 |---------|---------|-----------|---------------------------------------|
291 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
292 |---------|---------|-----------|---------------------------------------|
293 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
294 |---------|---------|-----------|---------------------------------------|
295 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
296 |---------|---------|-----------|---------------------------------------|
297 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
298 +-----------------------------------------------------------------------+
299
300 * @{
301 */
302
303 /**
304 * @brief Initialize the UART mode according to the specified
305 * parameters in the UART_InitTypeDef and initialize the associated handle.
306 * @param huart UART handle.
307 * @retval HAL status
308 */
HAL_UART_Init(UART_HandleTypeDef * huart)309 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
310 {
311 /* Check the UART handle allocation */
312 if (huart == NULL)
313 {
314 return HAL_ERROR;
315 }
316
317 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
318 {
319 /* Check the parameters */
320 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
321 }
322 else
323 {
324 /* Check the parameters */
325 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
326 }
327
328 if (huart->gState == HAL_UART_STATE_RESET)
329 {
330 /* Allocate lock resource and initialize it */
331 huart->Lock = HAL_UNLOCKED;
332
333 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
334 UART_InitCallbacksToDefault(huart);
335
336 if (huart->MspInitCallback == NULL)
337 {
338 huart->MspInitCallback = HAL_UART_MspInit;
339 }
340
341 /* Init the low level hardware */
342 huart->MspInitCallback(huart);
343 #else
344 /* Init the low level hardware : GPIO, CLOCK */
345 HAL_UART_MspInit(huart);
346 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
347 }
348
349 huart->gState = HAL_UART_STATE_BUSY;
350
351 __HAL_UART_DISABLE(huart);
352
353 /* Perform advanced settings configuration */
354 /* For some items, configuration requires to be done prior TE and RE bits are set */
355 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
356 {
357 UART_AdvFeatureConfig(huart);
358 }
359
360 /* Set the UART Communication parameters */
361 if (UART_SetConfig(huart) == HAL_ERROR)
362 {
363 return HAL_ERROR;
364 }
365
366 /* In asynchronous mode, the following bits must be kept cleared:
367 - LINEN and CLKEN bits in the USART_CR2 register,
368 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
369 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
370 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
371
372 __HAL_UART_ENABLE(huart);
373
374 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
375 return (UART_CheckIdleState(huart));
376 }
377
378 /**
379 * @brief Initialize the half-duplex mode according to the specified
380 * parameters in the UART_InitTypeDef and creates the associated handle.
381 * @param huart UART handle.
382 * @retval HAL status
383 */
HAL_HalfDuplex_Init(UART_HandleTypeDef * huart)384 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
385 {
386 /* Check the UART handle allocation */
387 if (huart == NULL)
388 {
389 return HAL_ERROR;
390 }
391
392 /* Check UART instance */
393 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
394
395 if (huart->gState == HAL_UART_STATE_RESET)
396 {
397 /* Allocate lock resource and initialize it */
398 huart->Lock = HAL_UNLOCKED;
399
400 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
401 UART_InitCallbacksToDefault(huart);
402
403 if (huart->MspInitCallback == NULL)
404 {
405 huart->MspInitCallback = HAL_UART_MspInit;
406 }
407
408 /* Init the low level hardware */
409 huart->MspInitCallback(huart);
410 #else
411 /* Init the low level hardware : GPIO, CLOCK */
412 HAL_UART_MspInit(huart);
413 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
414 }
415
416 huart->gState = HAL_UART_STATE_BUSY;
417
418 __HAL_UART_DISABLE(huart);
419
420 /* Perform advanced settings configuration */
421 /* For some items, configuration requires to be done prior TE and RE bits are set */
422 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
423 {
424 UART_AdvFeatureConfig(huart);
425 }
426
427 /* Set the UART Communication parameters */
428 if (UART_SetConfig(huart) == HAL_ERROR)
429 {
430 return HAL_ERROR;
431 }
432
433 /* In half-duplex mode, the following bits must be kept cleared:
434 - LINEN and CLKEN bits in the USART_CR2 register,
435 - SCEN and IREN bits in the USART_CR3 register.*/
436 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
437 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
438
439 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
440 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
441
442 __HAL_UART_ENABLE(huart);
443
444 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
445 return (UART_CheckIdleState(huart));
446 }
447
448
449 /**
450 * @brief Initialize the LIN mode according to the specified
451 * parameters in the UART_InitTypeDef and creates the associated handle.
452 * @param huart UART handle.
453 * @param BreakDetectLength Specifies the LIN break detection length.
454 * This parameter can be one of the following values:
455 * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
456 * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
457 * @retval HAL status
458 */
HAL_LIN_Init(UART_HandleTypeDef * huart,uint32_t BreakDetectLength)459 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
460 {
461 /* Check the UART handle allocation */
462 if (huart == NULL)
463 {
464 return HAL_ERROR;
465 }
466
467 /* Check the LIN UART instance */
468 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
469 /* Check the Break detection length parameter */
470 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
471
472 /* LIN mode limited to 16-bit oversampling only */
473 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
474 {
475 return HAL_ERROR;
476 }
477 /* LIN mode limited to 8-bit data length */
478 if (huart->Init.WordLength != UART_WORDLENGTH_8B)
479 {
480 return HAL_ERROR;
481 }
482
483 if (huart->gState == HAL_UART_STATE_RESET)
484 {
485 /* Allocate lock resource and initialize it */
486 huart->Lock = HAL_UNLOCKED;
487
488 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
489 UART_InitCallbacksToDefault(huart);
490
491 if (huart->MspInitCallback == NULL)
492 {
493 huart->MspInitCallback = HAL_UART_MspInit;
494 }
495
496 /* Init the low level hardware */
497 huart->MspInitCallback(huart);
498 #else
499 /* Init the low level hardware : GPIO, CLOCK */
500 HAL_UART_MspInit(huart);
501 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
502 }
503
504 huart->gState = HAL_UART_STATE_BUSY;
505
506 __HAL_UART_DISABLE(huart);
507
508 /* Perform advanced settings configuration */
509 /* For some items, configuration requires to be done prior TE and RE bits are set */
510 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
511 {
512 UART_AdvFeatureConfig(huart);
513 }
514
515 /* Set the UART Communication parameters */
516 if (UART_SetConfig(huart) == HAL_ERROR)
517 {
518 return HAL_ERROR;
519 }
520
521 /* In LIN mode, the following bits must be kept cleared:
522 - LINEN and CLKEN bits in the USART_CR2 register,
523 - SCEN and IREN bits in the USART_CR3 register.*/
524 CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
525 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
526
527 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
528 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
529
530 /* Set the USART LIN Break detection length. */
531 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
532
533 __HAL_UART_ENABLE(huart);
534
535 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
536 return (UART_CheckIdleState(huart));
537 }
538
539
540 /**
541 * @brief Initialize the multiprocessor mode according to the specified
542 * parameters in the UART_InitTypeDef and initialize the associated handle.
543 * @param huart UART handle.
544 * @param Address UART node address (4-, 6-, 7- or 8-bit long).
545 * @param WakeUpMethod Specifies the UART wakeup method.
546 * This parameter can be one of the following values:
547 * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
548 * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
549 * @note If the user resorts to idle line detection wake up, the Address parameter
550 * is useless and ignored by the initialization function.
551 * @note If the user resorts to address mark wake up, the address length detection
552 * is configured by default to 4 bits only. For the UART to be able to
553 * manage 6-, 7- or 8-bit long addresses detection, the API
554 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
555 * HAL_MultiProcessor_Init().
556 * @retval HAL status
557 */
HAL_MultiProcessor_Init(UART_HandleTypeDef * huart,uint8_t Address,uint32_t WakeUpMethod)558 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
559 {
560 /* Check the UART handle allocation */
561 if (huart == NULL)
562 {
563 return HAL_ERROR;
564 }
565
566 /* Check the wake up method parameter */
567 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
568
569 if (huart->gState == HAL_UART_STATE_RESET)
570 {
571 /* Allocate lock resource and initialize it */
572 huart->Lock = HAL_UNLOCKED;
573
574 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
575 UART_InitCallbacksToDefault(huart);
576
577 if (huart->MspInitCallback == NULL)
578 {
579 huart->MspInitCallback = HAL_UART_MspInit;
580 }
581
582 /* Init the low level hardware */
583 huart->MspInitCallback(huart);
584 #else
585 /* Init the low level hardware : GPIO, CLOCK */
586 HAL_UART_MspInit(huart);
587 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
588 }
589
590 huart->gState = HAL_UART_STATE_BUSY;
591
592 __HAL_UART_DISABLE(huart);
593
594 /* Perform advanced settings configuration */
595 /* For some items, configuration requires to be done prior TE and RE bits are set */
596 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
597 {
598 UART_AdvFeatureConfig(huart);
599 }
600
601 /* Set the UART Communication parameters */
602 if (UART_SetConfig(huart) == HAL_ERROR)
603 {
604 return HAL_ERROR;
605 }
606
607 /* In multiprocessor mode, the following bits must be kept cleared:
608 - LINEN and CLKEN bits in the USART_CR2 register,
609 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
610 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
611 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
612
613 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
614 {
615 /* If address mark wake up method is chosen, set the USART address node */
616 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
617 }
618
619 /* Set the wake up method by setting the WAKE bit in the CR1 register */
620 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
621
622 __HAL_UART_ENABLE(huart);
623
624 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
625 return (UART_CheckIdleState(huart));
626 }
627
628
629 /**
630 * @brief DeInitialize the UART peripheral.
631 * @param huart UART handle.
632 * @retval HAL status
633 */
HAL_UART_DeInit(UART_HandleTypeDef * huart)634 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
635 {
636 /* Check the UART handle allocation */
637 if (huart == NULL)
638 {
639 return HAL_ERROR;
640 }
641
642 /* Check the parameters */
643 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
644
645 huart->gState = HAL_UART_STATE_BUSY;
646
647 __HAL_UART_DISABLE(huart);
648
649 huart->Instance->CR1 = 0x0U;
650 huart->Instance->CR2 = 0x0U;
651 huart->Instance->CR3 = 0x0U;
652
653 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
654 if (huart->MspDeInitCallback == NULL)
655 {
656 huart->MspDeInitCallback = HAL_UART_MspDeInit;
657 }
658 /* DeInit the low level hardware */
659 huart->MspDeInitCallback(huart);
660 #else
661 /* DeInit the low level hardware */
662 HAL_UART_MspDeInit(huart);
663 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
664
665 huart->ErrorCode = HAL_UART_ERROR_NONE;
666 huart->gState = HAL_UART_STATE_RESET;
667 huart->RxState = HAL_UART_STATE_RESET;
668 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
669 huart->RxEventType = HAL_UART_RXEVENT_TC;
670
671 __HAL_UNLOCK(huart);
672
673 return HAL_OK;
674 }
675
676 /**
677 * @brief Initialize the UART MSP.
678 * @param huart UART handle.
679 * @retval None
680 */
HAL_UART_MspInit(UART_HandleTypeDef * huart)681 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
682 {
683 /* Prevent unused argument(s) compilation warning */
684 UNUSED(huart);
685
686 /* NOTE : This function should not be modified, when the callback is needed,
687 the HAL_UART_MspInit can be implemented in the user file
688 */
689 }
690
691 /**
692 * @brief DeInitialize the UART MSP.
693 * @param huart UART handle.
694 * @retval None
695 */
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)696 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
697 {
698 /* Prevent unused argument(s) compilation warning */
699 UNUSED(huart);
700
701 /* NOTE : This function should not be modified, when the callback is needed,
702 the HAL_UART_MspDeInit can be implemented in the user file
703 */
704 }
705
706 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
707 /**
708 * @brief Register a User UART Callback
709 * To be used to override the weak predefined callback
710 * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
711 * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to register
712 * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
713 * @param huart uart handle
714 * @param CallbackID ID of the callback to be registered
715 * This parameter can be one of the following values:
716 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
717 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
718 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
719 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
720 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
721 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
722 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
723 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
724 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
725 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
726 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
727 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
728 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
729 * @param pCallback pointer to the Callback function
730 * @retval HAL status
731 */
HAL_UART_RegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID,pUART_CallbackTypeDef pCallback)732 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
733 pUART_CallbackTypeDef pCallback)
734 {
735 HAL_StatusTypeDef status = HAL_OK;
736
737 if (pCallback == NULL)
738 {
739 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
740
741 return HAL_ERROR;
742 }
743
744 if (huart->gState == HAL_UART_STATE_READY)
745 {
746 switch (CallbackID)
747 {
748 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
749 huart->TxHalfCpltCallback = pCallback;
750 break;
751
752 case HAL_UART_TX_COMPLETE_CB_ID :
753 huart->TxCpltCallback = pCallback;
754 break;
755
756 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
757 huart->RxHalfCpltCallback = pCallback;
758 break;
759
760 case HAL_UART_RX_COMPLETE_CB_ID :
761 huart->RxCpltCallback = pCallback;
762 break;
763
764 case HAL_UART_ERROR_CB_ID :
765 huart->ErrorCallback = pCallback;
766 break;
767
768 case HAL_UART_ABORT_COMPLETE_CB_ID :
769 huart->AbortCpltCallback = pCallback;
770 break;
771
772 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
773 huart->AbortTransmitCpltCallback = pCallback;
774 break;
775
776 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
777 huart->AbortReceiveCpltCallback = pCallback;
778 break;
779
780 case HAL_UART_WAKEUP_CB_ID :
781 huart->WakeupCallback = pCallback;
782 break;
783
784 case HAL_UART_RX_FIFO_FULL_CB_ID :
785 huart->RxFifoFullCallback = pCallback;
786 break;
787
788 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
789 huart->TxFifoEmptyCallback = pCallback;
790 break;
791
792 case HAL_UART_MSPINIT_CB_ID :
793 huart->MspInitCallback = pCallback;
794 break;
795
796 case HAL_UART_MSPDEINIT_CB_ID :
797 huart->MspDeInitCallback = pCallback;
798 break;
799
800 default :
801 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
802
803 status = HAL_ERROR;
804 break;
805 }
806 }
807 else if (huart->gState == HAL_UART_STATE_RESET)
808 {
809 switch (CallbackID)
810 {
811 case HAL_UART_MSPINIT_CB_ID :
812 huart->MspInitCallback = pCallback;
813 break;
814
815 case HAL_UART_MSPDEINIT_CB_ID :
816 huart->MspDeInitCallback = pCallback;
817 break;
818
819 default :
820 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
821
822 status = HAL_ERROR;
823 break;
824 }
825 }
826 else
827 {
828 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
829
830 status = HAL_ERROR;
831 }
832
833 return status;
834 }
835
836 /**
837 * @brief Unregister an UART Callback
838 * UART callaback is redirected to the weak predefined callback
839 * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
840 * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to un-register
841 * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
842 * @param huart uart handle
843 * @param CallbackID ID of the callback to be unregistered
844 * This parameter can be one of the following values:
845 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
846 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
847 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
848 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
849 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
850 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
851 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
852 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
853 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
854 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
855 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
856 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
857 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
858 * @retval HAL status
859 */
HAL_UART_UnRegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID)860 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
861 {
862 HAL_StatusTypeDef status = HAL_OK;
863
864 if (HAL_UART_STATE_READY == huart->gState)
865 {
866 switch (CallbackID)
867 {
868 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
869 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
870 break;
871
872 case HAL_UART_TX_COMPLETE_CB_ID :
873 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
874 break;
875
876 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
877 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
878 break;
879
880 case HAL_UART_RX_COMPLETE_CB_ID :
881 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
882 break;
883
884 case HAL_UART_ERROR_CB_ID :
885 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
886 break;
887
888 case HAL_UART_ABORT_COMPLETE_CB_ID :
889 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
890 break;
891
892 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
893 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak
894 AbortTransmitCpltCallback */
895 break;
896
897 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
898 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak
899 AbortReceiveCpltCallback */
900 break;
901
902 case HAL_UART_WAKEUP_CB_ID :
903 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
904 break;
905
906 case HAL_UART_RX_FIFO_FULL_CB_ID :
907 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
908 break;
909
910 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
911 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
912 break;
913
914 case HAL_UART_MSPINIT_CB_ID :
915 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
916 break;
917
918 case HAL_UART_MSPDEINIT_CB_ID :
919 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
920 break;
921
922 default :
923 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
924
925 status = HAL_ERROR;
926 break;
927 }
928 }
929 else if (HAL_UART_STATE_RESET == huart->gState)
930 {
931 switch (CallbackID)
932 {
933 case HAL_UART_MSPINIT_CB_ID :
934 huart->MspInitCallback = HAL_UART_MspInit;
935 break;
936
937 case HAL_UART_MSPDEINIT_CB_ID :
938 huart->MspDeInitCallback = HAL_UART_MspDeInit;
939 break;
940
941 default :
942 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
943
944 status = HAL_ERROR;
945 break;
946 }
947 }
948 else
949 {
950 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
951
952 status = HAL_ERROR;
953 }
954
955 return status;
956 }
957
958 /**
959 * @brief Register a User UART Rx Event Callback
960 * To be used instead of the weak predefined callback
961 * @param huart Uart handle
962 * @param pCallback Pointer to the Rx Event Callback function
963 * @retval HAL status
964 */
HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef * huart,pUART_RxEventCallbackTypeDef pCallback)965 HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
966 {
967 HAL_StatusTypeDef status = HAL_OK;
968
969 if (pCallback == NULL)
970 {
971 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
972
973 return HAL_ERROR;
974 }
975
976 /* Process locked */
977 __HAL_LOCK(huart);
978
979 if (huart->gState == HAL_UART_STATE_READY)
980 {
981 huart->RxEventCallback = pCallback;
982 }
983 else
984 {
985 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
986
987 status = HAL_ERROR;
988 }
989
990 /* Release Lock */
991 __HAL_UNLOCK(huart);
992
993 return status;
994 }
995
996 /**
997 * @brief UnRegister the UART Rx Event Callback
998 * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
999 * @param huart Uart handle
1000 * @retval HAL status
1001 */
HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef * huart)1002 HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
1003 {
1004 HAL_StatusTypeDef status = HAL_OK;
1005
1006 /* Process locked */
1007 __HAL_LOCK(huart);
1008
1009 if (huart->gState == HAL_UART_STATE_READY)
1010 {
1011 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
1012 }
1013 else
1014 {
1015 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
1016
1017 status = HAL_ERROR;
1018 }
1019
1020 /* Release Lock */
1021 __HAL_UNLOCK(huart);
1022 return status;
1023 }
1024
1025 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1026
1027 /**
1028 * @}
1029 */
1030
1031 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
1032 * @brief UART Transmit/Receive functions
1033 *
1034 @verbatim
1035 ===============================================================================
1036 ##### IO operation functions #####
1037 ===============================================================================
1038 This subsection provides a set of functions allowing to manage the UART asynchronous
1039 and Half duplex data transfers.
1040
1041 (#) There are two mode of transfer:
1042 (+) Blocking mode: The communication is performed in polling mode.
1043 The HAL status of all data processing is returned by the same function
1044 after finishing transfer.
1045 (+) Non-Blocking mode: The communication is performed using Interrupts
1046 or DMA, These API's return the HAL status.
1047 The end of the data processing will be indicated through the
1048 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
1049 using DMA mode.
1050 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
1051 will be executed respectively at the end of the transmit or Receive process
1052 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
1053
1054 (#) Blocking mode API's are :
1055 (+) HAL_UART_Transmit()
1056 (+) HAL_UART_Receive()
1057
1058 (#) Non-Blocking mode API's with Interrupt are :
1059 (+) HAL_UART_Transmit_IT()
1060 (+) HAL_UART_Receive_IT()
1061 (+) HAL_UART_IRQHandler()
1062
1063 (#) Non-Blocking mode API's with DMA are :
1064 (+) HAL_UART_Transmit_DMA()
1065 (+) HAL_UART_Receive_DMA()
1066 (+) HAL_UART_DMAPause()
1067 (+) HAL_UART_DMAResume()
1068 (+) HAL_UART_DMAStop()
1069
1070 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
1071 (+) HAL_UART_TxHalfCpltCallback()
1072 (+) HAL_UART_TxCpltCallback()
1073 (+) HAL_UART_RxHalfCpltCallback()
1074 (+) HAL_UART_RxCpltCallback()
1075 (+) HAL_UART_ErrorCallback()
1076
1077 (#) Non-Blocking mode transfers could be aborted using Abort API's :
1078 (+) HAL_UART_Abort()
1079 (+) HAL_UART_AbortTransmit()
1080 (+) HAL_UART_AbortReceive()
1081 (+) HAL_UART_Abort_IT()
1082 (+) HAL_UART_AbortTransmit_IT()
1083 (+) HAL_UART_AbortReceive_IT()
1084
1085 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
1086 (+) HAL_UART_AbortCpltCallback()
1087 (+) HAL_UART_AbortTransmitCpltCallback()
1088 (+) HAL_UART_AbortReceiveCpltCallback()
1089
1090 (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced
1091 reception services:
1092 (+) HAL_UARTEx_RxEventCallback()
1093
1094 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1095 Errors are handled as follows :
1096 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1097 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
1098 in Interrupt mode reception .
1099 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
1100 to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1101 Transfer is kept ongoing on UART side.
1102 If user wants to abort it, Abort services should be called by user.
1103 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1104 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1105 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
1106 user callback is executed.
1107
1108 -@- In the Half duplex communication, it is forbidden to run the transmit
1109 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1110
1111 @endverbatim
1112 * @{
1113 */
1114
1115 /**
1116 * @brief Send an amount of data in blocking mode.
1117 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1118 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1119 * of u16 provided through pData.
1120 * @note When FIFO mode is enabled, writing a data in the TDR register adds one
1121 * data to the TXFIFO. Write operations to the TDR register are performed
1122 * when TXFNF flag is set. From hardware perspective, TXFNF flag and
1123 * TXE are mapped on the same bit-field.
1124 * @param huart UART handle.
1125 * @param pData Pointer to data buffer (u8 or u16 data elements).
1126 * @param Size Amount of data elements (u8 or u16) to be sent.
1127 * @param Timeout Timeout duration.
1128 * @retval HAL status
1129 */
HAL_UART_Transmit(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size,uint32_t Timeout)1130 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
1131 {
1132 const uint8_t *pdata8bits;
1133 const uint16_t *pdata16bits;
1134 uint32_t tickstart;
1135
1136 /* Check that a Tx process is not already ongoing */
1137 if (huart->gState == HAL_UART_STATE_READY)
1138 {
1139 if ((pData == NULL) || (Size == 0U))
1140 {
1141 return HAL_ERROR;
1142 }
1143
1144 /* Disable the UART DMA Tx request if enabled */
1145 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1146 {
1147 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1148 }
1149
1150 huart->ErrorCode = HAL_UART_ERROR_NONE;
1151 huart->gState = HAL_UART_STATE_BUSY_TX;
1152
1153 /* Init tickstart for timeout management */
1154 tickstart = HAL_GetTick();
1155
1156 huart->TxXferSize = Size;
1157 huart->TxXferCount = Size;
1158
1159 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1160 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1161 {
1162 pdata8bits = NULL;
1163 pdata16bits = (const uint16_t *) pData;
1164 }
1165 else
1166 {
1167 pdata8bits = pData;
1168 pdata16bits = NULL;
1169 }
1170
1171 while (huart->TxXferCount > 0U)
1172 {
1173 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1174 {
1175
1176 huart->gState = HAL_UART_STATE_READY;
1177
1178 return HAL_TIMEOUT;
1179 }
1180 if (pdata8bits == NULL)
1181 {
1182 huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
1183 pdata16bits++;
1184 }
1185 else
1186 {
1187 huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
1188 pdata8bits++;
1189 }
1190 huart->TxXferCount--;
1191 }
1192
1193 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1194 {
1195 huart->gState = HAL_UART_STATE_READY;
1196
1197 return HAL_TIMEOUT;
1198 }
1199
1200 /* At end of Tx process, restore huart->gState to Ready */
1201 huart->gState = HAL_UART_STATE_READY;
1202
1203 return HAL_OK;
1204 }
1205 else
1206 {
1207 return HAL_BUSY;
1208 }
1209 }
1210
1211 /**
1212 * @brief Receive an amount of data in blocking mode.
1213 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1214 * the received data is handled as a set of u16. In this case, Size must indicate the number
1215 * of u16 available through pData.
1216 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
1217 * is not empty. Read operations from the RDR register are performed when
1218 * RXFNE flag is set. From hardware perspective, RXFNE flag and
1219 * RXNE are mapped on the same bit-field.
1220 * @param huart UART handle.
1221 * @param pData Pointer to data buffer (u8 or u16 data elements).
1222 * @param Size Amount of data elements (u8 or u16) to be received.
1223 * @param Timeout Timeout duration.
1224 * @retval HAL status
1225 */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1226 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1227 {
1228 uint8_t *pdata8bits;
1229 uint16_t *pdata16bits;
1230 uint16_t uhMask;
1231 uint32_t tickstart;
1232
1233 /* Check that a Rx process is not already ongoing */
1234 if (huart->RxState == HAL_UART_STATE_READY)
1235 {
1236 if ((pData == NULL) || (Size == 0U))
1237 {
1238 return HAL_ERROR;
1239 }
1240
1241 /* Disable the UART DMA Rx request if enabled */
1242 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1243 {
1244 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1245 }
1246
1247 huart->ErrorCode = HAL_UART_ERROR_NONE;
1248 huart->RxState = HAL_UART_STATE_BUSY_RX;
1249 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1250
1251 /* Init tickstart for timeout management */
1252 tickstart = HAL_GetTick();
1253
1254 huart->RxXferSize = Size;
1255 huart->RxXferCount = Size;
1256
1257 /* Computation of UART mask to apply to RDR register */
1258 UART_MASK_COMPUTATION(huart);
1259 uhMask = huart->Mask;
1260
1261 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1262 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1263 {
1264 pdata8bits = NULL;
1265 pdata16bits = (uint16_t *) pData;
1266 }
1267 else
1268 {
1269 pdata8bits = pData;
1270 pdata16bits = NULL;
1271 }
1272
1273 /* as long as data have to be received */
1274 while (huart->RxXferCount > 0U)
1275 {
1276 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1277 {
1278 huart->RxState = HAL_UART_STATE_READY;
1279
1280 return HAL_TIMEOUT;
1281 }
1282 if (pdata8bits == NULL)
1283 {
1284 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
1285 pdata16bits++;
1286 }
1287 else
1288 {
1289 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1290 pdata8bits++;
1291 }
1292 huart->RxXferCount--;
1293 }
1294
1295 /* At end of Rx process, restore huart->RxState to Ready */
1296 huart->RxState = HAL_UART_STATE_READY;
1297
1298 return HAL_OK;
1299 }
1300 else
1301 {
1302 return HAL_BUSY;
1303 }
1304 }
1305
1306 /**
1307 * @brief Send an amount of data in interrupt mode.
1308 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1309 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1310 * of u16 provided through pData.
1311 * @param huart UART handle.
1312 * @param pData Pointer to data buffer (u8 or u16 data elements).
1313 * @param Size Amount of data elements (u8 or u16) to be sent.
1314 * @retval HAL status
1315 */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1316 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1317 {
1318 /* Check that a Tx process is not already ongoing */
1319 if (huart->gState == HAL_UART_STATE_READY)
1320 {
1321 if ((pData == NULL) || (Size == 0U))
1322 {
1323 return HAL_ERROR;
1324 }
1325
1326 /* Disable the UART DMA Tx request if enabled */
1327 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1328 {
1329 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1330 }
1331
1332 huart->pTxBuffPtr = pData;
1333 huart->TxXferSize = Size;
1334 huart->TxXferCount = Size;
1335 huart->TxISR = NULL;
1336
1337 huart->ErrorCode = HAL_UART_ERROR_NONE;
1338 huart->gState = HAL_UART_STATE_BUSY_TX;
1339
1340 /* Configure Tx interrupt processing */
1341 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1342 {
1343 /* Set the Tx ISR function pointer according to the data word length */
1344 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1345 {
1346 huart->TxISR = UART_TxISR_16BIT_FIFOEN;
1347 }
1348 else
1349 {
1350 huart->TxISR = UART_TxISR_8BIT_FIFOEN;
1351 }
1352
1353 /* Enable the TX FIFO threshold interrupt */
1354 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1355 }
1356 else
1357 {
1358 /* Set the Tx ISR function pointer according to the data word length */
1359 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1360 {
1361 huart->TxISR = UART_TxISR_16BIT;
1362 }
1363 else
1364 {
1365 huart->TxISR = UART_TxISR_8BIT;
1366 }
1367
1368 /* Enable the Transmit Data Register Empty interrupt */
1369 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1370 }
1371
1372 return HAL_OK;
1373 }
1374 else
1375 {
1376 return HAL_BUSY;
1377 }
1378 }
1379
1380 /**
1381 * @brief Receive an amount of data in interrupt mode.
1382 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1383 * the received data is handled as a set of u16. In this case, Size must indicate the number
1384 * of u16 available through pData.
1385 * @param huart UART handle.
1386 * @param pData Pointer to data buffer (u8 or u16 data elements).
1387 * @param Size Amount of data elements (u8 or u16) to be received.
1388 * @retval HAL status
1389 */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1390 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1391 {
1392 /* Check that a Rx process is not already ongoing */
1393 if (huart->RxState == HAL_UART_STATE_READY)
1394 {
1395 if ((pData == NULL) || (Size == 0U))
1396 {
1397 return HAL_ERROR;
1398 }
1399
1400 /* Set Reception type to Standard reception */
1401 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1402
1403 /* Disable the UART DMA Rx request if enabled */
1404 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1405 {
1406 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1407 }
1408
1409 if (!(IS_LPUART_INSTANCE(huart->Instance)))
1410 {
1411 /* Check that USART RTOEN bit is set */
1412 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
1413 {
1414 /* Enable the UART Receiver Timeout Interrupt */
1415 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
1416 }
1417 }
1418
1419 return (UART_Start_Receive_IT(huart, pData, Size));
1420 }
1421 else
1422 {
1423 return HAL_BUSY;
1424 }
1425 }
1426
1427 #ifdef HAL_DMA_MODULE_ENABLED
1428 /**
1429 * @brief Send an amount of data in DMA mode.
1430 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1431 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1432 * of u16 provided through pData.
1433 * @param huart UART handle.
1434 * @param pData Pointer to data buffer (u8 or u16 data elements).
1435 * @param Size Amount of data elements (u8 or u16) to be sent.
1436 * @retval HAL status
1437 */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1438 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1439 {
1440 HAL_StatusTypeDef status;
1441 uint16_t nbByte = Size;
1442
1443 /* Check that a Tx process is not already ongoing */
1444 if (huart->gState == HAL_UART_STATE_READY)
1445 {
1446 if ((pData == NULL) || (Size == 0U))
1447 {
1448 return HAL_ERROR;
1449 }
1450
1451 huart->pTxBuffPtr = pData;
1452 huart->TxXferSize = Size;
1453 huart->TxXferCount = Size;
1454
1455 huart->ErrorCode = HAL_UART_ERROR_NONE;
1456 huart->gState = HAL_UART_STATE_BUSY_TX;
1457
1458 if (huart->hdmatx != NULL)
1459 {
1460 /* Set the UART DMA transfer complete callback */
1461 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1462
1463 /* Set the UART DMA Half transfer complete callback */
1464 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1465
1466 /* Set the DMA error callback */
1467 huart->hdmatx->XferErrorCallback = UART_DMAError;
1468
1469 /* Set the DMA abort callback */
1470 huart->hdmatx->XferAbortCallback = NULL;
1471
1472 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1473 should be aligned on a u16 frontier, so nbByte should be equal to Size * 2 */
1474 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1475 {
1476 nbByte = Size * 2U;
1477 }
1478
1479 /* Check linked list mode */
1480 if ((huart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1481 {
1482 if ((huart->hdmatx->LinkedListQueue != NULL) && (huart->hdmatx->LinkedListQueue->Head != NULL))
1483 {
1484 /* Set DMA data size */
1485 huart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1486
1487 /* Set DMA source address */
1488 huart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)huart->pTxBuffPtr;
1489
1490 /* Set DMA destination address */
1491 huart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1492 (uint32_t)&huart->Instance->TDR;
1493
1494 /* Enable the UART transmit DMA channel */
1495 status = HAL_DMAEx_List_Start_IT(huart->hdmatx);
1496 }
1497 else
1498 {
1499 /* Update status */
1500 status = HAL_ERROR;
1501 }
1502 }
1503 else
1504 {
1505 /* Enable the UART transmit DMA channel */
1506 status = HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, nbByte);
1507 }
1508
1509 if (status != HAL_OK)
1510 {
1511 /* Set error code to DMA */
1512 huart->ErrorCode = HAL_UART_ERROR_DMA;
1513
1514 /* Restore huart->gState to ready */
1515 huart->gState = HAL_UART_STATE_READY;
1516
1517 return HAL_ERROR;
1518 }
1519 }
1520 /* Clear the TC flag in the ICR register */
1521 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1522
1523 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1524 in the UART CR3 register */
1525 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1526
1527 return HAL_OK;
1528 }
1529 else
1530 {
1531 return HAL_BUSY;
1532 }
1533 }
1534
1535 /**
1536 * @brief Receive an amount of data in DMA mode.
1537 * @note When the UART parity is enabled (PCE = 1), the received data contain
1538 * the parity bit (MSB position).
1539 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1540 * the received data is handled as a set of u16. In this case, Size must indicate the number
1541 * of u16 available through pData.
1542 * @param huart UART handle.
1543 * @param pData Pointer to data buffer (u8 or u16 data elements).
1544 * @param Size Amount of data elements (u8 or u16) to be received.
1545 * @retval HAL status
1546 */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1547 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1548 {
1549 /* Check that a Rx process is not already ongoing */
1550 if (huart->RxState == HAL_UART_STATE_READY)
1551 {
1552 if ((pData == NULL) || (Size == 0U))
1553 {
1554 return HAL_ERROR;
1555 }
1556
1557 /* Set Reception type to Standard reception */
1558 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1559
1560 if (!(IS_LPUART_INSTANCE(huart->Instance)))
1561 {
1562 /* Check that USART RTOEN bit is set */
1563 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
1564 {
1565 /* Enable the UART Receiver Timeout Interrupt */
1566 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
1567 }
1568 }
1569
1570 return (UART_Start_Receive_DMA(huart, pData, Size));
1571 }
1572 else
1573 {
1574 return HAL_BUSY;
1575 }
1576 }
1577
1578 /**
1579 * @brief Pause the DMA Transfer.
1580 * @param huart UART handle.
1581 * @retval HAL status
1582 */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1583 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1584 {
1585 const HAL_UART_StateTypeDef gstate = huart->gState;
1586 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1587
1588 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1589 (gstate == HAL_UART_STATE_BUSY_TX))
1590 {
1591 /* Suspend the UART DMA Tx channel : use blocking DMA Suspend API (no callback) */
1592 if (huart->hdmatx != NULL)
1593 {
1594 /* Set the UART DMA Suspend callback to Null.
1595 No call back execution at end of DMA Suspend procedure */
1596 huart->hdmatx->XferSuspendCallback = NULL;
1597
1598 if (HAL_DMAEx_Suspend(huart->hdmatx) != HAL_OK)
1599 {
1600 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1601 {
1602 /* Set error code to DMA */
1603 huart->ErrorCode = HAL_UART_ERROR_DMA;
1604
1605 return HAL_TIMEOUT;
1606 }
1607 }
1608 }
1609 }
1610 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1611 (rxstate == HAL_UART_STATE_BUSY_RX))
1612 {
1613 /* Suspend the UART DMA Rx channel : use blocking DMA Suspend API (no callback) */
1614 if (huart->hdmarx != NULL)
1615 {
1616 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1617 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1618 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1619
1620 /* Set the UART DMA Suspend callback to Null.
1621 No call back execution at end of DMA Suspend procedure */
1622 huart->hdmarx->XferSuspendCallback = NULL;
1623
1624 if (HAL_DMAEx_Suspend(huart->hdmarx) != HAL_OK)
1625 {
1626 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1627 {
1628 /* Set error code to DMA */
1629 huart->ErrorCode = HAL_UART_ERROR_DMA;
1630
1631 return HAL_TIMEOUT;
1632 }
1633 }
1634 }
1635 }
1636
1637 return HAL_OK;
1638 }
1639
1640 /**
1641 * @brief Resume the DMA Transfer.
1642 * @param huart UART handle.
1643 * @retval HAL status
1644 */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1645 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1646 {
1647 if (huart->gState == HAL_UART_STATE_BUSY_TX)
1648 {
1649 /* Resume the UART DMA Tx channel */
1650 if (huart->hdmatx != NULL)
1651 {
1652 if (HAL_DMAEx_Resume(huart->hdmatx) != HAL_OK)
1653 {
1654 /* Set error code to DMA */
1655 huart->ErrorCode = HAL_UART_ERROR_DMA;
1656
1657 return HAL_ERROR;
1658 }
1659 }
1660 }
1661 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1662 {
1663 /* Clear the Overrun flag before resuming the Rx transfer */
1664 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1665
1666 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1667 if (huart->Init.Parity != UART_PARITY_NONE)
1668 {
1669 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1670 }
1671 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1672
1673 /* Resume the UART DMA Rx channel */
1674 if (huart->hdmarx != NULL)
1675 {
1676 if (HAL_DMAEx_Resume(huart->hdmarx) != HAL_OK)
1677 {
1678 /* Set error code to DMA */
1679 huart->ErrorCode = HAL_UART_ERROR_DMA;
1680
1681 return HAL_ERROR;
1682 }
1683 }
1684 }
1685
1686 return HAL_OK;
1687 }
1688
1689 /**
1690 * @brief Stop the DMA Transfer.
1691 * @param huart UART handle.
1692 * @retval HAL status
1693 */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1694 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1695 {
1696 /* The Lock is not implemented on this API to allow the user application
1697 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1698 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1699 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1700 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1701 the stream and the corresponding call back is executed. */
1702
1703 const HAL_UART_StateTypeDef gstate = huart->gState;
1704 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1705
1706 /* Stop UART DMA Tx request if ongoing */
1707 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1708 (gstate == HAL_UART_STATE_BUSY_TX))
1709 {
1710 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1711
1712 /* Abort the UART DMA Tx channel */
1713 if (huart->hdmatx != NULL)
1714 {
1715 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1716 {
1717 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1718 {
1719 /* Set error code to DMA */
1720 huart->ErrorCode = HAL_UART_ERROR_DMA;
1721
1722 return HAL_TIMEOUT;
1723 }
1724 }
1725 }
1726
1727 UART_EndTxTransfer(huart);
1728 }
1729
1730 /* Stop UART DMA Rx request if ongoing */
1731 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1732 (rxstate == HAL_UART_STATE_BUSY_RX))
1733 {
1734 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1735
1736 /* Abort the UART DMA Rx channel */
1737 if (huart->hdmarx != NULL)
1738 {
1739 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1740 {
1741 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1742 {
1743 /* Set error code to DMA */
1744 huart->ErrorCode = HAL_UART_ERROR_DMA;
1745
1746 return HAL_TIMEOUT;
1747 }
1748 }
1749 }
1750
1751 UART_EndRxTransfer(huart);
1752 }
1753
1754 return HAL_OK;
1755 }
1756 #endif /* HAL_DMA_MODULE_ENABLED */
1757
1758 /**
1759 * @brief Abort ongoing transfers (blocking mode).
1760 * @param huart UART handle.
1761 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1762 * This procedure performs following operations :
1763 * - Disable UART Interrupts (Tx and Rx)
1764 * - Disable the DMA transfer in the peripheral register (if enabled)
1765 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1766 * - Set handle State to READY
1767 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1768 * @retval HAL status
1769 */
HAL_UART_Abort(UART_HandleTypeDef * huart)1770 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1771 {
1772 /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
1773 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE |
1774 USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1775 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
1776
1777 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1778 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1779 {
1780 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1781 }
1782
1783 #ifdef HAL_DMA_MODULE_ENABLED
1784 /* Abort the UART DMA Tx channel if enabled */
1785 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1786 {
1787 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1788 if (huart->hdmatx != NULL)
1789 {
1790 /* Set the UART DMA Abort callback to Null.
1791 No call back execution at end of DMA abort procedure */
1792 huart->hdmatx->XferAbortCallback = NULL;
1793
1794 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1795 {
1796 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1797 {
1798 /* Set error code to DMA */
1799 huart->ErrorCode = HAL_UART_ERROR_DMA;
1800
1801 return HAL_TIMEOUT;
1802 }
1803 }
1804 }
1805 }
1806
1807 /* Abort the UART DMA Rx channel if enabled */
1808 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1809 {
1810 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1811 if (huart->hdmarx != NULL)
1812 {
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;
1816
1817 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1818 {
1819 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1820 {
1821 /* Set error code to DMA */
1822 huart->ErrorCode = HAL_UART_ERROR_DMA;
1823
1824 return HAL_TIMEOUT;
1825 }
1826 }
1827 }
1828 }
1829 #endif /* HAL_DMA_MODULE_ENABLED */
1830
1831 /* Reset Tx and Rx transfer counters */
1832 huart->TxXferCount = 0U;
1833 huart->RxXferCount = 0U;
1834
1835 /* Clear the Error flags in the ICR register */
1836 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1837
1838 /* Flush the whole TX FIFO (if needed) */
1839 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1840 {
1841 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1842 }
1843
1844 /* Discard the received data */
1845 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1846
1847 /* Restore huart->gState and huart->RxState to Ready */
1848 huart->gState = HAL_UART_STATE_READY;
1849 huart->RxState = HAL_UART_STATE_READY;
1850 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1851
1852 huart->ErrorCode = HAL_UART_ERROR_NONE;
1853
1854 return HAL_OK;
1855 }
1856
1857 /**
1858 * @brief Abort ongoing Transmit transfer (blocking mode).
1859 * @param huart UART handle.
1860 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1861 * This procedure performs following operations :
1862 * - Disable UART Interrupts (Tx)
1863 * - Disable the DMA transfer in the peripheral register (if enabled)
1864 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1865 * - Set handle State to READY
1866 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1867 * @retval HAL status
1868 */
HAL_UART_AbortTransmit(UART_HandleTypeDef * huart)1869 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1870 {
1871 /* Disable TCIE, TXEIE and TXFTIE interrupts */
1872 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1873 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1874
1875 #ifdef HAL_DMA_MODULE_ENABLED
1876 /* Abort the UART DMA Tx channel if enabled */
1877 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1878 {
1879 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1880 if (huart->hdmatx != NULL)
1881 {
1882 /* Set the UART DMA Abort callback to Null.
1883 No call back execution at end of DMA abort procedure */
1884 huart->hdmatx->XferAbortCallback = NULL;
1885
1886 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1887 {
1888 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1889 {
1890 /* Set error code to DMA */
1891 huart->ErrorCode = HAL_UART_ERROR_DMA;
1892
1893 return HAL_TIMEOUT;
1894 }
1895 }
1896 }
1897 }
1898 #endif /* HAL_DMA_MODULE_ENABLED */
1899
1900 /* Reset Tx transfer counter */
1901 huart->TxXferCount = 0U;
1902
1903 /* Flush the whole TX FIFO (if needed) */
1904 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1905 {
1906 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1907 }
1908
1909 /* Restore huart->gState to Ready */
1910 huart->gState = HAL_UART_STATE_READY;
1911
1912 return HAL_OK;
1913 }
1914
1915 /**
1916 * @brief Abort ongoing Receive transfer (blocking mode).
1917 * @param huart UART handle.
1918 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1919 * This procedure performs following operations :
1920 * - Disable UART Interrupts (Rx)
1921 * - Disable the DMA transfer in the peripheral register (if enabled)
1922 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1923 * - Set handle State to READY
1924 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1925 * @retval HAL status
1926 */
HAL_UART_AbortReceive(UART_HandleTypeDef * huart)1927 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1928 {
1929 /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
1930 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
1931 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
1932
1933 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1934 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1935 {
1936 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1937 }
1938
1939 #ifdef HAL_DMA_MODULE_ENABLED
1940 /* Abort the UART DMA Rx channel if enabled */
1941 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1942 {
1943 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1944 if (huart->hdmarx != NULL)
1945 {
1946 /* Set the UART DMA Abort callback to Null.
1947 No call back execution at end of DMA abort procedure */
1948 huart->hdmarx->XferAbortCallback = NULL;
1949
1950 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1951 {
1952 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1953 {
1954 /* Set error code to DMA */
1955 huart->ErrorCode = HAL_UART_ERROR_DMA;
1956
1957 return HAL_TIMEOUT;
1958 }
1959 }
1960 }
1961 }
1962 #endif /* HAL_DMA_MODULE_ENABLED */
1963
1964 /* Reset Rx transfer counter */
1965 huart->RxXferCount = 0U;
1966
1967 /* Clear the Error flags in the ICR register */
1968 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1969
1970 /* Discard the received data */
1971 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1972
1973 /* Restore huart->RxState to Ready */
1974 huart->RxState = HAL_UART_STATE_READY;
1975 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1976
1977 return HAL_OK;
1978 }
1979
1980 /**
1981 * @brief Abort ongoing transfers (Interrupt mode).
1982 * @param huart UART handle.
1983 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1984 * This procedure performs following operations :
1985 * - Disable UART Interrupts (Tx and Rx)
1986 * - Disable the DMA transfer in the peripheral register (if enabled)
1987 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1988 * - Set handle State to READY
1989 * - At abort completion, call user abort complete callback
1990 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1991 * considered as completed only when user abort complete callback is executed (not when exiting function).
1992 * @retval HAL status
1993 */
HAL_UART_Abort_IT(UART_HandleTypeDef * huart)1994 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1995 {
1996 uint32_t abortcplt = 1U;
1997
1998 /* Disable interrupts */
1999 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE |
2000 USART_CR1_TXEIE_TXFNFIE));
2001 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2002
2003 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
2004 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2005 {
2006 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
2007 }
2008
2009 #ifdef HAL_DMA_MODULE_ENABLED
2010 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
2011 before any call to DMA Abort functions */
2012 /* DMA Tx Handle is valid */
2013 if (huart->hdmatx != NULL)
2014 {
2015 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
2016 Otherwise, set it to NULL */
2017 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2018 {
2019 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
2020 }
2021 else
2022 {
2023 huart->hdmatx->XferAbortCallback = NULL;
2024 }
2025 }
2026 /* DMA Rx Handle is valid */
2027 if (huart->hdmarx != NULL)
2028 {
2029 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
2030 Otherwise, set it to NULL */
2031 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2032 {
2033 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
2034 }
2035 else
2036 {
2037 huart->hdmarx->XferAbortCallback = NULL;
2038 }
2039 }
2040
2041 /* Abort the UART DMA Tx channel if enabled */
2042 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2043 {
2044 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2045 if (huart->hdmatx != NULL)
2046 {
2047 /* UART Tx DMA Abort callback has already been initialised :
2048 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2049
2050 /* Abort DMA TX */
2051 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2052 {
2053 huart->hdmatx->XferAbortCallback = NULL;
2054 }
2055 else
2056 {
2057 abortcplt = 0U;
2058 }
2059 }
2060 }
2061
2062 /* Abort the UART DMA Rx channel if enabled */
2063 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2064 {
2065 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2066 if (huart->hdmarx != NULL)
2067 {
2068 /* UART Rx DMA Abort callback has already been initialised :
2069 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2070
2071 /* Abort DMA RX */
2072 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2073 {
2074 huart->hdmarx->XferAbortCallback = NULL;
2075 abortcplt = 1U;
2076 }
2077 else
2078 {
2079 abortcplt = 0U;
2080 }
2081 }
2082 }
2083 #endif /* HAL_DMA_MODULE_ENABLED */
2084
2085 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2086 if (abortcplt == 1U)
2087 {
2088 /* Reset Tx and Rx transfer counters */
2089 huart->TxXferCount = 0U;
2090 huart->RxXferCount = 0U;
2091
2092 /* Clear ISR function pointers */
2093 huart->RxISR = NULL;
2094 huart->TxISR = NULL;
2095
2096 /* Reset errorCode */
2097 huart->ErrorCode = HAL_UART_ERROR_NONE;
2098
2099 /* Clear the Error flags in the ICR register */
2100 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2101
2102 /* Flush the whole TX FIFO (if needed) */
2103 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2104 {
2105 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2106 }
2107
2108 /* Discard the received data */
2109 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2110
2111 /* Restore huart->gState and huart->RxState to Ready */
2112 huart->gState = HAL_UART_STATE_READY;
2113 huart->RxState = HAL_UART_STATE_READY;
2114 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2115
2116 /* As no DMA to be aborted, call directly user Abort complete callback */
2117 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2118 /* Call registered Abort complete callback */
2119 huart->AbortCpltCallback(huart);
2120 #else
2121 /* Call legacy weak Abort complete callback */
2122 HAL_UART_AbortCpltCallback(huart);
2123 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2124 }
2125
2126 return HAL_OK;
2127 }
2128
2129 /**
2130 * @brief Abort ongoing Transmit transfer (Interrupt mode).
2131 * @param huart UART handle.
2132 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
2133 * This procedure performs following operations :
2134 * - Disable UART Interrupts (Tx)
2135 * - Disable the DMA transfer in the peripheral register (if enabled)
2136 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2137 * - Set handle State to READY
2138 * - At abort completion, call user abort complete callback
2139 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2140 * considered as completed only when user abort complete callback is executed (not when exiting function).
2141 * @retval HAL status
2142 */
HAL_UART_AbortTransmit_IT(UART_HandleTypeDef * huart)2143 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
2144 {
2145 /* Disable interrupts */
2146 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
2147 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
2148
2149 #ifdef HAL_DMA_MODULE_ENABLED
2150 /* Abort the UART DMA Tx channel if enabled */
2151 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2152 {
2153 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2154 if (huart->hdmatx != NULL)
2155 {
2156 /* Set the UART DMA Abort callback :
2157 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2158 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2159
2160 /* Abort DMA TX */
2161 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2162 {
2163 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2164 huart->hdmatx->XferAbortCallback(huart->hdmatx);
2165 }
2166 }
2167 else
2168 {
2169 /* Reset Tx transfer counter */
2170 huart->TxXferCount = 0U;
2171
2172 /* Clear TxISR function pointers */
2173 huart->TxISR = NULL;
2174
2175 /* Restore huart->gState to Ready */
2176 huart->gState = HAL_UART_STATE_READY;
2177
2178 /* As no DMA to be aborted, call directly user Abort complete callback */
2179 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2180 /* Call registered Abort Transmit Complete Callback */
2181 huart->AbortTransmitCpltCallback(huart);
2182 #else
2183 /* Call legacy weak Abort Transmit Complete Callback */
2184 HAL_UART_AbortTransmitCpltCallback(huart);
2185 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2186 }
2187 }
2188 else
2189 #endif /* HAL_DMA_MODULE_ENABLED */
2190 {
2191 /* Reset Tx transfer counter */
2192 huart->TxXferCount = 0U;
2193
2194 /* Clear TxISR function pointers */
2195 huart->TxISR = NULL;
2196
2197 /* Flush the whole TX FIFO (if needed) */
2198 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2199 {
2200 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2201 }
2202
2203 /* Restore huart->gState to Ready */
2204 huart->gState = HAL_UART_STATE_READY;
2205
2206 /* As no DMA to be aborted, call directly user Abort complete callback */
2207 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2208 /* Call registered Abort Transmit Complete Callback */
2209 huart->AbortTransmitCpltCallback(huart);
2210 #else
2211 /* Call legacy weak Abort Transmit Complete Callback */
2212 HAL_UART_AbortTransmitCpltCallback(huart);
2213 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2214 }
2215
2216 return HAL_OK;
2217 }
2218
2219 /**
2220 * @brief Abort ongoing Receive transfer (Interrupt mode).
2221 * @param huart UART handle.
2222 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2223 * This procedure performs following operations :
2224 * - Disable UART Interrupts (Rx)
2225 * - Disable the DMA transfer in the peripheral register (if enabled)
2226 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2227 * - Set handle State to READY
2228 * - At abort completion, call user abort complete callback
2229 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2230 * considered as completed only when user abort complete callback is executed (not when exiting function).
2231 * @retval HAL status
2232 */
HAL_UART_AbortReceive_IT(UART_HandleTypeDef * huart)2233 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2234 {
2235 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2236 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
2237 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2238
2239 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
2240 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2241 {
2242 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
2243 }
2244
2245 #ifdef HAL_DMA_MODULE_ENABLED
2246 /* Abort the UART DMA Rx channel if enabled */
2247 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2248 {
2249 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2250 if (huart->hdmarx != NULL)
2251 {
2252 /* Set the UART DMA Abort callback :
2253 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2254 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2255
2256 /* Abort DMA RX */
2257 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2258 {
2259 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2260 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2261 }
2262 }
2263 else
2264 {
2265 /* Reset Rx transfer counter */
2266 huart->RxXferCount = 0U;
2267
2268 /* Clear RxISR function pointer */
2269 huart->pRxBuffPtr = NULL;
2270
2271 /* Clear the Error flags in the ICR register */
2272 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2273
2274 /* Discard the received data */
2275 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2276
2277 /* Restore huart->RxState to Ready */
2278 huart->RxState = HAL_UART_STATE_READY;
2279 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2280
2281 /* As no DMA to be aborted, call directly user Abort complete callback */
2282 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2283 /* Call registered Abort Receive Complete Callback */
2284 huart->AbortReceiveCpltCallback(huart);
2285 #else
2286 /* Call legacy weak Abort Receive Complete Callback */
2287 HAL_UART_AbortReceiveCpltCallback(huart);
2288 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2289 }
2290 }
2291 else
2292 #endif /* HAL_DMA_MODULE_ENABLED */
2293 {
2294 /* Reset Rx transfer counter */
2295 huart->RxXferCount = 0U;
2296
2297 /* Clear RxISR function pointer */
2298 huart->pRxBuffPtr = NULL;
2299
2300 /* Clear the Error flags in the ICR register */
2301 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2302
2303 /* Restore huart->RxState to Ready */
2304 huart->RxState = HAL_UART_STATE_READY;
2305 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2306
2307 /* As no DMA to be aborted, call directly user Abort complete callback */
2308 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2309 /* Call registered Abort Receive Complete Callback */
2310 huart->AbortReceiveCpltCallback(huart);
2311 #else
2312 /* Call legacy weak Abort Receive Complete Callback */
2313 HAL_UART_AbortReceiveCpltCallback(huart);
2314 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2315 }
2316
2317 return HAL_OK;
2318 }
2319
2320 /**
2321 * @brief Handle UART interrupt request.
2322 * @param huart UART handle.
2323 * @retval None
2324 */
HAL_UART_IRQHandler(UART_HandleTypeDef * huart)2325 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2326 {
2327 uint32_t isrflags = READ_REG(huart->Instance->ISR);
2328 uint32_t cr1its = READ_REG(huart->Instance->CR1);
2329 uint32_t cr3its = READ_REG(huart->Instance->CR3);
2330
2331 uint32_t errorflags;
2332 uint32_t errorcode;
2333
2334 /* If no error occurs */
2335 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2336 if (errorflags == 0U)
2337 {
2338 /* UART in mode Receiver ---------------------------------------------------*/
2339 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2340 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2341 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2342 {
2343 if (huart->RxISR != NULL)
2344 {
2345 huart->RxISR(huart);
2346 }
2347 return;
2348 }
2349 }
2350
2351 /* If some errors occur */
2352 if ((errorflags != 0U)
2353 && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2354 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
2355 {
2356 /* UART parity error interrupt occurred -------------------------------------*/
2357 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2358 {
2359 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2360
2361 huart->ErrorCode |= HAL_UART_ERROR_PE;
2362 }
2363
2364 /* UART frame error interrupt occurred --------------------------------------*/
2365 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2366 {
2367 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2368
2369 huart->ErrorCode |= HAL_UART_ERROR_FE;
2370 }
2371
2372 /* UART noise error interrupt occurred --------------------------------------*/
2373 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2374 {
2375 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2376
2377 huart->ErrorCode |= HAL_UART_ERROR_NE;
2378 }
2379
2380 /* UART Over-Run interrupt occurred -----------------------------------------*/
2381 if (((isrflags & USART_ISR_ORE) != 0U)
2382 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2383 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2384 {
2385 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2386
2387 huart->ErrorCode |= HAL_UART_ERROR_ORE;
2388 }
2389
2390 /* UART Receiver Timeout interrupt occurred ---------------------------------*/
2391 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2392 {
2393 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
2394
2395 huart->ErrorCode |= HAL_UART_ERROR_RTO;
2396 }
2397
2398 /* Call UART Error Call back function if need be ----------------------------*/
2399 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2400 {
2401 /* UART in mode Receiver --------------------------------------------------*/
2402 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2403 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2404 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2405 {
2406 if (huart->RxISR != NULL)
2407 {
2408 huart->RxISR(huart);
2409 }
2410 }
2411
2412 /* If Error is to be considered as blocking :
2413 - Receiver Timeout error in Reception
2414 - Overrun error in Reception
2415 - any error occurs in DMA mode reception
2416 */
2417 errorcode = huart->ErrorCode;
2418 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
2419 ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
2420 {
2421 /* Blocking error : transfer is aborted
2422 Set the UART state ready to be able to start again the process,
2423 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2424 UART_EndRxTransfer(huart);
2425
2426 #ifdef HAL_DMA_MODULE_ENABLED
2427 /* Abort the UART DMA Rx channel if enabled */
2428 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2429 {
2430 /* Abort the UART DMA Rx channel */
2431 if (huart->hdmarx != NULL)
2432 {
2433 /* Set the UART DMA Abort callback :
2434 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2435 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2436
2437 /* Abort DMA RX */
2438 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2439 {
2440 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2441 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2442 }
2443 }
2444 else
2445 {
2446 /* Call user error callback */
2447 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2448 /*Call registered error callback*/
2449 huart->ErrorCallback(huart);
2450 #else
2451 /*Call legacy weak error callback*/
2452 HAL_UART_ErrorCallback(huart);
2453 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2454
2455 }
2456 }
2457 else
2458 #endif /* HAL_DMA_MODULE_ENABLED */
2459 {
2460 /* Call user error callback */
2461 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2462 /*Call registered error callback*/
2463 huart->ErrorCallback(huart);
2464 #else
2465 /*Call legacy weak error callback*/
2466 HAL_UART_ErrorCallback(huart);
2467 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2468 }
2469 }
2470 else
2471 {
2472 /* Non Blocking error : transfer could go on.
2473 Error is notified to user through user error callback */
2474 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2475 /*Call registered error callback*/
2476 huart->ErrorCallback(huart);
2477 #else
2478 /*Call legacy weak error callback*/
2479 HAL_UART_ErrorCallback(huart);
2480 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2481 huart->ErrorCode = HAL_UART_ERROR_NONE;
2482 }
2483 }
2484 return;
2485
2486 } /* End if some error occurs */
2487
2488 /* Check current reception Mode :
2489 If Reception till IDLE event has been selected : */
2490 if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2491 && ((isrflags & USART_ISR_IDLE) != 0U)
2492 && ((cr1its & USART_ISR_IDLE) != 0U))
2493 {
2494 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
2495
2496 #ifdef HAL_DMA_MODULE_ENABLED
2497 /* Check if DMA mode is enabled in UART */
2498 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2499 {
2500 /* DMA mode enabled */
2501 /* Check received length : If all expected data are received, do nothing,
2502 (DMA cplt callback will be called).
2503 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2504 uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
2505 if ((nb_remaining_rx_data > 0U)
2506 && (nb_remaining_rx_data < huart->RxXferSize))
2507 {
2508 /* Reception is not complete */
2509 huart->RxXferCount = nb_remaining_rx_data;
2510
2511 /* In Normal mode, end DMA xfer and HAL UART Rx process*/
2512 if (huart->hdmarx->Mode != DMA_LINKEDLIST_CIRCULAR)
2513 {
2514 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2515 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
2516 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2517
2518 /* At end of Rx process, restore huart->RxState to Ready */
2519 huart->RxState = HAL_UART_STATE_READY;
2520 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2521
2522 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2523
2524 /* Last bytes received, so no need as the abort is immediate */
2525 (void)HAL_DMA_Abort(huart->hdmarx);
2526 }
2527
2528 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2529 In this case, Rx Event type is Idle Event */
2530 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2531
2532 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2533 /*Call registered Rx Event callback*/
2534 huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2535 #else
2536 /*Call legacy weak Rx Event callback*/
2537 HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2538 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2539 }
2540 return;
2541 }
2542 else
2543 {
2544 #endif /* HAL_DMA_MODULE_ENABLED */
2545 /* DMA mode not enabled */
2546 /* Check received length : If all expected data are received, do nothing.
2547 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2548 uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
2549 if ((huart->RxXferCount > 0U)
2550 && (nb_rx_data > 0U))
2551 {
2552 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
2553 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2554
2555 /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
2556 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2557
2558 /* Rx process is completed, restore huart->RxState to Ready */
2559 huart->RxState = HAL_UART_STATE_READY;
2560 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2561
2562 /* Clear RxISR function pointer */
2563 huart->RxISR = NULL;
2564
2565 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2566
2567 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2568 In this case, Rx Event type is Idle Event */
2569 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2570
2571 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2572 /*Call registered Rx complete callback*/
2573 huart->RxEventCallback(huart, nb_rx_data);
2574 #else
2575 /*Call legacy weak Rx Event callback*/
2576 HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
2577 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2578 }
2579 return;
2580 #ifdef HAL_DMA_MODULE_ENABLED
2581 }
2582 #endif /* HAL_DMA_MODULE_ENABLED */
2583 }
2584
2585 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2586 if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2587 {
2588 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2589
2590 /* UART Rx state is not reset as a reception process might be ongoing.
2591 If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2592
2593 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2594 /* Call registered Wakeup Callback */
2595 huart->WakeupCallback(huart);
2596 #else
2597 /* Call legacy weak Wakeup Callback */
2598 HAL_UARTEx_WakeupCallback(huart);
2599 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2600 return;
2601 }
2602
2603 /* UART in mode Transmitter ------------------------------------------------*/
2604 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2605 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2606 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2607 {
2608 if (huart->TxISR != NULL)
2609 {
2610 huart->TxISR(huart);
2611 }
2612 return;
2613 }
2614
2615 /* UART in mode Transmitter (transmission end) -----------------------------*/
2616 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2617 {
2618 UART_EndTransmit_IT(huart);
2619 return;
2620 }
2621
2622 /* UART TX Fifo Empty occurred ----------------------------------------------*/
2623 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2624 {
2625 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2626 /* Call registered Tx Fifo Empty Callback */
2627 huart->TxFifoEmptyCallback(huart);
2628 #else
2629 /* Call legacy weak Tx Fifo Empty Callback */
2630 HAL_UARTEx_TxFifoEmptyCallback(huart);
2631 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2632 return;
2633 }
2634
2635 /* UART RX Fifo Full occurred ----------------------------------------------*/
2636 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2637 {
2638 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2639 /* Call registered Rx Fifo Full Callback */
2640 huart->RxFifoFullCallback(huart);
2641 #else
2642 /* Call legacy weak Rx Fifo Full Callback */
2643 HAL_UARTEx_RxFifoFullCallback(huart);
2644 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2645 return;
2646 }
2647 }
2648
2649 /**
2650 * @brief Tx Transfer completed callback.
2651 * @param huart UART handle.
2652 * @retval None
2653 */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)2654 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2655 {
2656 /* Prevent unused argument(s) compilation warning */
2657 UNUSED(huart);
2658
2659 /* NOTE : This function should not be modified, when the callback is needed,
2660 the HAL_UART_TxCpltCallback can be implemented in the user file.
2661 */
2662 }
2663
2664 /**
2665 * @brief Tx Half Transfer completed callback.
2666 * @param huart UART handle.
2667 * @retval None
2668 */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)2669 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2670 {
2671 /* Prevent unused argument(s) compilation warning */
2672 UNUSED(huart);
2673
2674 /* NOTE: This function should not be modified, when the callback is needed,
2675 the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2676 */
2677 }
2678
2679 /**
2680 * @brief Rx Transfer completed callback.
2681 * @param huart UART handle.
2682 * @retval None
2683 */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)2684 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2685 {
2686 /* Prevent unused argument(s) compilation warning */
2687 UNUSED(huart);
2688
2689 /* NOTE : This function should not be modified, when the callback is needed,
2690 the HAL_UART_RxCpltCallback can be implemented in the user file.
2691 */
2692 }
2693
2694 /**
2695 * @brief Rx Half Transfer completed callback.
2696 * @param huart UART handle.
2697 * @retval None
2698 */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)2699 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2700 {
2701 /* Prevent unused argument(s) compilation warning */
2702 UNUSED(huart);
2703
2704 /* NOTE: This function should not be modified, when the callback is needed,
2705 the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2706 */
2707 }
2708
2709 /**
2710 * @brief UART error callback.
2711 * @param huart UART handle.
2712 * @retval None
2713 */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)2714 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2715 {
2716 /* Prevent unused argument(s) compilation warning */
2717 UNUSED(huart);
2718
2719 /* NOTE : This function should not be modified, when the callback is needed,
2720 the HAL_UART_ErrorCallback can be implemented in the user file.
2721 */
2722 }
2723
2724 /**
2725 * @brief UART Abort Complete callback.
2726 * @param huart UART handle.
2727 * @retval None
2728 */
HAL_UART_AbortCpltCallback(UART_HandleTypeDef * huart)2729 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2730 {
2731 /* Prevent unused argument(s) compilation warning */
2732 UNUSED(huart);
2733
2734 /* NOTE : This function should not be modified, when the callback is needed,
2735 the HAL_UART_AbortCpltCallback can be implemented in the user file.
2736 */
2737 }
2738
2739 /**
2740 * @brief UART Abort Complete callback.
2741 * @param huart UART handle.
2742 * @retval None
2743 */
HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef * huart)2744 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2745 {
2746 /* Prevent unused argument(s) compilation warning */
2747 UNUSED(huart);
2748
2749 /* NOTE : This function should not be modified, when the callback is needed,
2750 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2751 */
2752 }
2753
2754 /**
2755 * @brief UART Abort Receive Complete callback.
2756 * @param huart UART handle.
2757 * @retval None
2758 */
HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef * huart)2759 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2760 {
2761 /* Prevent unused argument(s) compilation warning */
2762 UNUSED(huart);
2763
2764 /* NOTE : This function should not be modified, when the callback is needed,
2765 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2766 */
2767 }
2768
2769 /**
2770 * @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
2771 * @param huart UART handle
2772 * @param Size Number of data available in application reception buffer (indicates a position in
2773 * reception buffer until which, data are available)
2774 * @retval None
2775 */
HAL_UARTEx_RxEventCallback(UART_HandleTypeDef * huart,uint16_t Size)2776 __weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
2777 {
2778 /* Prevent unused argument(s) compilation warning */
2779 UNUSED(huart);
2780 UNUSED(Size);
2781
2782 /* NOTE : This function should not be modified, when the callback is needed,
2783 the HAL_UARTEx_RxEventCallback can be implemented in the user file.
2784 */
2785 }
2786
2787 /**
2788 * @}
2789 */
2790
2791 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2792 * @brief UART control functions
2793 *
2794 @verbatim
2795 ===============================================================================
2796 ##### Peripheral Control functions #####
2797 ===============================================================================
2798 [..]
2799 This subsection provides a set of functions allowing to control the UART.
2800 (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2801 (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2802 (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2803 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2804 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2805 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2806 (+) UART_SetConfig() API configures the UART peripheral
2807 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2808 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2809 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2810 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2811 (+) HAL_LIN_SendBreak() API transmits the break characters
2812 @endverbatim
2813 * @{
2814 */
2815
2816 /**
2817 * @brief Update on the fly the receiver timeout value in RTOR register.
2818 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2819 * the configuration information for the specified UART module.
2820 * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout
2821 * value must be less or equal to 0x0FFFFFFFF.
2822 * @retval None
2823 */
HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef * huart,uint32_t TimeoutValue)2824 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2825 {
2826 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2827 {
2828 assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2829 MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2830 }
2831 }
2832
2833 /**
2834 * @brief Enable the UART receiver timeout feature.
2835 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2836 * the configuration information for the specified UART module.
2837 * @retval HAL status
2838 */
HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef * huart)2839 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2840 {
2841 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2842 {
2843 if (huart->gState == HAL_UART_STATE_READY)
2844 {
2845 /* Process Locked */
2846 __HAL_LOCK(huart);
2847
2848 huart->gState = HAL_UART_STATE_BUSY;
2849
2850 /* Set the USART RTOEN bit */
2851 SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2852
2853 huart->gState = HAL_UART_STATE_READY;
2854
2855 /* Process Unlocked */
2856 __HAL_UNLOCK(huart);
2857
2858 return HAL_OK;
2859 }
2860 else
2861 {
2862 return HAL_BUSY;
2863 }
2864 }
2865 else
2866 {
2867 return HAL_ERROR;
2868 }
2869 }
2870
2871 /**
2872 * @brief Disable the UART receiver timeout feature.
2873 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2874 * the configuration information for the specified UART module.
2875 * @retval HAL status
2876 */
HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef * huart)2877 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2878 {
2879 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2880 {
2881 if (huart->gState == HAL_UART_STATE_READY)
2882 {
2883 /* Process Locked */
2884 __HAL_LOCK(huart);
2885
2886 huart->gState = HAL_UART_STATE_BUSY;
2887
2888 /* Clear the USART RTOEN bit */
2889 CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2890
2891 huart->gState = HAL_UART_STATE_READY;
2892
2893 /* Process Unlocked */
2894 __HAL_UNLOCK(huart);
2895
2896 return HAL_OK;
2897 }
2898 else
2899 {
2900 return HAL_BUSY;
2901 }
2902 }
2903 else
2904 {
2905 return HAL_ERROR;
2906 }
2907 }
2908
2909 /**
2910 * @brief Enable UART in mute mode (does not mean UART enters mute mode;
2911 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2912 * @param huart UART handle.
2913 * @retval HAL status
2914 */
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef * huart)2915 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2916 {
2917 __HAL_LOCK(huart);
2918
2919 huart->gState = HAL_UART_STATE_BUSY;
2920
2921 /* Enable USART mute mode by setting the MME bit in the CR1 register */
2922 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2923
2924 huart->gState = HAL_UART_STATE_READY;
2925
2926 return (UART_CheckIdleState(huart));
2927 }
2928
2929 /**
2930 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode
2931 * as it may not have been in mute mode at this very moment).
2932 * @param huart UART handle.
2933 * @retval HAL status
2934 */
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef * huart)2935 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2936 {
2937 __HAL_LOCK(huart);
2938
2939 huart->gState = HAL_UART_STATE_BUSY;
2940
2941 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2942 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2943
2944 huart->gState = HAL_UART_STATE_READY;
2945
2946 return (UART_CheckIdleState(huart));
2947 }
2948
2949 /**
2950 * @brief Enter UART mute mode (means UART actually enters mute mode).
2951 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2952 * @param huart UART handle.
2953 * @retval None
2954 */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)2955 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2956 {
2957 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2958 }
2959
2960 /**
2961 * @brief Enable the UART transmitter and disable the UART receiver.
2962 * @param huart UART handle.
2963 * @retval HAL status
2964 */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)2965 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2966 {
2967 __HAL_LOCK(huart);
2968 huart->gState = HAL_UART_STATE_BUSY;
2969
2970 /* Clear TE and RE bits */
2971 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2972
2973 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2974 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2975
2976 huart->gState = HAL_UART_STATE_READY;
2977
2978 __HAL_UNLOCK(huart);
2979
2980 return HAL_OK;
2981 }
2982
2983 /**
2984 * @brief Enable the UART receiver and disable the UART transmitter.
2985 * @param huart UART handle.
2986 * @retval HAL status.
2987 */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)2988 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2989 {
2990 __HAL_LOCK(huart);
2991 huart->gState = HAL_UART_STATE_BUSY;
2992
2993 /* Clear TE and RE bits */
2994 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2995
2996 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2997 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2998
2999 huart->gState = HAL_UART_STATE_READY;
3000
3001 __HAL_UNLOCK(huart);
3002
3003 return HAL_OK;
3004 }
3005
3006
3007 /**
3008 * @brief Transmit break characters.
3009 * @param huart UART handle.
3010 * @retval HAL status
3011 */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)3012 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
3013 {
3014 /* Check the parameters */
3015 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
3016
3017 __HAL_LOCK(huart);
3018
3019 huart->gState = HAL_UART_STATE_BUSY;
3020
3021 /* Send break characters */
3022 __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
3023
3024 huart->gState = HAL_UART_STATE_READY;
3025
3026 __HAL_UNLOCK(huart);
3027
3028 return HAL_OK;
3029 }
3030
3031 /**
3032 * @}
3033 */
3034
3035 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
3036 * @brief UART Peripheral State functions
3037 *
3038 @verbatim
3039 ==============================================================================
3040 ##### Peripheral State and Error functions #####
3041 ==============================================================================
3042 [..]
3043 This subsection provides functions allowing to :
3044 (+) Return the UART handle state.
3045 (+) Return the UART handle error code
3046
3047 @endverbatim
3048 * @{
3049 */
3050
3051 /**
3052 * @brief Return the UART handle state.
3053 * @param huart Pointer to a UART_HandleTypeDef structure that contains
3054 * the configuration information for the specified UART.
3055 * @retval HAL state
3056 */
HAL_UART_GetState(const UART_HandleTypeDef * huart)3057 HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
3058 {
3059 uint32_t temp1;
3060 uint32_t temp2;
3061 temp1 = huart->gState;
3062 temp2 = huart->RxState;
3063
3064 return (HAL_UART_StateTypeDef)(temp1 | temp2);
3065 }
3066
3067 /**
3068 * @brief Return the UART handle error code.
3069 * @param huart Pointer to a UART_HandleTypeDef structure that contains
3070 * the configuration information for the specified UART.
3071 * @retval UART Error Code
3072 */
HAL_UART_GetError(const UART_HandleTypeDef * huart)3073 uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
3074 {
3075 return huart->ErrorCode;
3076 }
3077 /**
3078 * @}
3079 */
3080
3081 /**
3082 * @}
3083 */
3084
3085 /** @defgroup UART_Private_Functions UART Private Functions
3086 * @{
3087 */
3088
3089 /**
3090 * @brief Initialize the callbacks to their default values.
3091 * @param huart UART handle.
3092 * @retval none
3093 */
3094 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(UART_HandleTypeDef * huart)3095 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
3096 {
3097 /* Init the UART Callback settings */
3098 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
3099 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
3100 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
3101 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
3102 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
3103 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
3104 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
3105 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
3106 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
3107 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
3108 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
3109 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
3110
3111 }
3112 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3113
3114 /**
3115 * @brief Configure the UART peripheral.
3116 * @param huart UART handle.
3117 * @retval HAL status
3118 */
UART_SetConfig(UART_HandleTypeDef * huart)3119 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
3120 {
3121 uint32_t tmpreg;
3122 uint16_t brrtemp;
3123 uint32_t clocksource;
3124 uint32_t usartdiv;
3125 HAL_StatusTypeDef ret = HAL_OK;
3126 uint32_t lpuart_ker_ck_pres;
3127 uint32_t pclk;
3128
3129 /* Check the parameters */
3130 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
3131 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
3132 if (UART_INSTANCE_LOWPOWER(huart))
3133 {
3134 assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
3135 }
3136 else
3137 {
3138 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
3139 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
3140 }
3141
3142 assert_param(IS_UART_PARITY(huart->Init.Parity));
3143 assert_param(IS_UART_MODE(huart->Init.Mode));
3144 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
3145 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
3146 assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
3147
3148 /*-------------------------- USART CR1 Configuration -----------------------*/
3149 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
3150 * the UART Word Length, Parity, Mode and oversampling:
3151 * set the M bits according to huart->Init.WordLength value
3152 * set PCE and PS bits according to huart->Init.Parity value
3153 * set TE and RE bits according to huart->Init.Mode value
3154 * set OVER8 bit according to huart->Init.OverSampling value */
3155 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
3156 MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3157
3158 /*-------------------------- USART CR2 Configuration -----------------------*/
3159 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
3160 * to huart->Init.StopBits value */
3161 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
3162
3163 /*-------------------------- USART CR3 Configuration -----------------------*/
3164 /* Configure
3165 * - UART HardWare Flow Control: set CTSE and RTSE bits according
3166 * to huart->Init.HwFlowCtl value
3167 * - one-bit sampling method versus three samples' majority rule according
3168 * to huart->Init.OneBitSampling (not applicable to LPUART) */
3169 tmpreg = (uint32_t)huart->Init.HwFlowCtl;
3170
3171 if (!(UART_INSTANCE_LOWPOWER(huart)))
3172 {
3173 tmpreg |= huart->Init.OneBitSampling;
3174 }
3175 MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
3176
3177 /*-------------------------- USART PRESC Configuration -----------------------*/
3178 /* Configure
3179 * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
3180 MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
3181
3182 /*-------------------------- USART BRR Configuration -----------------------*/
3183 UART_GETCLOCKSOURCE(huart, clocksource);
3184
3185 /* Check LPUART instance */
3186 if (UART_INSTANCE_LOWPOWER(huart))
3187 {
3188 /* Retrieve frequency clock */
3189 pclk = HAL_RCCEx_GetPeriphCLKFreq(clocksource);
3190
3191 /* If proper clock source reported */
3192 if (pclk != 0U)
3193 {
3194 /* Compute clock after Prescaler */
3195 lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]);
3196
3197 /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
3198 if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
3199 (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
3200 {
3201 ret = HAL_ERROR;
3202 }
3203 else
3204 {
3205 /* Check computed UsartDiv value is in allocated range
3206 (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */
3207 usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3208 if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
3209 {
3210 huart->Instance->BRR = usartdiv;
3211 }
3212 else
3213 {
3214 ret = HAL_ERROR;
3215 }
3216 } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) ||
3217 (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
3218 } /* if (pclk != 0) */
3219 }
3220 /* Check UART Over Sampling to set Baud Rate Register */
3221 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3222 {
3223 pclk = HAL_RCCEx_GetPeriphCLKFreq(clocksource);
3224
3225 /* USARTDIV must be greater than or equal to 0d16 */
3226 if (pclk != 0U)
3227 {
3228 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3229 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3230 {
3231 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3232 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3233 huart->Instance->BRR = brrtemp;
3234 }
3235 else
3236 {
3237 ret = HAL_ERROR;
3238 }
3239 }
3240 }
3241 else
3242 {
3243 pclk = HAL_RCCEx_GetPeriphCLKFreq(clocksource);
3244
3245 if (pclk != 0U)
3246 {
3247 /* USARTDIV must be greater than or equal to 0d16 */
3248 usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3249 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3250 {
3251 huart->Instance->BRR = (uint16_t)usartdiv;
3252 }
3253 else
3254 {
3255 ret = HAL_ERROR;
3256 }
3257 }
3258 }
3259
3260 /* Initialize the number of data to process during RX/TX ISR execution */
3261 huart->NbTxDataToProcess = 1;
3262 huart->NbRxDataToProcess = 1;
3263
3264 /* Clear ISR function pointers */
3265 huart->RxISR = NULL;
3266 huart->TxISR = NULL;
3267
3268 return ret;
3269 }
3270
3271 /**
3272 * @brief Configure the UART peripheral advanced features.
3273 * @param huart UART handle.
3274 * @retval None
3275 */
UART_AdvFeatureConfig(UART_HandleTypeDef * huart)3276 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3277 {
3278 /* Check whether the set of advanced features to configure is properly set */
3279 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3280
3281 /* if required, configure RX/TX pins swap */
3282 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3283 {
3284 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3285 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3286 }
3287
3288 /* if required, configure TX pin active level inversion */
3289 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3290 {
3291 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3292 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3293 }
3294
3295 /* if required, configure RX pin active level inversion */
3296 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3297 {
3298 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3299 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3300 }
3301
3302 /* if required, configure data inversion */
3303 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3304 {
3305 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3306 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3307 }
3308
3309 /* if required, configure RX overrun detection disabling */
3310 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3311 {
3312 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3313 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3314 }
3315
3316 #ifdef HAL_DMA_MODULE_ENABLED
3317 /* if required, configure DMA disabling on reception error */
3318 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3319 {
3320 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3321 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3322 }
3323 #endif /* HAL_DMA_MODULE_ENABLED */
3324
3325 /* if required, configure auto Baud rate detection scheme */
3326 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3327 {
3328 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3329 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3330 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3331 /* set auto Baudrate detection parameters if detection is enabled */
3332 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3333 {
3334 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3335 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3336 }
3337 }
3338
3339 /* if required, configure MSB first on communication line */
3340 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3341 {
3342 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3343 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3344 }
3345 }
3346
3347 /**
3348 * @brief Check the UART Idle State.
3349 * @param huart UART handle.
3350 * @retval HAL status
3351 */
UART_CheckIdleState(UART_HandleTypeDef * huart)3352 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3353 {
3354 uint32_t tickstart;
3355
3356 /* Initialize the UART ErrorCode */
3357 huart->ErrorCode = HAL_UART_ERROR_NONE;
3358
3359 /* Init tickstart for timeout management */
3360 tickstart = HAL_GetTick();
3361
3362 /* Check if the Transmitter is enabled */
3363 if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3364 {
3365 /* Wait until TEACK flag is set */
3366 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3367 {
3368 /* Disable TXE interrupt for the interrupt process */
3369 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE));
3370
3371 huart->gState = HAL_UART_STATE_READY;
3372
3373 __HAL_UNLOCK(huart);
3374
3375 /* Timeout occurred */
3376 return HAL_TIMEOUT;
3377 }
3378 }
3379
3380 /* Check if the Receiver is enabled */
3381 if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3382 {
3383 /* Wait until REACK flag is set */
3384 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3385 {
3386 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error)
3387 interrupts for the interrupt process */
3388 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3389 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3390
3391 huart->RxState = HAL_UART_STATE_READY;
3392
3393 __HAL_UNLOCK(huart);
3394
3395 /* Timeout occurred */
3396 return HAL_TIMEOUT;
3397 }
3398 }
3399
3400 /* Initialize the UART State */
3401 huart->gState = HAL_UART_STATE_READY;
3402 huart->RxState = HAL_UART_STATE_READY;
3403 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3404 huart->RxEventType = HAL_UART_RXEVENT_TC;
3405
3406 __HAL_UNLOCK(huart);
3407
3408 return HAL_OK;
3409 }
3410
3411 /**
3412 * @brief This function handles UART Communication Timeout. It waits
3413 * until a flag is no longer in the specified status.
3414 * @param huart UART handle.
3415 * @param Flag Specifies the UART flag to check
3416 * @param Status The actual Flag status (SET or RESET)
3417 * @param Tickstart Tick start value
3418 * @param Timeout Timeout duration
3419 * @retval HAL status
3420 */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3421 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3422 uint32_t Tickstart, uint32_t Timeout)
3423 {
3424 /* Wait until flag is set */
3425 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3426 {
3427 /* Check for the Timeout */
3428 if (Timeout != HAL_MAX_DELAY)
3429 {
3430 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3431 {
3432
3433 return HAL_TIMEOUT;
3434 }
3435
3436 if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U)
3437 {
3438 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
3439 {
3440 /* Clear Overrun Error flag*/
3441 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
3442
3443 /* Blocking error : transfer is aborted
3444 Set the UART state ready to be able to start again the process,
3445 Disable Rx Interrupts if ongoing */
3446 UART_EndRxTransfer(huart);
3447
3448 huart->ErrorCode = HAL_UART_ERROR_ORE;
3449
3450 /* Process Unlocked */
3451 __HAL_UNLOCK(huart);
3452
3453 return HAL_ERROR;
3454 }
3455 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3456 {
3457 /* Clear Receiver Timeout flag*/
3458 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3459
3460 /* Blocking error : transfer is aborted
3461 Set the UART state ready to be able to start again the process,
3462 Disable Rx Interrupts if ongoing */
3463 UART_EndRxTransfer(huart);
3464
3465 huart->ErrorCode = HAL_UART_ERROR_RTO;
3466
3467 /* Process Unlocked */
3468 __HAL_UNLOCK(huart);
3469
3470 return HAL_TIMEOUT;
3471 }
3472 }
3473 }
3474 }
3475 return HAL_OK;
3476 }
3477
3478 /**
3479 * @brief Start Receive operation in interrupt mode.
3480 * @note This function could be called by all HAL UART API providing reception in Interrupt mode.
3481 * @note When calling this function, parameters validity is considered as already checked,
3482 * i.e. Rx State, buffer address, ...
3483 * UART Handle is assumed as Locked.
3484 * @param huart UART handle.
3485 * @param pData Pointer to data buffer (u8 or u16 data elements).
3486 * @param Size Amount of data elements (u8 or u16) to be received.
3487 * @retval HAL status
3488 */
UART_Start_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3489 HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3490 {
3491 huart->pRxBuffPtr = pData;
3492 huart->RxXferSize = Size;
3493 huart->RxXferCount = Size;
3494 huart->RxISR = NULL;
3495
3496 /* Computation of UART mask to apply to RDR register */
3497 UART_MASK_COMPUTATION(huart);
3498
3499 huart->ErrorCode = HAL_UART_ERROR_NONE;
3500 huart->RxState = HAL_UART_STATE_BUSY_RX;
3501
3502 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3503 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3504
3505 /* Configure Rx interrupt processing */
3506 if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
3507 {
3508 /* Set the Rx ISR function pointer according to the data word length */
3509 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3510 {
3511 huart->RxISR = UART_RxISR_16BIT_FIFOEN;
3512 }
3513 else
3514 {
3515 huart->RxISR = UART_RxISR_8BIT_FIFOEN;
3516 }
3517
3518 /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
3519 if (huart->Init.Parity != UART_PARITY_NONE)
3520 {
3521 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3522 }
3523 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
3524 }
3525 else
3526 {
3527 /* Set the Rx ISR function pointer according to the data word length */
3528 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3529 {
3530 huart->RxISR = UART_RxISR_16BIT;
3531 }
3532 else
3533 {
3534 huart->RxISR = UART_RxISR_8BIT;
3535 }
3536
3537 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
3538 if (huart->Init.Parity != UART_PARITY_NONE)
3539 {
3540 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
3541 }
3542 else
3543 {
3544 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3545 }
3546 }
3547 return HAL_OK;
3548 }
3549
3550 #ifdef HAL_DMA_MODULE_ENABLED
3551 /**
3552 * @brief Start Receive operation in DMA mode.
3553 * @note This function could be called by all HAL UART API providing reception in DMA mode.
3554 * @note When calling this function, parameters validity is considered as already checked,
3555 * i.e. Rx State, buffer address, ...
3556 * UART Handle is assumed as Locked.
3557 * @param huart UART handle.
3558 * @param pData Pointer to data buffer (u8 or u16 data elements).
3559 * @param Size Amount of data elements (u8 or u16) to be received.
3560 * @retval HAL status
3561 */
UART_Start_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3562 HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3563 {
3564 HAL_StatusTypeDef status;
3565 uint16_t nbByte = Size;
3566
3567 huart->pRxBuffPtr = pData;
3568 huart->RxXferSize = Size;
3569
3570 huart->ErrorCode = HAL_UART_ERROR_NONE;
3571 huart->RxState = HAL_UART_STATE_BUSY_RX;
3572
3573 if (huart->hdmarx != NULL)
3574 {
3575 /* Set the UART DMA transfer complete callback */
3576 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
3577
3578 /* Set the UART DMA Half transfer complete callback */
3579 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
3580
3581 /* Set the DMA error callback */
3582 huart->hdmarx->XferErrorCallback = UART_DMAError;
3583
3584 /* Set the DMA abort callback */
3585 huart->hdmarx->XferAbortCallback = NULL;
3586
3587 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
3588 should be aligned on a u16 frontier, so nbByte should be equal to Size * 2 */
3589 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3590 {
3591 nbByte = Size * 2U;
3592 }
3593
3594 /* Check linked list mode */
3595 if ((huart->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
3596 {
3597 if ((huart->hdmarx->LinkedListQueue != NULL) && (huart->hdmarx->LinkedListQueue->Head != NULL))
3598 {
3599 /* Set DMA data size */
3600 huart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
3601
3602 /* Set DMA source address */
3603 huart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
3604 (uint32_t)&huart->Instance->RDR;
3605
3606 /* Set DMA destination address */
3607 huart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)huart->pRxBuffPtr;
3608
3609 /* Enable the UART receive DMA channel */
3610 status = HAL_DMAEx_List_Start_IT(huart->hdmarx);
3611 }
3612 else
3613 {
3614 /* Update status */
3615 status = HAL_ERROR;
3616 }
3617 }
3618 else
3619 {
3620 /* Enable the UART receive DMA channel */
3621 status = HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, nbByte);
3622 }
3623
3624 if (status != HAL_OK)
3625 {
3626 /* Set error code to DMA */
3627 huart->ErrorCode = HAL_UART_ERROR_DMA;
3628
3629 /* Restore huart->RxState to ready */
3630 huart->RxState = HAL_UART_STATE_READY;
3631
3632 return HAL_ERROR;
3633 }
3634 }
3635
3636 /* Enable the UART Parity Error Interrupt */
3637 if (huart->Init.Parity != UART_PARITY_NONE)
3638 {
3639 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3640 }
3641
3642 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3643 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3644
3645 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
3646 in the UART CR3 register */
3647 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3648
3649 return HAL_OK;
3650 }
3651
3652
3653 /**
3654 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3655 * @param huart UART handle.
3656 * @retval None
3657 */
UART_EndTxTransfer(UART_HandleTypeDef * huart)3658 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3659 {
3660 /* Disable TXEIE, TCIE, TXFT interrupts */
3661 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3662 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3663
3664 /* At end of Tx process, restore huart->gState to Ready */
3665 huart->gState = HAL_UART_STATE_READY;
3666 }
3667 #endif /* HAL_DMA_MODULE_ENABLED */
3668
3669
3670 /**
3671 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3672 * @param huart UART handle.
3673 * @retval None
3674 */
UART_EndRxTransfer(UART_HandleTypeDef * huart)3675 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3676 {
3677 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3678 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3679 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3680
3681 /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
3682 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3683 {
3684 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3685 }
3686
3687 /* At end of Rx process, restore huart->RxState to Ready */
3688 huart->RxState = HAL_UART_STATE_READY;
3689 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3690
3691 /* Reset RxIsr function pointer */
3692 huart->RxISR = NULL;
3693 }
3694
3695
3696 #ifdef HAL_DMA_MODULE_ENABLED
3697 /**
3698 * @brief DMA UART transmit process complete callback.
3699 * @param hdma DMA handle.
3700 * @retval None
3701 */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)3702 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3703 {
3704 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3705
3706 /* Check if DMA in circular mode */
3707 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
3708 {
3709 huart->TxXferCount = 0U;
3710
3711 /* Enable the UART Transmit Complete Interrupt */
3712 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3713 }
3714 /* DMA Circular mode */
3715 else
3716 {
3717 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3718 /*Call registered Tx complete callback*/
3719 huart->TxCpltCallback(huart);
3720 #else
3721 /*Call legacy weak Tx complete callback*/
3722 HAL_UART_TxCpltCallback(huart);
3723 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3724 }
3725 }
3726
3727 /**
3728 * @brief DMA UART transmit process half complete callback.
3729 * @param hdma DMA handle.
3730 * @retval None
3731 */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)3732 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3733 {
3734 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3735
3736 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3737 /*Call registered Tx Half complete callback*/
3738 huart->TxHalfCpltCallback(huart);
3739 #else
3740 /*Call legacy weak Tx Half complete callback*/
3741 HAL_UART_TxHalfCpltCallback(huart);
3742 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3743 }
3744
3745 /**
3746 * @brief DMA UART receive process complete callback.
3747 * @param hdma DMA handle.
3748 * @retval None
3749 */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3750 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3751 {
3752 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3753
3754 /* Check if DMA in circular mode */
3755 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
3756 {
3757 huart->RxXferCount = 0U;
3758
3759 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3760 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3761 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3762
3763 /* At end of Rx process, restore huart->RxState to Ready */
3764 huart->RxState = HAL_UART_STATE_READY;
3765
3766 /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
3767 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3768 {
3769 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3770 }
3771 }
3772
3773 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3774 In this case, Rx Event type is Transfer Complete */
3775 huart->RxEventType = HAL_UART_RXEVENT_TC;
3776
3777 /* Check current reception Mode :
3778 If Reception till IDLE event has been selected : use Rx Event callback */
3779 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3780 {
3781 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3782 /*Call registered Rx Event callback*/
3783 huart->RxEventCallback(huart, huart->RxXferSize);
3784 #else
3785 /*Call legacy weak Rx Event callback*/
3786 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
3787 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3788 }
3789 else
3790 {
3791 /* In other cases : use Rx Complete callback */
3792 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3793 /*Call registered Rx complete callback*/
3794 huart->RxCpltCallback(huart);
3795 #else
3796 /*Call legacy weak Rx complete callback*/
3797 HAL_UART_RxCpltCallback(huart);
3798 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3799 }
3800 }
3801
3802 /**
3803 * @brief DMA UART receive process half complete callback.
3804 * @param hdma DMA handle.
3805 * @retval None
3806 */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)3807 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3808 {
3809 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3810
3811 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3812 In this case, Rx Event type is Half Transfer */
3813 huart->RxEventType = HAL_UART_RXEVENT_HT;
3814
3815 /* Check current reception Mode :
3816 If Reception till IDLE event has been selected : use Rx Event callback */
3817 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3818 {
3819 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3820 /*Call registered Rx Event callback*/
3821 huart->RxEventCallback(huart, huart->RxXferSize / 2U);
3822 #else
3823 /*Call legacy weak Rx Event callback*/
3824 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
3825 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3826 }
3827 else
3828 {
3829 /* In other cases : use Rx Half Complete callback */
3830 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3831 /*Call registered Rx Half complete callback*/
3832 huart->RxHalfCpltCallback(huart);
3833 #else
3834 /*Call legacy weak Rx Half complete callback*/
3835 HAL_UART_RxHalfCpltCallback(huart);
3836 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3837 }
3838 }
3839
3840 /**
3841 * @brief DMA UART communication error callback.
3842 * @param hdma DMA handle.
3843 * @retval None
3844 */
UART_DMAError(DMA_HandleTypeDef * hdma)3845 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3846 {
3847 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3848
3849 const HAL_UART_StateTypeDef gstate = huart->gState;
3850 const HAL_UART_StateTypeDef rxstate = huart->RxState;
3851
3852 /* Stop UART DMA Tx request if ongoing */
3853 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3854 (gstate == HAL_UART_STATE_BUSY_TX))
3855 {
3856 huart->TxXferCount = 0U;
3857 UART_EndTxTransfer(huart);
3858 }
3859
3860 /* Stop UART DMA Rx request if ongoing */
3861 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3862 (rxstate == HAL_UART_STATE_BUSY_RX))
3863 {
3864 huart->RxXferCount = 0U;
3865 UART_EndRxTransfer(huart);
3866 }
3867
3868 huart->ErrorCode |= HAL_UART_ERROR_DMA;
3869
3870 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3871 /*Call registered error callback*/
3872 huart->ErrorCallback(huart);
3873 #else
3874 /*Call legacy weak error callback*/
3875 HAL_UART_ErrorCallback(huart);
3876 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3877 }
3878
3879 /**
3880 * @brief DMA UART communication abort callback, when initiated by HAL services on Error
3881 * (To be called at end of DMA Abort procedure following error occurrence).
3882 * @param hdma DMA handle.
3883 * @retval None
3884 */
UART_DMAAbortOnError(DMA_HandleTypeDef * hdma)3885 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3886 {
3887 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3888 huart->RxXferCount = 0U;
3889 huart->TxXferCount = 0U;
3890
3891 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3892 /*Call registered error callback*/
3893 huart->ErrorCallback(huart);
3894 #else
3895 /*Call legacy weak error callback*/
3896 HAL_UART_ErrorCallback(huart);
3897 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3898 }
3899
3900 /**
3901 * @brief DMA UART Tx communication abort callback, when initiated by user
3902 * (To be called at end of DMA Tx Abort procedure following user abort request).
3903 * @note When this callback is executed, User Abort complete call back is called only if no
3904 * Abort still ongoing for Rx DMA Handle.
3905 * @param hdma DMA handle.
3906 * @retval None
3907 */
UART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3908 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3909 {
3910 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3911
3912 huart->hdmatx->XferAbortCallback = NULL;
3913
3914 /* Check if an Abort process is still ongoing */
3915 if (huart->hdmarx != NULL)
3916 {
3917 if (huart->hdmarx->XferAbortCallback != NULL)
3918 {
3919 return;
3920 }
3921 }
3922
3923 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3924 huart->TxXferCount = 0U;
3925 huart->RxXferCount = 0U;
3926
3927 /* Reset errorCode */
3928 huart->ErrorCode = HAL_UART_ERROR_NONE;
3929
3930 /* Clear the Error flags in the ICR register */
3931 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3932
3933 /* Flush the whole TX FIFO (if needed) */
3934 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3935 {
3936 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3937 }
3938
3939 /* Restore huart->gState and huart->RxState to Ready */
3940 huart->gState = HAL_UART_STATE_READY;
3941 huart->RxState = HAL_UART_STATE_READY;
3942 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3943
3944 /* Call user Abort complete callback */
3945 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3946 /* Call registered Abort complete callback */
3947 huart->AbortCpltCallback(huart);
3948 #else
3949 /* Call legacy weak Abort complete callback */
3950 HAL_UART_AbortCpltCallback(huart);
3951 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3952 }
3953
3954
3955 /**
3956 * @brief DMA UART Rx communication abort callback, when initiated by user
3957 * (To be called at end of DMA Rx Abort procedure following user abort request).
3958 * @note When this callback is executed, User Abort complete call back is called only if no
3959 * Abort still ongoing for Tx DMA Handle.
3960 * @param hdma DMA handle.
3961 * @retval None
3962 */
UART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3963 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3964 {
3965 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3966
3967 huart->hdmarx->XferAbortCallback = NULL;
3968
3969 /* Check if an Abort process is still ongoing */
3970 if (huart->hdmatx != NULL)
3971 {
3972 if (huart->hdmatx->XferAbortCallback != NULL)
3973 {
3974 return;
3975 }
3976 }
3977
3978 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3979 huart->TxXferCount = 0U;
3980 huart->RxXferCount = 0U;
3981
3982 /* Reset errorCode */
3983 huart->ErrorCode = HAL_UART_ERROR_NONE;
3984
3985 /* Clear the Error flags in the ICR register */
3986 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3987
3988 /* Discard the received data */
3989 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3990
3991 /* Restore huart->gState and huart->RxState to Ready */
3992 huart->gState = HAL_UART_STATE_READY;
3993 huart->RxState = HAL_UART_STATE_READY;
3994 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3995
3996 /* Call user Abort complete callback */
3997 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3998 /* Call registered Abort complete callback */
3999 huart->AbortCpltCallback(huart);
4000 #else
4001 /* Call legacy weak Abort complete callback */
4002 HAL_UART_AbortCpltCallback(huart);
4003 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4004 }
4005
4006
4007 /**
4008 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
4009 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
4010 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
4011 * and leads to user Tx Abort Complete callback execution).
4012 * @param hdma DMA handle.
4013 * @retval None
4014 */
UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)4015 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
4016 {
4017 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
4018
4019 huart->TxXferCount = 0U;
4020
4021 /* Flush the whole TX FIFO (if needed) */
4022 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
4023 {
4024 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
4025 }
4026
4027 /* Restore huart->gState to Ready */
4028 huart->gState = HAL_UART_STATE_READY;
4029
4030 /* Call user Abort complete callback */
4031 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4032 /* Call registered Abort Transmit Complete Callback */
4033 huart->AbortTransmitCpltCallback(huart);
4034 #else
4035 /* Call legacy weak Abort Transmit Complete Callback */
4036 HAL_UART_AbortTransmitCpltCallback(huart);
4037 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4038 }
4039
4040 /**
4041 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
4042 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
4043 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
4044 * and leads to user Rx Abort Complete callback execution).
4045 * @param hdma DMA handle.
4046 * @retval None
4047 */
UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)4048 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
4049 {
4050 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
4051
4052 huart->RxXferCount = 0U;
4053
4054 /* Clear the Error flags in the ICR register */
4055 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
4056
4057 /* Discard the received data */
4058 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4059
4060 /* Restore huart->RxState to Ready */
4061 huart->RxState = HAL_UART_STATE_READY;
4062 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4063
4064 /* Call user Abort complete callback */
4065 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4066 /* Call registered Abort Receive Complete Callback */
4067 huart->AbortReceiveCpltCallback(huart);
4068 #else
4069 /* Call legacy weak Abort Receive Complete Callback */
4070 HAL_UART_AbortReceiveCpltCallback(huart);
4071 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4072 }
4073 #endif /* HAL_DMA_MODULE_ENABLED */
4074
4075 /**
4076 * @brief TX interrupt handler for 7 or 8 bits data word length .
4077 * @note Function is called under interruption only, once
4078 * interruptions have been enabled by HAL_UART_Transmit_IT().
4079 * @param huart UART handle.
4080 * @retval None
4081 */
UART_TxISR_8BIT(UART_HandleTypeDef * huart)4082 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
4083 {
4084 /* Check that a Tx process is ongoing */
4085 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4086 {
4087 if (huart->TxXferCount == 0U)
4088 {
4089 /* Disable the UART Transmit Data Register Empty Interrupt */
4090 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4091
4092 /* Enable the UART Transmit Complete Interrupt */
4093 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4094 }
4095 else
4096 {
4097 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4098 huart->pTxBuffPtr++;
4099 huart->TxXferCount--;
4100 }
4101 }
4102 }
4103
4104 /**
4105 * @brief TX interrupt handler for 9 bits data word length.
4106 * @note Function is called under interruption only, once
4107 * interruptions have been enabled by HAL_UART_Transmit_IT().
4108 * @param huart UART handle.
4109 * @retval None
4110 */
UART_TxISR_16BIT(UART_HandleTypeDef * huart)4111 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
4112 {
4113 const uint16_t *tmp;
4114
4115 /* Check that a Tx process is ongoing */
4116 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4117 {
4118 if (huart->TxXferCount == 0U)
4119 {
4120 /* Disable the UART Transmit Data Register Empty Interrupt */
4121 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4122
4123 /* Enable the UART Transmit Complete Interrupt */
4124 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4125 }
4126 else
4127 {
4128 tmp = (const uint16_t *) huart->pTxBuffPtr;
4129 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4130 huart->pTxBuffPtr += 2U;
4131 huart->TxXferCount--;
4132 }
4133 }
4134 }
4135
4136 /**
4137 * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4138 * @note Function is called under interruption only, once
4139 * interruptions have been enabled by HAL_UART_Transmit_IT().
4140 * @param huart UART handle.
4141 * @retval None
4142 */
UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4143 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4144 {
4145 uint16_t nb_tx_data;
4146
4147 /* Check that a Tx process is ongoing */
4148 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4149 {
4150 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4151 {
4152 if (huart->TxXferCount == 0U)
4153 {
4154 /* Disable the TX FIFO threshold interrupt */
4155 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4156
4157 /* Enable the UART Transmit Complete Interrupt */
4158 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4159
4160 break; /* force exit loop */
4161 }
4162 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4163 {
4164 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4165 huart->pTxBuffPtr++;
4166 huart->TxXferCount--;
4167 }
4168 else
4169 {
4170 /* Nothing to do */
4171 }
4172 }
4173 }
4174 }
4175
4176 /**
4177 * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4178 * @note Function is called under interruption only, once
4179 * interruptions have been enabled by HAL_UART_Transmit_IT().
4180 * @param huart UART handle.
4181 * @retval None
4182 */
UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4183 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4184 {
4185 const uint16_t *tmp;
4186 uint16_t nb_tx_data;
4187
4188 /* Check that a Tx process is ongoing */
4189 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4190 {
4191 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4192 {
4193 if (huart->TxXferCount == 0U)
4194 {
4195 /* Disable the TX FIFO threshold interrupt */
4196 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4197
4198 /* Enable the UART Transmit Complete Interrupt */
4199 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4200
4201 break; /* force exit loop */
4202 }
4203 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4204 {
4205 tmp = (const uint16_t *) huart->pTxBuffPtr;
4206 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4207 huart->pTxBuffPtr += 2U;
4208 huart->TxXferCount--;
4209 }
4210 else
4211 {
4212 /* Nothing to do */
4213 }
4214 }
4215 }
4216 }
4217
4218 /**
4219 * @brief Wrap up transmission in non-blocking mode.
4220 * @param huart pointer to a UART_HandleTypeDef structure that contains
4221 * the configuration information for the specified UART module.
4222 * @retval None
4223 */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)4224 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
4225 {
4226 /* Disable the UART Transmit Complete Interrupt */
4227 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4228
4229 /* Tx process is ended, restore huart->gState to Ready */
4230 huart->gState = HAL_UART_STATE_READY;
4231
4232 /* Cleat TxISR function pointer */
4233 huart->TxISR = NULL;
4234
4235 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4236 /*Call registered Tx complete callback*/
4237 huart->TxCpltCallback(huart);
4238 #else
4239 /*Call legacy weak Tx complete callback*/
4240 HAL_UART_TxCpltCallback(huart);
4241 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4242 }
4243
4244 /**
4245 * @brief RX interrupt handler for 7 or 8 bits data word length .
4246 * @param huart UART handle.
4247 * @retval None
4248 */
UART_RxISR_8BIT(UART_HandleTypeDef * huart)4249 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
4250 {
4251 uint16_t uhMask = huart->Mask;
4252 uint16_t uhdata;
4253
4254 /* Check that a Rx process is ongoing */
4255 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4256 {
4257 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4258 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4259 huart->pRxBuffPtr++;
4260 huart->RxXferCount--;
4261
4262 if (huart->RxXferCount == 0U)
4263 {
4264 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
4265 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4266
4267 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4268 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4269
4270 /* Rx process is completed, restore huart->RxState to Ready */
4271 huart->RxState = HAL_UART_STATE_READY;
4272
4273 /* Clear RxISR function pointer */
4274 huart->RxISR = NULL;
4275
4276 /* Initialize type of RxEvent to Transfer Complete */
4277 huart->RxEventType = HAL_UART_RXEVENT_TC;
4278
4279 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4280 {
4281 /* Check that USART RTOEN bit is set */
4282 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4283 {
4284 /* Enable the UART Receiver Timeout Interrupt */
4285 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4286 }
4287 }
4288
4289 /* Check current reception Mode :
4290 If Reception till IDLE event has been selected : */
4291 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4292 {
4293 /* Set reception type to Standard */
4294 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4295
4296 /* Disable IDLE interrupt */
4297 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4298
4299 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4300 {
4301 /* Clear IDLE Flag */
4302 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4303 }
4304
4305 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4306 /*Call registered Rx Event callback*/
4307 huart->RxEventCallback(huart, huart->RxXferSize);
4308 #else
4309 /*Call legacy weak Rx Event callback*/
4310 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4311 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4312 }
4313 else
4314 {
4315 /* Standard reception API called */
4316 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4317 /*Call registered Rx complete callback*/
4318 huart->RxCpltCallback(huart);
4319 #else
4320 /*Call legacy weak Rx complete callback*/
4321 HAL_UART_RxCpltCallback(huart);
4322 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4323 }
4324 }
4325 }
4326 else
4327 {
4328 /* Clear RXNE interrupt flag */
4329 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4330 }
4331 }
4332
4333 /**
4334 * @brief RX interrupt handler for 9 bits data word length .
4335 * @note Function is called under interruption only, once
4336 * interruptions have been enabled by HAL_UART_Receive_IT()
4337 * @param huart UART handle.
4338 * @retval None
4339 */
UART_RxISR_16BIT(UART_HandleTypeDef * huart)4340 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
4341 {
4342 uint16_t *tmp;
4343 uint16_t uhMask = huart->Mask;
4344 uint16_t uhdata;
4345
4346 /* Check that a Rx process is ongoing */
4347 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4348 {
4349 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4350 tmp = (uint16_t *) huart->pRxBuffPtr ;
4351 *tmp = (uint16_t)(uhdata & uhMask);
4352 huart->pRxBuffPtr += 2U;
4353 huart->RxXferCount--;
4354
4355 if (huart->RxXferCount == 0U)
4356 {
4357 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
4358 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4359
4360 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4361 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4362
4363 /* Rx process is completed, restore huart->RxState to Ready */
4364 huart->RxState = HAL_UART_STATE_READY;
4365
4366 /* Clear RxISR function pointer */
4367 huart->RxISR = NULL;
4368
4369 /* Initialize type of RxEvent to Transfer Complete */
4370 huart->RxEventType = HAL_UART_RXEVENT_TC;
4371
4372 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4373 {
4374 /* Check that USART RTOEN bit is set */
4375 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4376 {
4377 /* Enable the UART Receiver Timeout Interrupt */
4378 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4379 }
4380 }
4381
4382 /* Check current reception Mode :
4383 If Reception till IDLE event has been selected : */
4384 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4385 {
4386 /* Set reception type to Standard */
4387 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4388
4389 /* Disable IDLE interrupt */
4390 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4391
4392 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4393 {
4394 /* Clear IDLE Flag */
4395 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4396 }
4397
4398 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4399 /*Call registered Rx Event callback*/
4400 huart->RxEventCallback(huart, huart->RxXferSize);
4401 #else
4402 /*Call legacy weak Rx Event callback*/
4403 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4404 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4405 }
4406 else
4407 {
4408 /* Standard reception API called */
4409 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4410 /*Call registered Rx complete callback*/
4411 huart->RxCpltCallback(huart);
4412 #else
4413 /*Call legacy weak Rx complete callback*/
4414 HAL_UART_RxCpltCallback(huart);
4415 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4416 }
4417 }
4418 }
4419 else
4420 {
4421 /* Clear RXNE interrupt flag */
4422 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4423 }
4424 }
4425
4426 /**
4427 * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4428 * @note Function is called under interruption only, once
4429 * interruptions have been enabled by HAL_UART_Receive_IT()
4430 * @param huart UART handle.
4431 * @retval None
4432 */
UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4433 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4434 {
4435 uint16_t uhMask = huart->Mask;
4436 uint16_t uhdata;
4437 uint16_t nb_rx_data;
4438 uint16_t rxdatacount;
4439 uint32_t isrflags = READ_REG(huart->Instance->ISR);
4440 uint32_t cr1its = READ_REG(huart->Instance->CR1);
4441 uint32_t cr3its = READ_REG(huart->Instance->CR3);
4442
4443 /* Check that a Rx process is ongoing */
4444 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4445 {
4446 nb_rx_data = huart->NbRxDataToProcess;
4447 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4448 {
4449 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4450 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4451 huart->pRxBuffPtr++;
4452 huart->RxXferCount--;
4453 isrflags = READ_REG(huart->Instance->ISR);
4454
4455 /* If some non blocking errors occurred */
4456 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4457 {
4458 /* UART parity error interrupt occurred -------------------------------------*/
4459 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4460 {
4461 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4462
4463 huart->ErrorCode |= HAL_UART_ERROR_PE;
4464 }
4465
4466 /* UART frame error interrupt occurred --------------------------------------*/
4467 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4468 {
4469 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4470
4471 huart->ErrorCode |= HAL_UART_ERROR_FE;
4472 }
4473
4474 /* UART noise error interrupt occurred --------------------------------------*/
4475 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4476 {
4477 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4478
4479 huart->ErrorCode |= HAL_UART_ERROR_NE;
4480 }
4481
4482 /* Call UART Error Call back function if need be ----------------------------*/
4483 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4484 {
4485 /* Non Blocking error : transfer could go on.
4486 Error is notified to user through user error callback */
4487 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4488 /*Call registered error callback*/
4489 huart->ErrorCallback(huart);
4490 #else
4491 /*Call legacy weak error callback*/
4492 HAL_UART_ErrorCallback(huart);
4493 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4494 huart->ErrorCode = HAL_UART_ERROR_NONE;
4495 }
4496 }
4497
4498 if (huart->RxXferCount == 0U)
4499 {
4500 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4501 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4502
4503 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4504 and RX FIFO Threshold interrupt */
4505 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4506
4507 /* Rx process is completed, restore huart->RxState to Ready */
4508 huart->RxState = HAL_UART_STATE_READY;
4509
4510 /* Clear RxISR function pointer */
4511 huart->RxISR = NULL;
4512
4513 /* Initialize type of RxEvent to Transfer Complete */
4514 huart->RxEventType = HAL_UART_RXEVENT_TC;
4515
4516 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4517 {
4518 /* Check that USART RTOEN bit is set */
4519 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4520 {
4521 /* Enable the UART Receiver Timeout Interrupt */
4522 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4523 }
4524 }
4525
4526 /* Check current reception Mode :
4527 If Reception till IDLE event has been selected : */
4528 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4529 {
4530 /* Set reception type to Standard */
4531 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4532
4533 /* Disable IDLE interrupt */
4534 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4535
4536 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4537 {
4538 /* Clear IDLE Flag */
4539 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4540 }
4541
4542 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4543 /*Call registered Rx Event callback*/
4544 huart->RxEventCallback(huart, huart->RxXferSize);
4545 #else
4546 /*Call legacy weak Rx Event callback*/
4547 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4548 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4549 }
4550 else
4551 {
4552 /* Standard reception API called */
4553 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4554 /*Call registered Rx complete callback*/
4555 huart->RxCpltCallback(huart);
4556 #else
4557 /*Call legacy weak Rx complete callback*/
4558 HAL_UART_RxCpltCallback(huart);
4559 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4560 }
4561 }
4562 }
4563
4564 /* When remaining number of bytes to receive is less than the RX FIFO
4565 threshold, next incoming frames are processed as if FIFO mode was
4566 disabled (i.e. one interrupt per received frame).
4567 */
4568 rxdatacount = huart->RxXferCount;
4569 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4570 {
4571 /* Disable the UART RXFT interrupt*/
4572 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4573
4574 /* Update the RxISR function pointer */
4575 huart->RxISR = UART_RxISR_8BIT;
4576
4577 /* Enable the UART Data Register Not Empty interrupt */
4578 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4579 }
4580 }
4581 else
4582 {
4583 /* Clear RXNE interrupt flag */
4584 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4585 }
4586 }
4587
4588 /**
4589 * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4590 * @note Function is called under interruption only, once
4591 * interruptions have been enabled by HAL_UART_Receive_IT()
4592 * @param huart UART handle.
4593 * @retval None
4594 */
UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4595 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4596 {
4597 uint16_t *tmp;
4598 uint16_t uhMask = huart->Mask;
4599 uint16_t uhdata;
4600 uint16_t nb_rx_data;
4601 uint16_t rxdatacount;
4602 uint32_t isrflags = READ_REG(huart->Instance->ISR);
4603 uint32_t cr1its = READ_REG(huart->Instance->CR1);
4604 uint32_t cr3its = READ_REG(huart->Instance->CR3);
4605
4606 /* Check that a Rx process is ongoing */
4607 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4608 {
4609 nb_rx_data = huart->NbRxDataToProcess;
4610 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4611 {
4612 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4613 tmp = (uint16_t *) huart->pRxBuffPtr ;
4614 *tmp = (uint16_t)(uhdata & uhMask);
4615 huart->pRxBuffPtr += 2U;
4616 huart->RxXferCount--;
4617 isrflags = READ_REG(huart->Instance->ISR);
4618
4619 /* If some non blocking errors occurred */
4620 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4621 {
4622 /* UART parity error interrupt occurred -------------------------------------*/
4623 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4624 {
4625 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4626
4627 huart->ErrorCode |= HAL_UART_ERROR_PE;
4628 }
4629
4630 /* UART frame error interrupt occurred --------------------------------------*/
4631 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4632 {
4633 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4634
4635 huart->ErrorCode |= HAL_UART_ERROR_FE;
4636 }
4637
4638 /* UART noise error interrupt occurred --------------------------------------*/
4639 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4640 {
4641 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4642
4643 huart->ErrorCode |= HAL_UART_ERROR_NE;
4644 }
4645
4646 /* Call UART Error Call back function if need be ----------------------------*/
4647 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4648 {
4649 /* Non Blocking error : transfer could go on.
4650 Error is notified to user through user error callback */
4651 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4652 /*Call registered error callback*/
4653 huart->ErrorCallback(huart);
4654 #else
4655 /*Call legacy weak error callback*/
4656 HAL_UART_ErrorCallback(huart);
4657 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4658 huart->ErrorCode = HAL_UART_ERROR_NONE;
4659 }
4660 }
4661
4662 if (huart->RxXferCount == 0U)
4663 {
4664 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4665 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4666
4667 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4668 and RX FIFO Threshold interrupt */
4669 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4670
4671 /* Rx process is completed, restore huart->RxState to Ready */
4672 huart->RxState = HAL_UART_STATE_READY;
4673
4674 /* Clear RxISR function pointer */
4675 huart->RxISR = NULL;
4676
4677 /* Initialize type of RxEvent to Transfer Complete */
4678 huart->RxEventType = HAL_UART_RXEVENT_TC;
4679
4680 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4681 {
4682 /* Check that USART RTOEN bit is set */
4683 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4684 {
4685 /* Enable the UART Receiver Timeout Interrupt */
4686 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4687 }
4688 }
4689
4690 /* Check current reception Mode :
4691 If Reception till IDLE event has been selected : */
4692 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4693 {
4694 /* Set reception type to Standard */
4695 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4696
4697 /* Disable IDLE interrupt */
4698 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4699
4700 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4701 {
4702 /* Clear IDLE Flag */
4703 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4704 }
4705
4706 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4707 /*Call registered Rx Event callback*/
4708 huart->RxEventCallback(huart, huart->RxXferSize);
4709 #else
4710 /*Call legacy weak Rx Event callback*/
4711 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4712 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4713 }
4714 else
4715 {
4716 /* Standard reception API called */
4717 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4718 /*Call registered Rx complete callback*/
4719 huart->RxCpltCallback(huart);
4720 #else
4721 /*Call legacy weak Rx complete callback*/
4722 HAL_UART_RxCpltCallback(huart);
4723 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4724 }
4725 }
4726 }
4727
4728 /* When remaining number of bytes to receive is less than the RX FIFO
4729 threshold, next incoming frames are processed as if FIFO mode was
4730 disabled (i.e. one interrupt per received frame).
4731 */
4732 rxdatacount = huart->RxXferCount;
4733 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4734 {
4735 /* Disable the UART RXFT interrupt*/
4736 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4737
4738 /* Update the RxISR function pointer */
4739 huart->RxISR = UART_RxISR_16BIT;
4740
4741 /* Enable the UART Data Register Not Empty interrupt */
4742 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4743 }
4744 }
4745 else
4746 {
4747 /* Clear RXNE interrupt flag */
4748 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4749 }
4750 }
4751
4752 /**
4753 * @}
4754 */
4755
4756 #endif /* HAL_UART_MODULE_ENABLED */
4757 /**
4758 * @}
4759 */
4760
4761 /**
4762 * @}
4763 */
4764