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