1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_usart.c
4   * @author  MCD Application Team
5   * @brief   USART HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
8   *          Peripheral (USART).
9   *           + Initialization and de-initialization functions
10   *           + IO operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State and Error functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2017 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26  ===============================================================================
27                         ##### How to use this driver #####
28  ===============================================================================
29     [..]
30       The USART HAL driver can be used as follows:
31 
32       (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
33       (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
34           (++) Enable the USARTx interface clock.
35           (++) USART pins configuration:
36             (+++) Enable the clock for the USART GPIOs.
37             (+++) Configure these USART pins as alternate function pull-up.
38           (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
39                 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
40             (+++) Configure the USARTx interrupt priority.
41             (+++) Enable the NVIC USART IRQ handle.
42             (++) USART interrupts handling:
43               -@@-   The specific USART interrupts (Transmission complete interrupt,
44                   RXNE interrupt and Error Interrupts) will be managed using the macros
45                   __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
46           (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
47                HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_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 USART DMA Tx/Rx handle.
53             (+++) Configure the priority and enable the NVIC for the transfer
54                   complete interrupt on the DMA Tx/Rx channel.
55 
56       (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
57           (Receiver/Transmitter) in the husart handle Init structure.
58 
59       (#) Initialize the USART registers by calling the HAL_USART_Init() API:
60           (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
61                by calling the customized HAL_USART_MspInit(&husart) API.
62 
63     [..]
64      (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
65         HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
66         HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
67 
68     ##### Callback registration #####
69     ==================================
70 
71     [..]
72     The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
73     allows the user to configure dynamically the driver callbacks.
74 
75     [..]
76     Use Function HAL_USART_RegisterCallback() to register a user callback.
77     Function HAL_USART_RegisterCallback() allows to register following callbacks:
78     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
79     (+) TxCpltCallback            : Tx Complete Callback.
80     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
81     (+) RxCpltCallback            : Rx Complete Callback.
82     (+) TxRxCpltCallback          : Tx Rx Complete Callback.
83     (+) ErrorCallback             : Error Callback.
84     (+) AbortCpltCallback         : Abort Complete Callback.
85     (+) RxFifoFullCallback        : Rx Fifo Full Callback.
86     (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
87     (+) MspInitCallback           : USART MspInit.
88     (+) MspDeInitCallback         : USART MspDeInit.
89     This function takes as parameters the HAL peripheral handle, the Callback ID
90     and a pointer to the user callback function.
91 
92     [..]
93     Use function HAL_USART_UnRegisterCallback() to reset a callback to the default
94     weak (surcharged) function.
95     HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
96     and the Callback ID.
97     This function allows to reset following callbacks:
98     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
99     (+) TxCpltCallback            : Tx Complete Callback.
100     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
101     (+) RxCpltCallback            : Rx Complete Callback.
102     (+) TxRxCpltCallback          : Tx Rx Complete Callback.
103     (+) ErrorCallback             : Error Callback.
104     (+) AbortCpltCallback         : Abort Complete Callback.
105     (+) RxFifoFullCallback        : Rx Fifo Full Callback.
106     (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
107     (+) MspInitCallback           : USART MspInit.
108     (+) MspDeInitCallback         : USART MspDeInit.
109 
110     [..]
111     By default, after the HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
112     all callbacks are set to the corresponding weak (surcharged) functions:
113     examples HAL_USART_TxCpltCallback(), HAL_USART_RxHalfCpltCallback().
114     Exception done for MspInit and MspDeInit functions that are respectively
115     reset to the legacy weak (surcharged) functions in the HAL_USART_Init()
116     and HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
117     If not, MspInit or MspDeInit are not null, the HAL_USART_Init() and HAL_USART_DeInit()
118     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
119 
120     [..]
121     Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
122     Exception done MspInit/MspDeInit that can be registered/unregistered
123     in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
124     MspInit/DeInit callbacks can be used during the Init/DeInit.
125     In that case first register the MspInit/MspDeInit user callbacks
126     using HAL_USART_RegisterCallback() before calling HAL_USART_DeInit()
127     or HAL_USART_Init() function.
128 
129     [..]
130     When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
131     not defined, the callback registration feature is not available
132     and weak (surcharged) callbacks are used.
133 
134 
135   @endverbatim
136   ******************************************************************************
137   */
138 
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32l4xx_hal.h"
141 
142 /** @addtogroup STM32L4xx_HAL_Driver
143   * @{
144   */
145 
146 /** @defgroup USART USART
147   * @brief HAL USART Synchronous module driver
148   * @{
149   */
150 
151 #ifdef HAL_USART_MODULE_ENABLED
152 
153 /* Private typedef -----------------------------------------------------------*/
154 /* Private define ------------------------------------------------------------*/
155 /** @defgroup USART_Private_Constants USART Private Constants
156   * @{
157   */
158 #define USART_DUMMY_DATA          ((uint16_t) 0xFFFF)           /*!< USART transmitted dummy data                     */
159 #define USART_TEACK_REACK_TIMEOUT             1000U             /*!< USART TX or RX enable acknowledge time-out value */
160 #if defined(USART_CR1_FIFOEN)
161 #define USART_CR1_FIELDS          ((uint32_t)(USART_CR1_M |  USART_CR1_PCE | USART_CR1_PS    | \
162                                               USART_CR1_TE | USART_CR1_RE  | USART_CR1_OVER8 | \
163                                               USART_CR1_FIFOEN ))                                  /*!< USART CR1 fields of parameters set by USART_SetConfig API */
164 
165 #define USART_CR2_FIELDS          ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
166                                               USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \
167                                               USART_CR2_DIS_NSS))                                  /*!< USART CR2 fields of parameters set by USART_SetConfig API */
168 
169 #define USART_CR3_FIELDS          ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG ))             /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */
170 #else
171 #define USART_CR1_FIELDS          ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
172                                               USART_CR1_TE | USART_CR1_RE  | USART_CR1_OVER8))    /*!< USART CR1 fields of parameters set by USART_SetConfig API */
173 #define USART_CR2_FIELDS          ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
174                                               USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
175 #endif /* USART_CR1_FIFOEN */
176 
177 #define USART_BRR_MIN    0x10U        /* USART BRR minimum authorized value */
178 #define USART_BRR_MAX    0xFFFFU      /* USART BRR maximum authorized value */
179 /**
180   * @}
181   */
182 
183 /* Private macros ------------------------------------------------------------*/
184 /* Private variables ---------------------------------------------------------*/
185 /* Private function prototypes -----------------------------------------------*/
186 /** @addtogroup USART_Private_Functions
187   * @{
188   */
189 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
190 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
191 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
192 static void USART_EndTransfer(USART_HandleTypeDef *husart);
193 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
194 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
195 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
196 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
197 static void USART_DMAError(DMA_HandleTypeDef *hdma);
198 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
199 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
200 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
201 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
202                                                       uint32_t Tickstart, uint32_t Timeout);
203 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
204 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
205 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart);
206 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart);
207 #if defined(USART_CR1_FIFOEN)
208 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
209 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
210 #endif /* USART_CR1_FIFOEN */
211 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart);
212 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart);
213 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart);
214 #if defined(USART_CR1_FIFOEN)
215 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
216 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
217 #endif /* USART_CR1_FIFOEN */
218 
219 
220 /**
221   * @}
222   */
223 
224 /* Exported functions --------------------------------------------------------*/
225 
226 /** @defgroup USART_Exported_Functions USART Exported Functions
227   * @{
228   */
229 
230 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
231   * @brief    Initialization and Configuration functions
232   *
233 @verbatim
234  ===============================================================================
235             ##### Initialization and Configuration functions #####
236  ===============================================================================
237     [..]
238     This subsection provides a set of functions allowing to initialize the USART
239     in asynchronous and in synchronous modes.
240       (+) For the asynchronous mode only these parameters can be configured:
241         (++) Baud Rate
242         (++) Word Length
243         (++) Stop Bit
244         (++) Parity: If the parity is enabled, then the MSB bit of the data written
245              in the data register is transmitted but is changed by the parity bit.
246         (++) USART polarity
247         (++) USART phase
248         (++) USART LastBit
249         (++) Receiver/transmitter modes
250 
251     [..]
252     The HAL_USART_Init() function follows the USART  synchronous configuration
253     procedure (details for the procedure are available in reference manual).
254 
255 @endverbatim
256 
257   Depending on the frame length defined by the M1 and M0 bits (7-bit,
258   8-bit or 9-bit), the possible USART formats are listed in the
259   following table.
260 
261     Table 1. USART frame format.
262     +-----------------------------------------------------------------------+
263     |  M1 bit |  M0 bit |  PCE bit  |            USART frame                |
264     |---------|---------|-----------|---------------------------------------|
265     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
266     |---------|---------|-----------|---------------------------------------|
267     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
268     |---------|---------|-----------|---------------------------------------|
269     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
270     |---------|---------|-----------|---------------------------------------|
271     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
272     |---------|---------|-----------|---------------------------------------|
273     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
274     |---------|---------|-----------|---------------------------------------|
275     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
276     +-----------------------------------------------------------------------+
277 
278   * @{
279   */
280 
281 /**
282   * @brief  Initialize the USART mode according to the specified
283   *         parameters in the USART_InitTypeDef and initialize the associated handle.
284   * @param  husart USART handle.
285   * @retval HAL status
286   */
HAL_USART_Init(USART_HandleTypeDef * husart)287 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
288 {
289   /* Check the USART handle allocation */
290   if (husart == NULL)
291   {
292     return HAL_ERROR;
293   }
294 
295   /* Check the parameters */
296   assert_param(IS_USART_INSTANCE(husart->Instance));
297 
298   if (husart->State == HAL_USART_STATE_RESET)
299   {
300     /* Allocate lock resource and initialize it */
301     husart->Lock = HAL_UNLOCKED;
302 
303 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
304     USART_InitCallbacksToDefault(husart);
305 
306     if (husart->MspInitCallback == NULL)
307     {
308       husart->MspInitCallback = HAL_USART_MspInit;
309     }
310 
311     /* Init the low level hardware */
312     husart->MspInitCallback(husart);
313 #else
314     /* Init the low level hardware : GPIO, CLOCK */
315     HAL_USART_MspInit(husart);
316 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
317   }
318 
319   husart->State = HAL_USART_STATE_BUSY;
320 
321   /* Disable the Peripheral */
322   __HAL_USART_DISABLE(husart);
323 
324   /* Set the Usart Communication parameters */
325   if (USART_SetConfig(husart) == HAL_ERROR)
326   {
327     return HAL_ERROR;
328   }
329 
330   /* In Synchronous mode, the following bits must be kept cleared:
331   - LINEN bit in the USART_CR2 register
332   - HDSEL, SCEN and IREN bits in the USART_CR3 register.
333   */
334   husart->Instance->CR2 &= ~USART_CR2_LINEN;
335   husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
336 
337   /* Enable the Peripheral */
338   __HAL_USART_ENABLE(husart);
339 
340   /* TEACK and/or REACK to check before moving husart->State to Ready */
341   return (USART_CheckIdleState(husart));
342 }
343 
344 /**
345   * @brief DeInitialize the USART peripheral.
346   * @param  husart USART handle.
347   * @retval HAL status
348   */
HAL_USART_DeInit(USART_HandleTypeDef * husart)349 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
350 {
351   /* Check the USART handle allocation */
352   if (husart == NULL)
353   {
354     return HAL_ERROR;
355   }
356 
357   /* Check the parameters */
358   assert_param(IS_USART_INSTANCE(husart->Instance));
359 
360   husart->State = HAL_USART_STATE_BUSY;
361 
362   husart->Instance->CR1 = 0x0U;
363   husart->Instance->CR2 = 0x0U;
364   husart->Instance->CR3 = 0x0U;
365 
366 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
367   if (husart->MspDeInitCallback == NULL)
368   {
369     husart->MspDeInitCallback = HAL_USART_MspDeInit;
370   }
371   /* DeInit the low level hardware */
372   husart->MspDeInitCallback(husart);
373 #else
374   /* DeInit the low level hardware */
375   HAL_USART_MspDeInit(husart);
376 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
377 
378   husart->ErrorCode = HAL_USART_ERROR_NONE;
379   husart->State = HAL_USART_STATE_RESET;
380 
381   /* Process Unlock */
382   __HAL_UNLOCK(husart);
383 
384   return HAL_OK;
385 }
386 
387 /**
388   * @brief Initialize the USART MSP.
389   * @param husart USART handle.
390   * @retval None
391   */
HAL_USART_MspInit(USART_HandleTypeDef * husart)392 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
393 {
394   /* Prevent unused argument(s) compilation warning */
395   UNUSED(husart);
396 
397   /* NOTE : This function should not be modified, when the callback is needed,
398             the HAL_USART_MspInit can be implemented in the user file
399    */
400 }
401 
402 /**
403   * @brief DeInitialize the USART MSP.
404   * @param husart USART handle.
405   * @retval None
406   */
HAL_USART_MspDeInit(USART_HandleTypeDef * husart)407 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
408 {
409   /* Prevent unused argument(s) compilation warning */
410   UNUSED(husart);
411 
412   /* NOTE : This function should not be modified, when the callback is needed,
413             the HAL_USART_MspDeInit can be implemented in the user file
414    */
415 }
416 
417 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
418 /**
419   * @brief  Register a User USART Callback
420   *         To be used instead of the weak predefined callback
421   * @param  husart usart handle
422   * @param  CallbackID ID of the callback to be registered
423   *         This parameter can be one of the following values:
424   *           @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
425   *           @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
426   *           @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
427   *           @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
428   *           @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
429   *           @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
430   *           @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
431   *           @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
432   *           @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
433   *           @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
434   *           @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
435   * @param  pCallback pointer to the Callback function
436   * @retval HAL status
437 +  */
HAL_USART_RegisterCallback(USART_HandleTypeDef * husart,HAL_USART_CallbackIDTypeDef CallbackID,pUSART_CallbackTypeDef pCallback)438 HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
439                                              pUSART_CallbackTypeDef pCallback)
440 {
441   HAL_StatusTypeDef status = HAL_OK;
442 
443   if (pCallback == NULL)
444   {
445     /* Update the error code */
446     husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
447 
448     return HAL_ERROR;
449   }
450   /* Process locked */
451   __HAL_LOCK(husart);
452 
453   if (husart->State == HAL_USART_STATE_READY)
454   {
455     switch (CallbackID)
456     {
457       case HAL_USART_TX_HALFCOMPLETE_CB_ID :
458         husart->TxHalfCpltCallback = pCallback;
459         break;
460 
461       case HAL_USART_TX_COMPLETE_CB_ID :
462         husart->TxCpltCallback = pCallback;
463         break;
464 
465       case HAL_USART_RX_HALFCOMPLETE_CB_ID :
466         husart->RxHalfCpltCallback = pCallback;
467         break;
468 
469       case HAL_USART_RX_COMPLETE_CB_ID :
470         husart->RxCpltCallback = pCallback;
471         break;
472 
473       case HAL_USART_TX_RX_COMPLETE_CB_ID :
474         husart->TxRxCpltCallback = pCallback;
475         break;
476 
477       case HAL_USART_ERROR_CB_ID :
478         husart->ErrorCallback = pCallback;
479         break;
480 
481       case HAL_USART_ABORT_COMPLETE_CB_ID :
482         husart->AbortCpltCallback = pCallback;
483         break;
484 
485 #if defined(USART_CR1_FIFOEN)
486       case HAL_USART_RX_FIFO_FULL_CB_ID :
487         husart->RxFifoFullCallback = pCallback;
488         break;
489 
490       case HAL_USART_TX_FIFO_EMPTY_CB_ID :
491         husart->TxFifoEmptyCallback = pCallback;
492         break;
493 #endif /* USART_CR1_FIFOEN */
494 
495       case HAL_USART_MSPINIT_CB_ID :
496         husart->MspInitCallback = pCallback;
497         break;
498 
499       case HAL_USART_MSPDEINIT_CB_ID :
500         husart->MspDeInitCallback = pCallback;
501         break;
502 
503       default :
504         /* Update the error code */
505         husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
506 
507         /* Return error status */
508         status =  HAL_ERROR;
509         break;
510     }
511   }
512   else if (husart->State == HAL_USART_STATE_RESET)
513   {
514     switch (CallbackID)
515     {
516       case HAL_USART_MSPINIT_CB_ID :
517         husart->MspInitCallback = pCallback;
518         break;
519 
520       case HAL_USART_MSPDEINIT_CB_ID :
521         husart->MspDeInitCallback = pCallback;
522         break;
523 
524       default :
525         /* Update the error code */
526         husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
527 
528         /* Return error status */
529         status =  HAL_ERROR;
530         break;
531     }
532   }
533   else
534   {
535     /* Update the error code */
536     husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
537 
538     /* Return error status */
539     status =  HAL_ERROR;
540   }
541 
542   /* Release Lock */
543   __HAL_UNLOCK(husart);
544 
545   return status;
546 }
547 
548 /**
549   * @brief  Unregister an USART Callback
550   *         USART callaback is redirected to the weak predefined callback
551   * @param  husart usart handle
552   * @param  CallbackID ID of the callback to be unregistered
553   *         This parameter can be one of the following values:
554   *           @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
555   *           @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
556   *           @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
557   *           @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
558   *           @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
559   *           @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
560   *           @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
561   *           @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
562   *           @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
563   *           @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
564   *           @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
565   * @retval HAL status
566   */
HAL_USART_UnRegisterCallback(USART_HandleTypeDef * husart,HAL_USART_CallbackIDTypeDef CallbackID)567 HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
568 {
569   HAL_StatusTypeDef status = HAL_OK;
570 
571   /* Process locked */
572   __HAL_LOCK(husart);
573 
574   if (HAL_USART_STATE_READY == husart->State)
575   {
576     switch (CallbackID)
577     {
578       case HAL_USART_TX_HALFCOMPLETE_CB_ID :
579         husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback  */
580         break;
581 
582       case HAL_USART_TX_COMPLETE_CB_ID :
583         husart->TxCpltCallback = HAL_USART_TxCpltCallback;                       /* Legacy weak TxCpltCallback       */
584         break;
585 
586       case HAL_USART_RX_HALFCOMPLETE_CB_ID :
587         husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback   */
588         break;
589 
590       case HAL_USART_RX_COMPLETE_CB_ID :
591         husart->RxCpltCallback = HAL_USART_RxCpltCallback;                       /* Legacy weak RxCpltCallback       */
592         break;
593 
594       case HAL_USART_TX_RX_COMPLETE_CB_ID :
595         husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback;                   /* Legacy weak TxRxCpltCallback     */
596         break;
597 
598       case HAL_USART_ERROR_CB_ID :
599         husart->ErrorCallback = HAL_USART_ErrorCallback;                         /* Legacy weak ErrorCallback        */
600         break;
601 
602       case HAL_USART_ABORT_COMPLETE_CB_ID :
603         husart->AbortCpltCallback = HAL_USART_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback    */
604         break;
605 
606 #if defined(USART_CR1_FIFOEN)
607       case HAL_USART_RX_FIFO_FULL_CB_ID :
608         husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback;             /* Legacy weak RxFifoFullCallback   */
609         break;
610 
611       case HAL_USART_TX_FIFO_EMPTY_CB_ID :
612         husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback;           /* Legacy weak TxFifoEmptyCallback  */
613         break;
614 #endif /* USART_CR1_FIFOEN */
615 
616       case HAL_USART_MSPINIT_CB_ID :
617         husart->MspInitCallback = HAL_USART_MspInit;                             /* Legacy weak MspInitCallback      */
618         break;
619 
620       case HAL_USART_MSPDEINIT_CB_ID :
621         husart->MspDeInitCallback = HAL_USART_MspDeInit;                         /* Legacy weak MspDeInitCallback    */
622         break;
623 
624       default :
625         /* Update the error code */
626         husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
627 
628         /* Return error status */
629         status =  HAL_ERROR;
630         break;
631     }
632   }
633   else if (HAL_USART_STATE_RESET == husart->State)
634   {
635     switch (CallbackID)
636     {
637       case HAL_USART_MSPINIT_CB_ID :
638         husart->MspInitCallback = HAL_USART_MspInit;
639         break;
640 
641       case HAL_USART_MSPDEINIT_CB_ID :
642         husart->MspDeInitCallback = HAL_USART_MspDeInit;
643         break;
644 
645       default :
646         /* Update the error code */
647         husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
648 
649         /* Return error status */
650         status =  HAL_ERROR;
651         break;
652     }
653   }
654   else
655   {
656     /* Update the error code */
657     husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
658 
659     /* Return error status */
660     status =  HAL_ERROR;
661   }
662 
663   /* Release Lock */
664   __HAL_UNLOCK(husart);
665 
666   return status;
667 }
668 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
669 
670 
671 /**
672   * @}
673   */
674 
675 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
676   * @brief   USART Transmit and Receive functions
677   *
678 @verbatim
679  ===============================================================================
680                       ##### IO operation functions #####
681  ===============================================================================
682     [..] This subsection provides a set of functions allowing to manage the USART synchronous
683     data transfers.
684 
685     [..] The USART supports master mode only: it cannot receive or send data related to an input
686          clock (SCLK is always an output).
687 
688     [..]
689 
690     (#) There are two modes of transfer:
691         (++) Blocking mode: The communication is performed in polling mode.
692              The HAL status of all data processing is returned by the same function
693              after finishing transfer.
694         (++) No-Blocking mode: The communication is performed using Interrupts
695              or DMA, These API's return the HAL status.
696              The end of the data processing will be indicated through the
697              dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
698              using DMA mode.
699              The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
700              will be executed respectively at the end of the transmit or Receive process
701              The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
702 
703     (#) Blocking mode API's are :
704         (++) HAL_USART_Transmit() in simplex mode
705         (++) HAL_USART_Receive() in full duplex receive only
706         (++) HAL_USART_TransmitReceive() in full duplex mode
707 
708     (#) Non-Blocking mode API's with Interrupt are :
709         (++) HAL_USART_Transmit_IT() in simplex mode
710         (++) HAL_USART_Receive_IT() in full duplex receive only
711         (++) HAL_USART_TransmitReceive_IT() in full duplex mode
712         (++) HAL_USART_IRQHandler()
713 
714     (#) No-Blocking mode API's  with DMA are :
715         (++) HAL_USART_Transmit_DMA() in simplex mode
716         (++) HAL_USART_Receive_DMA() in full duplex receive only
717         (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
718         (++) HAL_USART_DMAPause()
719         (++) HAL_USART_DMAResume()
720         (++) HAL_USART_DMAStop()
721 
722     (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
723         (++) HAL_USART_TxCpltCallback()
724         (++) HAL_USART_RxCpltCallback()
725         (++) HAL_USART_TxHalfCpltCallback()
726         (++) HAL_USART_RxHalfCpltCallback()
727         (++) HAL_USART_ErrorCallback()
728         (++) HAL_USART_TxRxCpltCallback()
729 
730     (#) Non-Blocking mode transfers could be aborted using Abort API's :
731         (++) HAL_USART_Abort()
732         (++) HAL_USART_Abort_IT()
733 
734     (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
735         (++) HAL_USART_AbortCpltCallback()
736 
737     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
738         Errors are handled as follows :
739         (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
740              to be evaluated by user : this concerns Frame Error,
741              Parity Error or Noise Error in Interrupt mode reception .
742              Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify
743              error type, and HAL_USART_ErrorCallback() user callback is executed.
744              Transfer is kept ongoing on USART side.
745              If user wants to abort it, Abort services should be called by user.
746         (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
747              This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
748              Error code is set to allow user to identify error type,
749              and HAL_USART_ErrorCallback() user callback is executed.
750 
751 @endverbatim
752   * @{
753   */
754 
755 /**
756   * @brief  Simplex send an amount of data in blocking mode.
757   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
758   *         the sent data is handled as a set of u16. In this case, Size must indicate the number
759   *         of u16 provided through pTxData.
760   * @param  husart USART handle.
761   * @param  pTxData Pointer to data buffer (u8 or u16 data elements).
762   * @param  Size Amount of data elements (u8 or u16) to be sent.
763   * @param  Timeout Timeout duration.
764   * @retval HAL status
765   */
HAL_USART_Transmit(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size,uint32_t Timeout)766 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size,
767                                      uint32_t Timeout)
768 {
769   const uint8_t  *ptxdata8bits;
770   const uint16_t *ptxdata16bits;
771   uint32_t tickstart;
772 
773   if (husart->State == HAL_USART_STATE_READY)
774   {
775     if ((pTxData == NULL) || (Size == 0U))
776     {
777       return  HAL_ERROR;
778     }
779 
780     /* Process Locked */
781     __HAL_LOCK(husart);
782 
783     husart->ErrorCode = HAL_USART_ERROR_NONE;
784     husart->State = HAL_USART_STATE_BUSY_TX;
785 
786     /* Init tickstart for timeout management */
787     tickstart = HAL_GetTick();
788 
789     husart->TxXferSize = Size;
790     husart->TxXferCount = Size;
791 
792     /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
793     if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
794     {
795       ptxdata8bits  = NULL;
796       ptxdata16bits = (const uint16_t *) pTxData;
797     }
798     else
799     {
800       ptxdata8bits  = pTxData;
801       ptxdata16bits = NULL;
802     }
803 
804     /* Check the remaining data to be sent */
805     while (husart->TxXferCount > 0U)
806     {
807       if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
808       {
809         return HAL_TIMEOUT;
810       }
811       if (ptxdata8bits == NULL)
812       {
813         husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
814         ptxdata16bits++;
815       }
816       else
817       {
818         husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
819         ptxdata8bits++;
820       }
821 
822       husart->TxXferCount--;
823     }
824 
825     if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
826     {
827       return HAL_TIMEOUT;
828     }
829 
830     /* Clear Transmission Complete Flag */
831     __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
832 
833     /* Clear overrun flag and discard the received data */
834     __HAL_USART_CLEAR_OREFLAG(husart);
835     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
836     __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
837 
838     /* At end of Tx process, restore husart->State to Ready */
839     husart->State = HAL_USART_STATE_READY;
840 
841     /* Process Unlocked */
842     __HAL_UNLOCK(husart);
843 
844     return HAL_OK;
845   }
846   else
847   {
848     return HAL_BUSY;
849   }
850 }
851 
852 /**
853   * @brief Receive an amount of data in blocking mode.
854   * @note   To receive synchronous data, dummy data are simultaneously transmitted.
855   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
856   *         the received data is handled as a set of u16. In this case, Size must indicate the number
857   *         of u16 available through pRxData.
858   * @param husart USART handle.
859   * @param pRxData Pointer to data buffer (u8 or u16 data elements).
860   * @param Size Amount of data elements (u8 or u16) to be received.
861   * @param Timeout Timeout duration.
862   * @retval HAL status
863   */
HAL_USART_Receive(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)864 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
865 {
866   uint8_t  *prxdata8bits;
867   uint16_t *prxdata16bits;
868   uint16_t uhMask;
869   uint32_t tickstart;
870 
871   if (husart->State == HAL_USART_STATE_READY)
872   {
873     if ((pRxData == NULL) || (Size == 0U))
874     {
875       return  HAL_ERROR;
876     }
877 
878     /* Process Locked */
879     __HAL_LOCK(husart);
880 
881     husart->ErrorCode = HAL_USART_ERROR_NONE;
882     husart->State = HAL_USART_STATE_BUSY_RX;
883 
884     /* Init tickstart for timeout management */
885     tickstart = HAL_GetTick();
886 
887     husart->RxXferSize = Size;
888     husart->RxXferCount = Size;
889 
890     /* Computation of USART mask to apply to RDR register */
891     USART_MASK_COMPUTATION(husart);
892     uhMask = husart->Mask;
893 
894     /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
895     if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
896     {
897       prxdata8bits  = NULL;
898       prxdata16bits = (uint16_t *) pRxData;
899     }
900     else
901     {
902       prxdata8bits  = pRxData;
903       prxdata16bits = NULL;
904     }
905 
906     /* as long as data have to be received */
907     while (husart->RxXferCount > 0U)
908     {
909 #if defined(USART_CR2_SLVEN)
910       if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
911 #endif /* USART_CR2_SLVEN */
912       {
913         /* Wait until TXE flag is set to send dummy byte in order to generate the
914         * clock for the slave to send data.
915         * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
916         * can be written for all the cases. */
917         if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
918         {
919           return HAL_TIMEOUT;
920         }
921         husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
922       }
923 
924       /* Wait for RXNE Flag */
925       if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
926       {
927         return HAL_TIMEOUT;
928       }
929 
930       if (prxdata8bits == NULL)
931       {
932         *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
933         prxdata16bits++;
934       }
935       else
936       {
937         *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
938         prxdata8bits++;
939       }
940 
941       husart->RxXferCount--;
942 
943     }
944 
945 #if defined(USART_CR2_SLVEN)
946     /* Clear SPI slave underrun flag and discard transmit data */
947     if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
948     {
949       __HAL_USART_CLEAR_UDRFLAG(husart);
950       __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
951     }
952 #endif /* USART_CR2_SLVEN */
953 
954     /* At end of Rx process, restore husart->State to Ready */
955     husart->State = HAL_USART_STATE_READY;
956 
957     /* Process Unlocked */
958     __HAL_UNLOCK(husart);
959 
960     return HAL_OK;
961   }
962   else
963   {
964     return HAL_BUSY;
965   }
966 }
967 
968 /**
969   * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
970   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
971   *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
972   *         of u16 available through pTxData and through pRxData.
973   * @param  husart USART handle.
974   * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
975   * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
976   * @param  Size amount of data elements (u8 or u16) to be sent (same amount to be received).
977   * @param  Timeout Timeout duration.
978   * @retval HAL status
979   */
HAL_USART_TransmitReceive(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)980 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
981                                             uint16_t Size, uint32_t Timeout)
982 {
983   uint8_t  *prxdata8bits;
984   uint16_t *prxdata16bits;
985   const uint8_t  *ptxdata8bits;
986   const uint16_t *ptxdata16bits;
987   uint16_t uhMask;
988   uint16_t rxdatacount;
989   uint32_t tickstart;
990 
991   if (husart->State == HAL_USART_STATE_READY)
992   {
993     if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
994     {
995       return  HAL_ERROR;
996     }
997 
998     /* Process Locked */
999     __HAL_LOCK(husart);
1000 
1001     husart->ErrorCode = HAL_USART_ERROR_NONE;
1002     husart->State = HAL_USART_STATE_BUSY_RX;
1003 
1004     /* Init tickstart for timeout management */
1005     tickstart = HAL_GetTick();
1006 
1007     husart->RxXferSize = Size;
1008     husart->TxXferSize = Size;
1009     husart->TxXferCount = Size;
1010     husart->RxXferCount = Size;
1011 
1012     /* Computation of USART mask to apply to RDR register */
1013     USART_MASK_COMPUTATION(husart);
1014     uhMask = husart->Mask;
1015 
1016     /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1017     if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1018     {
1019       prxdata8bits  = NULL;
1020       ptxdata8bits  = NULL;
1021       ptxdata16bits = (const uint16_t *) pTxData;
1022       prxdata16bits = (uint16_t *) pRxData;
1023     }
1024     else
1025     {
1026       prxdata8bits  = pRxData;
1027       ptxdata8bits  = pTxData;
1028       ptxdata16bits = NULL;
1029       prxdata16bits = NULL;
1030     }
1031 
1032 #if defined(USART_CR2_SLVEN)
1033     if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE))
1034 #else
1035     if (husart->TxXferCount == 0x01U)
1036 #endif /* USART_CR2_SLVEN */
1037     {
1038       /* Wait until TXE flag is set to send data */
1039       if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1040       {
1041         return HAL_TIMEOUT;
1042       }
1043       if (ptxdata8bits == NULL)
1044       {
1045         husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1046         ptxdata16bits++;
1047       }
1048       else
1049       {
1050         husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1051         ptxdata8bits++;
1052       }
1053 
1054       husart->TxXferCount--;
1055     }
1056 
1057     /* Check the remain data to be sent */
1058     /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
1059     rxdatacount = husart->RxXferCount;
1060     while ((husart->TxXferCount > 0U) || (rxdatacount > 0U))
1061     {
1062       if (husart->TxXferCount > 0U)
1063       {
1064         /* Wait until TXE flag is set to send data */
1065         if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1066         {
1067           return HAL_TIMEOUT;
1068         }
1069         if (ptxdata8bits == NULL)
1070         {
1071           husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1072           ptxdata16bits++;
1073         }
1074         else
1075         {
1076           husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1077           ptxdata8bits++;
1078         }
1079 
1080         husart->TxXferCount--;
1081       }
1082 
1083       if (husart->RxXferCount > 0U)
1084       {
1085         /* Wait for RXNE Flag */
1086         if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1087         {
1088           return HAL_TIMEOUT;
1089         }
1090 
1091         if (prxdata8bits == NULL)
1092         {
1093           *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
1094           prxdata16bits++;
1095         }
1096         else
1097         {
1098           *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
1099           prxdata8bits++;
1100         }
1101 
1102         husart->RxXferCount--;
1103       }
1104       rxdatacount = husart->RxXferCount;
1105     }
1106 
1107     /* At end of TxRx process, restore husart->State to Ready */
1108     husart->State = HAL_USART_STATE_READY;
1109 
1110     /* Process Unlocked */
1111     __HAL_UNLOCK(husart);
1112 
1113     return HAL_OK;
1114   }
1115   else
1116   {
1117     return HAL_BUSY;
1118   }
1119 }
1120 
1121 /**
1122   * @brief  Send an amount of data in interrupt mode.
1123   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1124   *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1125   *         of u16 provided through pTxData.
1126   * @param  husart USART handle.
1127   * @param  pTxData pointer to data buffer (u8 or u16 data elements).
1128   * @param  Size amount of data elements (u8 or u16) to be sent.
1129   * @retval HAL status
1130   */
HAL_USART_Transmit_IT(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size)1131 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1132 {
1133   if (husart->State == HAL_USART_STATE_READY)
1134   {
1135     if ((pTxData == NULL) || (Size == 0U))
1136     {
1137       return HAL_ERROR;
1138     }
1139 
1140     /* Process Locked */
1141     __HAL_LOCK(husart);
1142 
1143     husart->pTxBuffPtr  = pTxData;
1144     husart->TxXferSize  = Size;
1145     husart->TxXferCount = Size;
1146     husart->TxISR       = NULL;
1147 
1148     husart->ErrorCode = HAL_USART_ERROR_NONE;
1149     husart->State     = HAL_USART_STATE_BUSY_TX;
1150 
1151     /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1152     are not managed by the USART Transmit Process to avoid the overrun interrupt
1153     when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1154     to benefit for the frame error and noise interrupts the usart mode should be
1155     configured only for transmit "USART_MODE_TX" */
1156 
1157 #if defined(USART_CR1_FIFOEN)
1158     /* Configure Tx interrupt processing */
1159     if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1160     {
1161       /* Set the Tx ISR function pointer according to the data word length */
1162       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1163       {
1164         husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1165       }
1166       else
1167       {
1168         husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1169       }
1170 
1171       /* Process Unlocked */
1172       __HAL_UNLOCK(husart);
1173 
1174       /* Enable the TX FIFO threshold interrupt */
1175       __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT);
1176     }
1177     else
1178 #endif /* USART_CR1_FIFOEN */
1179     {
1180       /* Set the Tx ISR function pointer according to the data word length */
1181       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1182       {
1183         husart->TxISR = USART_TxISR_16BIT;
1184       }
1185       else
1186       {
1187         husart->TxISR = USART_TxISR_8BIT;
1188       }
1189 
1190       /* Process Unlocked */
1191       __HAL_UNLOCK(husart);
1192 
1193       /* Enable the USART Transmit Data Register Empty Interrupt */
1194       __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
1195     }
1196 
1197     return HAL_OK;
1198   }
1199   else
1200   {
1201     return HAL_BUSY;
1202   }
1203 }
1204 
1205 /**
1206   * @brief Receive an amount of data in interrupt mode.
1207   * @note   To receive synchronous data, dummy data are simultaneously transmitted.
1208   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1209   *         the received data is handled as a set of u16. In this case, Size must indicate the number
1210   *         of u16 available through pRxData.
1211   * @param  husart USART handle.
1212   * @param  pRxData pointer to data buffer (u8 or u16 data elements).
1213   * @param  Size amount of data elements (u8 or u16) to be received.
1214   * @retval HAL status
1215   */
HAL_USART_Receive_IT(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size)1216 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1217 {
1218 #if defined(USART_CR1_FIFOEN)
1219   uint16_t nb_dummy_data;
1220 #endif /* USART_CR1_FIFOEN */
1221 
1222   if (husart->State == HAL_USART_STATE_READY)
1223   {
1224     if ((pRxData == NULL) || (Size == 0U))
1225     {
1226       return HAL_ERROR;
1227     }
1228 
1229     /* Process Locked */
1230     __HAL_LOCK(husart);
1231 
1232     husart->pRxBuffPtr  = pRxData;
1233     husart->RxXferSize  = Size;
1234     husart->RxXferCount = Size;
1235     husart->RxISR       = NULL;
1236 
1237     USART_MASK_COMPUTATION(husart);
1238 
1239     husart->ErrorCode = HAL_USART_ERROR_NONE;
1240     husart->State = HAL_USART_STATE_BUSY_RX;
1241 
1242     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1243     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1244 
1245 #if defined(USART_CR1_FIFOEN)
1246     /* Configure Rx interrupt processing */
1247     if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1248     {
1249       /* Set the Rx ISR function pointer according to the data word length */
1250       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1251       {
1252         husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1253       }
1254       else
1255       {
1256         husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1257       }
1258 
1259       /* Process Unlocked */
1260       __HAL_UNLOCK(husart);
1261 
1262       /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
1263       if (husart->Init.Parity != USART_PARITY_NONE)
1264       {
1265         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1266       }
1267       SET_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
1268     }
1269     else
1270 #endif /* USART_CR1_FIFOEN */
1271     {
1272       /* Set the Rx ISR function pointer according to the data word length */
1273       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1274       {
1275         husart->RxISR = USART_RxISR_16BIT;
1276       }
1277       else
1278       {
1279         husart->RxISR = USART_RxISR_8BIT;
1280       }
1281 
1282       /* Process Unlocked */
1283       __HAL_UNLOCK(husart);
1284 
1285       /* Enable the USART Parity Error and Data Register not empty Interrupts */
1286 #if defined(USART_CR1_FIFOEN)
1287       if (husart->Init.Parity != USART_PARITY_NONE)
1288       {
1289         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1290       }
1291       else
1292       {
1293         SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1294       }
1295 #else
1296       if (husart->Init.Parity != USART_PARITY_NONE)
1297       {
1298         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1299       }
1300       else
1301       {
1302         SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
1303       }
1304 #endif /* USART_CR1_FIFOEN */
1305     }
1306 
1307 #if defined(USART_CR2_SLVEN)
1308     if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
1309 #endif /* USART_CR2_SLVEN */
1310     {
1311       /* Send dummy data in order to generate the clock for the Slave to send the next data.
1312          When FIFO mode is disabled only one data must be transferred.
1313          When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold.
1314       */
1315 #if defined(USART_CR1_FIFOEN)
1316       if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1317       {
1318         for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--)
1319         {
1320           husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1321         }
1322       }
1323       else
1324 #endif /* USART_CR1_FIFOEN */
1325       {
1326         husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1327       }
1328     }
1329 
1330     return HAL_OK;
1331   }
1332   else
1333   {
1334     return HAL_BUSY;
1335   }
1336 }
1337 
1338 /**
1339   * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1340   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1341   *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1342   *         of u16 available through pTxData and through pRxData.
1343   * @param  husart USART handle.
1344   * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
1345   * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
1346   * @param  Size amount of data elements (u8 or u16) to be sent (same amount to be received).
1347   * @retval HAL status
1348   */
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1349 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1350                                                uint16_t Size)
1351 {
1352 
1353   if (husart->State == HAL_USART_STATE_READY)
1354   {
1355     if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1356     {
1357       return HAL_ERROR;
1358     }
1359 
1360     /* Process Locked */
1361     __HAL_LOCK(husart);
1362 
1363     husart->pRxBuffPtr = pRxData;
1364     husart->RxXferSize = Size;
1365     husart->RxXferCount = Size;
1366     husart->pTxBuffPtr = pTxData;
1367     husart->TxXferSize = Size;
1368     husart->TxXferCount = Size;
1369 
1370     /* Computation of USART mask to apply to RDR register */
1371     USART_MASK_COMPUTATION(husart);
1372 
1373     husart->ErrorCode = HAL_USART_ERROR_NONE;
1374     husart->State = HAL_USART_STATE_BUSY_TX_RX;
1375 
1376 #if defined(USART_CR1_FIFOEN)
1377     /* Configure TxRx interrupt processing */
1378     if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1379     {
1380       /* Set the Rx ISR function pointer according to the data word length */
1381       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1382       {
1383         husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1384         husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1385       }
1386       else
1387       {
1388         husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1389         husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1390       }
1391 
1392       /* Process Locked */
1393       __HAL_UNLOCK(husart);
1394 
1395       /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1396       SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1397 
1398       if (husart->Init.Parity != USART_PARITY_NONE)
1399       {
1400         /* Enable the USART Parity Error interrupt  */
1401         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1402       }
1403 
1404       /* Enable the TX and  RX FIFO Threshold interrupts */
1405       SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE));
1406     }
1407     else
1408 #endif /* USART_CR1_FIFOEN */
1409     {
1410       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1411       {
1412         husart->TxISR = USART_TxISR_16BIT;
1413         husart->RxISR = USART_RxISR_16BIT;
1414       }
1415       else
1416       {
1417         husart->TxISR = USART_TxISR_8BIT;
1418         husart->RxISR = USART_RxISR_8BIT;
1419       }
1420 
1421       /* Process Locked */
1422       __HAL_UNLOCK(husart);
1423 
1424       /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1425       SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1426 
1427       /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1428 #if defined(USART_CR1_FIFOEN)
1429       if (husart->Init.Parity != USART_PARITY_NONE)
1430       {
1431         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1432       }
1433       else
1434       {
1435         SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1436       }
1437 #else
1438       if (husart->Init.Parity != USART_PARITY_NONE)
1439       {
1440         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1441       }
1442       else
1443       {
1444         SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
1445       }
1446 #endif /* USART_CR1_FIFOEN */
1447 
1448       /* Enable the USART Transmit Data Register Empty Interrupt */
1449 #if defined(USART_CR1_FIFOEN)
1450       SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1451 #else
1452       SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
1453 #endif /* USART_CR1_FIFOEN */
1454     }
1455 
1456     return HAL_OK;
1457   }
1458   else
1459   {
1460     return HAL_BUSY;
1461   }
1462 }
1463 
1464 /**
1465   * @brief Send an amount of data in DMA mode.
1466   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1467   *         the sent data is handled as a set of u16. In this case, Size must indicate the number
1468   *         of u16 provided through pTxData.
1469   * @param  husart USART handle.
1470   * @param  pTxData pointer to data buffer (u8 or u16 data elements).
1471   * @param  Size amount of data elements (u8 or u16) to be sent.
1472   * @retval HAL status
1473   */
HAL_USART_Transmit_DMA(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size)1474 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1475 {
1476   HAL_StatusTypeDef status = HAL_OK;
1477   const uint32_t *tmp;
1478 
1479   if (husart->State == HAL_USART_STATE_READY)
1480   {
1481     if ((pTxData == NULL) || (Size == 0U))
1482     {
1483       return HAL_ERROR;
1484     }
1485 
1486     /* Process Locked */
1487     __HAL_LOCK(husart);
1488 
1489     husart->pTxBuffPtr = pTxData;
1490     husart->TxXferSize = Size;
1491     husart->TxXferCount = Size;
1492 
1493     husart->ErrorCode = HAL_USART_ERROR_NONE;
1494     husart->State = HAL_USART_STATE_BUSY_TX;
1495 
1496     if (husart->hdmatx != NULL)
1497     {
1498       /* Set the USART DMA transfer complete callback */
1499       husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1500 
1501       /* Set the USART DMA Half transfer complete callback */
1502       husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1503 
1504       /* Set the DMA error callback */
1505       husart->hdmatx->XferErrorCallback = USART_DMAError;
1506 
1507       /* Enable the USART transmit DMA channel */
1508       tmp = (const uint32_t *)&pTxData;
1509       status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1510     }
1511 
1512     if (status == HAL_OK)
1513     {
1514       /* Clear the TC flag in the ICR register */
1515       __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1516 
1517       /* Process Unlocked */
1518       __HAL_UNLOCK(husart);
1519 
1520       /* Enable the DMA transfer for transmit request by setting the DMAT bit
1521          in the USART CR3 register */
1522       SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1523 
1524       return HAL_OK;
1525     }
1526     else
1527     {
1528       /* Set error code to DMA */
1529       husart->ErrorCode = HAL_USART_ERROR_DMA;
1530 
1531       /* Process Unlocked */
1532       __HAL_UNLOCK(husart);
1533 
1534       /* Restore husart->State to ready */
1535       husart->State = HAL_USART_STATE_READY;
1536 
1537       return HAL_ERROR;
1538     }
1539   }
1540   else
1541   {
1542     return HAL_BUSY;
1543   }
1544 }
1545 
1546 /**
1547   * @brief Receive an amount of data in DMA mode.
1548   * @note   When the USART parity is enabled (PCE = 1), the received data contain
1549   *         the parity bit (MSB position).
1550   * @note   The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1551   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1552   *         the received data is handled as a set of u16. In this case, Size must indicate the number
1553   *         of u16 available through pRxData.
1554   * @param  husart USART handle.
1555   * @param  pRxData pointer to data buffer (u8 or u16 data elements).
1556   * @param  Size amount of data elements (u8 or u16) to be received.
1557   * @retval HAL status
1558   */
HAL_USART_Receive_DMA(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size)1559 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1560 {
1561   HAL_StatusTypeDef status = HAL_OK;
1562   uint32_t *tmp = (uint32_t *)&pRxData;
1563 
1564   /* Check that a Rx process is not already ongoing */
1565   if (husart->State == HAL_USART_STATE_READY)
1566   {
1567     if ((pRxData == NULL) || (Size == 0U))
1568     {
1569       return HAL_ERROR;
1570     }
1571 
1572     /* Process Locked */
1573     __HAL_LOCK(husart);
1574 
1575     husart->pRxBuffPtr = pRxData;
1576     husart->RxXferSize = Size;
1577     husart->pTxBuffPtr = pRxData;
1578     husart->TxXferSize = Size;
1579 
1580     husart->ErrorCode = HAL_USART_ERROR_NONE;
1581     husart->State = HAL_USART_STATE_BUSY_RX;
1582 
1583     if (husart->hdmarx != NULL)
1584     {
1585       /* Set the USART DMA Rx transfer complete callback */
1586       husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1587 
1588       /* Set the USART DMA Half transfer complete callback */
1589       husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1590 
1591       /* Set the USART DMA Rx transfer error callback */
1592       husart->hdmarx->XferErrorCallback = USART_DMAError;
1593 
1594       /* Enable the USART receive DMA channel */
1595       status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
1596     }
1597 
1598 #if defined(USART_CR2_SLVEN)
1599     if ((status == HAL_OK) &&
1600         (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
1601 #endif /* USART_CR2_SLVEN */
1602     {
1603       /* Enable the USART transmit DMA channel: the transmit channel is used in order
1604          to generate in the non-blocking mode the clock to the slave device,
1605          this mode isn't a simplex receive mode but a full-duplex receive mode */
1606 
1607       /* Set the USART DMA Tx Complete and Error callback to Null */
1608       if (husart->hdmatx != NULL)
1609       {
1610         husart->hdmatx->XferErrorCallback = NULL;
1611         husart->hdmatx->XferHalfCpltCallback = NULL;
1612         husart->hdmatx->XferCpltCallback = NULL;
1613         status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1614       }
1615     }
1616 
1617     if (status == HAL_OK)
1618     {
1619       /* Process Unlocked */
1620       __HAL_UNLOCK(husart);
1621 
1622       if (husart->Init.Parity != USART_PARITY_NONE)
1623       {
1624         /* Enable the USART Parity Error Interrupt */
1625         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1626       }
1627 
1628       /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1629       SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1630 
1631       /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1632          in the USART CR3 register */
1633       SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1634 
1635       /* Enable the DMA transfer for transmit request by setting the DMAT bit
1636          in the USART CR3 register */
1637       SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1638 
1639       return HAL_OK;
1640     }
1641     else
1642     {
1643       if (husart->hdmarx != NULL)
1644       {
1645         status = HAL_DMA_Abort(husart->hdmarx);
1646       }
1647 
1648       /* No need to check on error code */
1649       UNUSED(status);
1650 
1651       /* Set error code to DMA */
1652       husart->ErrorCode = HAL_USART_ERROR_DMA;
1653 
1654       /* Process Unlocked */
1655       __HAL_UNLOCK(husart);
1656 
1657       /* Restore husart->State to ready */
1658       husart->State = HAL_USART_STATE_READY;
1659 
1660       return HAL_ERROR;
1661     }
1662   }
1663   else
1664   {
1665     return HAL_BUSY;
1666   }
1667 }
1668 
1669 /**
1670   * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1671   * @note   When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1672   * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1673   *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1674   *         of u16 available through pTxData and through pRxData.
1675   * @param  husart USART handle.
1676   * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
1677   * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
1678   * @param  Size amount of data elements (u8 or u16) to be received/sent.
1679   * @retval HAL status
1680   */
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1681 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1682                                                 uint16_t Size)
1683 {
1684   HAL_StatusTypeDef status;
1685   const uint32_t *tmp;
1686 
1687   if (husart->State == HAL_USART_STATE_READY)
1688   {
1689     if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1690     {
1691       return HAL_ERROR;
1692     }
1693 
1694     /* Process Locked */
1695     __HAL_LOCK(husart);
1696 
1697     husart->pRxBuffPtr = pRxData;
1698     husart->RxXferSize = Size;
1699     husart->pTxBuffPtr = pTxData;
1700     husart->TxXferSize = Size;
1701 
1702     husart->ErrorCode = HAL_USART_ERROR_NONE;
1703     husart->State = HAL_USART_STATE_BUSY_TX_RX;
1704 
1705     if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
1706     {
1707       /* Set the USART DMA Rx transfer complete callback */
1708       husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1709 
1710       /* Set the USART DMA Half transfer complete callback */
1711       husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1712 
1713       /* Set the USART DMA Tx transfer complete callback */
1714       husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1715 
1716       /* Set the USART DMA Half transfer complete callback */
1717       husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1718 
1719       /* Set the USART DMA Tx transfer error callback */
1720       husart->hdmatx->XferErrorCallback = USART_DMAError;
1721 
1722       /* Set the USART DMA Rx transfer error callback */
1723       husart->hdmarx->XferErrorCallback = USART_DMAError;
1724 
1725       /* Enable the USART receive DMA channel */
1726       tmp = (uint32_t *)&pRxData;
1727       status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(const uint32_t *)tmp, Size);
1728 
1729       /* Enable the USART transmit DMA channel */
1730       if (status == HAL_OK)
1731       {
1732         tmp = (const uint32_t *)&pTxData;
1733         status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
1734       }
1735     }
1736     else
1737     {
1738       status = HAL_ERROR;
1739     }
1740 
1741     if (status == HAL_OK)
1742     {
1743       /* Process Unlocked */
1744       __HAL_UNLOCK(husart);
1745 
1746       if (husart->Init.Parity != USART_PARITY_NONE)
1747       {
1748         /* Enable the USART Parity Error Interrupt */
1749         SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1750       }
1751 
1752       /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1753       SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1754 
1755       /* Clear the TC flag in the ICR register */
1756       __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1757 
1758       /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1759          in the USART CR3 register */
1760       SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1761 
1762       /* Enable the DMA transfer for transmit request by setting the DMAT bit
1763          in the USART CR3 register */
1764       SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1765 
1766       return HAL_OK;
1767     }
1768     else
1769     {
1770       if (husart->hdmarx != NULL)
1771       {
1772         status = HAL_DMA_Abort(husart->hdmarx);
1773       }
1774 
1775       /* No need to check on error code */
1776       UNUSED(status);
1777 
1778       /* Set error code to DMA */
1779       husart->ErrorCode = HAL_USART_ERROR_DMA;
1780 
1781       /* Process Unlocked */
1782       __HAL_UNLOCK(husart);
1783 
1784       /* Restore husart->State to ready */
1785       husart->State = HAL_USART_STATE_READY;
1786 
1787       return HAL_ERROR;
1788     }
1789   }
1790   else
1791   {
1792     return HAL_BUSY;
1793   }
1794 }
1795 
1796 /**
1797   * @brief Pause the DMA Transfer.
1798   * @param  husart USART handle.
1799   * @retval HAL status
1800   */
HAL_USART_DMAPause(USART_HandleTypeDef * husart)1801 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1802 {
1803   const HAL_USART_StateTypeDef state = husart->State;
1804 
1805   /* Process Locked */
1806   __HAL_LOCK(husart);
1807 
1808   if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
1809       (state == HAL_USART_STATE_BUSY_TX))
1810   {
1811     /* Disable the USART DMA Tx request */
1812     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1813   }
1814   else if ((state == HAL_USART_STATE_BUSY_RX) ||
1815            (state == HAL_USART_STATE_BUSY_TX_RX))
1816   {
1817     if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1818     {
1819       /* Disable the USART DMA Tx request */
1820       CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1821     }
1822     if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1823     {
1824       /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1825       CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1826       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1827 
1828       /* Disable the USART DMA Rx request */
1829       CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1830     }
1831   }
1832   else
1833   {
1834     /* Nothing to do */
1835   }
1836 
1837   /* Process Unlocked */
1838   __HAL_UNLOCK(husart);
1839 
1840   return HAL_OK;
1841 }
1842 
1843 /**
1844   * @brief Resume the DMA Transfer.
1845   * @param  husart USART handle.
1846   * @retval HAL status
1847   */
HAL_USART_DMAResume(USART_HandleTypeDef * husart)1848 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1849 {
1850   const HAL_USART_StateTypeDef state = husart->State;
1851 
1852   /* Process Locked */
1853   __HAL_LOCK(husart);
1854 
1855   if (state == HAL_USART_STATE_BUSY_TX)
1856   {
1857     /* Enable the USART DMA Tx request */
1858     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1859   }
1860   else if ((state == HAL_USART_STATE_BUSY_RX) ||
1861            (state == HAL_USART_STATE_BUSY_TX_RX))
1862   {
1863     /* Clear the Overrun flag before resuming the Rx transfer*/
1864     __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
1865 
1866     /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1867     if (husart->Init.Parity != USART_PARITY_NONE)
1868     {
1869       SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1870     }
1871     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1872 
1873     /* Enable the USART DMA Rx request  before the DMA Tx request */
1874     SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1875 
1876     /* Enable the USART DMA Tx request */
1877     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1878   }
1879   else
1880   {
1881     /* Nothing to do */
1882   }
1883 
1884   /* Process Unlocked */
1885   __HAL_UNLOCK(husart);
1886 
1887   return HAL_OK;
1888 }
1889 
1890 /**
1891   * @brief Stop the DMA Transfer.
1892   * @param  husart USART handle.
1893   * @retval HAL status
1894   */
HAL_USART_DMAStop(USART_HandleTypeDef * husart)1895 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1896 {
1897   /* The Lock is not implemented on this API to allow the user application
1898      to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1899      HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1900      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1901      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1902      the stream and the corresponding call back is executed. */
1903 
1904   /* Disable the USART Tx/Rx DMA requests */
1905   CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1906   CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1907 
1908   /* Abort the USART DMA tx channel */
1909   if (husart->hdmatx != NULL)
1910   {
1911     if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1912     {
1913       if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1914       {
1915         /* Set error code to DMA */
1916         husart->ErrorCode = HAL_USART_ERROR_DMA;
1917 
1918         return HAL_TIMEOUT;
1919       }
1920     }
1921   }
1922   /* Abort the USART DMA rx channel */
1923   if (husart->hdmarx != NULL)
1924   {
1925     if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
1926     {
1927       if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1928       {
1929         /* Set error code to DMA */
1930         husart->ErrorCode = HAL_USART_ERROR_DMA;
1931 
1932         return HAL_TIMEOUT;
1933       }
1934     }
1935   }
1936 
1937   USART_EndTransfer(husart);
1938   husart->State = HAL_USART_STATE_READY;
1939 
1940   return HAL_OK;
1941 }
1942 
1943 /**
1944   * @brief  Abort ongoing transfers (blocking mode).
1945   * @param  husart USART handle.
1946   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1947   *         This procedure performs following operations :
1948   *           - Disable USART Interrupts (Tx and Rx)
1949   *           - Disable the DMA transfer in the peripheral register (if enabled)
1950   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1951   *           - Set handle State to READY
1952   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1953   * @retval HAL status
1954   */
HAL_USART_Abort(USART_HandleTypeDef * husart)1955 HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
1956 {
1957 #if defined(USART_CR1_FIFOEN)
1958   /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1959   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
1960                                     USART_CR1_TCIE));
1961   CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1962 #else
1963   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1964   CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1965 #endif /* USART_CR1_FIFOEN */
1966 
1967   /* Abort the USART DMA Tx channel if enabled */
1968   if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1969   {
1970     /* Disable the USART DMA Tx request if enabled */
1971     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1972 
1973     /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1974     if (husart->hdmatx != NULL)
1975     {
1976       /* Set the USART DMA Abort callback to Null.
1977          No call back execution at end of DMA abort procedure */
1978       husart->hdmatx->XferAbortCallback = NULL;
1979 
1980       if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
1981       {
1982         if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1983         {
1984           /* Set error code to DMA */
1985           husart->ErrorCode = HAL_USART_ERROR_DMA;
1986 
1987           return HAL_TIMEOUT;
1988         }
1989       }
1990     }
1991   }
1992 
1993   /* Abort the USART DMA Rx channel if enabled */
1994   if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1995   {
1996     /* Disable the USART DMA Rx request if enabled */
1997     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1998 
1999     /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
2000     if (husart->hdmarx != NULL)
2001     {
2002       /* Set the USART DMA Abort callback to Null.
2003          No call back execution at end of DMA abort procedure */
2004       husart->hdmarx->XferAbortCallback = NULL;
2005 
2006       if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
2007       {
2008         if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
2009         {
2010           /* Set error code to DMA */
2011           husart->ErrorCode = HAL_USART_ERROR_DMA;
2012 
2013           return HAL_TIMEOUT;
2014         }
2015       }
2016     }
2017   }
2018 
2019   /* Reset Tx and Rx transfer counters */
2020   husart->TxXferCount = 0U;
2021   husart->RxXferCount = 0U;
2022 
2023   /* Clear the Error flags in the ICR register */
2024   __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2025 
2026 #if defined(USART_CR1_FIFOEN)
2027   /* Flush the whole TX FIFO (if needed) */
2028   if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2029   {
2030     __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2031   }
2032 #endif /* USART_CR1_FIFOEN */
2033 
2034   /* Discard the received data */
2035   __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2036 
2037   /* Restore husart->State to Ready */
2038   husart->State  = HAL_USART_STATE_READY;
2039 
2040   /* Reset Handle ErrorCode to No Error */
2041   husart->ErrorCode = HAL_USART_ERROR_NONE;
2042 
2043   return HAL_OK;
2044 }
2045 
2046 /**
2047   * @brief  Abort ongoing transfers (Interrupt mode).
2048   * @param  husart USART handle.
2049   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
2050   *         This procedure performs following operations :
2051   *           - Disable USART Interrupts (Tx and Rx)
2052   *           - Disable the DMA transfer in the peripheral register (if enabled)
2053   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2054   *           - Set handle State to READY
2055   *           - At abort completion, call user abort complete callback
2056   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
2057   *         considered as completed only when user abort complete callback is executed (not when exiting function).
2058   * @retval HAL status
2059   */
HAL_USART_Abort_IT(USART_HandleTypeDef * husart)2060 HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
2061 {
2062   uint32_t abortcplt = 1U;
2063 
2064 #if defined(USART_CR1_FIFOEN)
2065   /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2066   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2067                                     USART_CR1_TCIE));
2068   CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2069 #else
2070   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
2071   CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2072 #endif /* USART_CR1_FIFOEN */
2073 
2074   /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
2075      before any call to DMA Abort functions */
2076   /* DMA Tx Handle is valid */
2077   if (husart->hdmatx != NULL)
2078   {
2079     /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
2080        Otherwise, set it to NULL */
2081     if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2082     {
2083       husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
2084     }
2085     else
2086     {
2087       husart->hdmatx->XferAbortCallback = NULL;
2088     }
2089   }
2090   /* DMA Rx Handle is valid */
2091   if (husart->hdmarx != NULL)
2092   {
2093     /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
2094        Otherwise, set it to NULL */
2095     if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2096     {
2097       husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
2098     }
2099     else
2100     {
2101       husart->hdmarx->XferAbortCallback = NULL;
2102     }
2103   }
2104 
2105   /* Abort the USART DMA Tx channel if enabled */
2106   if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2107   {
2108     /* Disable DMA Tx at USART level */
2109     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2110 
2111     /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2112     if (husart->hdmatx != NULL)
2113     {
2114       /* USART Tx DMA Abort callback has already been initialised :
2115          will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2116 
2117       /* Abort DMA TX */
2118       if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
2119       {
2120         husart->hdmatx->XferAbortCallback = NULL;
2121       }
2122       else
2123       {
2124         abortcplt = 0U;
2125       }
2126     }
2127   }
2128 
2129   /* Abort the USART DMA Rx channel if enabled */
2130   if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2131   {
2132     /* Disable the USART DMA Rx request if enabled */
2133     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2134 
2135     /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2136     if (husart->hdmarx != NULL)
2137     {
2138       /* USART Rx DMA Abort callback has already been initialised :
2139          will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2140 
2141       /* Abort DMA RX */
2142       if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2143       {
2144         husart->hdmarx->XferAbortCallback = NULL;
2145         abortcplt = 1U;
2146       }
2147       else
2148       {
2149         abortcplt = 0U;
2150       }
2151     }
2152   }
2153 
2154   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2155   if (abortcplt == 1U)
2156   {
2157     /* Reset Tx and Rx transfer counters */
2158     husart->TxXferCount = 0U;
2159     husart->RxXferCount = 0U;
2160 
2161     /* Reset errorCode */
2162     husart->ErrorCode = HAL_USART_ERROR_NONE;
2163 
2164     /* Clear the Error flags in the ICR register */
2165     __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2166 
2167 #if defined(USART_CR1_FIFOEN)
2168     /* Flush the whole TX FIFO (if needed) */
2169     if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2170     {
2171       __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2172     }
2173 #endif /* USART_CR1_FIFOEN */
2174 
2175     /* Discard the received data */
2176     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2177 
2178     /* Restore husart->State to Ready */
2179     husart->State  = HAL_USART_STATE_READY;
2180 
2181     /* As no DMA to be aborted, call directly user Abort complete callback */
2182 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2183     /* Call registered Abort Complete Callback */
2184     husart->AbortCpltCallback(husart);
2185 #else
2186     /* Call legacy weak Abort Complete Callback */
2187     HAL_USART_AbortCpltCallback(husart);
2188 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2189   }
2190 
2191   return HAL_OK;
2192 }
2193 
2194 /**
2195   * @brief  Handle USART interrupt request.
2196   * @param  husart USART handle.
2197   * @retval None
2198   */
HAL_USART_IRQHandler(USART_HandleTypeDef * husart)2199 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
2200 {
2201   uint32_t isrflags   = READ_REG(husart->Instance->ISR);
2202   uint32_t cr1its     = READ_REG(husart->Instance->CR1);
2203   uint32_t cr3its     = READ_REG(husart->Instance->CR3);
2204 
2205   uint32_t errorflags;
2206   uint32_t errorcode;
2207 
2208   /* If no error occurs */
2209 #if defined(USART_CR2_SLVEN)
2210   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF |
2211                                       USART_ISR_UDR));
2212 #else
2213   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2214 #endif /* USART_CR2_SLVEN */
2215   if (errorflags == 0U)
2216   {
2217     /* USART in mode Receiver ---------------------------------------------------*/
2218 #if defined(USART_CR1_FIFOEN)
2219     if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2220         && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2221             || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2222 #else
2223     if (((isrflags & USART_ISR_RXNE) != 0U)
2224         && ((cr1its & USART_CR1_RXNEIE) != 0U))
2225 #endif /* USART_CR1_FIFOEN */
2226     {
2227       if (husart->RxISR != NULL)
2228       {
2229         husart->RxISR(husart);
2230       }
2231       return;
2232     }
2233   }
2234 
2235   /* If some errors occur */
2236 #if defined(USART_CR1_FIFOEN)
2237   if ((errorflags != 0U)
2238       && (((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2239           || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
2240 #else
2241   if ((errorflags != 0U)
2242       && (((cr3its & USART_CR3_EIE) != 0U)
2243           || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != 0U)))
2244 #endif /* USART_CR1_FIFOEN */
2245   {
2246     /* USART parity error interrupt occurred -------------------------------------*/
2247     if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2248     {
2249       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
2250 
2251       husart->ErrorCode |= HAL_USART_ERROR_PE;
2252     }
2253 
2254     /* USART frame error interrupt occurred --------------------------------------*/
2255     if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2256     {
2257       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
2258 
2259       husart->ErrorCode |= HAL_USART_ERROR_FE;
2260     }
2261 
2262     /* USART noise error interrupt occurred --------------------------------------*/
2263     if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2264     {
2265       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
2266 
2267       husart->ErrorCode |= HAL_USART_ERROR_NE;
2268     }
2269 
2270     /* USART Over-Run interrupt occurred -----------------------------------------*/
2271 #if defined(USART_CR1_FIFOEN)
2272     if (((isrflags & USART_ISR_ORE) != 0U)
2273         && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2274             ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2275 #else
2276     if (((isrflags & USART_ISR_ORE) != 0U)
2277         && (((cr1its & USART_CR1_RXNEIE) != 0U) ||
2278             ((cr3its & USART_CR3_EIE) != 0U)))
2279 #endif /* USART_CR1_FIFOEN */
2280     {
2281       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
2282 
2283       husart->ErrorCode |= HAL_USART_ERROR_ORE;
2284     }
2285 
2286     /* USART Receiver Timeout interrupt occurred ---------------------------------*/
2287     if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2288     {
2289       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF);
2290 
2291       husart->ErrorCode |= HAL_USART_ERROR_RTO;
2292     }
2293 
2294 #if defined(USART_CR2_SLVEN)
2295     /* USART SPI slave underrun error interrupt occurred -------------------------*/
2296     if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2297     {
2298       /* Ignore SPI slave underrun errors when reception is going on */
2299       if (husart->State == HAL_USART_STATE_BUSY_RX)
2300       {
2301         __HAL_USART_CLEAR_UDRFLAG(husart);
2302         return;
2303       }
2304       else
2305       {
2306         __HAL_USART_CLEAR_UDRFLAG(husart);
2307         husart->ErrorCode |= HAL_USART_ERROR_UDR;
2308       }
2309     }
2310 #endif /* USART_CR2_SLVEN */
2311 
2312     /* Call USART Error Call back function if need be --------------------------*/
2313     if (husart->ErrorCode != HAL_USART_ERROR_NONE)
2314     {
2315       /* USART in mode Receiver ---------------------------------------------------*/
2316 #if defined(USART_CR1_FIFOEN)
2317       if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2318           && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2319               || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2320 #else
2321       if (((isrflags & USART_ISR_RXNE) != 0U)
2322           && ((cr1its & USART_CR1_RXNEIE) != 0U))
2323 #endif /* USART_CR1_FIFOEN */
2324       {
2325         if (husart->RxISR != NULL)
2326         {
2327           husart->RxISR(husart);
2328         }
2329       }
2330 
2331       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2332          consider error as blocking */
2333       errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE;
2334       if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) ||
2335           (errorcode != 0U))
2336       {
2337         /* Blocking error : transfer is aborted
2338            Set the USART state ready to be able to start again the process,
2339            Disable Interrupts, and disable DMA requests, if ongoing */
2340         USART_EndTransfer(husart);
2341 
2342         /* Abort the USART DMA Rx channel if enabled */
2343         if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2344         {
2345           /* Disable the USART DMA Rx request if enabled */
2346           CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
2347 
2348           /* Abort the USART DMA Tx channel */
2349           if (husart->hdmatx != NULL)
2350           {
2351             /* Set the USART Tx DMA Abort callback to NULL : no callback
2352                executed at end of DMA abort procedure */
2353             husart->hdmatx->XferAbortCallback = NULL;
2354 
2355             /* Abort DMA TX */
2356             (void)HAL_DMA_Abort_IT(husart->hdmatx);
2357           }
2358 
2359           /* Abort the USART DMA Rx channel */
2360           if (husart->hdmarx != NULL)
2361           {
2362             /* Set the USART Rx DMA Abort callback :
2363                will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2364             husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
2365 
2366             /* Abort DMA RX */
2367             if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2368             {
2369               /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2370               husart->hdmarx->XferAbortCallback(husart->hdmarx);
2371             }
2372           }
2373           else
2374           {
2375             /* Call user error callback */
2376 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2377             /* Call registered Error Callback */
2378             husart->ErrorCallback(husart);
2379 #else
2380             /* Call legacy weak Error Callback */
2381             HAL_USART_ErrorCallback(husart);
2382 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2383           }
2384         }
2385         else
2386         {
2387           /* Call user error callback */
2388 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2389           /* Call registered Error Callback */
2390           husart->ErrorCallback(husart);
2391 #else
2392           /* Call legacy weak Error Callback */
2393           HAL_USART_ErrorCallback(husart);
2394 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2395         }
2396       }
2397       else
2398       {
2399         /* Non Blocking error : transfer could go on.
2400            Error is notified to user through user error callback */
2401 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2402         /* Call registered Error Callback */
2403         husart->ErrorCallback(husart);
2404 #else
2405         /* Call legacy weak Error Callback */
2406         HAL_USART_ErrorCallback(husart);
2407 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2408         husart->ErrorCode = HAL_USART_ERROR_NONE;
2409       }
2410     }
2411     return;
2412 
2413   } /* End if some error occurs */
2414 
2415 
2416   /* USART in mode Transmitter ------------------------------------------------*/
2417 #if defined(USART_CR1_FIFOEN)
2418   if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2419       && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2420           || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2421 #else
2422   if (((isrflags & USART_ISR_TXE) != 0U)
2423       && ((cr1its & USART_CR1_TXEIE) != 0U))
2424 #endif /* USART_CR1_FIFOEN */
2425   {
2426     if (husart->TxISR != NULL)
2427     {
2428       husart->TxISR(husart);
2429     }
2430     return;
2431   }
2432 
2433   /* USART in mode Transmitter (transmission end) -----------------------------*/
2434   if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2435   {
2436     USART_EndTransmit_IT(husart);
2437     return;
2438   }
2439 
2440 #if defined(USART_CR1_FIFOEN)
2441   /* USART TX Fifo Empty occurred ----------------------------------------------*/
2442   if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2443   {
2444 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2445     /* Call registered Tx Fifo Empty Callback */
2446     husart->TxFifoEmptyCallback(husart);
2447 #else
2448     /* Call legacy weak Tx Fifo Empty Callback */
2449     HAL_USARTEx_TxFifoEmptyCallback(husart);
2450 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2451     return;
2452   }
2453 
2454   /* USART RX Fifo Full occurred ----------------------------------------------*/
2455   if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2456   {
2457 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2458     /* Call registered Rx Fifo Full Callback */
2459     husart->RxFifoFullCallback(husart);
2460 #else
2461     /* Call legacy weak Rx Fifo Full Callback */
2462     HAL_USARTEx_RxFifoFullCallback(husart);
2463 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2464     return;
2465   }
2466 #endif /* USART_CR1_FIFOEN */
2467 }
2468 
2469 /**
2470   * @brief Tx Transfer completed callback.
2471   * @param husart USART handle.
2472   * @retval None
2473   */
HAL_USART_TxCpltCallback(USART_HandleTypeDef * husart)2474 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
2475 {
2476   /* Prevent unused argument(s) compilation warning */
2477   UNUSED(husart);
2478 
2479   /* NOTE : This function should not be modified, when the callback is needed,
2480             the HAL_USART_TxCpltCallback can be implemented in the user file.
2481    */
2482 }
2483 
2484 /**
2485   * @brief  Tx Half Transfer completed callback.
2486   * @param husart USART handle.
2487   * @retval None
2488   */
HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef * husart)2489 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
2490 {
2491   /* Prevent unused argument(s) compilation warning */
2492   UNUSED(husart);
2493 
2494   /* NOTE: This function should not be modified, when the callback is needed,
2495            the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2496    */
2497 }
2498 
2499 /**
2500   * @brief  Rx Transfer completed callback.
2501   * @param husart USART handle.
2502   * @retval None
2503   */
HAL_USART_RxCpltCallback(USART_HandleTypeDef * husart)2504 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
2505 {
2506   /* Prevent unused argument(s) compilation warning */
2507   UNUSED(husart);
2508 
2509   /* NOTE: This function should not be modified, when the callback is needed,
2510            the HAL_USART_RxCpltCallback can be implemented in the user file.
2511    */
2512 }
2513 
2514 /**
2515   * @brief Rx Half Transfer completed callback.
2516   * @param husart USART handle.
2517   * @retval None
2518   */
HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef * husart)2519 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
2520 {
2521   /* Prevent unused argument(s) compilation warning */
2522   UNUSED(husart);
2523 
2524   /* NOTE : This function should not be modified, when the callback is needed,
2525             the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2526    */
2527 }
2528 
2529 /**
2530   * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2531   * @param husart USART handle.
2532   * @retval None
2533   */
HAL_USART_TxRxCpltCallback(USART_HandleTypeDef * husart)2534 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
2535 {
2536   /* Prevent unused argument(s) compilation warning */
2537   UNUSED(husart);
2538 
2539   /* NOTE : This function should not be modified, when the callback is needed,
2540             the HAL_USART_TxRxCpltCallback can be implemented in the user file
2541    */
2542 }
2543 
2544 /**
2545   * @brief USART error callback.
2546   * @param husart USART handle.
2547   * @retval None
2548   */
HAL_USART_ErrorCallback(USART_HandleTypeDef * husart)2549 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
2550 {
2551   /* Prevent unused argument(s) compilation warning */
2552   UNUSED(husart);
2553 
2554   /* NOTE : This function should not be modified, when the callback is needed,
2555             the HAL_USART_ErrorCallback can be implemented in the user file.
2556    */
2557 }
2558 
2559 /**
2560   * @brief  USART Abort Complete callback.
2561   * @param  husart USART handle.
2562   * @retval None
2563   */
HAL_USART_AbortCpltCallback(USART_HandleTypeDef * husart)2564 __weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
2565 {
2566   /* Prevent unused argument(s) compilation warning */
2567   UNUSED(husart);
2568 
2569   /* NOTE : This function should not be modified, when the callback is needed,
2570             the HAL_USART_AbortCpltCallback can be implemented in the user file.
2571    */
2572 }
2573 
2574 /**
2575   * @}
2576   */
2577 
2578 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2579   *  @brief   USART Peripheral State and Error functions
2580   *
2581 @verbatim
2582   ==============================================================================
2583             ##### Peripheral State and Error functions #####
2584   ==============================================================================
2585     [..]
2586     This subsection provides functions allowing to :
2587       (+) Return the USART handle state
2588       (+) Return the USART handle error code
2589 
2590 @endverbatim
2591   * @{
2592   */
2593 
2594 
2595 /**
2596   * @brief Return the USART handle state.
2597   * @param husart pointer to a USART_HandleTypeDef structure that contains
2598   *              the configuration information for the specified USART.
2599   * @retval USART handle state
2600   */
HAL_USART_GetState(const USART_HandleTypeDef * husart)2601 HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart)
2602 {
2603   return husart->State;
2604 }
2605 
2606 /**
2607   * @brief Return the USART error code.
2608   * @param husart pointer to a USART_HandleTypeDef structure that contains
2609   *              the configuration information for the specified USART.
2610   * @retval USART handle Error Code
2611   */
HAL_USART_GetError(const USART_HandleTypeDef * husart)2612 uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart)
2613 {
2614   return husart->ErrorCode;
2615 }
2616 
2617 /**
2618   * @}
2619   */
2620 
2621 /**
2622   * @}
2623   */
2624 
2625 /** @defgroup USART_Private_Functions USART Private Functions
2626   * @{
2627   */
2628 
2629 /**
2630   * @brief  Initialize the callbacks to their default values.
2631   * @param  husart USART handle.
2632   * @retval none
2633   */
2634 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
USART_InitCallbacksToDefault(USART_HandleTypeDef * husart)2635 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
2636 {
2637   /* Init the USART Callback settings */
2638   husart->TxHalfCpltCallback        = HAL_USART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
2639   husart->TxCpltCallback            = HAL_USART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
2640   husart->RxHalfCpltCallback        = HAL_USART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
2641   husart->RxCpltCallback            = HAL_USART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
2642   husart->TxRxCpltCallback          = HAL_USART_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback          */
2643   husart->ErrorCallback             = HAL_USART_ErrorCallback;             /* Legacy weak ErrorCallback             */
2644   husart->AbortCpltCallback         = HAL_USART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
2645 #if defined(USART_CR1_FIFOEN)
2646   husart->RxFifoFullCallback        = HAL_USARTEx_RxFifoFullCallback;      /* Legacy weak RxFifoFullCallback        */
2647   husart->TxFifoEmptyCallback       = HAL_USARTEx_TxFifoEmptyCallback;     /* Legacy weak TxFifoEmptyCallback       */
2648 #endif /* USART_CR1_FIFOEN */
2649 }
2650 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2651 
2652 /**
2653   * @brief  End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2654   * @param  husart USART handle.
2655   * @retval None
2656   */
USART_EndTransfer(USART_HandleTypeDef * husart)2657 static void USART_EndTransfer(USART_HandleTypeDef *husart)
2658 {
2659 #if defined(USART_CR1_FIFOEN)
2660   /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2661   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2662                                     USART_CR1_TCIE));
2663   CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2664 #else
2665   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2666   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
2667   CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2668 #endif /* USART_CR1_FIFOEN */
2669 
2670   /* At end of process, restore husart->State to Ready */
2671   husart->State = HAL_USART_STATE_READY;
2672 }
2673 
2674 /**
2675   * @brief DMA USART transmit process complete callback.
2676   * @param  hdma DMA handle.
2677   * @retval None
2678   */
USART_DMATransmitCplt(DMA_HandleTypeDef * hdma)2679 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2680 {
2681   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2682 
2683   /* DMA Normal mode */
2684   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
2685   {
2686     husart->TxXferCount = 0U;
2687 
2688     if (husart->State == HAL_USART_STATE_BUSY_TX)
2689     {
2690       /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2691          in the USART CR3 register */
2692       CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2693 
2694       /* Enable the USART Transmit Complete Interrupt */
2695       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2696     }
2697   }
2698   /* DMA Circular mode */
2699   else
2700   {
2701     if (husart->State == HAL_USART_STATE_BUSY_TX)
2702     {
2703 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2704       /* Call registered Tx Complete Callback */
2705       husart->TxCpltCallback(husart);
2706 #else
2707       /* Call legacy weak Tx Complete Callback */
2708       HAL_USART_TxCpltCallback(husart);
2709 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2710     }
2711   }
2712 }
2713 
2714 /**
2715   * @brief DMA USART transmit process half complete callback.
2716   * @param  hdma DMA handle.
2717   * @retval None
2718   */
USART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2719 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2720 {
2721   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2722 
2723 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2724   /* Call registered Tx Half Complete Callback */
2725   husart->TxHalfCpltCallback(husart);
2726 #else
2727   /* Call legacy weak Tx Half Complete Callback */
2728   HAL_USART_TxHalfCpltCallback(husart);
2729 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2730 }
2731 
2732 /**
2733   * @brief DMA USART receive process complete callback.
2734   * @param  hdma DMA handle.
2735   * @retval None
2736   */
USART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2737 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2738 {
2739   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2740 
2741   /* DMA Normal mode */
2742   if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
2743   {
2744     husart->RxXferCount = 0U;
2745 
2746     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2747     CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2748     CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2749 
2750     /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2751        in USART CR3 register */
2752     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2753     /* similarly, disable the DMA TX transfer that was started to provide the
2754        clock to the slave device */
2755     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2756 
2757     if (husart->State == HAL_USART_STATE_BUSY_RX)
2758     {
2759 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2760       /* Call registered Rx Complete Callback */
2761       husart->RxCpltCallback(husart);
2762 #else
2763       /* Call legacy weak Rx Complete Callback */
2764       HAL_USART_RxCpltCallback(husart);
2765 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2766     }
2767     /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2768     else
2769     {
2770 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2771       /* Call registered Tx Rx Complete Callback */
2772       husart->TxRxCpltCallback(husart);
2773 #else
2774       /* Call legacy weak Tx Rx Complete Callback */
2775       HAL_USART_TxRxCpltCallback(husart);
2776 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2777     }
2778     husart->State = HAL_USART_STATE_READY;
2779   }
2780   /* DMA circular mode */
2781   else
2782   {
2783     if (husart->State == HAL_USART_STATE_BUSY_RX)
2784     {
2785 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2786       /* Call registered Rx Complete Callback */
2787       husart->RxCpltCallback(husart);
2788 #else
2789       /* Call legacy weak Rx Complete Callback */
2790       HAL_USART_RxCpltCallback(husart);
2791 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2792     }
2793     /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2794     else
2795     {
2796 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2797       /* Call registered Tx Rx Complete Callback */
2798       husart->TxRxCpltCallback(husart);
2799 #else
2800       /* Call legacy weak Tx Rx Complete Callback */
2801       HAL_USART_TxRxCpltCallback(husart);
2802 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2803     }
2804   }
2805 }
2806 
2807 /**
2808   * @brief DMA USART receive process half complete callback.
2809   * @param  hdma DMA handle.
2810   * @retval None
2811   */
USART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2812 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2813 {
2814   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2815 
2816 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2817   /* Call registered Rx Half Complete Callback */
2818   husart->RxHalfCpltCallback(husart);
2819 #else
2820   /* Call legacy weak Rx Half Complete Callback */
2821   HAL_USART_RxHalfCpltCallback(husart);
2822 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2823 }
2824 
2825 /**
2826   * @brief DMA USART communication error callback.
2827   * @param  hdma DMA handle.
2828   * @retval None
2829   */
USART_DMAError(DMA_HandleTypeDef * hdma)2830 static void USART_DMAError(DMA_HandleTypeDef *hdma)
2831 {
2832   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2833 
2834   husart->RxXferCount = 0U;
2835   husart->TxXferCount = 0U;
2836   USART_EndTransfer(husart);
2837 
2838   husart->ErrorCode |= HAL_USART_ERROR_DMA;
2839   husart->State = HAL_USART_STATE_READY;
2840 
2841 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2842   /* Call registered Error Callback */
2843   husart->ErrorCallback(husart);
2844 #else
2845   /* Call legacy weak Error Callback */
2846   HAL_USART_ErrorCallback(husart);
2847 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2848 }
2849 
2850 /**
2851   * @brief  DMA USART communication abort callback, when initiated by HAL services on Error
2852   *         (To be called at end of DMA Abort procedure following error occurrence).
2853   * @param  hdma DMA handle.
2854   * @retval None
2855   */
USART_DMAAbortOnError(DMA_HandleTypeDef * hdma)2856 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2857 {
2858   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2859   husart->RxXferCount = 0U;
2860   husart->TxXferCount = 0U;
2861 
2862 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2863   /* Call registered Error Callback */
2864   husart->ErrorCallback(husart);
2865 #else
2866   /* Call legacy weak Error Callback */
2867   HAL_USART_ErrorCallback(husart);
2868 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2869 }
2870 
2871 /**
2872   * @brief  DMA USART Tx communication abort callback, when initiated by user
2873   *         (To be called at end of DMA Tx Abort procedure following user abort request).
2874   * @note   When this callback is executed, User Abort complete call back is called only if no
2875   *         Abort still ongoing for Rx DMA Handle.
2876   * @param  hdma DMA handle.
2877   * @retval None
2878   */
USART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2879 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2880 {
2881   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2882 
2883   husart->hdmatx->XferAbortCallback = NULL;
2884 
2885   /* Check if an Abort process is still ongoing */
2886   if (husart->hdmarx != NULL)
2887   {
2888     if (husart->hdmarx->XferAbortCallback != NULL)
2889     {
2890       return;
2891     }
2892   }
2893 
2894   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2895   husart->TxXferCount = 0U;
2896   husart->RxXferCount = 0U;
2897 
2898   /* Reset errorCode */
2899   husart->ErrorCode = HAL_USART_ERROR_NONE;
2900 
2901   /* Clear the Error flags in the ICR register */
2902   __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2903 
2904   /* Restore husart->State to Ready */
2905   husart->State = HAL_USART_STATE_READY;
2906 
2907   /* Call user Abort complete callback */
2908 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2909   /* Call registered Abort Complete Callback */
2910   husart->AbortCpltCallback(husart);
2911 #else
2912   /* Call legacy weak Abort Complete Callback */
2913   HAL_USART_AbortCpltCallback(husart);
2914 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2915 
2916 }
2917 
2918 
2919 /**
2920   * @brief  DMA USART Rx communication abort callback, when initiated by user
2921   *         (To be called at end of DMA Rx Abort procedure following user abort request).
2922   * @note   When this callback is executed, User Abort complete call back is called only if no
2923   *         Abort still ongoing for Tx DMA Handle.
2924   * @param  hdma DMA handle.
2925   * @retval None
2926   */
USART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)2927 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2928 {
2929   USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2930 
2931   husart->hdmarx->XferAbortCallback = NULL;
2932 
2933   /* Check if an Abort process is still ongoing */
2934   if (husart->hdmatx != NULL)
2935   {
2936     if (husart->hdmatx->XferAbortCallback != NULL)
2937     {
2938       return;
2939     }
2940   }
2941 
2942   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2943   husart->TxXferCount = 0U;
2944   husart->RxXferCount = 0U;
2945 
2946   /* Reset errorCode */
2947   husart->ErrorCode = HAL_USART_ERROR_NONE;
2948 
2949   /* Clear the Error flags in the ICR register */
2950   __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2951 
2952   /* Restore husart->State to Ready */
2953   husart->State  = HAL_USART_STATE_READY;
2954 
2955   /* Call user Abort complete callback */
2956 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2957   /* Call registered Abort Complete Callback */
2958   husart->AbortCpltCallback(husart);
2959 #else
2960   /* Call legacy weak Abort Complete Callback */
2961   HAL_USART_AbortCpltCallback(husart);
2962 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2963 }
2964 
2965 
2966 /**
2967   * @brief  Handle USART Communication Timeout. It waits
2968   *         until a flag is no longer in the specified status.
2969   * @param  husart USART handle.
2970   * @param  Flag Specifies the USART flag to check.
2971   * @param  Status the actual Flag status (SET or RESET).
2972   * @param  Tickstart Tick start value
2973   * @param  Timeout timeout duration.
2974   * @retval HAL status
2975   */
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef * husart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)2976 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
2977                                                       uint32_t Tickstart, uint32_t Timeout)
2978 {
2979   /* Wait until flag is set */
2980   while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
2981   {
2982     /* Check for the Timeout */
2983     if (Timeout != HAL_MAX_DELAY)
2984     {
2985       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2986       {
2987         husart->State = HAL_USART_STATE_READY;
2988 
2989         /* Process Unlocked */
2990         __HAL_UNLOCK(husart);
2991 
2992         return HAL_TIMEOUT;
2993       }
2994     }
2995   }
2996   return HAL_OK;
2997 }
2998 
2999 /**
3000   * @brief Configure the USART peripheral.
3001   * @param husart USART handle.
3002   * @retval HAL status
3003   */
USART_SetConfig(USART_HandleTypeDef * husart)3004 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
3005 {
3006   uint32_t tmpreg;
3007   USART_ClockSourceTypeDef clocksource;
3008   HAL_StatusTypeDef ret                = HAL_OK;
3009   uint16_t brrtemp;
3010   uint32_t usartdiv                    = 0x00000000;
3011   uint32_t pclk;
3012 
3013   /* Check the parameters */
3014   assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
3015   assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
3016   assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
3017   assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
3018   assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
3019   assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
3020   assert_param(IS_USART_PARITY(husart->Init.Parity));
3021   assert_param(IS_USART_MODE(husart->Init.Mode));
3022 #if defined(USART_PRESC_PRESCALER)
3023   assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler));
3024 #endif /* USART_PRESC_PRESCALER */
3025 
3026   /*-------------------------- USART CR1 Configuration -----------------------*/
3027   /* Clear M, PCE, PS, TE and RE bits and configure
3028   *  the USART Word Length, Parity and Mode:
3029   *  set the M bits according to husart->Init.WordLength value
3030   *  set PCE and PS bits according to husart->Init.Parity value
3031   *  set TE and RE bits according to husart->Init.Mode value
3032   *  force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
3033   tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
3034   MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3035 
3036   /*---------------------------- USART CR2 Configuration ---------------------*/
3037   /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
3038    * set CPOL bit according to husart->Init.CLKPolarity value
3039    * set CPHA bit according to husart->Init.CLKPhase value
3040    * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
3041    * set STOP[13:12] bits according to husart->Init.StopBits value */
3042   tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
3043   tmpreg |= (uint32_t)husart->Init.CLKLastBit;
3044   tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
3045   tmpreg |= (uint32_t)husart->Init.StopBits;
3046   MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
3047 
3048 #if defined(USART_PRESC_PRESCALER)
3049   /*-------------------------- USART PRESC Configuration -----------------------*/
3050   /* Configure
3051    * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
3052   MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler);
3053 #endif /* USART_PRESC_PRESCALER */
3054 
3055   /*-------------------------- USART BRR Configuration -----------------------*/
3056   /* BRR is filled-up according to OVER8 bit setting which is forced to 1     */
3057   USART_GETCLOCKSOURCE(husart, clocksource);
3058 
3059   switch (clocksource)
3060   {
3061     case USART_CLOCKSOURCE_PCLK1:
3062       pclk = HAL_RCC_GetPCLK1Freq();
3063 #if defined(USART_PRESC_PRESCALER)
3064       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3065 #else
3066       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate));
3067 #endif /* USART_PRESC_PRESCALER */
3068       break;
3069     case USART_CLOCKSOURCE_PCLK2:
3070       pclk = HAL_RCC_GetPCLK2Freq();
3071 #if defined(USART_PRESC_PRESCALER)
3072       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3073 #else
3074       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate));
3075 #endif /* USART_PRESC_PRESCALER */
3076       break;
3077     case USART_CLOCKSOURCE_HSI:
3078 #if defined(USART_PRESC_PRESCALER)
3079       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3080 #else
3081       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate));
3082 #endif /* USART_PRESC_PRESCALER */
3083       break;
3084     case USART_CLOCKSOURCE_SYSCLK:
3085       pclk = HAL_RCC_GetSysClockFreq();
3086 #if defined(USART_PRESC_PRESCALER)
3087       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3088 #else
3089       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate));
3090 #endif /* USART_PRESC_PRESCALER */
3091       break;
3092     case USART_CLOCKSOURCE_LSE:
3093 #if defined(USART_PRESC_PRESCALER)
3094       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3095 #else
3096       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate));
3097 #endif /* USART_PRESC_PRESCALER */
3098       break;
3099     default:
3100       ret = HAL_ERROR;
3101       break;
3102   }
3103 
3104   /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
3105   if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
3106   {
3107     brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3108     brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3109     husart->Instance->BRR = brrtemp;
3110   }
3111   else
3112   {
3113     ret = HAL_ERROR;
3114   }
3115 
3116 #if defined(USART_CR1_FIFOEN)
3117   /* Initialize the number of data to process during RX/TX ISR execution */
3118   husart->NbTxDataToProcess = 1U;
3119   husart->NbRxDataToProcess = 1U;
3120 #endif /* USART_CR1_FIFOEN */
3121 
3122   /* Clear ISR function pointers */
3123   husart->RxISR   = NULL;
3124   husart->TxISR   = NULL;
3125 
3126   return ret;
3127 }
3128 
3129 /**
3130   * @brief Check the USART Idle State.
3131   * @param husart USART handle.
3132   * @retval HAL status
3133   */
USART_CheckIdleState(USART_HandleTypeDef * husart)3134 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
3135 {
3136   uint32_t tickstart;
3137 
3138   /* Initialize the USART ErrorCode */
3139   husart->ErrorCode = HAL_USART_ERROR_NONE;
3140 
3141   /* Init tickstart for timeout management */
3142   tickstart = HAL_GetTick();
3143 
3144   /* Check if the Transmitter is enabled */
3145   if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3146   {
3147     /* Wait until TEACK flag is set */
3148     if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3149     {
3150       /* Timeout occurred */
3151       return HAL_TIMEOUT;
3152     }
3153   }
3154   /* Check if the Receiver is enabled */
3155   if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3156   {
3157     /* Wait until REACK flag is set */
3158     if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3159     {
3160       /* Timeout occurred */
3161       return HAL_TIMEOUT;
3162     }
3163   }
3164 
3165   /* Initialize the USART state*/
3166   husart->State = HAL_USART_STATE_READY;
3167 
3168   /* Process Unlocked */
3169   __HAL_UNLOCK(husart);
3170 
3171   return HAL_OK;
3172 }
3173 
3174 /**
3175   * @brief  Simplex send an amount of data in non-blocking mode.
3176   * @note   Function called under interruption only, once
3177   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3178   * @note   The USART errors are not managed to avoid the overrun error.
3179   * @note   ISR function executed when FIFO mode is disabled and when the
3180   *         data word length is less than 9 bits long.
3181   * @param  husart USART handle.
3182   * @retval None
3183   */
USART_TxISR_8BIT(USART_HandleTypeDef * husart)3184 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
3185 {
3186   const HAL_USART_StateTypeDef state = husart->State;
3187 
3188   /* Check that a Tx process is ongoing */
3189   if ((state == HAL_USART_STATE_BUSY_TX) ||
3190       (state == HAL_USART_STATE_BUSY_TX_RX))
3191   {
3192     if (husart->TxXferCount == 0U)
3193     {
3194       /* Disable the USART Transmit data register empty interrupt */
3195       __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3196 
3197       /* Enable the USART Transmit Complete Interrupt */
3198       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3199     }
3200     else
3201     {
3202       husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3203       husart->pTxBuffPtr++;
3204       husart->TxXferCount--;
3205     }
3206   }
3207 }
3208 
3209 /**
3210   * @brief  Simplex send an amount of data in non-blocking mode.
3211   * @note   Function called under interruption only, once
3212   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3213   * @note   The USART errors are not managed to avoid the overrun error.
3214   * @note   ISR function executed when FIFO mode is disabled and when the
3215   *         data word length is 9 bits long.
3216   * @param  husart USART handle.
3217   * @retval None
3218   */
USART_TxISR_16BIT(USART_HandleTypeDef * husart)3219 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
3220 {
3221   const HAL_USART_StateTypeDef state = husart->State;
3222   const uint16_t *tmp;
3223 
3224   if ((state == HAL_USART_STATE_BUSY_TX) ||
3225       (state == HAL_USART_STATE_BUSY_TX_RX))
3226   {
3227     if (husart->TxXferCount == 0U)
3228     {
3229       /* Disable the USART Transmit data register empty interrupt */
3230       __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3231 
3232       /* Enable the USART Transmit Complete Interrupt */
3233       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3234     }
3235     else
3236     {
3237       tmp = (const uint16_t *) husart->pTxBuffPtr;
3238       husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3239       husart->pTxBuffPtr += 2U;
3240       husart->TxXferCount--;
3241     }
3242   }
3243 }
3244 
3245 #if defined(USART_CR1_FIFOEN)
3246 /**
3247   * @brief  Simplex send an amount of data in non-blocking mode.
3248   * @note   Function called under interruption only, once
3249   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3250   * @note   The USART errors are not managed to avoid the overrun error.
3251   * @note   ISR function executed when FIFO mode is enabled and when the
3252   *         data word length is less than 9 bits long.
3253   * @param  husart USART handle.
3254   * @retval None
3255   */
USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3256 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3257 {
3258   const HAL_USART_StateTypeDef state = husart->State;
3259   uint16_t  nb_tx_data;
3260 
3261   /* Check that a Tx process is ongoing */
3262   if ((state == HAL_USART_STATE_BUSY_TX) ||
3263       (state == HAL_USART_STATE_BUSY_TX_RX))
3264   {
3265     for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3266     {
3267       if (husart->TxXferCount == 0U)
3268       {
3269         /* Disable the TX FIFO threshold interrupt */
3270         __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3271 
3272         /* Enable the USART Transmit Complete Interrupt */
3273         __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3274 
3275         break; /* force exit loop */
3276       }
3277       else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3278       {
3279         husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3280         husart->pTxBuffPtr++;
3281         husart->TxXferCount--;
3282       }
3283       else
3284       {
3285         /* Nothing to do */
3286       }
3287     }
3288   }
3289 }
3290 
3291 /**
3292   * @brief  Simplex send an amount of data in non-blocking mode.
3293   * @note   Function called under interruption only, once
3294   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3295   * @note   The USART errors are not managed to avoid the overrun error.
3296   * @note   ISR function executed when FIFO mode is enabled and when the
3297   *         data word length is 9 bits long.
3298   * @param  husart USART handle.
3299   * @retval None
3300   */
USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3301 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3302 {
3303   const HAL_USART_StateTypeDef state = husart->State;
3304   const uint16_t *tmp;
3305   uint16_t  nb_tx_data;
3306 
3307   /* Check that a Tx process is ongoing */
3308   if ((state == HAL_USART_STATE_BUSY_TX) ||
3309       (state == HAL_USART_STATE_BUSY_TX_RX))
3310   {
3311     for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3312     {
3313       if (husart->TxXferCount == 0U)
3314       {
3315         /* Disable the TX FIFO threshold interrupt */
3316         __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3317 
3318         /* Enable the USART Transmit Complete Interrupt */
3319         __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3320 
3321         break; /* force exit loop */
3322       }
3323       else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3324       {
3325         tmp = (const uint16_t *) husart->pTxBuffPtr;
3326         husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3327         husart->pTxBuffPtr += 2U;
3328         husart->TxXferCount--;
3329       }
3330       else
3331       {
3332         /* Nothing to do */
3333       }
3334     }
3335   }
3336 }
3337 #endif /* USART_CR1_FIFOEN */
3338 
3339 /**
3340   * @brief  Wraps up transmission in non-blocking mode.
3341   * @param  husart Pointer to a USART_HandleTypeDef structure that contains
3342   *                the configuration information for the specified USART module.
3343   * @retval None
3344   */
USART_EndTransmit_IT(USART_HandleTypeDef * husart)3345 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3346 {
3347   /* Disable the USART Transmit Complete Interrupt */
3348   __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3349 
3350   /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3351   __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3352 
3353   /* Clear TxISR function pointer */
3354   husart->TxISR = NULL;
3355 
3356   if (husart->State == HAL_USART_STATE_BUSY_TX)
3357   {
3358     /* Clear overrun flag and discard the received data */
3359     __HAL_USART_CLEAR_OREFLAG(husart);
3360     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3361 
3362     /* Tx process is completed, restore husart->State to Ready */
3363     husart->State = HAL_USART_STATE_READY;
3364 
3365 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3366     /* Call registered Tx Complete Callback */
3367     husart->TxCpltCallback(husart);
3368 #else
3369     /* Call legacy weak Tx Complete Callback */
3370     HAL_USART_TxCpltCallback(husart);
3371 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3372   }
3373   else if (husart->RxXferCount == 0U)
3374   {
3375     /* TxRx process is completed, restore husart->State to Ready */
3376     husart->State = HAL_USART_STATE_READY;
3377 
3378 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3379     /* Call registered Tx Rx Complete Callback */
3380     husart->TxRxCpltCallback(husart);
3381 #else
3382     /* Call legacy weak Tx Rx Complete Callback */
3383     HAL_USART_TxRxCpltCallback(husart);
3384 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3385   }
3386   else
3387   {
3388     /* Nothing to do */
3389   }
3390 }
3391 
3392 
3393 /**
3394   * @brief  Simplex receive an amount of data in non-blocking mode.
3395   * @note   Function called under interruption only, once
3396   *         interruptions have been enabled by HAL_USART_Receive_IT().
3397   * @note   ISR function executed when FIFO mode is disabled and when the
3398   *         data word length is less than 9 bits long.
3399   * @param  husart USART handle
3400   * @retval None
3401   */
USART_RxISR_8BIT(USART_HandleTypeDef * husart)3402 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3403 {
3404   const HAL_USART_StateTypeDef state = husart->State;
3405   uint16_t txdatacount;
3406   uint16_t uhMask = husart->Mask;
3407 #if defined(USART_CR1_FIFOEN)
3408   uint32_t txftie;
3409 #endif /* USART_CR1_FIFOEN */
3410 
3411   if ((state == HAL_USART_STATE_BUSY_RX) ||
3412       (state == HAL_USART_STATE_BUSY_TX_RX))
3413   {
3414     *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3415     husart->pRxBuffPtr++;
3416     husart->RxXferCount--;
3417 
3418     if (husart->RxXferCount == 0U)
3419     {
3420       /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3421 #if defined(USART_CR1_FIFOEN)
3422       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3423 #else
3424       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3425 #endif /* USART_CR1_FIFOEN */
3426 
3427       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3428       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3429 
3430       /* Clear RxISR function pointer */
3431       husart->RxISR = NULL;
3432 
3433 #if defined(USART_CR1_FIFOEN)
3434       /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3435       txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3436 #else
3437       /* txdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
3438 #endif /* USART_CR1_FIFOEN */
3439       txdatacount = husart->TxXferCount;
3440 
3441       if (state == HAL_USART_STATE_BUSY_RX)
3442       {
3443 #if defined(USART_CR2_SLVEN)
3444         /* Clear SPI slave underrun flag and discard transmit data */
3445         if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3446         {
3447           __HAL_USART_CLEAR_UDRFLAG(husart);
3448           __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3449         }
3450 #endif /* USART_CR2_SLVEN */
3451 
3452         /* Rx process is completed, restore husart->State to Ready */
3453         husart->State = HAL_USART_STATE_READY;
3454 
3455 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3456         /* Call registered Rx Complete Callback */
3457         husart->RxCpltCallback(husart);
3458 #else
3459         /* Call legacy weak Rx Complete Callback */
3460         HAL_USART_RxCpltCallback(husart);
3461 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3462       }
3463 #if defined(USART_CR1_FIFOEN)
3464       else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3465                (txftie != USART_CR3_TXFTIE) &&
3466                (txdatacount == 0U))
3467 #else
3468       else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3469                (txdatacount == 0U))
3470 #endif /* USART_CR1_FIFOEN */
3471       {
3472         /* TxRx process is completed, restore husart->State to Ready */
3473         husart->State = HAL_USART_STATE_READY;
3474 
3475 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3476         /* Call registered Tx Rx Complete Callback */
3477         husart->TxRxCpltCallback(husart);
3478 #else
3479         /* Call legacy weak Tx Rx Complete Callback */
3480         HAL_USART_TxRxCpltCallback(husart);
3481 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3482       }
3483       else
3484       {
3485         /* Nothing to do */
3486       }
3487     }
3488 #if defined(USART_CR2_SLVEN)
3489     else if ((state == HAL_USART_STATE_BUSY_RX) &&
3490              (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3491 #else
3492     else if (state == HAL_USART_STATE_BUSY_RX)
3493 #endif /* USART_CR2_SLVEN */
3494     {
3495       /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3496       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3497     }
3498     else
3499     {
3500       /* Nothing to do */
3501     }
3502   }
3503 }
3504 
3505 /**
3506   * @brief  Simplex receive an amount of data in non-blocking mode.
3507   * @note   Function called under interruption only, once
3508   *         interruptions have been enabled by HAL_USART_Receive_IT().
3509   * @note   ISR function executed when FIFO mode is disabled and when the
3510   *         data word length is 9 bits long.
3511   * @param  husart USART handle
3512   * @retval None
3513   */
USART_RxISR_16BIT(USART_HandleTypeDef * husart)3514 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
3515 {
3516   const HAL_USART_StateTypeDef state = husart->State;
3517   uint16_t txdatacount;
3518   uint16_t *tmp;
3519   uint16_t uhMask = husart->Mask;
3520 #if defined(USART_CR1_FIFOEN)
3521   uint32_t txftie;
3522 #endif /* USART_CR1_FIFOEN */
3523 
3524   if ((state == HAL_USART_STATE_BUSY_RX) ||
3525       (state == HAL_USART_STATE_BUSY_TX_RX))
3526   {
3527     tmp = (uint16_t *) husart->pRxBuffPtr;
3528     *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3529     husart->pRxBuffPtr += 2U;
3530     husart->RxXferCount--;
3531 
3532     if (husart->RxXferCount == 0U)
3533     {
3534       /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3535 #if defined(USART_CR1_FIFOEN)
3536       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3537 #else
3538       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3539 #endif /* USART_CR1_FIFOEN */
3540 
3541       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3542       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3543 
3544       /* Clear RxISR function pointer */
3545       husart->RxISR = NULL;
3546 
3547 #if defined(USART_CR1_FIFOEN)
3548       /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3549       txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3550 #else
3551       /* txdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
3552 #endif /* USART_CR1_FIFOEN */
3553       txdatacount = husart->TxXferCount;
3554 
3555       if (state == HAL_USART_STATE_BUSY_RX)
3556       {
3557 #if defined(USART_CR2_SLVEN)
3558         /* Clear SPI slave underrun flag and discard transmit data */
3559         if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3560         {
3561           __HAL_USART_CLEAR_UDRFLAG(husart);
3562           __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3563         }
3564 #endif /* USART_CR2_SLVEN */
3565 
3566         /* Rx process is completed, restore husart->State to Ready */
3567         husart->State = HAL_USART_STATE_READY;
3568 
3569 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3570         /* Call registered Rx Complete Callback */
3571         husart->RxCpltCallback(husart);
3572 #else
3573         /* Call legacy weak Rx Complete Callback */
3574         HAL_USART_RxCpltCallback(husart);
3575 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3576       }
3577 #if defined(USART_CR1_FIFOEN)
3578       else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3579                (txftie != USART_CR3_TXFTIE) &&
3580                (txdatacount == 0U))
3581 #else
3582       else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3583                (txdatacount == 0U))
3584 #endif /* USART_CR1_FIFOEN */
3585       {
3586         /* TxRx process is completed, restore husart->State to Ready */
3587         husart->State = HAL_USART_STATE_READY;
3588 
3589 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3590         /* Call registered Tx Rx Complete Callback */
3591         husart->TxRxCpltCallback(husart);
3592 #else
3593         /* Call legacy weak Tx Rx Complete Callback */
3594         HAL_USART_TxRxCpltCallback(husart);
3595 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3596       }
3597       else
3598       {
3599         /* Nothing to do */
3600       }
3601     }
3602 #if defined(USART_CR2_SLVEN)
3603     else if ((state == HAL_USART_STATE_BUSY_RX) &&
3604              (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3605 #else
3606     else if (state == HAL_USART_STATE_BUSY_RX)
3607 #endif /* USART_CR2_SLVEN */
3608     {
3609       /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3610       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3611     }
3612     else
3613     {
3614       /* Nothing to do */
3615     }
3616   }
3617 }
3618 
3619 #if defined(USART_CR1_FIFOEN)
3620 /**
3621   * @brief  Simplex receive an amount of data in non-blocking mode.
3622   * @note   Function called under interruption only, once
3623   *         interruptions have been enabled by HAL_USART_Receive_IT().
3624   * @note   ISR function executed when FIFO mode is enabled and when the
3625   *         data word length is less than 9 bits long.
3626   * @param  husart USART handle
3627   * @retval None
3628   */
USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3629 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3630 {
3631   HAL_USART_StateTypeDef state = husart->State;
3632   uint16_t txdatacount;
3633   uint16_t rxdatacount;
3634   uint16_t uhMask = husart->Mask;
3635   uint16_t nb_rx_data;
3636   uint32_t txftie;
3637 
3638   /* Check that a Rx process is ongoing */
3639   if ((state == HAL_USART_STATE_BUSY_RX) ||
3640       (state == HAL_USART_STATE_BUSY_TX_RX))
3641   {
3642     for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3643     {
3644       if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3645       {
3646         *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
3647         husart->pRxBuffPtr++;
3648         husart->RxXferCount--;
3649 
3650         if (husart->RxXferCount == 0U)
3651         {
3652           /* Disable the USART Parity Error Interrupt */
3653           CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3654 
3655           /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3656              and RX FIFO Threshold interrupt */
3657           CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3658 
3659           /* Clear RxISR function pointer */
3660           husart->RxISR = NULL;
3661 
3662           /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3663           txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3664           txdatacount = husart->TxXferCount;
3665 
3666           if (state == HAL_USART_STATE_BUSY_RX)
3667           {
3668 #if defined(USART_CR2_SLVEN)
3669             /* Clear SPI slave underrun flag and discard transmit data */
3670             if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3671             {
3672               __HAL_USART_CLEAR_UDRFLAG(husart);
3673               __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3674             }
3675 #endif /* USART_CR2_SLVEN */
3676 
3677             /* Rx process is completed, restore husart->State to Ready */
3678             husart->State = HAL_USART_STATE_READY;
3679             state = HAL_USART_STATE_READY;
3680 
3681 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3682             /* Call registered Rx Complete Callback */
3683             husart->RxCpltCallback(husart);
3684 #else
3685             /* Call legacy weak Rx Complete Callback */
3686             HAL_USART_RxCpltCallback(husart);
3687 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3688           }
3689           else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3690                    (txftie != USART_CR3_TXFTIE) &&
3691                    (txdatacount == 0U))
3692           {
3693             /* TxRx process is completed, restore husart->State to Ready */
3694             husart->State = HAL_USART_STATE_READY;
3695             state = HAL_USART_STATE_READY;
3696 
3697 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3698             /* Call registered Tx Rx Complete Callback */
3699             husart->TxRxCpltCallback(husart);
3700 #else
3701             /* Call legacy weak Tx Rx Complete Callback */
3702             HAL_USART_TxRxCpltCallback(husart);
3703 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3704           }
3705           else
3706           {
3707             /* Nothing to do */
3708           }
3709         }
3710 #if defined(USART_CR2_SLVEN)
3711         else if ((state == HAL_USART_STATE_BUSY_RX) &&
3712                  (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3713 #else
3714         else if (state == HAL_USART_STATE_BUSY_RX)
3715 #endif /* USART_CR2_SLVEN */
3716         {
3717           /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3718           husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3719         }
3720         else
3721         {
3722           /* Nothing to do */
3723         }
3724       }
3725     }
3726 
3727     /* When remaining number of bytes to receive is less than the RX FIFO
3728     threshold, next incoming frames are processed as if FIFO mode was
3729     disabled (i.e. one interrupt per received frame).
3730     */
3731     rxdatacount = husart->RxXferCount;
3732     if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3733     {
3734       /* Disable the USART RXFT interrupt*/
3735       CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3736 
3737       /* Update the RxISR function pointer */
3738       husart->RxISR = USART_RxISR_8BIT;
3739 
3740       /* Enable the USART Data Register Not Empty interrupt */
3741       SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3742 
3743 #if defined(USART_CR2_SLVEN)
3744       if ((husart->TxXferCount == 0U) &&
3745           (state == HAL_USART_STATE_BUSY_TX_RX) &&
3746           (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3747 #else
3748       if ((husart->TxXferCount == 0U) &&
3749           (state == HAL_USART_STATE_BUSY_TX_RX))
3750 #endif /* USART_CR2_SLVEN */
3751       {
3752         /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3753         husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3754       }
3755     }
3756   }
3757   else
3758   {
3759     /* Clear RXNE interrupt flag */
3760     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3761   }
3762 }
3763 
3764 /**
3765   * @brief  Simplex receive an amount of data in non-blocking mode.
3766   * @note   Function called under interruption only, once
3767   *         interruptions have been enabled by HAL_USART_Receive_IT().
3768   * @note   ISR function executed when FIFO mode is enabled and when the
3769   *         data word length is 9 bits long.
3770   * @param  husart USART handle
3771   * @retval None
3772   */
USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3773 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3774 {
3775   HAL_USART_StateTypeDef state = husart->State;
3776   uint16_t txdatacount;
3777   uint16_t rxdatacount;
3778   uint16_t *tmp;
3779   uint16_t uhMask = husart->Mask;
3780   uint16_t nb_rx_data;
3781   uint32_t txftie;
3782 
3783   /* Check that a Tx process is ongoing */
3784   if ((state == HAL_USART_STATE_BUSY_RX) ||
3785       (state == HAL_USART_STATE_BUSY_TX_RX))
3786   {
3787     for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3788     {
3789       if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3790       {
3791         tmp = (uint16_t *) husart->pRxBuffPtr;
3792         *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3793         husart->pRxBuffPtr += 2U;
3794         husart->RxXferCount--;
3795 
3796         if (husart->RxXferCount == 0U)
3797         {
3798           /* Disable the USART Parity Error Interrupt */
3799           CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3800 
3801           /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3802              and RX FIFO Threshold interrupt */
3803           CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3804 
3805           /* Clear RxISR function pointer */
3806           husart->RxISR = NULL;
3807 
3808           /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3809           txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3810           txdatacount = husart->TxXferCount;
3811 
3812           if (state == HAL_USART_STATE_BUSY_RX)
3813           {
3814 #if defined(USART_CR2_SLVEN)
3815             /* Clear SPI slave underrun flag and discard transmit data */
3816             if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3817             {
3818               __HAL_USART_CLEAR_UDRFLAG(husart);
3819               __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3820             }
3821 #endif /* USART_CR2_SLVEN */
3822 
3823             /* Rx process is completed, restore husart->State to Ready */
3824             husart->State = HAL_USART_STATE_READY;
3825             state = HAL_USART_STATE_READY;
3826 
3827 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3828             /* Call registered Rx Complete Callback */
3829             husart->RxCpltCallback(husart);
3830 #else
3831             /* Call legacy weak Rx Complete Callback */
3832             HAL_USART_RxCpltCallback(husart);
3833 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3834           }
3835           else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3836                    (txftie != USART_CR3_TXFTIE) &&
3837                    (txdatacount == 0U))
3838           {
3839             /* TxRx process is completed, restore husart->State to Ready */
3840             husart->State = HAL_USART_STATE_READY;
3841             state = HAL_USART_STATE_READY;
3842 
3843 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3844             /* Call registered Tx Rx Complete Callback */
3845             husart->TxRxCpltCallback(husart);
3846 #else
3847             /* Call legacy weak Tx Rx Complete Callback */
3848             HAL_USART_TxRxCpltCallback(husart);
3849 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3850           }
3851           else
3852           {
3853             /* Nothing to do */
3854           }
3855         }
3856 #if defined(USART_CR2_SLVEN)
3857         else if ((state == HAL_USART_STATE_BUSY_RX) &&
3858                  (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3859 #else
3860         else if (state == HAL_USART_STATE_BUSY_RX)
3861 #endif /* USART_CR2_SLVEN */
3862         {
3863           /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3864           husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3865         }
3866         else
3867         {
3868           /* Nothing to do */
3869         }
3870       }
3871     }
3872 
3873     /* When remaining number of bytes to receive is less than the RX FIFO
3874     threshold, next incoming frames are processed as if FIFO mode was
3875     disabled (i.e. one interrupt per received frame).
3876     */
3877     rxdatacount = husart->RxXferCount;
3878     if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3879     {
3880       /* Disable the USART RXFT interrupt*/
3881       CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3882 
3883       /* Update the RxISR function pointer */
3884       husart->RxISR = USART_RxISR_16BIT;
3885 
3886       /* Enable the USART Data Register Not Empty interrupt */
3887       SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3888 
3889 #if defined(USART_CR2_SLVEN)
3890       if ((husart->TxXferCount == 0U) &&
3891           (state == HAL_USART_STATE_BUSY_TX_RX) &&
3892           (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3893 #else
3894       if ((husart->TxXferCount == 0U) &&
3895           (state == HAL_USART_STATE_BUSY_TX_RX))
3896 #endif /* USART_CR2_SLVEN */
3897       {
3898         /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3899         husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3900       }
3901     }
3902   }
3903   else
3904   {
3905     /* Clear RXNE interrupt flag */
3906     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3907   }
3908 }
3909 #endif /* USART_CR1_FIFOEN */
3910 
3911 /**
3912   * @}
3913   */
3914 
3915 #endif /* HAL_USART_MODULE_ENABLED */
3916 /**
3917   * @}
3918   */
3919 
3920 /**
3921   * @}
3922   */
3923 
3924