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