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