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