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