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