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