1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_usart.c
4   * @author  MCD Application Team
5   * @brief   USART HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
8   *          Peripheral (USART).
9   *           + Initialization and de-initialization functions
10   *           + IO operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State and Error functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2019 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26  ===============================================================================
27                         ##### How to use this driver #####
28  ===============================================================================
29     [..]
30       The USART HAL driver can be used as follows:
31 
32       (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
33       (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
34           (++) Enable the USARTx interface clock.
35           (++) USART pins configuration:
36             (+++) Enable the clock for the USART GPIOs.
37             (+++) Configure these USART pins as alternate function pull-up.
38           (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
39                 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
40             (+++) Configure the USARTx interrupt priority.
41             (+++) Enable the NVIC USART IRQ handle.
42             (++) USART interrupts handling:
43               -@@-   The specific USART interrupts (Transmission complete interrupt,
44                   RXNE interrupt and Error Interrupts) will be managed using the macros
45                   __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
46           (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
47                HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
48             (+++) Declare a DMA handle structure for the Tx/Rx channel.
49             (+++) Enable the DMAx interface clock.
50             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
51             (+++) Configure the DMA Tx/Rx channel.
52             (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
53             (+++) Configure the priority and enable the NVIC for the transfer
54                   complete interrupt on the DMA Tx/Rx channel.
55 
56       (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
57           (Receiver/Transmitter) in the husart handle Init structure.
58 
59       (#) Initialize the USART registers by calling the HAL_USART_Init() API:
60           (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
61                by calling the customized HAL_USART_MspInit(&husart) API.
62 
63     [..]
64      (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
65         HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
66         HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
67 
68     ##### Callback registration #####
69     ==================================
70 
71     [..]
72     The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
73     allows the user to configure dynamically the driver callbacks.
74 
75     [..]
76     Use Function HAL_USART_RegisterCallback() to register a user callback.
77     Function HAL_USART_RegisterCallback() allows to register following callbacks:
78     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
79     (+) TxCpltCallback            : Tx Complete Callback.
80     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
81     (+) RxCpltCallback            : Rx Complete Callback.
82     (+) TxRxCpltCallback          : Tx Rx Complete Callback.
83     (+) ErrorCallback             : Error Callback.
84     (+) AbortCpltCallback         : Abort Complete Callback.
85     (+) RxFifoFullCallback        : Rx Fifo Full Callback.
86     (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
87     (+) MspInitCallback           : USART MspInit.
88     (+) MspDeInitCallback         : USART MspDeInit.
89     This function takes as parameters the HAL peripheral handle, the Callback ID
90     and a pointer to the user callback function.
91 
92     [..]
93     Use function HAL_USART_UnRegisterCallback() to reset a callback to the default
94     weak (surcharged) function.
95     HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
96     and the Callback ID.
97     This function allows to reset following callbacks:
98     (+) TxHalfCpltCallback        : Tx Half Complete Callback.
99     (+) TxCpltCallback            : Tx Complete Callback.
100     (+) RxHalfCpltCallback        : Rx Half Complete Callback.
101     (+) RxCpltCallback            : Rx Complete Callback.
102     (+) TxRxCpltCallback          : Tx Rx Complete Callback.
103     (+) ErrorCallback             : Error Callback.
104     (+) AbortCpltCallback         : Abort Complete Callback.
105     (+) RxFifoFullCallback        : Rx Fifo Full Callback.
106     (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
107     (+) MspInitCallback           : USART MspInit.
108     (+) MspDeInitCallback         : USART MspDeInit.
109 
110     [..]
111     By default, after the HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
112     all callbacks are set to the corresponding weak (surcharged) functions:
113     examples HAL_USART_TxCpltCallback(), HAL_USART_RxHalfCpltCallback().
114     Exception done for MspInit and MspDeInit functions that are respectively
115     reset to the legacy weak (surcharged) functions in the HAL_USART_Init()
116     and HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
117     If not, MspInit or MspDeInit are not null, the HAL_USART_Init() and HAL_USART_DeInit()
118     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
119 
120     [..]
121     Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
122     Exception done MspInit/MspDeInit that can be registered/unregistered
123     in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
124     MspInit/DeInit callbacks can be used during the Init/DeInit.
125     In that case first register the MspInit/MspDeInit user callbacks
126     using HAL_USART_RegisterCallback() before calling HAL_USART_DeInit()
127     or HAL_USART_Init() function.
128 
129     [..]
130     When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
131     not defined, the callback registration feature is not available
132     and weak (surcharged) callbacks are used.
133 
134 
135   @endverbatim
136   ******************************************************************************
137   */
138 
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32l5xx_hal.h"
141 
142 /** @addtogroup STM32L5xx_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 (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
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 (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
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   uint32_t pclk;
2885 
2886   /* Check the parameters */
2887   assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
2888   assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
2889   assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
2890   assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
2891   assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
2892   assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
2893   assert_param(IS_USART_PARITY(husart->Init.Parity));
2894   assert_param(IS_USART_MODE(husart->Init.Mode));
2895   assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler));
2896 
2897   /*-------------------------- USART CR1 Configuration -----------------------*/
2898   /* Clear M, PCE, PS, TE and RE bits and configure
2899   *  the USART Word Length, Parity and Mode:
2900   *  set the M bits according to husart->Init.WordLength value
2901   *  set PCE and PS bits according to husart->Init.Parity value
2902   *  set TE and RE bits according to husart->Init.Mode value
2903   *  force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
2904   tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
2905   MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2906 
2907   /*---------------------------- USART CR2 Configuration ---------------------*/
2908   /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
2909    * set CPOL bit according to husart->Init.CLKPolarity value
2910    * set CPHA bit according to husart->Init.CLKPhase value
2911    * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
2912    * set STOP[13:12] bits according to husart->Init.StopBits value */
2913   tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
2914   tmpreg |= (uint32_t)husart->Init.CLKLastBit;
2915   tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
2916   tmpreg |= (uint32_t)husart->Init.StopBits;
2917   MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
2918 
2919   /*-------------------------- USART PRESC Configuration -----------------------*/
2920   /* Configure
2921    * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
2922   MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler);
2923 
2924   /*-------------------------- USART BRR Configuration -----------------------*/
2925   /* BRR is filled-up according to OVER8 bit setting which is forced to 1     */
2926   USART_GETCLOCKSOURCE(husart, clocksource);
2927 
2928   switch (clocksource)
2929   {
2930     case USART_CLOCKSOURCE_PCLK1:
2931       pclk = HAL_RCC_GetPCLK1Freq();
2932       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2933       break;
2934     case USART_CLOCKSOURCE_PCLK2:
2935       pclk = HAL_RCC_GetPCLK2Freq();
2936       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2937       break;
2938     case USART_CLOCKSOURCE_HSI:
2939       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2940       break;
2941     case USART_CLOCKSOURCE_SYSCLK:
2942       pclk = HAL_RCC_GetSysClockFreq();
2943       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2944       break;
2945     case USART_CLOCKSOURCE_LSE:
2946       usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
2947       break;
2948     default:
2949       ret = HAL_ERROR;
2950       break;
2951   }
2952 
2953   /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
2954   if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
2955   {
2956     brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
2957     brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
2958     husart->Instance->BRR = brrtemp;
2959   }
2960   else
2961   {
2962     ret = HAL_ERROR;
2963   }
2964 
2965   /* Initialize the number of data to process during RX/TX ISR execution */
2966   husart->NbTxDataToProcess = 1U;
2967   husart->NbRxDataToProcess = 1U;
2968 
2969   /* Clear ISR function pointers */
2970   husart->RxISR   = NULL;
2971   husart->TxISR   = NULL;
2972 
2973   return ret;
2974 }
2975 
2976 /**
2977   * @brief Check the USART Idle State.
2978   * @param husart USART handle.
2979   * @retval HAL status
2980   */
USART_CheckIdleState(USART_HandleTypeDef * husart)2981 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
2982 {
2983   uint32_t tickstart;
2984 
2985   /* Initialize the USART ErrorCode */
2986   husart->ErrorCode = HAL_USART_ERROR_NONE;
2987 
2988   /* Init tickstart for timeout management */
2989   tickstart = HAL_GetTick();
2990 
2991   /* Check if the Transmitter is enabled */
2992   if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
2993   {
2994     /* Wait until TEACK flag is set */
2995     if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
2996     {
2997       /* Timeout occurred */
2998       return HAL_TIMEOUT;
2999     }
3000   }
3001   /* Check if the Receiver is enabled */
3002   if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3003   {
3004     /* Wait until REACK flag is set */
3005     if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3006     {
3007       /* Timeout occurred */
3008       return HAL_TIMEOUT;
3009     }
3010   }
3011 
3012   /* Initialize the USART state*/
3013   husart->State = HAL_USART_STATE_READY;
3014 
3015   /* Process Unlocked */
3016   __HAL_UNLOCK(husart);
3017 
3018   return HAL_OK;
3019 }
3020 
3021 /**
3022   * @brief  Simplex send an amount of data in non-blocking mode.
3023   * @note   Function called under interruption only, once
3024   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3025   * @note   The USART errors are not managed to avoid the overrun error.
3026   * @note   ISR function executed when FIFO mode is disabled and when the
3027   *         data word length is less than 9 bits long.
3028   * @param  husart USART handle.
3029   * @retval None
3030   */
USART_TxISR_8BIT(USART_HandleTypeDef * husart)3031 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
3032 {
3033   const HAL_USART_StateTypeDef state = husart->State;
3034 
3035   /* Check that a Tx process is ongoing */
3036   if ((state == HAL_USART_STATE_BUSY_TX) ||
3037       (state == HAL_USART_STATE_BUSY_TX_RX))
3038   {
3039     if (husart->TxXferCount == 0U)
3040     {
3041       /* Disable the USART Transmit data register empty interrupt */
3042       __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3043 
3044       /* Enable the USART Transmit Complete Interrupt */
3045       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3046     }
3047     else
3048     {
3049       husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3050       husart->pTxBuffPtr++;
3051       husart->TxXferCount--;
3052     }
3053   }
3054 }
3055 
3056 /**
3057   * @brief  Simplex send an amount of data in non-blocking mode.
3058   * @note   Function called under interruption only, once
3059   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3060   * @note   The USART errors are not managed to avoid the overrun error.
3061   * @note   ISR function executed when FIFO mode is disabled and when the
3062   *         data word length is 9 bits long.
3063   * @param  husart USART handle.
3064   * @retval None
3065   */
USART_TxISR_16BIT(USART_HandleTypeDef * husart)3066 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
3067 {
3068   const HAL_USART_StateTypeDef state = husart->State;
3069   const uint16_t *tmp;
3070 
3071   if ((state == HAL_USART_STATE_BUSY_TX) ||
3072       (state == HAL_USART_STATE_BUSY_TX_RX))
3073   {
3074     if (husart->TxXferCount == 0U)
3075     {
3076       /* Disable the USART Transmit data register empty interrupt */
3077       __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3078 
3079       /* Enable the USART Transmit Complete Interrupt */
3080       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3081     }
3082     else
3083     {
3084       tmp = (const uint16_t *) husart->pTxBuffPtr;
3085       husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3086       husart->pTxBuffPtr += 2U;
3087       husart->TxXferCount--;
3088     }
3089   }
3090 }
3091 
3092 /**
3093   * @brief  Simplex send an amount of data in non-blocking mode.
3094   * @note   Function called under interruption only, once
3095   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3096   * @note   The USART errors are not managed to avoid the overrun error.
3097   * @note   ISR function executed when FIFO mode is enabled and when the
3098   *         data word length is less than 9 bits long.
3099   * @param  husart USART handle.
3100   * @retval None
3101   */
USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3102 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3103 {
3104   const HAL_USART_StateTypeDef state = husart->State;
3105   uint16_t  nb_tx_data;
3106 
3107   /* Check that a Tx process is ongoing */
3108   if ((state == HAL_USART_STATE_BUSY_TX) ||
3109       (state == HAL_USART_STATE_BUSY_TX_RX))
3110   {
3111     for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3112     {
3113       if (husart->TxXferCount == 0U)
3114       {
3115         /* Disable the TX FIFO threshold interrupt */
3116         __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3117 
3118         /* Enable the USART Transmit Complete Interrupt */
3119         __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3120 
3121         break; /* force exit loop */
3122       }
3123       else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3124       {
3125         husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3126         husart->pTxBuffPtr++;
3127         husart->TxXferCount--;
3128       }
3129       else
3130       {
3131         /* Nothing to do */
3132       }
3133     }
3134   }
3135 }
3136 
3137 /**
3138   * @brief  Simplex send an amount of data in non-blocking mode.
3139   * @note   Function called under interruption only, once
3140   *         interruptions have been enabled by HAL_USART_Transmit_IT().
3141   * @note   The USART errors are not managed to avoid the overrun error.
3142   * @note   ISR function executed when FIFO mode is enabled and when the
3143   *         data word length is 9 bits long.
3144   * @param  husart USART handle.
3145   * @retval None
3146   */
USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3147 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3148 {
3149   const HAL_USART_StateTypeDef state = husart->State;
3150   const uint16_t *tmp;
3151   uint16_t  nb_tx_data;
3152 
3153   /* Check that a Tx process is ongoing */
3154   if ((state == HAL_USART_STATE_BUSY_TX) ||
3155       (state == HAL_USART_STATE_BUSY_TX_RX))
3156   {
3157     for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3158     {
3159       if (husart->TxXferCount == 0U)
3160       {
3161         /* Disable the TX FIFO threshold interrupt */
3162         __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3163 
3164         /* Enable the USART Transmit Complete Interrupt */
3165         __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3166 
3167         break; /* force exit loop */
3168       }
3169       else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3170       {
3171         tmp = (const uint16_t *) husart->pTxBuffPtr;
3172         husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3173         husart->pTxBuffPtr += 2U;
3174         husart->TxXferCount--;
3175       }
3176       else
3177       {
3178         /* Nothing to do */
3179       }
3180     }
3181   }
3182 }
3183 
3184 /**
3185   * @brief  Wraps up transmission in non-blocking mode.
3186   * @param  husart Pointer to a USART_HandleTypeDef structure that contains
3187   *                the configuration information for the specified USART module.
3188   * @retval None
3189   */
USART_EndTransmit_IT(USART_HandleTypeDef * husart)3190 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3191 {
3192   /* Disable the USART Transmit Complete Interrupt */
3193   __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3194 
3195   /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3196   __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3197 
3198   /* Clear TxISR function pointer */
3199   husart->TxISR = NULL;
3200 
3201   if (husart->State == HAL_USART_STATE_BUSY_TX)
3202   {
3203     /* Clear overrun flag and discard the received data */
3204     __HAL_USART_CLEAR_OREFLAG(husart);
3205     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3206 
3207     /* Tx process is completed, restore husart->State to Ready */
3208     husart->State = HAL_USART_STATE_READY;
3209 
3210 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3211     /* Call registered Tx Complete Callback */
3212     husart->TxCpltCallback(husart);
3213 #else
3214     /* Call legacy weak Tx Complete Callback */
3215     HAL_USART_TxCpltCallback(husart);
3216 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3217   }
3218   else if (husart->RxXferCount == 0U)
3219   {
3220     /* TxRx process is completed, restore husart->State to Ready */
3221     husart->State = HAL_USART_STATE_READY;
3222 
3223 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3224     /* Call registered Tx Rx Complete Callback */
3225     husart->TxRxCpltCallback(husart);
3226 #else
3227     /* Call legacy weak Tx Rx Complete Callback */
3228     HAL_USART_TxRxCpltCallback(husart);
3229 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3230   }
3231   else
3232   {
3233     /* Nothing to do */
3234   }
3235 }
3236 
3237 
3238 /**
3239   * @brief  Simplex receive an amount of data in non-blocking mode.
3240   * @note   Function called under interruption only, once
3241   *         interruptions have been enabled by HAL_USART_Receive_IT().
3242   * @note   ISR function executed when FIFO mode is disabled and when the
3243   *         data word length is less than 9 bits long.
3244   * @param  husart USART handle
3245   * @retval None
3246   */
USART_RxISR_8BIT(USART_HandleTypeDef * husart)3247 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3248 {
3249   const HAL_USART_StateTypeDef state = husart->State;
3250   uint16_t txdatacount;
3251   uint16_t uhMask = husart->Mask;
3252   uint32_t txftie;
3253 
3254   if ((state == HAL_USART_STATE_BUSY_RX) ||
3255       (state == HAL_USART_STATE_BUSY_TX_RX))
3256   {
3257     *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3258     husart->pRxBuffPtr++;
3259     husart->RxXferCount--;
3260 
3261     if (husart->RxXferCount == 0U)
3262     {
3263       /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3264       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3265 
3266       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3267       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3268 
3269       /* Clear RxISR function pointer */
3270       husart->RxISR = NULL;
3271 
3272       /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3273       txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3274       txdatacount = husart->TxXferCount;
3275 
3276       if (state == HAL_USART_STATE_BUSY_RX)
3277       {
3278         /* Clear SPI slave underrun flag and discard transmit data */
3279         if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3280         {
3281           __HAL_USART_CLEAR_UDRFLAG(husart);
3282           __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3283         }
3284 
3285         /* Rx process is completed, restore husart->State to Ready */
3286         husart->State = HAL_USART_STATE_READY;
3287 
3288 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3289         /* Call registered Rx Complete Callback */
3290         husart->RxCpltCallback(husart);
3291 #else
3292         /* Call legacy weak Rx Complete Callback */
3293         HAL_USART_RxCpltCallback(husart);
3294 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3295       }
3296       else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3297                (txftie != USART_CR3_TXFTIE) &&
3298                (txdatacount == 0U))
3299       {
3300         /* TxRx process is completed, restore husart->State to Ready */
3301         husart->State = HAL_USART_STATE_READY;
3302 
3303 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3304         /* Call registered Tx Rx Complete Callback */
3305         husart->TxRxCpltCallback(husart);
3306 #else
3307         /* Call legacy weak Tx Rx Complete Callback */
3308         HAL_USART_TxRxCpltCallback(husart);
3309 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3310       }
3311       else
3312       {
3313         /* Nothing to do */
3314       }
3315     }
3316     else if ((state == HAL_USART_STATE_BUSY_RX) &&
3317              (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3318     {
3319       /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3320       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3321     }
3322     else
3323     {
3324       /* Nothing to do */
3325     }
3326   }
3327 }
3328 
3329 /**
3330   * @brief  Simplex receive an amount of data in non-blocking mode.
3331   * @note   Function called under interruption only, once
3332   *         interruptions have been enabled by HAL_USART_Receive_IT().
3333   * @note   ISR function executed when FIFO mode is disabled and when the
3334   *         data word length is 9 bits long.
3335   * @param  husart USART handle
3336   * @retval None
3337   */
USART_RxISR_16BIT(USART_HandleTypeDef * husart)3338 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
3339 {
3340   const HAL_USART_StateTypeDef state = husart->State;
3341   uint16_t txdatacount;
3342   uint16_t *tmp;
3343   uint16_t uhMask = husart->Mask;
3344   uint32_t txftie;
3345 
3346   if ((state == HAL_USART_STATE_BUSY_RX) ||
3347       (state == HAL_USART_STATE_BUSY_TX_RX))
3348   {
3349     tmp = (uint16_t *) husart->pRxBuffPtr;
3350     *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3351     husart->pRxBuffPtr += 2U;
3352     husart->RxXferCount--;
3353 
3354     if (husart->RxXferCount == 0U)
3355     {
3356       /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3357       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3358 
3359       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3360       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3361 
3362       /* Clear RxISR function pointer */
3363       husart->RxISR = NULL;
3364 
3365       /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3366       txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3367       txdatacount = husart->TxXferCount;
3368 
3369       if (state == HAL_USART_STATE_BUSY_RX)
3370       {
3371         /* Clear SPI slave underrun flag and discard transmit data */
3372         if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3373         {
3374           __HAL_USART_CLEAR_UDRFLAG(husart);
3375           __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3376         }
3377 
3378         /* Rx process is completed, restore husart->State to Ready */
3379         husart->State = HAL_USART_STATE_READY;
3380 
3381 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3382         /* Call registered Rx Complete Callback */
3383         husart->RxCpltCallback(husart);
3384 #else
3385         /* Call legacy weak Rx Complete Callback */
3386         HAL_USART_RxCpltCallback(husart);
3387 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3388       }
3389       else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3390                (txftie != USART_CR3_TXFTIE) &&
3391                (txdatacount == 0U))
3392       {
3393         /* TxRx process is completed, restore husart->State to Ready */
3394         husart->State = HAL_USART_STATE_READY;
3395 
3396 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3397         /* Call registered Tx Rx Complete Callback */
3398         husart->TxRxCpltCallback(husart);
3399 #else
3400         /* Call legacy weak Tx Rx Complete Callback */
3401         HAL_USART_TxRxCpltCallback(husart);
3402 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3403       }
3404       else
3405       {
3406         /* Nothing to do */
3407       }
3408     }
3409     else if ((state == HAL_USART_STATE_BUSY_RX) &&
3410              (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3411     {
3412       /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3413       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3414     }
3415     else
3416     {
3417       /* Nothing to do */
3418     }
3419   }
3420 }
3421 
3422 /**
3423   * @brief  Simplex receive an amount of data in non-blocking mode.
3424   * @note   Function called under interruption only, once
3425   *         interruptions have been enabled by HAL_USART_Receive_IT().
3426   * @note   ISR function executed when FIFO mode is enabled and when the
3427   *         data word length is less than 9 bits long.
3428   * @param  husart USART handle
3429   * @retval None
3430   */
USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3431 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3432 {
3433   HAL_USART_StateTypeDef state = husart->State;
3434   uint16_t txdatacount;
3435   uint16_t rxdatacount;
3436   uint16_t uhMask = husart->Mask;
3437   uint16_t nb_rx_data;
3438   uint32_t txftie;
3439 
3440   /* Check that a Rx process is ongoing */
3441   if ((state == HAL_USART_STATE_BUSY_RX) ||
3442       (state == HAL_USART_STATE_BUSY_TX_RX))
3443   {
3444     for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3445     {
3446       if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3447       {
3448         *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
3449         husart->pRxBuffPtr++;
3450         husart->RxXferCount--;
3451 
3452         if (husart->RxXferCount == 0U)
3453         {
3454           /* Disable the USART Parity Error Interrupt */
3455           CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3456 
3457           /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3458              and RX FIFO Threshold interrupt */
3459           CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3460 
3461           /* Clear RxISR function pointer */
3462           husart->RxISR = NULL;
3463 
3464           /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3465           txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3466           txdatacount = husart->TxXferCount;
3467 
3468           if (state == HAL_USART_STATE_BUSY_RX)
3469           {
3470             /* Clear SPI slave underrun flag and discard transmit data */
3471             if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3472             {
3473               __HAL_USART_CLEAR_UDRFLAG(husart);
3474               __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3475             }
3476 
3477             /* Rx process is completed, restore husart->State to Ready */
3478             husart->State = HAL_USART_STATE_READY;
3479             state = HAL_USART_STATE_READY;
3480 
3481 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3482             /* Call registered Rx Complete Callback */
3483             husart->RxCpltCallback(husart);
3484 #else
3485             /* Call legacy weak Rx Complete Callback */
3486             HAL_USART_RxCpltCallback(husart);
3487 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3488           }
3489           else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3490                    (txftie != USART_CR3_TXFTIE) &&
3491                    (txdatacount == 0U))
3492           {
3493             /* TxRx process is completed, restore husart->State to Ready */
3494             husart->State = HAL_USART_STATE_READY;
3495             state = HAL_USART_STATE_READY;
3496 
3497 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3498             /* Call registered Tx Rx Complete Callback */
3499             husart->TxRxCpltCallback(husart);
3500 #else
3501             /* Call legacy weak Tx Rx Complete Callback */
3502             HAL_USART_TxRxCpltCallback(husart);
3503 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3504           }
3505           else
3506           {
3507             /* Nothing to do */
3508           }
3509         }
3510         else if ((state == HAL_USART_STATE_BUSY_RX) &&
3511                  (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3512         {
3513           /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3514           husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3515         }
3516         else
3517         {
3518           /* Nothing to do */
3519         }
3520       }
3521     }
3522 
3523     /* When remaining number of bytes to receive is less than the RX FIFO
3524     threshold, next incoming frames are processed as if FIFO mode was
3525     disabled (i.e. one interrupt per received frame).
3526     */
3527     rxdatacount = husart->RxXferCount;
3528     if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3529     {
3530       /* Disable the USART RXFT interrupt*/
3531       CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3532 
3533       /* Update the RxISR function pointer */
3534       husart->RxISR = USART_RxISR_8BIT;
3535 
3536       /* Enable the USART Data Register Not Empty interrupt */
3537       SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3538 
3539       if ((husart->TxXferCount == 0U) &&
3540           (state == HAL_USART_STATE_BUSY_TX_RX) &&
3541           (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3542       {
3543         /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3544         husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3545       }
3546     }
3547   }
3548   else
3549   {
3550     /* Clear RXNE interrupt flag */
3551     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3552   }
3553 }
3554 
3555 /**
3556   * @brief  Simplex receive an amount of data in non-blocking mode.
3557   * @note   Function called under interruption only, once
3558   *         interruptions have been enabled by HAL_USART_Receive_IT().
3559   * @note   ISR function executed when FIFO mode is enabled and when the
3560   *         data word length is 9 bits long.
3561   * @param  husart USART handle
3562   * @retval None
3563   */
USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3564 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3565 {
3566   HAL_USART_StateTypeDef state = husart->State;
3567   uint16_t txdatacount;
3568   uint16_t rxdatacount;
3569   uint16_t *tmp;
3570   uint16_t uhMask = husart->Mask;
3571   uint16_t nb_rx_data;
3572   uint32_t txftie;
3573 
3574   /* Check that a Tx process is ongoing */
3575   if ((state == HAL_USART_STATE_BUSY_RX) ||
3576       (state == HAL_USART_STATE_BUSY_TX_RX))
3577   {
3578     for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3579     {
3580       if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3581       {
3582         tmp = (uint16_t *) husart->pRxBuffPtr;
3583         *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3584         husart->pRxBuffPtr += 2U;
3585         husart->RxXferCount--;
3586 
3587         if (husart->RxXferCount == 0U)
3588         {
3589           /* Disable the USART Parity Error Interrupt */
3590           CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3591 
3592           /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3593              and RX FIFO Threshold interrupt */
3594           CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3595 
3596           /* Clear RxISR function pointer */
3597           husart->RxISR = NULL;
3598 
3599           /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3600           txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3601           txdatacount = husart->TxXferCount;
3602 
3603           if (state == HAL_USART_STATE_BUSY_RX)
3604           {
3605             /* Clear SPI slave underrun flag and discard transmit data */
3606             if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3607             {
3608               __HAL_USART_CLEAR_UDRFLAG(husart);
3609               __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3610             }
3611 
3612             /* Rx process is completed, restore husart->State to Ready */
3613             husart->State = HAL_USART_STATE_READY;
3614             state = HAL_USART_STATE_READY;
3615 
3616 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3617             /* Call registered Rx Complete Callback */
3618             husart->RxCpltCallback(husart);
3619 #else
3620             /* Call legacy weak Rx Complete Callback */
3621             HAL_USART_RxCpltCallback(husart);
3622 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3623           }
3624           else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3625                    (txftie != USART_CR3_TXFTIE) &&
3626                    (txdatacount == 0U))
3627           {
3628             /* TxRx process is completed, restore husart->State to Ready */
3629             husart->State = HAL_USART_STATE_READY;
3630             state = HAL_USART_STATE_READY;
3631 
3632 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3633             /* Call registered Tx Rx Complete Callback */
3634             husart->TxRxCpltCallback(husart);
3635 #else
3636             /* Call legacy weak Tx Rx Complete Callback */
3637             HAL_USART_TxRxCpltCallback(husart);
3638 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3639           }
3640           else
3641           {
3642             /* Nothing to do */
3643           }
3644         }
3645         else if ((state == HAL_USART_STATE_BUSY_RX) &&
3646                  (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3647         {
3648           /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3649           husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3650         }
3651         else
3652         {
3653           /* Nothing to do */
3654         }
3655       }
3656     }
3657 
3658     /* When remaining number of bytes to receive is less than the RX FIFO
3659     threshold, next incoming frames are processed as if FIFO mode was
3660     disabled (i.e. one interrupt per received frame).
3661     */
3662     rxdatacount = husart->RxXferCount;
3663     if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3664     {
3665       /* Disable the USART RXFT interrupt*/
3666       CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3667 
3668       /* Update the RxISR function pointer */
3669       husart->RxISR = USART_RxISR_16BIT;
3670 
3671       /* Enable the USART Data Register Not Empty interrupt */
3672       SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3673 
3674       if ((husart->TxXferCount == 0U) &&
3675           (state == HAL_USART_STATE_BUSY_TX_RX) &&
3676           (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3677       {
3678         /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3679         husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3680       }
3681     }
3682   }
3683   else
3684   {
3685     /* Clear RXNE interrupt flag */
3686     __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3687   }
3688 }
3689 
3690 /**
3691   * @}
3692   */
3693 
3694 #endif /* HAL_USART_MODULE_ENABLED */
3695 /**
3696   * @}
3697   */
3698 
3699 /**
3700   * @}
3701   */
3702 
3703