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