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