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