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