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