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