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