source: trunk/firmware/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_usart.c

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