1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_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 "stm32g4xx_hal.h"
163 
164 /** @addtogroup STM32G4xx_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       else
2429       {
2430         /* If DMA is in Circular mode, Idle event is to be reported to user
2431            even if occurring after a Transfer Complete event from DMA */
2432         if (nb_remaining_rx_data == huart->RxXferSize)
2433         {
2434           if (HAL_IS_BIT_SET(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC))
2435           {
2436             /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2437                In this case, Rx Event type is Idle Event */
2438             huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2439 
2440 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2441             /*Call registered Rx Event callback*/
2442             huart->RxEventCallback(huart, huart->RxXferSize);
2443 #else
2444             /*Call legacy weak Rx Event callback*/
2445             HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
2446 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2447           }
2448         }
2449       }
2450       return;
2451     }
2452     else
2453     {
2454       /* DMA mode not enabled */
2455       /* Check received length : If all expected data are received, do nothing.
2456          Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2457       uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
2458       if ((huart->RxXferCount > 0U)
2459           && (nb_rx_data > 0U))
2460       {
2461         /* Disable the UART Parity Error Interrupt and RXNE interrupts */
2462         ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2463 
2464         /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
2465         ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2466 
2467         /* Rx process is completed, restore huart->RxState to Ready */
2468         huart->RxState = HAL_UART_STATE_READY;
2469         huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2470 
2471         /* Clear RxISR function pointer */
2472         huart->RxISR = NULL;
2473 
2474         ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2475 
2476         /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2477            In this case, Rx Event type is Idle Event */
2478         huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2479 
2480 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2481         /*Call registered Rx complete callback*/
2482         huart->RxEventCallback(huart, nb_rx_data);
2483 #else
2484         /*Call legacy weak Rx Event callback*/
2485         HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
2486 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2487       }
2488       return;
2489     }
2490   }
2491 
2492   /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2493   if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2494   {
2495     __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2496 
2497     /* UART Rx state is not reset as a reception process might be ongoing.
2498        If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2499 
2500 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2501     /* Call registered Wakeup Callback */
2502     huart->WakeupCallback(huart);
2503 #else
2504     /* Call legacy weak Wakeup Callback */
2505     HAL_UARTEx_WakeupCallback(huart);
2506 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2507     return;
2508   }
2509 
2510   /* UART in mode Transmitter ------------------------------------------------*/
2511   if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2512       && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2513           || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2514   {
2515     if (huart->TxISR != NULL)
2516     {
2517       huart->TxISR(huart);
2518     }
2519     return;
2520   }
2521 
2522   /* UART in mode Transmitter (transmission end) -----------------------------*/
2523   if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2524   {
2525     UART_EndTransmit_IT(huart);
2526     return;
2527   }
2528 
2529   /* UART TX Fifo Empty occurred ----------------------------------------------*/
2530   if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2531   {
2532 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2533     /* Call registered Tx Fifo Empty Callback */
2534     huart->TxFifoEmptyCallback(huart);
2535 #else
2536     /* Call legacy weak Tx Fifo Empty Callback */
2537     HAL_UARTEx_TxFifoEmptyCallback(huart);
2538 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2539     return;
2540   }
2541 
2542   /* UART RX Fifo Full occurred ----------------------------------------------*/
2543   if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2544   {
2545 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2546     /* Call registered Rx Fifo Full Callback */
2547     huart->RxFifoFullCallback(huart);
2548 #else
2549     /* Call legacy weak Rx Fifo Full Callback */
2550     HAL_UARTEx_RxFifoFullCallback(huart);
2551 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2552     return;
2553   }
2554 }
2555 
2556 /**
2557   * @brief Tx Transfer completed callback.
2558   * @param huart UART handle.
2559   * @retval None
2560   */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)2561 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2562 {
2563   /* Prevent unused argument(s) compilation warning */
2564   UNUSED(huart);
2565 
2566   /* NOTE : This function should not be modified, when the callback is needed,
2567             the HAL_UART_TxCpltCallback can be implemented in the user file.
2568    */
2569 }
2570 
2571 /**
2572   * @brief  Tx Half Transfer completed callback.
2573   * @param  huart UART handle.
2574   * @retval None
2575   */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)2576 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2577 {
2578   /* Prevent unused argument(s) compilation warning */
2579   UNUSED(huart);
2580 
2581   /* NOTE: This function should not be modified, when the callback is needed,
2582            the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2583    */
2584 }
2585 
2586 /**
2587   * @brief  Rx Transfer completed callback.
2588   * @param  huart UART handle.
2589   * @retval None
2590   */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)2591 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2592 {
2593   /* Prevent unused argument(s) compilation warning */
2594   UNUSED(huart);
2595 
2596   /* NOTE : This function should not be modified, when the callback is needed,
2597             the HAL_UART_RxCpltCallback can be implemented in the user file.
2598    */
2599 }
2600 
2601 /**
2602   * @brief  Rx Half Transfer completed callback.
2603   * @param  huart UART handle.
2604   * @retval None
2605   */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)2606 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2607 {
2608   /* Prevent unused argument(s) compilation warning */
2609   UNUSED(huart);
2610 
2611   /* NOTE: This function should not be modified, when the callback is needed,
2612            the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2613    */
2614 }
2615 
2616 /**
2617   * @brief  UART error callback.
2618   * @param  huart UART handle.
2619   * @retval None
2620   */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)2621 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2622 {
2623   /* Prevent unused argument(s) compilation warning */
2624   UNUSED(huart);
2625 
2626   /* NOTE : This function should not be modified, when the callback is needed,
2627             the HAL_UART_ErrorCallback can be implemented in the user file.
2628    */
2629 }
2630 
2631 /**
2632   * @brief  UART Abort Complete callback.
2633   * @param  huart UART handle.
2634   * @retval None
2635   */
HAL_UART_AbortCpltCallback(UART_HandleTypeDef * huart)2636 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2637 {
2638   /* Prevent unused argument(s) compilation warning */
2639   UNUSED(huart);
2640 
2641   /* NOTE : This function should not be modified, when the callback is needed,
2642             the HAL_UART_AbortCpltCallback can be implemented in the user file.
2643    */
2644 }
2645 
2646 /**
2647   * @brief  UART Abort Complete callback.
2648   * @param  huart UART handle.
2649   * @retval None
2650   */
HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef * huart)2651 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2652 {
2653   /* Prevent unused argument(s) compilation warning */
2654   UNUSED(huart);
2655 
2656   /* NOTE : This function should not be modified, when the callback is needed,
2657             the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2658    */
2659 }
2660 
2661 /**
2662   * @brief  UART Abort Receive Complete callback.
2663   * @param  huart UART handle.
2664   * @retval None
2665   */
HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef * huart)2666 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2667 {
2668   /* Prevent unused argument(s) compilation warning */
2669   UNUSED(huart);
2670 
2671   /* NOTE : This function should not be modified, when the callback is needed,
2672             the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2673    */
2674 }
2675 
2676 /**
2677   * @brief  Reception Event Callback (Rx event notification called after use of advanced reception service).
2678   * @param  huart UART handle
2679   * @param  Size  Number of data available in application reception buffer (indicates a position in
2680   *               reception buffer until which, data are available)
2681   * @retval None
2682   */
HAL_UARTEx_RxEventCallback(UART_HandleTypeDef * huart,uint16_t Size)2683 __weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
2684 {
2685   /* Prevent unused argument(s) compilation warning */
2686   UNUSED(huart);
2687   UNUSED(Size);
2688 
2689   /* NOTE : This function should not be modified, when the callback is needed,
2690             the HAL_UARTEx_RxEventCallback can be implemented in the user file.
2691    */
2692 }
2693 
2694 /**
2695   * @}
2696   */
2697 
2698 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2699   *  @brief   UART control functions
2700   *
2701 @verbatim
2702  ===============================================================================
2703                       ##### Peripheral Control functions #####
2704  ===============================================================================
2705     [..]
2706     This subsection provides a set of functions allowing to control the UART.
2707      (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2708      (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2709      (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2710      (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2711      (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2712      (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2713      (+) UART_SetConfig() API configures the UART peripheral
2714      (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2715      (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2716      (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2717      (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2718      (+) HAL_LIN_SendBreak() API transmits the break characters
2719 @endverbatim
2720   * @{
2721   */
2722 
2723 /**
2724   * @brief  Update on the fly the receiver timeout value in RTOR register.
2725   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2726   *                    the configuration information for the specified UART module.
2727   * @param  TimeoutValue receiver timeout value in number of baud blocks. The timeout
2728   *                     value must be less or equal to 0x0FFFFFFFF.
2729   * @retval None
2730   */
HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef * huart,uint32_t TimeoutValue)2731 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2732 {
2733   if (!(IS_LPUART_INSTANCE(huart->Instance)))
2734   {
2735     assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2736     MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2737   }
2738 }
2739 
2740 /**
2741   * @brief  Enable the UART receiver timeout feature.
2742   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2743   *                    the configuration information for the specified UART module.
2744   * @retval HAL status
2745   */
HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef * huart)2746 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2747 {
2748   if (!(IS_LPUART_INSTANCE(huart->Instance)))
2749   {
2750     if (huart->gState == HAL_UART_STATE_READY)
2751     {
2752       /* Process Locked */
2753       __HAL_LOCK(huart);
2754 
2755       huart->gState = HAL_UART_STATE_BUSY;
2756 
2757       /* Set the USART RTOEN bit */
2758       SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2759 
2760       huart->gState = HAL_UART_STATE_READY;
2761 
2762       /* Process Unlocked */
2763       __HAL_UNLOCK(huart);
2764 
2765       return HAL_OK;
2766     }
2767     else
2768     {
2769       return HAL_BUSY;
2770     }
2771   }
2772   else
2773   {
2774     return HAL_ERROR;
2775   }
2776 }
2777 
2778 /**
2779   * @brief  Disable the UART receiver timeout feature.
2780   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2781   *                    the configuration information for the specified UART module.
2782   * @retval HAL status
2783   */
HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef * huart)2784 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2785 {
2786   if (!(IS_LPUART_INSTANCE(huart->Instance)))
2787   {
2788     if (huart->gState == HAL_UART_STATE_READY)
2789     {
2790       /* Process Locked */
2791       __HAL_LOCK(huart);
2792 
2793       huart->gState = HAL_UART_STATE_BUSY;
2794 
2795       /* Clear the USART RTOEN bit */
2796       CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2797 
2798       huart->gState = HAL_UART_STATE_READY;
2799 
2800       /* Process Unlocked */
2801       __HAL_UNLOCK(huart);
2802 
2803       return HAL_OK;
2804     }
2805     else
2806     {
2807       return HAL_BUSY;
2808     }
2809   }
2810   else
2811   {
2812     return HAL_ERROR;
2813   }
2814 }
2815 
2816 /**
2817   * @brief  Enable UART in mute mode (does not mean UART enters mute mode;
2818   *         to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2819   * @param  huart UART handle.
2820   * @retval HAL status
2821   */
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef * huart)2822 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2823 {
2824   __HAL_LOCK(huart);
2825 
2826   huart->gState = HAL_UART_STATE_BUSY;
2827 
2828   /* Enable USART mute mode by setting the MME bit in the CR1 register */
2829   ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2830 
2831   huart->gState = HAL_UART_STATE_READY;
2832 
2833   return (UART_CheckIdleState(huart));
2834 }
2835 
2836 /**
2837   * @brief  Disable UART mute mode (does not mean the UART actually exits mute mode
2838   *         as it may not have been in mute mode at this very moment).
2839   * @param  huart UART handle.
2840   * @retval HAL status
2841   */
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef * huart)2842 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2843 {
2844   __HAL_LOCK(huart);
2845 
2846   huart->gState = HAL_UART_STATE_BUSY;
2847 
2848   /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2849   ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2850 
2851   huart->gState = HAL_UART_STATE_READY;
2852 
2853   return (UART_CheckIdleState(huart));
2854 }
2855 
2856 /**
2857   * @brief Enter UART mute mode (means UART actually enters mute mode).
2858   * @note  To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2859   * @param huart UART handle.
2860   * @retval None
2861   */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)2862 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2863 {
2864   __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2865 }
2866 
2867 /**
2868   * @brief  Enable the UART transmitter and disable the UART receiver.
2869   * @param  huart UART handle.
2870   * @retval HAL status
2871   */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)2872 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2873 {
2874   __HAL_LOCK(huart);
2875   huart->gState = HAL_UART_STATE_BUSY;
2876 
2877   /* Clear TE and RE bits */
2878   ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2879 
2880   /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2881   ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2882 
2883   huart->gState = HAL_UART_STATE_READY;
2884 
2885   __HAL_UNLOCK(huart);
2886 
2887   return HAL_OK;
2888 }
2889 
2890 /**
2891   * @brief  Enable the UART receiver and disable the UART transmitter.
2892   * @param  huart UART handle.
2893   * @retval HAL status.
2894   */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)2895 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2896 {
2897   __HAL_LOCK(huart);
2898   huart->gState = HAL_UART_STATE_BUSY;
2899 
2900   /* Clear TE and RE bits */
2901   ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2902 
2903   /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2904   ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2905 
2906   huart->gState = HAL_UART_STATE_READY;
2907 
2908   __HAL_UNLOCK(huart);
2909 
2910   return HAL_OK;
2911 }
2912 
2913 
2914 /**
2915   * @brief  Transmit break characters.
2916   * @param  huart UART handle.
2917   * @retval HAL status
2918   */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)2919 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
2920 {
2921   /* Check the parameters */
2922   assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
2923 
2924   __HAL_LOCK(huart);
2925 
2926   huart->gState = HAL_UART_STATE_BUSY;
2927 
2928   /* Send break characters */
2929   __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
2930 
2931   huart->gState = HAL_UART_STATE_READY;
2932 
2933   __HAL_UNLOCK(huart);
2934 
2935   return HAL_OK;
2936 }
2937 
2938 /**
2939   * @}
2940   */
2941 
2942 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
2943   *  @brief   UART Peripheral State functions
2944   *
2945 @verbatim
2946   ==============================================================================
2947             ##### Peripheral State and Error functions #####
2948   ==============================================================================
2949     [..]
2950     This subsection provides functions allowing to :
2951       (+) Return the UART handle state.
2952       (+) Return the UART handle error code
2953 
2954 @endverbatim
2955   * @{
2956   */
2957 
2958 /**
2959   * @brief Return the UART handle state.
2960   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2961   *               the configuration information for the specified UART.
2962   * @retval HAL state
2963   */
HAL_UART_GetState(const UART_HandleTypeDef * huart)2964 HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
2965 {
2966   uint32_t temp1;
2967   uint32_t temp2;
2968   temp1 = huart->gState;
2969   temp2 = huart->RxState;
2970 
2971   return (HAL_UART_StateTypeDef)(temp1 | temp2);
2972 }
2973 
2974 /**
2975   * @brief  Return the UART handle error code.
2976   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
2977   *               the configuration information for the specified UART.
2978   * @retval UART Error Code
2979   */
HAL_UART_GetError(const UART_HandleTypeDef * huart)2980 uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
2981 {
2982   return huart->ErrorCode;
2983 }
2984 /**
2985   * @}
2986   */
2987 
2988 /**
2989   * @}
2990   */
2991 
2992 /** @defgroup UART_Private_Functions UART Private Functions
2993   * @{
2994   */
2995 
2996 /**
2997   * @brief  Initialize the callbacks to their default values.
2998   * @param  huart UART handle.
2999   * @retval none
3000   */
3001 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(UART_HandleTypeDef * huart)3002 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
3003 {
3004   /* Init the UART Callback settings */
3005   huart->TxHalfCpltCallback        = HAL_UART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
3006   huart->TxCpltCallback            = HAL_UART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
3007   huart->RxHalfCpltCallback        = HAL_UART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
3008   huart->RxCpltCallback            = HAL_UART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
3009   huart->ErrorCallback             = HAL_UART_ErrorCallback;             /* Legacy weak ErrorCallback             */
3010   huart->AbortCpltCallback         = HAL_UART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
3011   huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
3012   huart->AbortReceiveCpltCallback  = HAL_UART_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
3013   huart->WakeupCallback            = HAL_UARTEx_WakeupCallback;          /* Legacy weak WakeupCallback            */
3014   huart->RxFifoFullCallback        = HAL_UARTEx_RxFifoFullCallback;      /* Legacy weak RxFifoFullCallback        */
3015   huart->TxFifoEmptyCallback       = HAL_UARTEx_TxFifoEmptyCallback;     /* Legacy weak TxFifoEmptyCallback       */
3016   huart->RxEventCallback           = HAL_UARTEx_RxEventCallback;         /* Legacy weak RxEventCallback           */
3017 
3018 }
3019 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3020 
3021 /**
3022   * @brief Configure the UART peripheral.
3023   * @param huart UART handle.
3024   * @retval HAL status
3025   */
UART_SetConfig(UART_HandleTypeDef * huart)3026 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
3027 {
3028   uint32_t tmpreg;
3029   uint16_t brrtemp;
3030   UART_ClockSourceTypeDef clocksource;
3031   uint32_t usartdiv;
3032   HAL_StatusTypeDef ret               = HAL_OK;
3033   uint32_t lpuart_ker_ck_pres;
3034   uint32_t pclk;
3035 
3036   /* Check the parameters */
3037   assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
3038   assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
3039   if (UART_INSTANCE_LOWPOWER(huart))
3040   {
3041     assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
3042   }
3043   else
3044   {
3045     assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
3046     assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
3047   }
3048 
3049   assert_param(IS_UART_PARITY(huart->Init.Parity));
3050   assert_param(IS_UART_MODE(huart->Init.Mode));
3051   assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
3052   assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
3053   assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
3054 
3055   /*-------------------------- USART CR1 Configuration -----------------------*/
3056   /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
3057   *  the UART Word Length, Parity, Mode and oversampling:
3058   *  set the M bits according to huart->Init.WordLength value
3059   *  set PCE and PS bits according to huart->Init.Parity value
3060   *  set TE and RE bits according to huart->Init.Mode value
3061   *  set OVER8 bit according to huart->Init.OverSampling value */
3062   tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
3063   MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3064 
3065   /*-------------------------- USART CR2 Configuration -----------------------*/
3066   /* Configure the UART Stop Bits: Set STOP[13:12] bits according
3067   * to huart->Init.StopBits value */
3068   MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
3069 
3070   /*-------------------------- USART CR3 Configuration -----------------------*/
3071   /* Configure
3072   * - UART HardWare Flow Control: set CTSE and RTSE bits according
3073   *   to huart->Init.HwFlowCtl value
3074   * - one-bit sampling method versus three samples' majority rule according
3075   *   to huart->Init.OneBitSampling (not applicable to LPUART) */
3076   tmpreg = (uint32_t)huart->Init.HwFlowCtl;
3077 
3078   if (!(UART_INSTANCE_LOWPOWER(huart)))
3079   {
3080     tmpreg |= huart->Init.OneBitSampling;
3081   }
3082   MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
3083 
3084   /*-------------------------- USART PRESC Configuration -----------------------*/
3085   /* Configure
3086   * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
3087   MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
3088 
3089   /*-------------------------- USART BRR Configuration -----------------------*/
3090   UART_GETCLOCKSOURCE(huart, clocksource);
3091 
3092   /* Check LPUART instance */
3093   if (UART_INSTANCE_LOWPOWER(huart))
3094   {
3095     /* Retrieve frequency clock */
3096     switch (clocksource)
3097     {
3098       case UART_CLOCKSOURCE_PCLK1:
3099         pclk = HAL_RCC_GetPCLK1Freq();
3100         break;
3101       case UART_CLOCKSOURCE_HSI:
3102         pclk = (uint32_t) HSI_VALUE;
3103         break;
3104       case UART_CLOCKSOURCE_SYSCLK:
3105         pclk = HAL_RCC_GetSysClockFreq();
3106         break;
3107       case UART_CLOCKSOURCE_LSE:
3108         pclk = (uint32_t) LSE_VALUE;
3109         break;
3110       default:
3111         pclk = 0U;
3112         ret = HAL_ERROR;
3113         break;
3114     }
3115 
3116     /* If proper clock source reported */
3117     if (pclk != 0U)
3118     {
3119       /* Compute clock after Prescaler */
3120       lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]);
3121 
3122       /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
3123       if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
3124           (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
3125       {
3126         ret = HAL_ERROR;
3127       }
3128       else
3129       {
3130         /* Check computed UsartDiv value is in allocated range
3131            (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */
3132         usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3133         if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
3134         {
3135           huart->Instance->BRR = usartdiv;
3136         }
3137         else
3138         {
3139           ret = HAL_ERROR;
3140         }
3141       } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) ||
3142                 (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
3143     } /* if (pclk != 0) */
3144   }
3145   /* Check UART Over Sampling to set Baud Rate Register */
3146   else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3147   {
3148     switch (clocksource)
3149     {
3150       case UART_CLOCKSOURCE_PCLK1:
3151         pclk = HAL_RCC_GetPCLK1Freq();
3152         break;
3153       case UART_CLOCKSOURCE_PCLK2:
3154         pclk = HAL_RCC_GetPCLK2Freq();
3155         break;
3156       case UART_CLOCKSOURCE_HSI:
3157         pclk = (uint32_t) HSI_VALUE;
3158         break;
3159       case UART_CLOCKSOURCE_SYSCLK:
3160         pclk = HAL_RCC_GetSysClockFreq();
3161         break;
3162       case UART_CLOCKSOURCE_LSE:
3163         pclk = (uint32_t) LSE_VALUE;
3164         break;
3165       default:
3166         pclk = 0U;
3167         ret = HAL_ERROR;
3168         break;
3169     }
3170 
3171     /* USARTDIV must be greater than or equal to 0d16 */
3172     if (pclk != 0U)
3173     {
3174       usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3175       if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3176       {
3177         brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3178         brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3179         huart->Instance->BRR = brrtemp;
3180       }
3181       else
3182       {
3183         ret = HAL_ERROR;
3184       }
3185     }
3186   }
3187   else
3188   {
3189     switch (clocksource)
3190     {
3191       case UART_CLOCKSOURCE_PCLK1:
3192         pclk = HAL_RCC_GetPCLK1Freq();
3193         break;
3194       case UART_CLOCKSOURCE_PCLK2:
3195         pclk = HAL_RCC_GetPCLK2Freq();
3196         break;
3197       case UART_CLOCKSOURCE_HSI:
3198         pclk = (uint32_t) HSI_VALUE;
3199         break;
3200       case UART_CLOCKSOURCE_SYSCLK:
3201         pclk = HAL_RCC_GetSysClockFreq();
3202         break;
3203       case UART_CLOCKSOURCE_LSE:
3204         pclk = (uint32_t) LSE_VALUE;
3205         break;
3206       default:
3207         pclk = 0U;
3208         ret = HAL_ERROR;
3209         break;
3210     }
3211 
3212     if (pclk != 0U)
3213     {
3214       /* USARTDIV must be greater than or equal to 0d16 */
3215       usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3216       if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3217       {
3218         huart->Instance->BRR = (uint16_t)usartdiv;
3219       }
3220       else
3221       {
3222         ret = HAL_ERROR;
3223       }
3224     }
3225   }
3226 
3227   /* Initialize the number of data to process during RX/TX ISR execution */
3228   huart->NbTxDataToProcess = 1;
3229   huart->NbRxDataToProcess = 1;
3230 
3231   /* Clear ISR function pointers */
3232   huart->RxISR = NULL;
3233   huart->TxISR = NULL;
3234 
3235   return ret;
3236 }
3237 
3238 /**
3239   * @brief Configure the UART peripheral advanced features.
3240   * @param huart UART handle.
3241   * @retval None
3242   */
UART_AdvFeatureConfig(UART_HandleTypeDef * huart)3243 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3244 {
3245   /* Check whether the set of advanced features to configure is properly set */
3246   assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3247 
3248   /* if required, configure RX/TX pins swap */
3249   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3250   {
3251     assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3252     MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3253   }
3254 
3255   /* if required, configure TX pin active level inversion */
3256   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3257   {
3258     assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3259     MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3260   }
3261 
3262   /* if required, configure RX pin active level inversion */
3263   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3264   {
3265     assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3266     MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3267   }
3268 
3269   /* if required, configure data inversion */
3270   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3271   {
3272     assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3273     MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3274   }
3275 
3276   /* if required, configure RX overrun detection disabling */
3277   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3278   {
3279     assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3280     MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3281   }
3282 
3283   /* if required, configure DMA disabling on reception error */
3284   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3285   {
3286     assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3287     MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3288   }
3289 
3290   /* if required, configure auto Baud rate detection scheme */
3291   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3292   {
3293     assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3294     assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3295     MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3296     /* set auto Baudrate detection parameters if detection is enabled */
3297     if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3298     {
3299       assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3300       MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3301     }
3302   }
3303 
3304   /* if required, configure MSB first on communication line */
3305   if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3306   {
3307     assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3308     MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3309   }
3310 }
3311 
3312 /**
3313   * @brief Check the UART Idle State.
3314   * @param huart UART handle.
3315   * @retval HAL status
3316   */
UART_CheckIdleState(UART_HandleTypeDef * huart)3317 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3318 {
3319   uint32_t tickstart;
3320 
3321   /* Initialize the UART ErrorCode */
3322   huart->ErrorCode = HAL_UART_ERROR_NONE;
3323 
3324   /* Init tickstart for timeout management */
3325   tickstart = HAL_GetTick();
3326 
3327   /* Check if the Transmitter is enabled */
3328   if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3329   {
3330     /* Wait until TEACK flag is set */
3331     if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3332     {
3333       /* Disable TXE interrupt for the interrupt process */
3334       ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE));
3335 
3336       huart->gState = HAL_UART_STATE_READY;
3337 
3338       __HAL_UNLOCK(huart);
3339 
3340       /* Timeout occurred */
3341       return HAL_TIMEOUT;
3342     }
3343   }
3344 
3345   /* Check if the Receiver is enabled */
3346   if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3347   {
3348     /* Wait until REACK flag is set */
3349     if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3350     {
3351       /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error)
3352       interrupts for the interrupt process */
3353       ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3354       ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3355 
3356       huart->RxState = HAL_UART_STATE_READY;
3357 
3358       __HAL_UNLOCK(huart);
3359 
3360       /* Timeout occurred */
3361       return HAL_TIMEOUT;
3362     }
3363   }
3364 
3365   /* Initialize the UART State */
3366   huart->gState = HAL_UART_STATE_READY;
3367   huart->RxState = HAL_UART_STATE_READY;
3368   huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3369   huart->RxEventType = HAL_UART_RXEVENT_TC;
3370 
3371   __HAL_UNLOCK(huart);
3372 
3373   return HAL_OK;
3374 }
3375 
3376 /**
3377   * @brief  This function handles UART Communication Timeout. It waits
3378   *                  until a flag is no longer in the specified status.
3379   * @param huart     UART handle.
3380   * @param Flag      Specifies the UART flag to check
3381   * @param Status    The actual Flag status (SET or RESET)
3382   * @param Tickstart Tick start value
3383   * @param Timeout   Timeout duration
3384   * @retval HAL status
3385   */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3386 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3387                                               uint32_t Tickstart, uint32_t Timeout)
3388 {
3389   /* Wait until flag is set */
3390   while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3391   {
3392     /* Check for the Timeout */
3393     if (Timeout != HAL_MAX_DELAY)
3394     {
3395       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3396       {
3397 
3398         return HAL_TIMEOUT;
3399       }
3400 
3401       if ((READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC))
3402       {
3403         if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
3404         {
3405           /* Clear Overrun Error flag*/
3406           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
3407 
3408           /* Blocking error : transfer is aborted
3409           Set the UART state ready to be able to start again the process,
3410           Disable Rx Interrupts if ongoing */
3411           UART_EndRxTransfer(huart);
3412 
3413           huart->ErrorCode = HAL_UART_ERROR_ORE;
3414 
3415           /* Process Unlocked */
3416           __HAL_UNLOCK(huart);
3417 
3418           return HAL_ERROR;
3419         }
3420         if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3421         {
3422           /* Clear Receiver Timeout flag*/
3423           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3424 
3425           /* Blocking error : transfer is aborted
3426           Set the UART state ready to be able to start again the process,
3427           Disable Rx Interrupts if ongoing */
3428           UART_EndRxTransfer(huart);
3429 
3430           huart->ErrorCode = HAL_UART_ERROR_RTO;
3431 
3432           /* Process Unlocked */
3433           __HAL_UNLOCK(huart);
3434 
3435           return HAL_TIMEOUT;
3436         }
3437       }
3438     }
3439   }
3440   return HAL_OK;
3441 }
3442 
3443 /**
3444   * @brief  Start Receive operation in interrupt mode.
3445   * @note   This function could be called by all HAL UART API providing reception in Interrupt mode.
3446   * @note   When calling this function, parameters validity is considered as already checked,
3447   *         i.e. Rx State, buffer address, ...
3448   *         UART Handle is assumed as Locked.
3449   * @param  huart UART handle.
3450   * @param  pData Pointer to data buffer (u8 or u16 data elements).
3451   * @param  Size  Amount of data elements (u8 or u16) to be received.
3452   * @retval HAL status
3453   */
UART_Start_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3454 HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3455 {
3456   huart->pRxBuffPtr  = pData;
3457   huart->RxXferSize  = Size;
3458   huart->RxXferCount = Size;
3459   huart->RxISR       = NULL;
3460 
3461   /* Computation of UART mask to apply to RDR register */
3462   UART_MASK_COMPUTATION(huart);
3463 
3464   huart->ErrorCode = HAL_UART_ERROR_NONE;
3465   huart->RxState = HAL_UART_STATE_BUSY_RX;
3466 
3467   /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3468   ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3469 
3470   /* Configure Rx interrupt processing */
3471   if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
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_FIFOEN;
3477     }
3478     else
3479     {
3480       huart->RxISR = UART_RxISR_8BIT_FIFOEN;
3481     }
3482 
3483     /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
3484     if (huart->Init.Parity != UART_PARITY_NONE)
3485     {
3486       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3487     }
3488     ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
3489   }
3490   else
3491   {
3492     /* Set the Rx ISR function pointer according to the data word length */
3493     if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3494     {
3495       huart->RxISR = UART_RxISR_16BIT;
3496     }
3497     else
3498     {
3499       huart->RxISR = UART_RxISR_8BIT;
3500     }
3501 
3502     /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
3503     if (huart->Init.Parity != UART_PARITY_NONE)
3504     {
3505       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
3506     }
3507     else
3508     {
3509       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3510     }
3511   }
3512   return HAL_OK;
3513 }
3514 
3515 /**
3516   * @brief  Start Receive operation in DMA mode.
3517   * @note   This function could be called by all HAL UART API providing reception in DMA mode.
3518   * @note   When calling this function, parameters validity is considered as already checked,
3519   *         i.e. Rx State, buffer address, ...
3520   *         UART Handle is assumed as Locked.
3521   * @param  huart UART handle.
3522   * @param  pData Pointer to data buffer (u8 or u16 data elements).
3523   * @param  Size  Amount of data elements (u8 or u16) to be received.
3524   * @retval HAL status
3525   */
UART_Start_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3526 HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3527 {
3528   huart->pRxBuffPtr = pData;
3529   huart->RxXferSize = Size;
3530 
3531   huart->ErrorCode = HAL_UART_ERROR_NONE;
3532   huart->RxState = HAL_UART_STATE_BUSY_RX;
3533 
3534   if (huart->hdmarx != NULL)
3535   {
3536     /* Set the UART DMA transfer complete callback */
3537     huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
3538 
3539     /* Set the UART DMA Half transfer complete callback */
3540     huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
3541 
3542     /* Set the DMA error callback */
3543     huart->hdmarx->XferErrorCallback = UART_DMAError;
3544 
3545     /* Set the DMA abort callback */
3546     huart->hdmarx->XferAbortCallback = NULL;
3547 
3548     /* Enable the DMA channel */
3549     if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
3550     {
3551       /* Set error code to DMA */
3552       huart->ErrorCode = HAL_UART_ERROR_DMA;
3553 
3554       /* Restore huart->RxState to ready */
3555       huart->RxState = HAL_UART_STATE_READY;
3556 
3557       return HAL_ERROR;
3558     }
3559   }
3560 
3561   /* Enable the UART Parity Error Interrupt */
3562   if (huart->Init.Parity != UART_PARITY_NONE)
3563   {
3564     ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3565   }
3566 
3567   /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3568   ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3569 
3570   /* Enable the DMA transfer for the receiver request by setting the DMAR bit
3571   in the UART CR3 register */
3572   ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3573 
3574   return HAL_OK;
3575 }
3576 
3577 
3578 /**
3579   * @brief  End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3580   * @param  huart UART handle.
3581   * @retval None
3582   */
UART_EndTxTransfer(UART_HandleTypeDef * huart)3583 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3584 {
3585   /* Disable TXEIE, TCIE, TXFT interrupts */
3586   ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3587   ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3588 
3589   /* At end of Tx process, restore huart->gState to Ready */
3590   huart->gState = HAL_UART_STATE_READY;
3591 }
3592 
3593 
3594 /**
3595   * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3596   * @param  huart UART handle.
3597   * @retval None
3598   */
UART_EndRxTransfer(UART_HandleTypeDef * huart)3599 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3600 {
3601   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3602   ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3603   ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3604 
3605   /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
3606   if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3607   {
3608     ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3609   }
3610 
3611   /* At end of Rx process, restore huart->RxState to Ready */
3612   huart->RxState = HAL_UART_STATE_READY;
3613   huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3614 
3615   /* Reset RxIsr function pointer */
3616   huart->RxISR = NULL;
3617 }
3618 
3619 
3620 /**
3621   * @brief DMA UART transmit process complete callback.
3622   * @param hdma DMA handle.
3623   * @retval None
3624   */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)3625 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3626 {
3627   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3628 
3629   /* DMA Normal mode */
3630   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3631   {
3632     huart->TxXferCount = 0U;
3633 
3634     /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3635        in the UART CR3 register */
3636     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
3637 
3638     /* Enable the UART Transmit Complete Interrupt */
3639     ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3640   }
3641   /* DMA Circular mode */
3642   else
3643   {
3644 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3645     /*Call registered Tx complete callback*/
3646     huart->TxCpltCallback(huart);
3647 #else
3648     /*Call legacy weak Tx complete callback*/
3649     HAL_UART_TxCpltCallback(huart);
3650 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3651   }
3652 }
3653 
3654 /**
3655   * @brief DMA UART transmit process half complete callback.
3656   * @param hdma DMA handle.
3657   * @retval None
3658   */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)3659 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3660 {
3661   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3662 
3663 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3664   /*Call registered Tx Half complete callback*/
3665   huart->TxHalfCpltCallback(huart);
3666 #else
3667   /*Call legacy weak Tx Half complete callback*/
3668   HAL_UART_TxHalfCpltCallback(huart);
3669 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3670 }
3671 
3672 /**
3673   * @brief DMA UART receive process complete callback.
3674   * @param hdma DMA handle.
3675   * @retval None
3676   */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3677 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3678 {
3679   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3680 
3681   /* DMA Normal mode */
3682   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3683   {
3684     huart->RxXferCount = 0U;
3685 
3686     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3687     ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3688     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3689 
3690     /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3691        in the UART CR3 register */
3692     ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3693 
3694     /* At end of Rx process, restore huart->RxState to Ready */
3695     huart->RxState = HAL_UART_STATE_READY;
3696 
3697     /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
3698     if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3699     {
3700       ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3701     }
3702   }
3703 
3704   /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3705      In this case, Rx Event type is Transfer Complete */
3706   huart->RxEventType = HAL_UART_RXEVENT_TC;
3707 
3708   /* Check current reception Mode :
3709      If Reception till IDLE event has been selected : use Rx Event callback */
3710   if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3711   {
3712 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3713     /*Call registered Rx Event callback*/
3714     huart->RxEventCallback(huart, huart->RxXferSize);
3715 #else
3716     /*Call legacy weak Rx Event callback*/
3717     HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
3718 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3719   }
3720   else
3721   {
3722     /* In other cases : use Rx Complete callback */
3723 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3724     /*Call registered Rx complete callback*/
3725     huart->RxCpltCallback(huart);
3726 #else
3727     /*Call legacy weak Rx complete callback*/
3728     HAL_UART_RxCpltCallback(huart);
3729 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3730   }
3731 }
3732 
3733 /**
3734   * @brief DMA UART receive process half complete callback.
3735   * @param hdma DMA handle.
3736   * @retval None
3737   */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)3738 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3739 {
3740   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3741 
3742   /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3743      In this case, Rx Event type is Half Transfer */
3744   huart->RxEventType = HAL_UART_RXEVENT_HT;
3745 
3746   /* Check current reception Mode :
3747      If Reception till IDLE event has been selected : use Rx Event callback */
3748   if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3749   {
3750 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3751     /*Call registered Rx Event callback*/
3752     huart->RxEventCallback(huart, huart->RxXferSize / 2U);
3753 #else
3754     /*Call legacy weak Rx Event callback*/
3755     HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
3756 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3757   }
3758   else
3759   {
3760     /* In other cases : use Rx Half Complete callback */
3761 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3762     /*Call registered Rx Half complete callback*/
3763     huart->RxHalfCpltCallback(huart);
3764 #else
3765     /*Call legacy weak Rx Half complete callback*/
3766     HAL_UART_RxHalfCpltCallback(huart);
3767 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3768   }
3769 }
3770 
3771 /**
3772   * @brief DMA UART communication error callback.
3773   * @param hdma DMA handle.
3774   * @retval None
3775   */
UART_DMAError(DMA_HandleTypeDef * hdma)3776 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3777 {
3778   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3779 
3780   const HAL_UART_StateTypeDef gstate = huart->gState;
3781   const HAL_UART_StateTypeDef rxstate = huart->RxState;
3782 
3783   /* Stop UART DMA Tx request if ongoing */
3784   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3785       (gstate == HAL_UART_STATE_BUSY_TX))
3786   {
3787     huart->TxXferCount = 0U;
3788     UART_EndTxTransfer(huart);
3789   }
3790 
3791   /* Stop UART DMA Rx request if ongoing */
3792   if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3793       (rxstate == HAL_UART_STATE_BUSY_RX))
3794   {
3795     huart->RxXferCount = 0U;
3796     UART_EndRxTransfer(huart);
3797   }
3798 
3799   huart->ErrorCode |= HAL_UART_ERROR_DMA;
3800 
3801 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3802   /*Call registered error callback*/
3803   huart->ErrorCallback(huart);
3804 #else
3805   /*Call legacy weak error callback*/
3806   HAL_UART_ErrorCallback(huart);
3807 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3808 }
3809 
3810 /**
3811   * @brief  DMA UART communication abort callback, when initiated by HAL services on Error
3812   *         (To be called at end of DMA Abort procedure following error occurrence).
3813   * @param  hdma DMA handle.
3814   * @retval None
3815   */
UART_DMAAbortOnError(DMA_HandleTypeDef * hdma)3816 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3817 {
3818   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3819   huart->RxXferCount = 0U;
3820 
3821 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3822   /*Call registered error callback*/
3823   huart->ErrorCallback(huart);
3824 #else
3825   /*Call legacy weak error callback*/
3826   HAL_UART_ErrorCallback(huart);
3827 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3828 }
3829 
3830 /**
3831   * @brief  DMA UART Tx communication abort callback, when initiated by user
3832   *         (To be called at end of DMA Tx Abort procedure following user abort request).
3833   * @note   When this callback is executed, User Abort complete call back is called only if no
3834   *         Abort still ongoing for Rx DMA Handle.
3835   * @param  hdma DMA handle.
3836   * @retval None
3837   */
UART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3838 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3839 {
3840   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3841 
3842   huart->hdmatx->XferAbortCallback = NULL;
3843 
3844   /* Check if an Abort process is still ongoing */
3845   if (huart->hdmarx != NULL)
3846   {
3847     if (huart->hdmarx->XferAbortCallback != NULL)
3848     {
3849       return;
3850     }
3851   }
3852 
3853   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3854   huart->TxXferCount = 0U;
3855   huart->RxXferCount = 0U;
3856 
3857   /* Reset errorCode */
3858   huart->ErrorCode = HAL_UART_ERROR_NONE;
3859 
3860   /* Clear the Error flags in the ICR register */
3861   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3862 
3863   /* Flush the whole TX FIFO (if needed) */
3864   if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3865   {
3866     __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3867   }
3868 
3869   /* Restore huart->gState and huart->RxState to Ready */
3870   huart->gState  = HAL_UART_STATE_READY;
3871   huart->RxState = HAL_UART_STATE_READY;
3872   huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3873 
3874   /* Call user Abort complete callback */
3875 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3876   /* Call registered Abort complete callback */
3877   huart->AbortCpltCallback(huart);
3878 #else
3879   /* Call legacy weak Abort complete callback */
3880   HAL_UART_AbortCpltCallback(huart);
3881 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3882 }
3883 
3884 
3885 /**
3886   * @brief  DMA UART Rx communication abort callback, when initiated by user
3887   *         (To be called at end of DMA Rx Abort procedure following user abort request).
3888   * @note   When this callback is executed, User Abort complete call back is called only if no
3889   *         Abort still ongoing for Tx DMA Handle.
3890   * @param  hdma DMA handle.
3891   * @retval None
3892   */
UART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3893 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3894 {
3895   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3896 
3897   huart->hdmarx->XferAbortCallback = NULL;
3898 
3899   /* Check if an Abort process is still ongoing */
3900   if (huart->hdmatx != NULL)
3901   {
3902     if (huart->hdmatx->XferAbortCallback != NULL)
3903     {
3904       return;
3905     }
3906   }
3907 
3908   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3909   huart->TxXferCount = 0U;
3910   huart->RxXferCount = 0U;
3911 
3912   /* Reset errorCode */
3913   huart->ErrorCode = HAL_UART_ERROR_NONE;
3914 
3915   /* Clear the Error flags in the ICR register */
3916   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3917 
3918   /* Discard the received data */
3919   __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3920 
3921   /* Restore huart->gState and huart->RxState to Ready */
3922   huart->gState  = HAL_UART_STATE_READY;
3923   huart->RxState = HAL_UART_STATE_READY;
3924   huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3925 
3926   /* Call user Abort complete callback */
3927 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3928   /* Call registered Abort complete callback */
3929   huart->AbortCpltCallback(huart);
3930 #else
3931   /* Call legacy weak Abort complete callback */
3932   HAL_UART_AbortCpltCallback(huart);
3933 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3934 }
3935 
3936 
3937 /**
3938   * @brief  DMA UART Tx communication abort callback, when initiated by user by a call to
3939   *         HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
3940   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
3941   *         and leads to user Tx Abort Complete callback execution).
3942   * @param  hdma DMA handle.
3943   * @retval None
3944   */
UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3945 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3946 {
3947   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3948 
3949   huart->TxXferCount = 0U;
3950 
3951   /* Flush the whole TX FIFO (if needed) */
3952   if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3953   {
3954     __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3955   }
3956 
3957   /* Restore huart->gState to Ready */
3958   huart->gState = HAL_UART_STATE_READY;
3959 
3960   /* Call user Abort complete callback */
3961 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3962   /* Call registered Abort Transmit Complete Callback */
3963   huart->AbortTransmitCpltCallback(huart);
3964 #else
3965   /* Call legacy weak Abort Transmit Complete Callback */
3966   HAL_UART_AbortTransmitCpltCallback(huart);
3967 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3968 }
3969 
3970 /**
3971   * @brief  DMA UART Rx communication abort callback, when initiated by user by a call to
3972   *         HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
3973   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
3974   *         and leads to user Rx Abort Complete callback execution).
3975   * @param  hdma DMA handle.
3976   * @retval None
3977   */
UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3978 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3979 {
3980   UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3981 
3982   huart->RxXferCount = 0U;
3983 
3984   /* Clear the Error flags in the ICR register */
3985   __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3986 
3987   /* Discard the received data */
3988   __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3989 
3990   /* Restore huart->RxState to Ready */
3991   huart->RxState = HAL_UART_STATE_READY;
3992   huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3993 
3994   /* Call user Abort complete callback */
3995 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3996   /* Call registered Abort Receive Complete Callback */
3997   huart->AbortReceiveCpltCallback(huart);
3998 #else
3999   /* Call legacy weak Abort Receive Complete Callback */
4000   HAL_UART_AbortReceiveCpltCallback(huart);
4001 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4002 }
4003 
4004 /**
4005   * @brief TX interrupt handler for 7 or 8 bits data word length .
4006   * @note   Function is called under interruption only, once
4007   *         interruptions have been enabled by HAL_UART_Transmit_IT().
4008   * @param huart UART handle.
4009   * @retval None
4010   */
UART_TxISR_8BIT(UART_HandleTypeDef * huart)4011 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
4012 {
4013   /* Check that a Tx process is ongoing */
4014   if (huart->gState == HAL_UART_STATE_BUSY_TX)
4015   {
4016     if (huart->TxXferCount == 0U)
4017     {
4018       /* Disable the UART Transmit Data Register Empty Interrupt */
4019       ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4020 
4021       /* Enable the UART Transmit Complete Interrupt */
4022       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4023     }
4024     else
4025     {
4026       huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4027       huart->pTxBuffPtr++;
4028       huart->TxXferCount--;
4029     }
4030   }
4031 }
4032 
4033 /**
4034   * @brief TX interrupt handler for 9 bits data word length.
4035   * @note   Function is called under interruption only, once
4036   *         interruptions have been enabled by HAL_UART_Transmit_IT().
4037   * @param huart UART handle.
4038   * @retval None
4039   */
UART_TxISR_16BIT(UART_HandleTypeDef * huart)4040 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
4041 {
4042   const uint16_t *tmp;
4043 
4044   /* Check that a Tx process is ongoing */
4045   if (huart->gState == HAL_UART_STATE_BUSY_TX)
4046   {
4047     if (huart->TxXferCount == 0U)
4048     {
4049       /* Disable the UART Transmit Data Register Empty Interrupt */
4050       ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4051 
4052       /* Enable the UART Transmit Complete Interrupt */
4053       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4054     }
4055     else
4056     {
4057       tmp = (const uint16_t *) huart->pTxBuffPtr;
4058       huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4059       huart->pTxBuffPtr += 2U;
4060       huart->TxXferCount--;
4061     }
4062   }
4063 }
4064 
4065 /**
4066   * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4067   * @note   Function is called under interruption only, once
4068   *         interruptions have been enabled by HAL_UART_Transmit_IT().
4069   * @param huart UART handle.
4070   * @retval None
4071   */
UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4072 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4073 {
4074   uint16_t  nb_tx_data;
4075 
4076   /* Check that a Tx process is ongoing */
4077   if (huart->gState == HAL_UART_STATE_BUSY_TX)
4078   {
4079     for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4080     {
4081       if (huart->TxXferCount == 0U)
4082       {
4083         /* Disable the TX FIFO threshold interrupt */
4084         ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4085 
4086         /* Enable the UART Transmit Complete Interrupt */
4087         ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4088 
4089         break; /* force exit loop */
4090       }
4091       else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4092       {
4093         huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4094         huart->pTxBuffPtr++;
4095         huart->TxXferCount--;
4096       }
4097       else
4098       {
4099         /* Nothing to do */
4100       }
4101     }
4102   }
4103 }
4104 
4105 /**
4106   * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4107   * @note   Function is called under interruption only, once
4108   *         interruptions have been enabled by HAL_UART_Transmit_IT().
4109   * @param huart UART handle.
4110   * @retval None
4111   */
UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4112 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4113 {
4114   const uint16_t *tmp;
4115   uint16_t  nb_tx_data;
4116 
4117   /* Check that a Tx process is ongoing */
4118   if (huart->gState == HAL_UART_STATE_BUSY_TX)
4119   {
4120     for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4121     {
4122       if (huart->TxXferCount == 0U)
4123       {
4124         /* Disable the TX FIFO threshold interrupt */
4125         ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4126 
4127         /* Enable the UART Transmit Complete Interrupt */
4128         ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4129 
4130         break; /* force exit loop */
4131       }
4132       else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4133       {
4134         tmp = (const uint16_t *) huart->pTxBuffPtr;
4135         huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4136         huart->pTxBuffPtr += 2U;
4137         huart->TxXferCount--;
4138       }
4139       else
4140       {
4141         /* Nothing to do */
4142       }
4143     }
4144   }
4145 }
4146 
4147 /**
4148   * @brief  Wrap up transmission in non-blocking mode.
4149   * @param  huart pointer to a UART_HandleTypeDef structure that contains
4150   *                the configuration information for the specified UART module.
4151   * @retval None
4152   */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)4153 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
4154 {
4155   /* Disable the UART Transmit Complete Interrupt */
4156   ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4157 
4158   /* Tx process is ended, restore huart->gState to Ready */
4159   huart->gState = HAL_UART_STATE_READY;
4160 
4161   /* Cleat TxISR function pointer */
4162   huart->TxISR = NULL;
4163 
4164 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4165   /*Call registered Tx complete callback*/
4166   huart->TxCpltCallback(huart);
4167 #else
4168   /*Call legacy weak Tx complete callback*/
4169   HAL_UART_TxCpltCallback(huart);
4170 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4171 }
4172 
4173 /**
4174   * @brief RX interrupt handler for 7 or 8 bits data word length .
4175   * @param huart UART handle.
4176   * @retval None
4177   */
UART_RxISR_8BIT(UART_HandleTypeDef * huart)4178 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
4179 {
4180   uint16_t uhMask = huart->Mask;
4181   uint16_t  uhdata;
4182 
4183   /* Check that a Rx process is ongoing */
4184   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4185   {
4186     uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4187     *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4188     huart->pRxBuffPtr++;
4189     huart->RxXferCount--;
4190 
4191     if (huart->RxXferCount == 0U)
4192     {
4193       /* Disable the UART Parity Error Interrupt and RXNE interrupts */
4194       ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4195 
4196       /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4197       ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4198 
4199       /* Rx process is completed, restore huart->RxState to Ready */
4200       huart->RxState = HAL_UART_STATE_READY;
4201 
4202       /* Clear RxISR function pointer */
4203       huart->RxISR = NULL;
4204 
4205       /* Initialize type of RxEvent to Transfer Complete */
4206       huart->RxEventType = HAL_UART_RXEVENT_TC;
4207 
4208       if (!(IS_LPUART_INSTANCE(huart->Instance)))
4209       {
4210         /* Check that USART RTOEN bit is set */
4211         if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4212         {
4213           /* Enable the UART Receiver Timeout Interrupt */
4214           ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4215         }
4216       }
4217 
4218       /* Check current reception Mode :
4219          If Reception till IDLE event has been selected : */
4220       if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4221       {
4222         /* Set reception type to Standard */
4223         huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4224 
4225         /* Disable IDLE interrupt */
4226         ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4227 
4228         if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4229         {
4230           /* Clear IDLE Flag */
4231           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4232         }
4233 
4234 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4235         /*Call registered Rx Event callback*/
4236         huart->RxEventCallback(huart, huart->RxXferSize);
4237 #else
4238         /*Call legacy weak Rx Event callback*/
4239         HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4240 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4241       }
4242       else
4243       {
4244         /* Standard reception API called */
4245 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4246         /*Call registered Rx complete callback*/
4247         huart->RxCpltCallback(huart);
4248 #else
4249         /*Call legacy weak Rx complete callback*/
4250         HAL_UART_RxCpltCallback(huart);
4251 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4252       }
4253     }
4254   }
4255   else
4256   {
4257     /* Clear RXNE interrupt flag */
4258     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4259   }
4260 }
4261 
4262 /**
4263   * @brief RX interrupt handler for 9 bits data word length .
4264   * @note   Function is called under interruption only, once
4265   *         interruptions have been enabled by HAL_UART_Receive_IT()
4266   * @param huart UART handle.
4267   * @retval None
4268   */
UART_RxISR_16BIT(UART_HandleTypeDef * huart)4269 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
4270 {
4271   uint16_t *tmp;
4272   uint16_t uhMask = huart->Mask;
4273   uint16_t  uhdata;
4274 
4275   /* Check that a Rx process is ongoing */
4276   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4277   {
4278     uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4279     tmp = (uint16_t *) huart->pRxBuffPtr ;
4280     *tmp = (uint16_t)(uhdata & uhMask);
4281     huart->pRxBuffPtr += 2U;
4282     huart->RxXferCount--;
4283 
4284     if (huart->RxXferCount == 0U)
4285     {
4286       /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
4287       ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4288 
4289       /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4290       ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4291 
4292       /* Rx process is completed, restore huart->RxState to Ready */
4293       huart->RxState = HAL_UART_STATE_READY;
4294 
4295       /* Clear RxISR function pointer */
4296       huart->RxISR = NULL;
4297 
4298       /* Initialize type of RxEvent to Transfer Complete */
4299       huart->RxEventType = HAL_UART_RXEVENT_TC;
4300 
4301       if (!(IS_LPUART_INSTANCE(huart->Instance)))
4302       {
4303         /* Check that USART RTOEN bit is set */
4304         if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4305         {
4306           /* Enable the UART Receiver Timeout Interrupt */
4307           ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4308         }
4309       }
4310 
4311       /* Check current reception Mode :
4312          If Reception till IDLE event has been selected : */
4313       if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4314       {
4315         /* Set reception type to Standard */
4316         huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4317 
4318         /* Disable IDLE interrupt */
4319         ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4320 
4321         if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4322         {
4323           /* Clear IDLE Flag */
4324           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4325         }
4326 
4327 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4328         /*Call registered Rx Event callback*/
4329         huart->RxEventCallback(huart, huart->RxXferSize);
4330 #else
4331         /*Call legacy weak Rx Event callback*/
4332         HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4333 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4334       }
4335       else
4336       {
4337         /* Standard reception API called */
4338 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4339         /*Call registered Rx complete callback*/
4340         huart->RxCpltCallback(huart);
4341 #else
4342         /*Call legacy weak Rx complete callback*/
4343         HAL_UART_RxCpltCallback(huart);
4344 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4345       }
4346     }
4347   }
4348   else
4349   {
4350     /* Clear RXNE interrupt flag */
4351     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4352   }
4353 }
4354 
4355 /**
4356   * @brief RX interrupt handler for 7 or 8  bits data word length and FIFO mode is enabled.
4357   * @note   Function is called under interruption only, once
4358   *         interruptions have been enabled by HAL_UART_Receive_IT()
4359   * @param huart UART handle.
4360   * @retval None
4361   */
UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4362 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4363 {
4364   uint16_t  uhMask = huart->Mask;
4365   uint16_t  uhdata;
4366   uint16_t  nb_rx_data;
4367   uint16_t  rxdatacount;
4368   uint32_t  isrflags = READ_REG(huart->Instance->ISR);
4369   uint32_t  cr1its   = READ_REG(huart->Instance->CR1);
4370   uint32_t  cr3its   = READ_REG(huart->Instance->CR3);
4371 
4372   /* Check that a Rx process is ongoing */
4373   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4374   {
4375     nb_rx_data = huart->NbRxDataToProcess;
4376     while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4377     {
4378       uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4379       *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4380       huart->pRxBuffPtr++;
4381       huart->RxXferCount--;
4382       isrflags = READ_REG(huart->Instance->ISR);
4383 
4384       /* If some non blocking errors occurred */
4385       if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4386       {
4387         /* UART parity error interrupt occurred -------------------------------------*/
4388         if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4389         {
4390           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4391 
4392           huart->ErrorCode |= HAL_UART_ERROR_PE;
4393         }
4394 
4395         /* UART frame error interrupt occurred --------------------------------------*/
4396         if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4397         {
4398           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4399 
4400           huart->ErrorCode |= HAL_UART_ERROR_FE;
4401         }
4402 
4403         /* UART noise error interrupt occurred --------------------------------------*/
4404         if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4405         {
4406           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4407 
4408           huart->ErrorCode |= HAL_UART_ERROR_NE;
4409         }
4410 
4411         /* Call UART Error Call back function if need be ----------------------------*/
4412         if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4413         {
4414           /* Non Blocking error : transfer could go on.
4415           Error is notified to user through user error callback */
4416 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4417           /*Call registered error callback*/
4418           huart->ErrorCallback(huart);
4419 #else
4420           /*Call legacy weak error callback*/
4421           HAL_UART_ErrorCallback(huart);
4422 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4423           huart->ErrorCode = HAL_UART_ERROR_NONE;
4424         }
4425       }
4426 
4427       if (huart->RxXferCount == 0U)
4428       {
4429         /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4430         ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4431 
4432         /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4433            and RX FIFO Threshold interrupt */
4434         ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4435 
4436         /* Rx process is completed, restore huart->RxState to Ready */
4437         huart->RxState = HAL_UART_STATE_READY;
4438 
4439         /* Clear RxISR function pointer */
4440         huart->RxISR = NULL;
4441 
4442         /* Initialize type of RxEvent to Transfer Complete */
4443         huart->RxEventType = HAL_UART_RXEVENT_TC;
4444 
4445         if (!(IS_LPUART_INSTANCE(huart->Instance)))
4446         {
4447           /* Check that USART RTOEN bit is set */
4448           if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4449           {
4450             /* Enable the UART Receiver Timeout Interrupt */
4451             ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4452           }
4453         }
4454 
4455         /* Check current reception Mode :
4456            If Reception till IDLE event has been selected : */
4457         if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4458         {
4459           /* Set reception type to Standard */
4460           huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4461 
4462           /* Disable IDLE interrupt */
4463           ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4464 
4465           if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4466           {
4467             /* Clear IDLE Flag */
4468             __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4469           }
4470 
4471 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4472           /*Call registered Rx Event callback*/
4473           huart->RxEventCallback(huart, huart->RxXferSize);
4474 #else
4475           /*Call legacy weak Rx Event callback*/
4476           HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4477 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4478         }
4479         else
4480         {
4481           /* Standard reception API called */
4482 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4483           /*Call registered Rx complete callback*/
4484           huart->RxCpltCallback(huart);
4485 #else
4486           /*Call legacy weak Rx complete callback*/
4487           HAL_UART_RxCpltCallback(huart);
4488 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4489         }
4490         break;
4491       }
4492     }
4493 
4494     /* When remaining number of bytes to receive is less than the RX FIFO
4495     threshold, next incoming frames are processed as if FIFO mode was
4496     disabled (i.e. one interrupt per received frame).
4497     */
4498     rxdatacount = huart->RxXferCount;
4499     if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4500     {
4501       /* Disable the UART RXFT interrupt*/
4502       ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4503 
4504       /* Update the RxISR function pointer */
4505       huart->RxISR = UART_RxISR_8BIT;
4506 
4507       /* Enable the UART Data Register Not Empty interrupt */
4508       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4509     }
4510   }
4511   else
4512   {
4513     /* Clear RXNE interrupt flag */
4514     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4515   }
4516 }
4517 
4518 /**
4519   * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4520   * @note   Function is called under interruption only, once
4521   *         interruptions have been enabled by HAL_UART_Receive_IT()
4522   * @param huart UART handle.
4523   * @retval None
4524   */
UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4525 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4526 {
4527   uint16_t *tmp;
4528   uint16_t  uhMask = huart->Mask;
4529   uint16_t  uhdata;
4530   uint16_t  nb_rx_data;
4531   uint16_t  rxdatacount;
4532   uint32_t  isrflags = READ_REG(huart->Instance->ISR);
4533   uint32_t  cr1its   = READ_REG(huart->Instance->CR1);
4534   uint32_t  cr3its   = READ_REG(huart->Instance->CR3);
4535 
4536   /* Check that a Rx process is ongoing */
4537   if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4538   {
4539     nb_rx_data = huart->NbRxDataToProcess;
4540     while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4541     {
4542       uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4543       tmp = (uint16_t *) huart->pRxBuffPtr ;
4544       *tmp = (uint16_t)(uhdata & uhMask);
4545       huart->pRxBuffPtr += 2U;
4546       huart->RxXferCount--;
4547       isrflags = READ_REG(huart->Instance->ISR);
4548 
4549       /* If some non blocking errors occurred */
4550       if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4551       {
4552         /* UART parity error interrupt occurred -------------------------------------*/
4553         if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4554         {
4555           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4556 
4557           huart->ErrorCode |= HAL_UART_ERROR_PE;
4558         }
4559 
4560         /* UART frame error interrupt occurred --------------------------------------*/
4561         if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4562         {
4563           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4564 
4565           huart->ErrorCode |= HAL_UART_ERROR_FE;
4566         }
4567 
4568         /* UART noise error interrupt occurred --------------------------------------*/
4569         if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4570         {
4571           __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4572 
4573           huart->ErrorCode |= HAL_UART_ERROR_NE;
4574         }
4575 
4576         /* Call UART Error Call back function if need be ----------------------------*/
4577         if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4578         {
4579           /* Non Blocking error : transfer could go on.
4580           Error is notified to user through user error callback */
4581 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4582           /*Call registered error callback*/
4583           huart->ErrorCallback(huart);
4584 #else
4585           /*Call legacy weak error callback*/
4586           HAL_UART_ErrorCallback(huart);
4587 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4588           huart->ErrorCode = HAL_UART_ERROR_NONE;
4589         }
4590       }
4591 
4592       if (huart->RxXferCount == 0U)
4593       {
4594         /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4595         ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4596 
4597         /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4598            and RX FIFO Threshold interrupt */
4599         ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4600 
4601         /* Rx process is completed, restore huart->RxState to Ready */
4602         huart->RxState = HAL_UART_STATE_READY;
4603 
4604         /* Clear RxISR function pointer */
4605         huart->RxISR = NULL;
4606 
4607         /* Initialize type of RxEvent to Transfer Complete */
4608         huart->RxEventType = HAL_UART_RXEVENT_TC;
4609 
4610         if (!(IS_LPUART_INSTANCE(huart->Instance)))
4611         {
4612           /* Check that USART RTOEN bit is set */
4613           if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4614           {
4615             /* Enable the UART Receiver Timeout Interrupt */
4616             ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4617           }
4618         }
4619 
4620         /* Check current reception Mode :
4621            If Reception till IDLE event has been selected : */
4622         if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4623         {
4624           /* Set reception type to Standard */
4625           huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4626 
4627           /* Disable IDLE interrupt */
4628           ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4629 
4630           if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4631           {
4632             /* Clear IDLE Flag */
4633             __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4634           }
4635 
4636 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4637           /*Call registered Rx Event callback*/
4638           huart->RxEventCallback(huart, huart->RxXferSize);
4639 #else
4640           /*Call legacy weak Rx Event callback*/
4641           HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4642 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4643         }
4644         else
4645         {
4646           /* Standard reception API called */
4647 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4648           /*Call registered Rx complete callback*/
4649           huart->RxCpltCallback(huart);
4650 #else
4651           /*Call legacy weak Rx complete callback*/
4652           HAL_UART_RxCpltCallback(huart);
4653 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4654         }
4655         break;
4656       }
4657     }
4658 
4659     /* When remaining number of bytes to receive is less than the RX FIFO
4660     threshold, next incoming frames are processed as if FIFO mode was
4661     disabled (i.e. one interrupt per received frame).
4662     */
4663     rxdatacount = huart->RxXferCount;
4664     if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4665     {
4666       /* Disable the UART RXFT interrupt*/
4667       ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4668 
4669       /* Update the RxISR function pointer */
4670       huart->RxISR = UART_RxISR_16BIT;
4671 
4672       /* Enable the UART Data Register Not Empty interrupt */
4673       ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4674     }
4675   }
4676   else
4677   {
4678     /* Clear RXNE interrupt flag */
4679     __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4680   }
4681 }
4682 
4683 /**
4684   * @}
4685   */
4686 
4687 #endif /* HAL_UART_MODULE_ENABLED */
4688 /**
4689   * @}
4690   */
4691 
4692 /**
4693   * @}
4694   */
4695 
4696