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