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