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