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