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