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