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