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