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