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