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