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