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