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