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