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