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