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