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