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