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