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