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