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