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