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