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