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