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