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