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