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