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