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