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