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