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