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