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