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