2 ******************************************************************************
3 * @file stm32f7xx_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
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral Control functions
12 * + Peripheral State and Error functions
15 ===============================================================================
16 ##### How to use this driver #####
17 ===============================================================================
19 The USART HAL driver can be used as follows:
21 (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
22 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
23 (++) Enable the USARTx interface clock.
24 (++) USART pins configuration:
25 (+++) Enable the clock for the USART GPIOs.
26 (+++) Configure these USART pins as alternate function pull-up.
27 (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
28 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
29 (+++) Configure the USARTx interrupt priority.
30 (+++) Enable the NVIC USART IRQ handle.
31 (++) USART interrupts handling:
32 -@@- The specific USART interrupts (Transmission complete interrupt,
33 RXNE interrupt and Error Interrupts) will be managed using the macros
34 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
35 (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
36 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
37 (+++) Declare a DMA handle structure for the Tx/Rx channel.
38 (+++) Enable the DMAx interface clock.
39 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40 (+++) Configure the DMA Tx/Rx channel.
41 (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
42 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
44 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
45 (Receiver/Transmitter) in the husart handle Init structure.
47 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
48 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
49 by calling the customized HAL_USART_MspInit(&husart) API.
52 (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
53 HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
54 HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
56 ##### Callback registration #####
57 ==================================
60 The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
61 allows the user to configure dynamically the driver callbacks.
64 Use Function @ref HAL_USART_RegisterCallback() to register a user callback.
65 Function @ref HAL_USART_RegisterCallback() allows to register following callbacks:
66 (+) TxHalfCpltCallback : Tx Half Complete Callback.
67 (+) TxCpltCallback : Tx Complete Callback.
68 (+) RxHalfCpltCallback : Rx Half Complete Callback.
69 (+) RxCpltCallback : Rx Complete Callback.
70 (+) TxRxCpltCallback : Tx Rx Complete Callback.
71 (+) ErrorCallback : Error Callback.
72 (+) AbortCpltCallback : Abort Complete Callback.
73 (+) MspInitCallback : USART MspInit.
74 (+) MspDeInitCallback : USART MspDeInit.
75 This function takes as parameters the HAL peripheral handle, the Callback ID
76 and a pointer to the user callback function.
79 Use function @ref HAL_USART_UnRegisterCallback() to reset a callback to the default
80 weak (surcharged) function.
81 @ref HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
83 This function allows to reset following callbacks:
84 (+) TxHalfCpltCallback : Tx Half Complete Callback.
85 (+) TxCpltCallback : Tx Complete Callback.
86 (+) RxHalfCpltCallback : Rx Half Complete Callback.
87 (+) RxCpltCallback : Rx Complete Callback.
88 (+) TxRxCpltCallback : Tx Rx Complete Callback.
89 (+) ErrorCallback : Error Callback.
90 (+) AbortCpltCallback : Abort Complete Callback.
91 (+) MspInitCallback : USART MspInit.
92 (+) MspDeInitCallback : USART MspDeInit.
95 By default, after the @ref HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
96 all callbacks are set to the corresponding weak (surcharged) functions:
97 examples @ref HAL_USART_TxCpltCallback(), @ref HAL_USART_RxHalfCpltCallback().
98 Exception done for MspInit and MspDeInit functions that are respectively
99 reset to the legacy weak (surcharged) functions in the @ref HAL_USART_Init()
100 and @ref HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
101 If not, MspInit or MspDeInit are not null, the @ref HAL_USART_Init() and @ref HAL_USART_DeInit()
102 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
105 Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
106 Exception done MspInit/MspDeInit that can be registered/unregistered
107 in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
108 MspInit/DeInit callbacks can be used during the Init/DeInit.
109 In that case first register the MspInit/MspDeInit user callbacks
110 using @ref HAL_USART_RegisterCallback() before calling @ref HAL_USART_DeInit()
111 or @ref HAL_USART_Init() function.
114 When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
115 not defined, the callback registration feature is not available
116 and weak (surcharged) callbacks are used.
120 ******************************************************************************
123 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
124 * All rights reserved.</center></h2>
126 * This software component is licensed by ST under BSD 3-Clause license,
127 * the "License"; You may not use this file except in compliance with the
128 * License. You may obtain a copy of the License at:
129 * opensource.org/licenses/BSD-3-Clause
131 ******************************************************************************
134 /* Includes ------------------------------------------------------------------*/
135 #include "stm32f7xx_hal.h"
137 /** @addtogroup STM32F7xx_HAL_Driver
141 /** @defgroup USART USART
142 * @brief HAL USART Synchronous module driver
146 #ifdef HAL_USART_MODULE_ENABLED
148 /* Private typedef -----------------------------------------------------------*/
149 /* Private define ------------------------------------------------------------*/
150 /** @defgroup USART_Private_Constants USART Private Constants
153 #define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
154 #define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
155 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
156 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< USART CR1 fields of parameters set by USART_SetConfig API */
157 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
158 USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
160 #define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */
161 #define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */
166 /* Private macros ------------------------------------------------------------*/
167 /* Private variables ---------------------------------------------------------*/
168 /* Private function prototypes -----------------------------------------------*/
169 /** @addtogroup USART_Private_Functions
172 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
173 void USART_InitCallbacksToDefault(USART_HandleTypeDef
*husart
);
174 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
175 static void USART_EndTransfer(USART_HandleTypeDef
*husart
);
176 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
);
177 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
);
178 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
);
179 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
);
180 static void USART_DMAError(DMA_HandleTypeDef
*hdma
);
181 static void USART_DMAAbortOnError(DMA_HandleTypeDef
*hdma
);
182 static void USART_DMATxAbortCallback(DMA_HandleTypeDef
*hdma
);
183 static void USART_DMARxAbortCallback(DMA_HandleTypeDef
*hdma
);
184 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
, uint32_t Tickstart
, uint32_t Timeout
);
185 static HAL_StatusTypeDef
USART_SetConfig(USART_HandleTypeDef
*husart
);
186 static HAL_StatusTypeDef
USART_CheckIdleState(USART_HandleTypeDef
*husart
);
187 static void USART_TxISR_8BIT(USART_HandleTypeDef
*husart
);
188 static void USART_TxISR_16BIT(USART_HandleTypeDef
*husart
);
189 static void USART_EndTransmit_IT(USART_HandleTypeDef
*husart
);
190 static void USART_RxISR_8BIT(USART_HandleTypeDef
*husart
);
191 static void USART_RxISR_16BIT(USART_HandleTypeDef
*husart
);
198 /* Exported functions --------------------------------------------------------*/
200 /** @defgroup USART_Exported_Functions USART Exported Functions
204 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
205 * @brief Initialization and Configuration functions
208 ===============================================================================
209 ##### Initialization and Configuration functions #####
210 ===============================================================================
212 This subsection provides a set of functions allowing to initialize the USART
213 in asynchronous and in synchronous modes.
214 (+) For the asynchronous mode only these parameters can be configured:
218 (++) Parity: If the parity is enabled, then the MSB bit of the data written
219 in the data register is transmitted but is changed by the parity bit.
223 (++) Receiver/transmitter modes
226 The HAL_USART_Init() function follows the USART synchronous configuration
227 procedure (details for the procedure are available in reference manual).
231 Depending on the frame length defined by the M1 and M0 bits (7-bit,
232 8-bit or 9-bit), the possible USART formats are listed in the
235 Table 1. USART frame format.
236 +-----------------------------------------------------------------------+
237 | M1 bit | M0 bit | PCE bit | USART frame |
238 |---------|---------|-----------|---------------------------------------|
239 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
240 |---------|---------|-----------|---------------------------------------|
241 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
242 |---------|---------|-----------|---------------------------------------|
243 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
244 |---------|---------|-----------|---------------------------------------|
245 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
246 |---------|---------|-----------|---------------------------------------|
247 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
248 |---------|---------|-----------|---------------------------------------|
249 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
250 +-----------------------------------------------------------------------+
256 * @brief Initialize the USART mode according to the specified
257 * parameters in the USART_InitTypeDef and initialize the associated handle.
258 * @param husart USART handle.
261 HAL_StatusTypeDef
HAL_USART_Init(USART_HandleTypeDef
*husart
)
263 /* Check the USART handle allocation */
269 /* Check the parameters */
270 assert_param(IS_USART_INSTANCE(husart
->Instance
));
272 if (husart
->State
== HAL_USART_STATE_RESET
)
274 /* Allocate lock resource and initialize it */
275 husart
->Lock
= HAL_UNLOCKED
;
277 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
278 USART_InitCallbacksToDefault(husart
);
280 if (husart
->MspInitCallback
== NULL
)
282 husart
->MspInitCallback
= HAL_USART_MspInit
;
285 /* Init the low level hardware */
286 husart
->MspInitCallback(husart
);
288 /* Init the low level hardware : GPIO, CLOCK */
289 HAL_USART_MspInit(husart
);
290 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
293 husart
->State
= HAL_USART_STATE_BUSY
;
295 /* Disable the Peripheral */
296 __HAL_USART_DISABLE(husart
);
298 /* Set the Usart Communication parameters */
299 if (USART_SetConfig(husart
) == HAL_ERROR
)
304 /* In Synchronous mode, the following bits must be kept cleared:
305 - LINEN bit in the USART_CR2 register
306 - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
307 husart
->Instance
->CR2
&= ~USART_CR2_LINEN
;
308 husart
->Instance
->CR3
&= ~(USART_CR3_SCEN
| USART_CR3_HDSEL
| USART_CR3_IREN
);
310 /* Enable the Peripheral */
311 __HAL_USART_ENABLE(husart
);
313 /* TEACK to check before moving husart->State to Ready */
314 return (USART_CheckIdleState(husart
));
318 * @brief DeInitialize the USART peripheral.
319 * @param husart USART handle.
322 HAL_StatusTypeDef
HAL_USART_DeInit(USART_HandleTypeDef
*husart
)
324 /* Check the USART handle allocation */
330 /* Check the parameters */
331 assert_param(IS_USART_INSTANCE(husart
->Instance
));
333 husart
->State
= HAL_USART_STATE_BUSY
;
335 husart
->Instance
->CR1
= 0x0U
;
336 husart
->Instance
->CR2
= 0x0U
;
337 husart
->Instance
->CR3
= 0x0U
;
339 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
340 if (husart
->MspDeInitCallback
== NULL
)
342 husart
->MspDeInitCallback
= HAL_USART_MspDeInit
;
344 /* DeInit the low level hardware */
345 husart
->MspDeInitCallback(husart
);
347 /* DeInit the low level hardware */
348 HAL_USART_MspDeInit(husart
);
349 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
351 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
352 husart
->State
= HAL_USART_STATE_RESET
;
355 __HAL_UNLOCK(husart
);
361 * @brief Initialize the USART MSP.
362 * @param husart USART handle.
365 __weak
void HAL_USART_MspInit(USART_HandleTypeDef
*husart
)
367 /* Prevent unused argument(s) compilation warning */
370 /* NOTE : This function should not be modified, when the callback is needed,
371 the HAL_USART_MspInit can be implemented in the user file
376 * @brief DeInitialize the USART MSP.
377 * @param husart USART handle.
380 __weak
void HAL_USART_MspDeInit(USART_HandleTypeDef
*husart
)
382 /* Prevent unused argument(s) compilation warning */
385 /* NOTE : This function should not be modified, when the callback is needed,
386 the HAL_USART_MspDeInit can be implemented in the user file
390 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
392 * @brief Register a User USART Callback
393 * To be used instead of the weak predefined callback
394 * @param husart usart handle
395 * @param CallbackID ID of the callback to be registered
396 * This parameter can be one of the following values:
397 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
398 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
399 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
400 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
401 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
402 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
403 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
404 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
405 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
406 * @param pCallback pointer to the Callback function
409 HAL_StatusTypeDef
HAL_USART_RegisterCallback(USART_HandleTypeDef
*husart
, HAL_USART_CallbackIDTypeDef CallbackID
, pUSART_CallbackTypeDef pCallback
)
411 HAL_StatusTypeDef status
= HAL_OK
;
413 if (pCallback
== NULL
)
415 /* Update the error code */
416 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
423 if (husart
->State
== HAL_USART_STATE_READY
)
427 case HAL_USART_TX_HALFCOMPLETE_CB_ID
:
428 husart
->TxHalfCpltCallback
= pCallback
;
431 case HAL_USART_TX_COMPLETE_CB_ID
:
432 husart
->TxCpltCallback
= pCallback
;
435 case HAL_USART_RX_HALFCOMPLETE_CB_ID
:
436 husart
->RxHalfCpltCallback
= pCallback
;
439 case HAL_USART_RX_COMPLETE_CB_ID
:
440 husart
->RxCpltCallback
= pCallback
;
443 case HAL_USART_TX_RX_COMPLETE_CB_ID
:
444 husart
->TxRxCpltCallback
= pCallback
;
447 case HAL_USART_ERROR_CB_ID
:
448 husart
->ErrorCallback
= pCallback
;
451 case HAL_USART_ABORT_COMPLETE_CB_ID
:
452 husart
->AbortCpltCallback
= pCallback
;
456 case HAL_USART_MSPINIT_CB_ID
:
457 husart
->MspInitCallback
= pCallback
;
460 case HAL_USART_MSPDEINIT_CB_ID
:
461 husart
->MspDeInitCallback
= pCallback
;
465 /* Update the error code */
466 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
468 /* Return error status */
473 else if (husart
->State
== HAL_USART_STATE_RESET
)
477 case HAL_USART_MSPINIT_CB_ID
:
478 husart
->MspInitCallback
= pCallback
;
481 case HAL_USART_MSPDEINIT_CB_ID
:
482 husart
->MspDeInitCallback
= pCallback
;
486 /* Update the error code */
487 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
489 /* Return error status */
496 /* Update the error code */
497 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
499 /* Return error status */
504 __HAL_UNLOCK(husart
);
510 * @brief Unregister an UART Callback
511 * UART callaback is redirected to the weak predefined callback
512 * @param husart uart handle
513 * @param CallbackID ID of the callback to be unregistered
514 * This parameter can be one of the following values:
515 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
516 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
517 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
518 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
519 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
520 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
521 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
522 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
523 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
526 HAL_StatusTypeDef
HAL_USART_UnRegisterCallback(USART_HandleTypeDef
*husart
, HAL_USART_CallbackIDTypeDef CallbackID
)
528 HAL_StatusTypeDef status
= HAL_OK
;
533 if (HAL_USART_STATE_READY
== husart
->State
)
537 case HAL_USART_TX_HALFCOMPLETE_CB_ID
:
538 husart
->TxHalfCpltCallback
= HAL_USART_TxHalfCpltCallback
; /* Legacy weak TxHalfCpltCallback */
541 case HAL_USART_TX_COMPLETE_CB_ID
:
542 husart
->TxCpltCallback
= HAL_USART_TxCpltCallback
; /* Legacy weak TxCpltCallback */
545 case HAL_USART_RX_HALFCOMPLETE_CB_ID
:
546 husart
->RxHalfCpltCallback
= HAL_USART_RxHalfCpltCallback
; /* Legacy weak RxHalfCpltCallback */
549 case HAL_USART_RX_COMPLETE_CB_ID
:
550 husart
->RxCpltCallback
= HAL_USART_RxCpltCallback
; /* Legacy weak RxCpltCallback */
553 case HAL_USART_TX_RX_COMPLETE_CB_ID
:
554 husart
->TxRxCpltCallback
= HAL_USART_TxRxCpltCallback
; /* Legacy weak TxRxCpltCallback */
557 case HAL_USART_ERROR_CB_ID
:
558 husart
->ErrorCallback
= HAL_USART_ErrorCallback
; /* Legacy weak ErrorCallback */
561 case HAL_USART_ABORT_COMPLETE_CB_ID
:
562 husart
->AbortCpltCallback
= HAL_USART_AbortCpltCallback
; /* Legacy weak AbortCpltCallback */
566 case HAL_USART_MSPINIT_CB_ID
:
567 husart
->MspInitCallback
= HAL_USART_MspInit
; /* Legacy weak MspInitCallback */
570 case HAL_USART_MSPDEINIT_CB_ID
:
571 husart
->MspDeInitCallback
= HAL_USART_MspDeInit
; /* Legacy weak MspDeInitCallback */
575 /* Update the error code */
576 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
578 /* Return error status */
583 else if (HAL_USART_STATE_RESET
== husart
->State
)
587 case HAL_USART_MSPINIT_CB_ID
:
588 husart
->MspInitCallback
= HAL_USART_MspInit
;
591 case HAL_USART_MSPDEINIT_CB_ID
:
592 husart
->MspDeInitCallback
= HAL_USART_MspDeInit
;
596 /* Update the error code */
597 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
599 /* Return error status */
606 /* Update the error code */
607 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
609 /* Return error status */
614 __HAL_UNLOCK(husart
);
618 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
625 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
626 * @brief USART Transmit and Receive functions
629 ===============================================================================
630 ##### IO operation functions #####
631 ===============================================================================
632 [..] This subsection provides a set of functions allowing to manage the USART synchronous
635 [..] The USART supports master mode only: it cannot receive or send data related to an input
636 clock (SCLK is always an output).
640 (#) There are two modes of transfer:
641 (++) Blocking mode: The communication is performed in polling mode.
642 The HAL status of all data processing is returned by the same function
643 after finishing transfer.
644 (++) No-Blocking mode: The communication is performed using Interrupts
645 or DMA, These API's return the HAL status.
646 The end of the data processing will be indicated through the
647 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
649 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
650 will be executed respectively at the end of the transmit or Receive process
651 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
653 (#) Blocking mode API's are :
654 (++) HAL_USART_Transmit() in simplex mode
655 (++) HAL_USART_Receive() in full duplex receive only
656 (++) HAL_USART_TransmitReceive() in full duplex mode
658 (#) Non-Blocking mode API's with Interrupt are :
659 (++) HAL_USART_Transmit_IT() in simplex mode
660 (++) HAL_USART_Receive_IT() in full duplex receive only
661 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
662 (++) HAL_USART_IRQHandler()
664 (#) No-Blocking mode API's with DMA are :
665 (++) HAL_USART_Transmit_DMA() in simplex mode
666 (++) HAL_USART_Receive_DMA() in full duplex receive only
667 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
668 (++) HAL_USART_DMAPause()
669 (++) HAL_USART_DMAResume()
670 (++) HAL_USART_DMAStop()
672 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
673 (++) HAL_USART_TxCpltCallback()
674 (++) HAL_USART_RxCpltCallback()
675 (++) HAL_USART_TxHalfCpltCallback()
676 (++) HAL_USART_RxHalfCpltCallback()
677 (++) HAL_USART_ErrorCallback()
678 (++) HAL_USART_TxRxCpltCallback()
680 (#) Non-Blocking mode transfers could be aborted using Abort API's :
681 (++) HAL_USART_Abort()
682 (++) HAL_USART_Abort_IT()
684 (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
685 (++) HAL_USART_AbortCpltCallback()
687 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
688 Errors are handled as follows :
689 (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
690 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
691 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
692 and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side.
693 If user wants to abort it, Abort services should be called by user.
694 (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
695 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
696 Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed.
703 * @brief Simplex send an amount of data in blocking mode.
704 * @param husart USART handle.
705 * @param pTxData Pointer to data buffer.
706 * @param Size Amount of data to be sent.
707 * @param Timeout Timeout duration.
710 HAL_StatusTypeDef
HAL_USART_Transmit(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
, uint32_t Timeout
)
712 uint8_t *ptxdata8bits
;
713 uint16_t *ptxdata16bits
;
716 if (husart
->State
== HAL_USART_STATE_READY
)
718 if ((pTxData
== NULL
) || (Size
== 0U))
726 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
727 husart
->State
= HAL_USART_STATE_BUSY_TX
;
729 /* Init tickstart for timeout managment*/
730 tickstart
= HAL_GetTick();
732 husart
->TxXferSize
= Size
;
733 husart
->TxXferCount
= Size
;
735 /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
736 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
739 ptxdata16bits
= (uint16_t *) pTxData
;
743 ptxdata8bits
= pTxData
;
744 ptxdata16bits
= NULL
;
747 /* Check the remaining data to be sent */
748 while (husart
->TxXferCount
> 0U)
750 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
754 if (ptxdata8bits
== NULL
)
756 husart
->Instance
->TDR
= (uint16_t)(*ptxdata16bits
& 0x01FFU
);
761 husart
->Instance
->TDR
= (uint8_t)(*ptxdata8bits
& 0xFFU
);
765 husart
->TxXferCount
--;
768 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, tickstart
, Timeout
) != HAL_OK
)
773 /* Clear Transmission Complete Flag */
774 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_TCF
);
776 /* Clear overrun flag and discard the received data */
777 __HAL_USART_CLEAR_OREFLAG(husart
);
778 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
779 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
781 /* At end of Tx process, restore husart->State to Ready */
782 husart
->State
= HAL_USART_STATE_READY
;
784 /* Process Unlocked */
785 __HAL_UNLOCK(husart
);
796 * @brief Receive an amount of data in blocking mode.
797 * @note To receive synchronous data, dummy data are simultaneously transmitted.
798 * @param husart USART handle.
799 * @param pRxData Pointer to data buffer.
800 * @param Size Amount of data to be received.
801 * @param Timeout Timeout duration.
804 HAL_StatusTypeDef
HAL_USART_Receive(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
806 uint8_t *prxdata8bits
;
807 uint16_t *prxdata16bits
;
811 if (husart
->State
== HAL_USART_STATE_READY
)
813 if ((pRxData
== NULL
) || (Size
== 0U))
821 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
822 husart
->State
= HAL_USART_STATE_BUSY_RX
;
824 /* Init tickstart for timeout managment*/
825 tickstart
= HAL_GetTick();
827 husart
->RxXferSize
= Size
;
828 husart
->RxXferCount
= Size
;
830 /* Computation of USART mask to apply to RDR register */
831 USART_MASK_COMPUTATION(husart
);
832 uhMask
= husart
->Mask
;
834 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
835 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
838 prxdata16bits
= (uint16_t *) pRxData
;
842 prxdata8bits
= pRxData
;
843 prxdata16bits
= NULL
;
846 /* as long as data have to be received */
847 while (husart
->RxXferCount
> 0U)
850 /* Wait until TXE flag is set to send dummy byte in order to generate the
851 * clock for the slave to send data.
852 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
853 * can be written for all the cases. */
854 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
858 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x0FF);
861 /* Wait for RXNE Flag */
862 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
867 if (prxdata8bits
== NULL
)
869 *prxdata16bits
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
874 *prxdata8bits
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)(uhMask
& 0xFFU
));
878 husart
->RxXferCount
--;
883 /* At end of Rx process, restore husart->State to Ready */
884 husart
->State
= HAL_USART_STATE_READY
;
886 /* Process Unlocked */
887 __HAL_UNLOCK(husart
);
898 * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
899 * @param husart USART handle.
900 * @param pTxData pointer to TX data buffer.
901 * @param pRxData pointer to RX data buffer.
902 * @param Size amount of data to be sent (same amount to be received).
903 * @param Timeout Timeout duration.
906 HAL_StatusTypeDef
HAL_USART_TransmitReceive(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
908 uint8_t *prxdata8bits
;
909 uint16_t *prxdata16bits
;
910 uint8_t *ptxdata8bits
;
911 uint16_t *ptxdata16bits
;
913 uint16_t rxdatacount
;
916 if (husart
->State
== HAL_USART_STATE_READY
)
918 if ((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
926 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
927 husart
->State
= HAL_USART_STATE_BUSY_RX
;
929 /* Init tickstart for timeout managment*/
930 tickstart
= HAL_GetTick();
932 husart
->RxXferSize
= Size
;
933 husart
->TxXferSize
= Size
;
934 husart
->TxXferCount
= Size
;
935 husart
->RxXferCount
= Size
;
937 /* Computation of USART mask to apply to RDR register */
938 USART_MASK_COMPUTATION(husart
);
939 uhMask
= husart
->Mask
;
941 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
942 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
946 ptxdata16bits
= (uint16_t *) pTxData
;
947 prxdata16bits
= (uint16_t *) pRxData
;
951 prxdata8bits
= pRxData
;
952 ptxdata8bits
= pTxData
;
953 ptxdata16bits
= NULL
;
954 prxdata16bits
= NULL
;
957 if (husart
->TxXferCount
== 0x01U
)
959 /* Wait until TXE flag is set to send data */
960 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
964 if (ptxdata8bits
== NULL
)
966 husart
->Instance
->TDR
= (uint16_t)(*ptxdata16bits
& uhMask
);
971 husart
->Instance
->TDR
= (uint8_t)(*ptxdata8bits
& (uint8_t)(uhMask
& 0xFFU
));
975 husart
->TxXferCount
--;
978 /* Check the remain data to be sent */
979 /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
980 rxdatacount
= husart
->RxXferCount
;
981 while ((husart
->TxXferCount
> 0U) || (rxdatacount
> 0U))
983 if (husart
->TxXferCount
> 0U)
985 /* Wait until TXE flag is set to send data */
986 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
990 if (ptxdata8bits
== NULL
)
992 husart
->Instance
->TDR
= (uint16_t)(*ptxdata16bits
& uhMask
);
997 husart
->Instance
->TDR
= (uint8_t)(*ptxdata8bits
& (uint8_t)(uhMask
& 0xFFU
));
1001 husart
->TxXferCount
--;
1004 if (husart
->RxXferCount
> 0U)
1006 /* Wait for RXNE Flag */
1007 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
1012 if (prxdata8bits
== NULL
)
1014 *prxdata16bits
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
1019 *prxdata8bits
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)(uhMask
& 0xFFU
));
1023 husart
->RxXferCount
--;
1025 rxdatacount
= husart
->RxXferCount
;
1028 /* At end of TxRx process, restore husart->State to Ready */
1029 husart
->State
= HAL_USART_STATE_READY
;
1031 /* Process Unlocked */
1032 __HAL_UNLOCK(husart
);
1043 * @brief Send an amount of data in interrupt mode.
1044 * @param husart USART handle.
1045 * @param pTxData pointer to data buffer.
1046 * @param Size amount of data to be sent.
1047 * @retval HAL status
1049 HAL_StatusTypeDef
HAL_USART_Transmit_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
1051 if (husart
->State
== HAL_USART_STATE_READY
)
1053 if ((pTxData
== NULL
) || (Size
== 0U))
1058 /* Process Locked */
1061 husart
->pTxBuffPtr
= pTxData
;
1062 husart
->TxXferSize
= Size
;
1063 husart
->TxXferCount
= Size
;
1064 husart
->TxISR
= NULL
;
1066 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1067 husart
->State
= HAL_USART_STATE_BUSY_TX
;
1069 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1070 are not managed by the USART Transmit Process to avoid the overrun interrupt
1071 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1072 to benefit for the frame error and noise interrupts the usart mode should be
1073 configured only for transmit "USART_MODE_TX" */
1076 /* Set the Tx ISR function pointer according to the data word length */
1077 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1079 husart
->TxISR
= USART_TxISR_16BIT
;
1083 husart
->TxISR
= USART_TxISR_8BIT
;
1086 /* Process Unlocked */
1087 __HAL_UNLOCK(husart
);
1089 /* Enable the USART Transmit Data Register Empty Interrupt */
1090 __HAL_USART_ENABLE_IT(husart
, USART_IT_TXE
);
1102 * @brief Receive an amount of data in interrupt mode.
1103 * @note To receive synchronous data, dummy data are simultaneously transmitted.
1104 * @param husart USART handle.
1105 * @param pRxData pointer to data buffer.
1106 * @param Size amount of data to be received.
1107 * @retval HAL status
1109 HAL_StatusTypeDef
HAL_USART_Receive_IT(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
1112 if (husart
->State
== HAL_USART_STATE_READY
)
1114 if ((pRxData
== NULL
) || (Size
== 0U))
1119 /* Process Locked */
1122 husart
->pRxBuffPtr
= pRxData
;
1123 husart
->RxXferSize
= Size
;
1124 husart
->RxXferCount
= Size
;
1125 husart
->RxISR
= NULL
;
1127 USART_MASK_COMPUTATION(husart
);
1129 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1130 husart
->State
= HAL_USART_STATE_BUSY_RX
;
1132 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1133 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1136 /* Set the Rx ISR function pointer according to the data word length */
1137 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1139 husart
->RxISR
= USART_RxISR_16BIT
;
1143 husart
->RxISR
= USART_RxISR_8BIT
;
1146 /* Process Unlocked */
1147 __HAL_UNLOCK(husart
);
1149 /* Enable the USART Parity Error and Data Register not empty Interrupts */
1150 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
| USART_CR1_RXNEIE
);
1154 /* Send dummy data in order to generate the clock for the Slave to send the next data.
1157 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
1170 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1171 * @param husart USART handle.
1172 * @param pTxData pointer to TX data buffer.
1173 * @param pRxData pointer to RX data buffer.
1174 * @param Size amount of data to be sent (same amount to be received).
1175 * @retval HAL status
1177 HAL_StatusTypeDef
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
)
1180 if (husart
->State
== HAL_USART_STATE_READY
)
1182 if ((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
1187 /* Process Locked */
1190 husart
->pRxBuffPtr
= pRxData
;
1191 husart
->RxXferSize
= Size
;
1192 husart
->RxXferCount
= Size
;
1193 husart
->pTxBuffPtr
= pTxData
;
1194 husart
->TxXferSize
= Size
;
1195 husart
->TxXferCount
= Size
;
1197 /* Computation of USART mask to apply to RDR register */
1198 USART_MASK_COMPUTATION(husart
);
1200 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1201 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
1204 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1206 husart
->TxISR
= USART_TxISR_16BIT
;
1207 husart
->RxISR
= USART_RxISR_16BIT
;
1211 husart
->TxISR
= USART_TxISR_8BIT
;
1212 husart
->RxISR
= USART_RxISR_8BIT
;
1215 /* Process Locked */
1216 __HAL_UNLOCK(husart
);
1218 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1219 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1221 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1222 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
| USART_CR1_RXNEIE
);
1224 /* Enable the USART Transmit Data Register Empty Interrupt */
1225 SET_BIT(husart
->Instance
->CR1
, USART_CR1_TXEIE
);
1237 * @brief Send an amount of data in DMA mode.
1238 * @param husart USART handle.
1239 * @param pTxData pointer to data buffer.
1240 * @param Size amount of data to be sent.
1241 * @retval HAL status
1243 HAL_StatusTypeDef
HAL_USART_Transmit_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
1245 HAL_StatusTypeDef status
= HAL_OK
;
1248 if (husart
->State
== HAL_USART_STATE_READY
)
1250 if ((pTxData
== NULL
) || (Size
== 0U))
1255 /* Process Locked */
1258 husart
->pTxBuffPtr
= pTxData
;
1259 husart
->TxXferSize
= Size
;
1260 husart
->TxXferCount
= Size
;
1262 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1263 husart
->State
= HAL_USART_STATE_BUSY_TX
;
1265 if (husart
->hdmatx
!= NULL
)
1267 /* Set the USART DMA transfer complete callback */
1268 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
1270 /* Set the USART DMA Half transfer complete callback */
1271 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
1273 /* Set the DMA error callback */
1274 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
1276 /* Enable the USART transmit DMA channel */
1277 tmp
= (uint32_t *)&pTxData
;
1278 status
= HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t *)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
1281 if (status
== HAL_OK
)
1283 /* Clear the TC flag in the ICR register */
1284 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_TCF
);
1286 /* Process Unlocked */
1287 __HAL_UNLOCK(husart
);
1289 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1290 in the USART CR3 register */
1291 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1297 /* Set error code to DMA */
1298 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1300 /* Process Unlocked */
1301 __HAL_UNLOCK(husart
);
1303 /* Restore husart->State to ready */
1304 husart
->State
= HAL_USART_STATE_READY
;
1316 * @brief Receive an amount of data in DMA mode.
1317 * @note When the USART parity is enabled (PCE = 1), the received data contain
1318 * the parity bit (MSB position).
1319 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1320 * @param husart USART handle.
1321 * @param pRxData pointer to data buffer.
1322 * @param Size amount of data to be received.
1323 * @retval HAL status
1325 HAL_StatusTypeDef
HAL_USART_Receive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
1327 HAL_StatusTypeDef status
= HAL_OK
;
1328 uint32_t *tmp
= (uint32_t *)&pRxData
;
1330 /* Check that a Rx process is not already ongoing */
1331 if (husart
->State
== HAL_USART_STATE_READY
)
1333 if ((pRxData
== NULL
) || (Size
== 0U))
1338 /* Process Locked */
1341 husart
->pRxBuffPtr
= pRxData
;
1342 husart
->RxXferSize
= Size
;
1343 husart
->pTxBuffPtr
= pRxData
;
1344 husart
->TxXferSize
= Size
;
1346 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1347 husart
->State
= HAL_USART_STATE_BUSY_RX
;
1349 if (husart
->hdmarx
!= NULL
)
1351 /* Set the USART DMA Rx transfer complete callback */
1352 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
1354 /* Set the USART DMA Half transfer complete callback */
1355 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
1357 /* Set the USART DMA Rx transfer error callback */
1358 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
1360 /* Enable the USART receive DMA channel */
1361 status
= HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->RDR
, *(uint32_t *)tmp
, Size
);
1365 /* Enable the USART transmit DMA channel: the transmit channel is used in order
1366 to generate in the non-blocking mode the clock to the slave device,
1367 this mode isn't a simplex receive mode but a full-duplex receive mode */
1369 /* Set the USART DMA Tx Complete and Error callback to Null */
1370 if (husart
->hdmatx
!= NULL
)
1372 husart
->hdmatx
->XferErrorCallback
= NULL
;
1373 husart
->hdmatx
->XferHalfCpltCallback
= NULL
;
1374 husart
->hdmatx
->XferCpltCallback
= NULL
;
1375 status
= HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t *)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
1379 if (status
== HAL_OK
)
1381 /* Process Unlocked */
1382 __HAL_UNLOCK(husart
);
1384 /* Enable the USART Parity Error Interrupt */
1385 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1387 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1388 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1390 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1391 in the USART CR3 register */
1392 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1394 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1395 in the USART CR3 register */
1396 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1402 if (husart
->hdmarx
!= NULL
)
1404 status
= HAL_DMA_Abort(husart
->hdmarx
);
1407 /* No need to check on error code */
1410 /* Set error code to DMA */
1411 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1413 /* Process Unlocked */
1414 __HAL_UNLOCK(husart
);
1416 /* Restore husart->State to ready */
1417 husart
->State
= HAL_USART_STATE_READY
;
1429 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1430 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1431 * @param husart USART handle.
1432 * @param pTxData pointer to TX data buffer.
1433 * @param pRxData pointer to RX data buffer.
1434 * @param Size amount of data to be received/sent.
1435 * @retval HAL status
1437 HAL_StatusTypeDef
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
)
1439 HAL_StatusTypeDef status
;
1442 if (husart
->State
== HAL_USART_STATE_READY
)
1444 if ((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
1449 /* Process Locked */
1452 husart
->pRxBuffPtr
= pRxData
;
1453 husart
->RxXferSize
= Size
;
1454 husart
->pTxBuffPtr
= pTxData
;
1455 husart
->TxXferSize
= Size
;
1457 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1458 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
1460 if ((husart
->hdmarx
!= NULL
) && (husart
->hdmatx
!= NULL
))
1462 /* Set the USART DMA Rx transfer complete callback */
1463 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
1465 /* Set the USART DMA Half transfer complete callback */
1466 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
1468 /* Set the USART DMA Tx transfer complete callback */
1469 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
1471 /* Set the USART DMA Half transfer complete callback */
1472 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
1474 /* Set the USART DMA Tx transfer error callback */
1475 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
1477 /* Set the USART DMA Rx transfer error callback */
1478 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
1480 /* Enable the USART receive DMA channel */
1481 tmp
= (uint32_t *)&pRxData
;
1482 status
= HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->RDR
, *(uint32_t *)tmp
, Size
);
1484 /* Enable the USART transmit DMA channel */
1485 if (status
== HAL_OK
)
1487 tmp
= (uint32_t *)&pTxData
;
1488 status
= HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t *)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
1496 if (status
== HAL_OK
)
1498 /* Process Unlocked */
1499 __HAL_UNLOCK(husart
);
1501 /* Enable the USART Parity Error Interrupt */
1502 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1504 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1505 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1507 /* Clear the TC flag in the ICR register */
1508 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_TCF
);
1510 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1511 in the USART CR3 register */
1512 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1514 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1515 in the USART CR3 register */
1516 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1522 if (husart
->hdmarx
!= NULL
)
1524 status
= HAL_DMA_Abort(husart
->hdmarx
);
1527 /* No need to check on error code */
1530 /* Set error code to DMA */
1531 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1533 /* Process Unlocked */
1534 __HAL_UNLOCK(husart
);
1536 /* Restore husart->State to ready */
1537 husart
->State
= HAL_USART_STATE_READY
;
1549 * @brief Pause the DMA Transfer.
1550 * @param husart USART handle.
1551 * @retval HAL status
1553 HAL_StatusTypeDef
HAL_USART_DMAPause(USART_HandleTypeDef
*husart
)
1555 const HAL_USART_StateTypeDef state
= husart
->State
;
1557 /* Process Locked */
1560 if ((HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
)) &&
1561 (state
== HAL_USART_STATE_BUSY_TX
))
1563 /* Disable the USART DMA Tx request */
1564 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1566 else if ((state
== HAL_USART_STATE_BUSY_RX
) ||
1567 (state
== HAL_USART_STATE_BUSY_TX_RX
))
1569 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1571 /* Disable the USART DMA Tx request */
1572 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1574 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1576 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1577 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1578 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1580 /* Disable the USART DMA Rx request */
1581 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1589 /* Process Unlocked */
1590 __HAL_UNLOCK(husart
);
1596 * @brief Resume the DMA Transfer.
1597 * @param husart USART handle.
1598 * @retval HAL status
1600 HAL_StatusTypeDef
HAL_USART_DMAResume(USART_HandleTypeDef
*husart
)
1602 const HAL_USART_StateTypeDef state
= husart
->State
;
1604 /* Process Locked */
1607 if (state
== HAL_USART_STATE_BUSY_TX
)
1609 /* Enable the USART DMA Tx request */
1610 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1612 else if ((state
== HAL_USART_STATE_BUSY_RX
) ||
1613 (state
== HAL_USART_STATE_BUSY_TX_RX
))
1615 /* Clear the Overrun flag before resuming the Rx transfer*/
1616 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
);
1618 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1619 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1620 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1622 /* Enable the USART DMA Rx request before the DMA Tx request */
1623 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1625 /* Enable the USART DMA Tx request */
1626 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1633 /* Process Unlocked */
1634 __HAL_UNLOCK(husart
);
1640 * @brief Stop the DMA Transfer.
1641 * @param husart USART handle.
1642 * @retval HAL status
1644 HAL_StatusTypeDef
HAL_USART_DMAStop(USART_HandleTypeDef
*husart
)
1646 /* The Lock is not implemented on this API to allow the user application
1647 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1648 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1649 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1650 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1651 the stream and the corresponding call back is executed. */
1653 /* Disable the USART Tx/Rx DMA requests */
1654 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1655 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1657 /* Abort the USART DMA tx channel */
1658 if (husart
->hdmatx
!= NULL
)
1660 if (HAL_DMA_Abort(husart
->hdmatx
) != HAL_OK
)
1662 if (HAL_DMA_GetError(husart
->hdmatx
) == HAL_DMA_ERROR_TIMEOUT
)
1664 /* Set error code to DMA */
1665 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1671 /* Abort the USART DMA rx channel */
1672 if (husart
->hdmarx
!= NULL
)
1674 if (HAL_DMA_Abort(husart
->hdmarx
) != HAL_OK
)
1676 if (HAL_DMA_GetError(husart
->hdmarx
) == HAL_DMA_ERROR_TIMEOUT
)
1678 /* Set error code to DMA */
1679 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1686 USART_EndTransfer(husart
);
1687 husart
->State
= HAL_USART_STATE_READY
;
1693 * @brief Abort ongoing transfers (blocking mode).
1694 * @param husart USART handle.
1695 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1696 * This procedure performs following operations :
1697 * - Disable USART Interrupts (Tx and Rx)
1698 * - Disable the DMA transfer in the peripheral register (if enabled)
1699 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1700 * - Set handle State to READY
1701 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1702 * @retval HAL status
1704 HAL_StatusTypeDef
HAL_USART_Abort(USART_HandleTypeDef
*husart
)
1706 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
| USART_CR1_TXEIE
| USART_CR1_TCIE
));
1707 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1709 /* Disable the USART DMA Tx request if enabled */
1710 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1712 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1714 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1715 if (husart
->hdmatx
!= NULL
)
1717 /* Set the USART DMA Abort callback to Null.
1718 No call back execution at end of DMA abort procedure */
1719 husart
->hdmatx
->XferAbortCallback
= NULL
;
1721 if (HAL_DMA_Abort(husart
->hdmatx
) != HAL_OK
)
1723 if (HAL_DMA_GetError(husart
->hdmatx
) == HAL_DMA_ERROR_TIMEOUT
)
1725 /* Set error code to DMA */
1726 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1734 /* Disable the USART DMA Rx request if enabled */
1735 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1737 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1739 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1740 if (husart
->hdmarx
!= NULL
)
1742 /* Set the USART DMA Abort callback to Null.
1743 No call back execution at end of DMA abort procedure */
1744 husart
->hdmarx
->XferAbortCallback
= NULL
;
1746 if (HAL_DMA_Abort(husart
->hdmarx
) != HAL_OK
)
1748 if (HAL_DMA_GetError(husart
->hdmarx
) == HAL_DMA_ERROR_TIMEOUT
)
1750 /* Set error code to DMA */
1751 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1759 /* Reset Tx and Rx transfer counters */
1760 husart
->TxXferCount
= 0U;
1761 husart
->RxXferCount
= 0U;
1763 /* Clear the Error flags in the ICR register */
1764 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
1767 /* Discard the received data */
1768 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
1770 /* Restore husart->State to Ready */
1771 husart
->State
= HAL_USART_STATE_READY
;
1773 /* Reset Handle ErrorCode to No Error */
1774 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1780 * @brief Abort ongoing transfers (Interrupt mode).
1781 * @param husart USART handle.
1782 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1783 * This procedure performs following operations :
1784 * - Disable USART Interrupts (Tx and Rx)
1785 * - Disable the DMA transfer in the peripheral register (if enabled)
1786 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1787 * - Set handle State to READY
1788 * - At abort completion, call user abort complete callback
1789 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1790 * considered as completed only when user abort complete callback is executed (not when exiting function).
1791 * @retval HAL status
1793 HAL_StatusTypeDef
HAL_USART_Abort_IT(USART_HandleTypeDef
*husart
)
1795 uint32_t abortcplt
= 1U;
1797 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
| USART_CR1_TXEIE
| USART_CR1_TCIE
));
1798 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1800 /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
1801 before any call to DMA Abort functions */
1802 /* DMA Tx Handle is valid */
1803 if (husart
->hdmatx
!= NULL
)
1805 /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
1806 Otherwise, set it to NULL */
1807 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1809 husart
->hdmatx
->XferAbortCallback
= USART_DMATxAbortCallback
;
1813 husart
->hdmatx
->XferAbortCallback
= NULL
;
1816 /* DMA Rx Handle is valid */
1817 if (husart
->hdmarx
!= NULL
)
1819 /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
1820 Otherwise, set it to NULL */
1821 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1823 husart
->hdmarx
->XferAbortCallback
= USART_DMARxAbortCallback
;
1827 husart
->hdmarx
->XferAbortCallback
= NULL
;
1831 /* Disable the USART DMA Tx request if enabled */
1832 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1834 /* Disable DMA Tx at USART level */
1835 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1837 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
1838 if (husart
->hdmatx
!= NULL
)
1840 /* USART Tx DMA Abort callback has already been initialised :
1841 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
1844 if (HAL_DMA_Abort_IT(husart
->hdmatx
) != HAL_OK
)
1846 husart
->hdmatx
->XferAbortCallback
= NULL
;
1855 /* Disable the USART DMA Rx request if enabled */
1856 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1858 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1860 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
1861 if (husart
->hdmarx
!= NULL
)
1863 /* USART Rx DMA Abort callback has already been initialised :
1864 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
1867 if (HAL_DMA_Abort_IT(husart
->hdmarx
) != HAL_OK
)
1869 husart
->hdmarx
->XferAbortCallback
= NULL
;
1879 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1880 if (abortcplt
== 1U)
1882 /* Reset Tx and Rx transfer counters */
1883 husart
->TxXferCount
= 0U;
1884 husart
->RxXferCount
= 0U;
1886 /* Reset errorCode */
1887 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1889 /* Clear the Error flags in the ICR register */
1890 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
1893 /* Discard the received data */
1894 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
1896 /* Restore husart->State to Ready */
1897 husart
->State
= HAL_USART_STATE_READY
;
1899 /* As no DMA to be aborted, call directly user Abort complete callback */
1900 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
1901 /* Call registered Abort Complete Callback */
1902 husart
->AbortCpltCallback(husart
);
1904 /* Call legacy weak Abort Complete Callback */
1905 HAL_USART_AbortCpltCallback(husart
);
1906 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
1913 * @brief Handle USART interrupt request.
1914 * @param husart USART handle.
1917 void HAL_USART_IRQHandler(USART_HandleTypeDef
*husart
)
1919 uint32_t isrflags
= READ_REG(husart
->Instance
->ISR
);
1920 uint32_t cr1its
= READ_REG(husart
->Instance
->CR1
);
1921 uint32_t cr3its
= READ_REG(husart
->Instance
->CR3
);
1923 uint32_t errorflags
;
1926 /* If no error occurs */
1927 errorflags
= (isrflags
& (uint32_t)(USART_ISR_PE
| USART_ISR_FE
| USART_ISR_ORE
| USART_ISR_NE
));
1928 if (errorflags
== 0U)
1930 /* USART in mode Receiver ---------------------------------------------------*/
1931 if (((isrflags
& USART_ISR_RXNE
) != 0U)
1932 && ((cr1its
& USART_CR1_RXNEIE
) != 0U))
1934 if (husart
->RxISR
!= NULL
)
1936 husart
->RxISR(husart
);
1942 /* If some errors occur */
1943 if ((errorflags
!= 0U)
1944 && (((cr3its
& USART_CR3_EIE
) != 0U)
1945 || ((cr1its
& (USART_CR1_RXNEIE
| USART_CR1_PEIE
)) != 0U)))
1947 /* USART parity error interrupt occurred -------------------------------------*/
1948 if (((isrflags
& USART_ISR_PE
) != 0U) && ((cr1its
& USART_CR1_PEIE
) != 0U))
1950 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_PEF
);
1952 husart
->ErrorCode
|= HAL_USART_ERROR_PE
;
1955 /* USART frame error interrupt occurred --------------------------------------*/
1956 if (((isrflags
& USART_ISR_FE
) != 0U) && ((cr3its
& USART_CR3_EIE
) != 0U))
1958 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_FEF
);
1960 husart
->ErrorCode
|= HAL_USART_ERROR_FE
;
1963 /* USART noise error interrupt occurred --------------------------------------*/
1964 if (((isrflags
& USART_ISR_NE
) != 0U) && ((cr3its
& USART_CR3_EIE
) != 0U))
1966 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_NEF
);
1968 husart
->ErrorCode
|= HAL_USART_ERROR_NE
;
1971 /* USART Over-Run interrupt occurred -----------------------------------------*/
1972 if (((isrflags
& USART_ISR_ORE
) != 0U)
1973 && (((cr1its
& USART_CR1_RXNEIE
) != 0U) ||
1974 ((cr3its
& USART_CR3_EIE
) != 0U)))
1976 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_OREF
);
1978 husart
->ErrorCode
|= HAL_USART_ERROR_ORE
;
1982 /* Call USART Error Call back function if need be --------------------------*/
1983 if (husart
->ErrorCode
!= HAL_USART_ERROR_NONE
)
1985 /* USART in mode Receiver ---------------------------------------------------*/
1986 if (((isrflags
& USART_ISR_RXNE
) != 0U)
1987 && ((cr1its
& USART_CR1_RXNEIE
) != 0U))
1989 if (husart
->RxISR
!= NULL
)
1991 husart
->RxISR(husart
);
1995 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1996 consider error as blocking */
1997 errorcode
= husart
->ErrorCode
& HAL_USART_ERROR_ORE
;
1998 if ((HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
)) ||
2001 /* Blocking error : transfer is aborted
2002 Set the USART state ready to be able to start again the process,
2003 Disable Interrupts, and disable DMA requests, if ongoing */
2004 USART_EndTransfer(husart
);
2006 /* Disable the USART DMA Rx request if enabled */
2007 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
2009 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
| USART_CR3_DMAR
);
2011 /* Abort the USART DMA Tx channel */
2012 if (husart
->hdmatx
!= NULL
)
2014 /* Set the USART Tx DMA Abort callback to NULL : no callback
2015 executed at end of DMA abort procedure */
2016 husart
->hdmatx
->XferAbortCallback
= NULL
;
2019 (void)HAL_DMA_Abort_IT(husart
->hdmatx
);
2022 /* Abort the USART DMA Rx channel */
2023 if (husart
->hdmarx
!= NULL
)
2025 /* Set the USART Rx DMA Abort callback :
2026 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2027 husart
->hdmarx
->XferAbortCallback
= USART_DMAAbortOnError
;
2030 if (HAL_DMA_Abort_IT(husart
->hdmarx
) != HAL_OK
)
2032 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2033 husart
->hdmarx
->XferAbortCallback(husart
->hdmarx
);
2038 /* Call user error callback */
2039 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2040 /* Call registered Error Callback */
2041 husart
->ErrorCallback(husart
);
2043 /* Call legacy weak Error Callback */
2044 HAL_USART_ErrorCallback(husart
);
2045 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2050 /* Call user error callback */
2051 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2052 /* Call registered Error Callback */
2053 husart
->ErrorCallback(husart
);
2055 /* Call legacy weak Error Callback */
2056 HAL_USART_ErrorCallback(husart
);
2057 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2062 /* Non Blocking error : transfer could go on.
2063 Error is notified to user through user error callback */
2064 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2065 /* Call registered Error Callback */
2066 husart
->ErrorCallback(husart
);
2068 /* Call legacy weak Error Callback */
2069 HAL_USART_ErrorCallback(husart
);
2070 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2071 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2076 } /* End if some error occurs */
2079 /* USART in mode Transmitter ------------------------------------------------*/
2080 if (((isrflags
& USART_ISR_TXE
) != 0U)
2081 && ((cr1its
& USART_CR1_TXEIE
) != 0U))
2083 if (husart
->TxISR
!= NULL
)
2085 husart
->TxISR(husart
);
2090 /* USART in mode Transmitter (transmission end) -----------------------------*/
2091 if (((isrflags
& USART_ISR_TC
) != 0U) && ((cr1its
& USART_CR1_TCIE
) != 0U))
2093 USART_EndTransmit_IT(husart
);
2100 * @brief Tx Transfer completed callback.
2101 * @param husart USART handle.
2104 __weak
void HAL_USART_TxCpltCallback(USART_HandleTypeDef
*husart
)
2106 /* Prevent unused argument(s) compilation warning */
2109 /* NOTE : This function should not be modified, when the callback is needed,
2110 the HAL_USART_TxCpltCallback can be implemented in the user file.
2115 * @brief Tx Half Transfer completed callback.
2116 * @param husart USART handle.
2119 __weak
void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef
*husart
)
2121 /* Prevent unused argument(s) compilation warning */
2124 /* NOTE: This function should not be modified, when the callback is needed,
2125 the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2130 * @brief Rx Transfer completed callback.
2131 * @param husart USART handle.
2134 __weak
void HAL_USART_RxCpltCallback(USART_HandleTypeDef
*husart
)
2136 /* Prevent unused argument(s) compilation warning */
2139 /* NOTE: This function should not be modified, when the callback is needed,
2140 the HAL_USART_RxCpltCallback can be implemented in the user file.
2145 * @brief Rx Half Transfer completed callback.
2146 * @param husart USART handle.
2149 __weak
void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef
*husart
)
2151 /* Prevent unused argument(s) compilation warning */
2154 /* NOTE : This function should not be modified, when the callback is needed,
2155 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2160 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2161 * @param husart USART handle.
2164 __weak
void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef
*husart
)
2166 /* Prevent unused argument(s) compilation warning */
2169 /* NOTE : This function should not be modified, when the callback is needed,
2170 the HAL_USART_TxRxCpltCallback can be implemented in the user file
2175 * @brief USART error callback.
2176 * @param husart USART handle.
2179 __weak
void HAL_USART_ErrorCallback(USART_HandleTypeDef
*husart
)
2181 /* Prevent unused argument(s) compilation warning */
2184 /* NOTE : This function should not be modified, when the callback is needed,
2185 the HAL_USART_ErrorCallback can be implemented in the user file.
2190 * @brief USART Abort Complete callback.
2191 * @param husart USART handle.
2194 __weak
void HAL_USART_AbortCpltCallback(USART_HandleTypeDef
*husart
)
2196 /* Prevent unused argument(s) compilation warning */
2199 /* NOTE : This function should not be modified, when the callback is needed,
2200 the HAL_USART_AbortCpltCallback can be implemented in the user file.
2208 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2209 * @brief USART Peripheral State and Error functions
2212 ==============================================================================
2213 ##### Peripheral State and Error functions #####
2214 ==============================================================================
2216 This subsection provides functions allowing to :
2217 (+) Return the USART handle state
2218 (+) Return the USART handle error code
2226 * @brief Return the USART handle state.
2227 * @param husart pointer to a USART_HandleTypeDef structure that contains
2228 * the configuration information for the specified USART.
2229 * @retval USART handle state
2231 HAL_USART_StateTypeDef
HAL_USART_GetState(USART_HandleTypeDef
*husart
)
2233 return husart
->State
;
2237 * @brief Return the USART error code.
2238 * @param husart pointer to a USART_HandleTypeDef structure that contains
2239 * the configuration information for the specified USART.
2240 * @retval USART handle Error Code
2242 uint32_t HAL_USART_GetError(USART_HandleTypeDef
*husart
)
2244 return husart
->ErrorCode
;
2255 /** @defgroup USART_Private_Functions USART Private Functions
2260 * @brief Initialize the callbacks to their default values.
2261 * @param husart USART handle.
2264 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2265 void USART_InitCallbacksToDefault(USART_HandleTypeDef
*husart
)
2267 /* Init the USART Callback settings */
2268 husart
->TxHalfCpltCallback
= HAL_USART_TxHalfCpltCallback
; /* Legacy weak TxHalfCpltCallback */
2269 husart
->TxCpltCallback
= HAL_USART_TxCpltCallback
; /* Legacy weak TxCpltCallback */
2270 husart
->RxHalfCpltCallback
= HAL_USART_RxHalfCpltCallback
; /* Legacy weak RxHalfCpltCallback */
2271 husart
->RxCpltCallback
= HAL_USART_RxCpltCallback
; /* Legacy weak RxCpltCallback */
2272 husart
->TxRxCpltCallback
= HAL_USART_TxRxCpltCallback
; /* Legacy weak TxRxCpltCallback */
2273 husart
->ErrorCallback
= HAL_USART_ErrorCallback
; /* Legacy weak ErrorCallback */
2274 husart
->AbortCpltCallback
= HAL_USART_AbortCpltCallback
; /* Legacy weak AbortCpltCallback */
2276 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2279 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2280 * @param husart USART handle.
2283 static void USART_EndTransfer(USART_HandleTypeDef
*husart
)
2285 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2286 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
| USART_CR1_TXEIE
| USART_CR1_TCIE
));
2287 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
2289 /* At end of process, restore husart->State to Ready */
2290 husart
->State
= HAL_USART_STATE_READY
;
2294 * @brief DMA USART transmit process complete callback.
2295 * @param hdma DMA handle.
2298 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
)
2300 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2302 /* DMA Normal mode */
2303 if (hdma
->Init
.Mode
!= DMA_CIRCULAR
)
2305 husart
->TxXferCount
= 0U;
2307 if (husart
->State
== HAL_USART_STATE_BUSY_TX
)
2309 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2310 in the USART CR3 register */
2311 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
2313 /* Enable the USART Transmit Complete Interrupt */
2314 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
2317 /* DMA Circular mode */
2320 if (husart
->State
== HAL_USART_STATE_BUSY_TX
)
2322 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2323 /* Call registered Tx Complete Callback */
2324 husart
->TxCpltCallback(husart
);
2326 /* Call legacy weak Tx Complete Callback */
2327 HAL_USART_TxCpltCallback(husart
);
2328 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2334 * @brief DMA USART transmit process half complete callback.
2335 * @param hdma DMA handle.
2338 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
)
2340 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2342 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2343 /* Call registered Tx Half Complete Callback */
2344 husart
->TxHalfCpltCallback(husart
);
2346 /* Call legacy weak Tx Half Complete Callback */
2347 HAL_USART_TxHalfCpltCallback(husart
);
2348 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2352 * @brief DMA USART receive process complete callback.
2353 * @param hdma DMA handle.
2356 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
)
2358 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2360 /* DMA Normal mode */
2361 if (hdma
->Init
.Mode
!= DMA_CIRCULAR
)
2363 husart
->RxXferCount
= 0U;
2365 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2366 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
2367 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
2369 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2370 in USART CR3 register */
2371 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
2372 /* similarly, disable the DMA TX transfer that was started to provide the
2373 clock to the slave device */
2374 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
2376 if (husart
->State
== HAL_USART_STATE_BUSY_RX
)
2378 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2379 /* Call registered Rx Complete Callback */
2380 husart
->RxCpltCallback(husart
);
2382 /* Call legacy weak Rx Complete Callback */
2383 HAL_USART_RxCpltCallback(husart
);
2384 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2386 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2389 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2390 /* Call registered Tx Rx Complete Callback */
2391 husart
->TxRxCpltCallback(husart
);
2393 /* Call legacy weak Tx Rx Complete Callback */
2394 HAL_USART_TxRxCpltCallback(husart
);
2395 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2397 husart
->State
= HAL_USART_STATE_READY
;
2399 /* DMA circular mode */
2402 if (husart
->State
== HAL_USART_STATE_BUSY_RX
)
2404 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2405 /* Call registered Rx Complete Callback */
2406 husart
->RxCpltCallback(husart
);
2408 /* Call legacy weak Rx Complete Callback */
2409 HAL_USART_RxCpltCallback(husart
);
2410 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2412 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2415 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2416 /* Call registered Tx Rx Complete Callback */
2417 husart
->TxRxCpltCallback(husart
);
2419 /* Call legacy weak Tx Rx Complete Callback */
2420 HAL_USART_TxRxCpltCallback(husart
);
2421 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2427 * @brief DMA USART receive process half complete callback.
2428 * @param hdma DMA handle.
2431 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
)
2433 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2435 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2436 /* Call registered Rx Half Complete Callback */
2437 husart
->RxHalfCpltCallback(husart
);
2439 /* Call legacy weak Rx Half Complete Callback */
2440 HAL_USART_RxHalfCpltCallback(husart
);
2441 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2445 * @brief DMA USART communication error callback.
2446 * @param hdma DMA handle.
2449 static void USART_DMAError(DMA_HandleTypeDef
*hdma
)
2451 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2453 husart
->RxXferCount
= 0U;
2454 husart
->TxXferCount
= 0U;
2455 USART_EndTransfer(husart
);
2457 husart
->ErrorCode
|= HAL_USART_ERROR_DMA
;
2458 husart
->State
= HAL_USART_STATE_READY
;
2460 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2461 /* Call registered Error Callback */
2462 husart
->ErrorCallback(husart
);
2464 /* Call legacy weak Error Callback */
2465 HAL_USART_ErrorCallback(husart
);
2466 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2470 * @brief DMA USART communication abort callback, when initiated by HAL services on Error
2471 * (To be called at end of DMA Abort procedure following error occurrence).
2472 * @param hdma DMA handle.
2475 static void USART_DMAAbortOnError(DMA_HandleTypeDef
*hdma
)
2477 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2478 husart
->RxXferCount
= 0U;
2479 husart
->TxXferCount
= 0U;
2481 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2482 /* Call registered Error Callback */
2483 husart
->ErrorCallback(husart
);
2485 /* Call legacy weak Error Callback */
2486 HAL_USART_ErrorCallback(husart
);
2487 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2491 * @brief DMA USART Tx communication abort callback, when initiated by user
2492 * (To be called at end of DMA Tx Abort procedure following user abort request).
2493 * @note When this callback is executed, User Abort complete call back is called only if no
2494 * Abort still ongoing for Rx DMA Handle.
2495 * @param hdma DMA handle.
2498 static void USART_DMATxAbortCallback(DMA_HandleTypeDef
*hdma
)
2500 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2502 husart
->hdmatx
->XferAbortCallback
= NULL
;
2504 /* Check if an Abort process is still ongoing */
2505 if (husart
->hdmarx
!= NULL
)
2507 if (husart
->hdmarx
->XferAbortCallback
!= NULL
)
2513 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2514 husart
->TxXferCount
= 0U;
2515 husart
->RxXferCount
= 0U;
2517 /* Reset errorCode */
2518 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2520 /* Clear the Error flags in the ICR register */
2521 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
2523 /* Restore husart->State to Ready */
2524 husart
->State
= HAL_USART_STATE_READY
;
2526 /* Call user Abort complete callback */
2527 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2528 /* Call registered Abort Complete Callback */
2529 husart
->AbortCpltCallback(husart
);
2531 /* Call legacy weak Abort Complete Callback */
2532 HAL_USART_AbortCpltCallback(husart
);
2533 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2539 * @brief DMA USART Rx communication abort callback, when initiated by user
2540 * (To be called at end of DMA Rx Abort procedure following user abort request).
2541 * @note When this callback is executed, User Abort complete call back is called only if no
2542 * Abort still ongoing for Tx DMA Handle.
2543 * @param hdma DMA handle.
2546 static void USART_DMARxAbortCallback(DMA_HandleTypeDef
*hdma
)
2548 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2550 husart
->hdmarx
->XferAbortCallback
= NULL
;
2552 /* Check if an Abort process is still ongoing */
2553 if (husart
->hdmatx
!= NULL
)
2555 if (husart
->hdmatx
->XferAbortCallback
!= NULL
)
2561 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2562 husart
->TxXferCount
= 0U;
2563 husart
->RxXferCount
= 0U;
2565 /* Reset errorCode */
2566 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2568 /* Clear the Error flags in the ICR register */
2569 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
2571 /* Restore husart->State to Ready */
2572 husart
->State
= HAL_USART_STATE_READY
;
2574 /* Call user Abort complete callback */
2575 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2576 /* Call registered Abort Complete Callback */
2577 husart
->AbortCpltCallback(husart
);
2579 /* Call legacy weak Abort Complete Callback */
2580 HAL_USART_AbortCpltCallback(husart
);
2581 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2586 * @brief Handle USART Communication Timeout.
2587 * @param husart USART handle.
2588 * @param Flag Specifies the USART flag to check.
2589 * @param Status the Flag status (SET or RESET).
2590 * @param Tickstart Tick start value
2591 * @param Timeout timeout duration.
2592 * @retval HAL status
2594 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
, uint32_t Tickstart
, uint32_t Timeout
)
2596 /* Wait until flag is set */
2597 while ((__HAL_USART_GET_FLAG(husart
, Flag
) ? SET
: RESET
) == Status
)
2599 /* Check for the Timeout */
2600 if (Timeout
!= HAL_MAX_DELAY
)
2602 if (((HAL_GetTick() - Tickstart
) > Timeout
) || (Timeout
== 0U))
2604 husart
->State
= HAL_USART_STATE_READY
;
2606 /* Process Unlocked */
2607 __HAL_UNLOCK(husart
);
2617 * @brief Configure the USART peripheral.
2618 * @param husart USART handle.
2619 * @retval HAL status
2621 static HAL_StatusTypeDef
USART_SetConfig(USART_HandleTypeDef
*husart
)
2624 USART_ClockSourceTypeDef clocksource
;
2625 HAL_StatusTypeDef ret
= HAL_OK
;
2627 uint32_t usartdiv
= 0x00000000;
2629 /* Check the parameters */
2630 assert_param(IS_USART_POLARITY(husart
->Init
.CLKPolarity
));
2631 assert_param(IS_USART_PHASE(husart
->Init
.CLKPhase
));
2632 assert_param(IS_USART_LASTBIT(husart
->Init
.CLKLastBit
));
2633 assert_param(IS_USART_BAUDRATE(husart
->Init
.BaudRate
));
2634 assert_param(IS_USART_WORD_LENGTH(husart
->Init
.WordLength
));
2635 assert_param(IS_USART_STOPBITS(husart
->Init
.StopBits
));
2636 assert_param(IS_USART_PARITY(husart
->Init
.Parity
));
2637 assert_param(IS_USART_MODE(husart
->Init
.Mode
));
2639 /*-------------------------- USART CR1 Configuration -----------------------*/
2640 /* Clear M, PCE, PS, TE and RE bits and configure
2641 * the USART Word Length, Parity and Mode:
2642 * set the M bits according to husart->Init.WordLength value
2643 * set PCE and PS bits according to husart->Init.Parity value
2644 * set TE and RE bits according to husart->Init.Mode value
2645 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
2646 tmpreg
= (uint32_t)husart
->Init
.WordLength
| husart
->Init
.Parity
| husart
->Init
.Mode
| USART_CR1_OVER8
;
2647 MODIFY_REG(husart
->Instance
->CR1
, USART_CR1_FIELDS
, tmpreg
);
2649 /*---------------------------- USART CR2 Configuration ---------------------*/
2650 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
2651 * set CPOL bit according to husart->Init.CLKPolarity value
2652 * set CPHA bit according to husart->Init.CLKPhase value
2653 * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
2654 * set STOP[13:12] bits according to husart->Init.StopBits value */
2655 tmpreg
= (uint32_t)(USART_CLOCK_ENABLE
);
2656 tmpreg
|= (uint32_t)husart
->Init
.CLKLastBit
;
2657 tmpreg
|= ((uint32_t)husart
->Init
.CLKPolarity
| (uint32_t)husart
->Init
.CLKPhase
);
2658 tmpreg
|= (uint32_t)husart
->Init
.StopBits
;
2659 MODIFY_REG(husart
->Instance
->CR2
, USART_CR2_FIELDS
, tmpreg
);
2662 /*-------------------------- USART BRR Configuration -----------------------*/
2663 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
2664 USART_GETCLOCKSOURCE(husart
, clocksource
);
2666 switch (clocksource
)
2668 case USART_CLOCKSOURCE_PCLK1
:
2669 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), husart
->Init
.BaudRate
));
2671 case USART_CLOCKSOURCE_PCLK2
:
2672 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), husart
->Init
.BaudRate
));
2674 case USART_CLOCKSOURCE_HSI
:
2675 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE
, husart
->Init
.BaudRate
));
2677 case USART_CLOCKSOURCE_SYSCLK
:
2678 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), husart
->Init
.BaudRate
));
2680 case USART_CLOCKSOURCE_LSE
:
2681 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE
, husart
->Init
.BaudRate
));
2688 /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
2689 if ((usartdiv
>= USART_BRR_MIN
) && (usartdiv
<= USART_BRR_MAX
))
2691 brrtemp
= (uint16_t)(usartdiv
& 0xFFF0U
);
2692 brrtemp
|= (uint16_t)((usartdiv
& (uint16_t)0x000FU
) >> 1U);
2693 husart
->Instance
->BRR
= brrtemp
;
2701 /* Clear ISR function pointers */
2702 husart
->RxISR
= NULL
;
2703 husart
->TxISR
= NULL
;
2709 * @brief Check the USART Idle State.
2710 * @param husart USART handle.
2711 * @retval HAL status
2713 static HAL_StatusTypeDef
USART_CheckIdleState(USART_HandleTypeDef
*husart
)
2717 /* Initialize the USART ErrorCode */
2718 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2720 /* Init tickstart for timeout managment*/
2721 tickstart
= HAL_GetTick();
2723 /* Check if the Transmitter is enabled */
2724 if ((husart
->Instance
->CR1
& USART_CR1_TE
) == USART_CR1_TE
)
2726 /* Wait until TEACK flag is set */
2727 if (USART_WaitOnFlagUntilTimeout(husart
, USART_ISR_TEACK
, RESET
, tickstart
, USART_TEACK_REACK_TIMEOUT
) != HAL_OK
)
2729 /* Timeout occurred */
2734 /* Initialize the USART state*/
2735 husart
->State
= HAL_USART_STATE_READY
;
2737 /* Process Unlocked */
2738 __HAL_UNLOCK(husart
);
2744 * @brief Simplex send an amount of data in non-blocking mode.
2745 * @note Function called under interruption only, once
2746 * interruptions have been enabled by HAL_USART_Transmit_IT().
2747 * @note The USART errors are not managed to avoid the overrun error.
2748 * @note ISR function executed when data word length is less than 9 bits long.
2749 * @param husart USART handle.
2752 static void USART_TxISR_8BIT(USART_HandleTypeDef
*husart
)
2754 const HAL_USART_StateTypeDef state
= husart
->State
;
2756 /* Check that a Tx process is ongoing */
2757 if ((state
== HAL_USART_STATE_BUSY_TX
) ||
2758 (state
== HAL_USART_STATE_BUSY_TX_RX
))
2760 if (husart
->TxXferCount
== 0U)
2762 /* Disable the USART Transmit data register empty interrupt */
2763 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
2765 /* Enable the USART Transmit Complete Interrupt */
2766 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
2770 husart
->Instance
->TDR
= (uint8_t)(*husart
->pTxBuffPtr
& (uint8_t)0xFF);
2771 husart
->pTxBuffPtr
++;
2772 husart
->TxXferCount
--;
2778 * @brief Simplex send an amount of data in non-blocking mode.
2779 * @note Function called under interruption only, once
2780 * interruptions have been enabled by HAL_USART_Transmit_IT().
2781 * @note The USART errors are not managed to avoid the overrun error.
2782 * @note ISR function executed when data word length is 9 bits long.
2783 * @param husart USART handle.
2786 static void USART_TxISR_16BIT(USART_HandleTypeDef
*husart
)
2788 const HAL_USART_StateTypeDef state
= husart
->State
;
2791 if ((state
== HAL_USART_STATE_BUSY_TX
) ||
2792 (state
== HAL_USART_STATE_BUSY_TX_RX
))
2794 if (husart
->TxXferCount
== 0U)
2796 /* Disable the USART Transmit data register empty interrupt */
2797 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
2799 /* Enable the USART Transmit Complete Interrupt */
2800 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
2804 tmp
= (uint16_t *) husart
->pTxBuffPtr
;
2805 husart
->Instance
->TDR
= (uint16_t)(*tmp
& 0x01FFU
);
2806 husart
->pTxBuffPtr
+= 2U;
2807 husart
->TxXferCount
--;
2814 * @brief Wraps up transmission in non-blocking mode.
2815 * @param husart Pointer to a USART_HandleTypeDef structure that contains
2816 * the configuration information for the specified USART module.
2819 static void USART_EndTransmit_IT(USART_HandleTypeDef
*husart
)
2821 /* Disable the USART Transmit Complete Interrupt */
2822 __HAL_USART_DISABLE_IT(husart
, USART_IT_TC
);
2824 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
2825 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
2827 /* Clear TxISR function pointer */
2828 husart
->TxISR
= NULL
;
2830 if (husart
->State
== HAL_USART_STATE_BUSY_TX
)
2832 /* Clear overrun flag and discard the received data */
2833 __HAL_USART_CLEAR_OREFLAG(husart
);
2834 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
2836 /* Tx process is completed, restore husart->State to Ready */
2837 husart
->State
= HAL_USART_STATE_READY
;
2839 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2840 /* Call registered Tx Complete Callback */
2841 husart
->TxCpltCallback(husart
);
2843 /* Call legacy weak Tx Complete Callback */
2844 HAL_USART_TxCpltCallback(husart
);
2845 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2847 else if (husart
->RxXferCount
== 0U)
2849 /* TxRx process is completed, restore husart->State to Ready */
2850 husart
->State
= HAL_USART_STATE_READY
;
2852 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2853 /* Call registered Tx Rx Complete Callback */
2854 husart
->TxRxCpltCallback(husart
);
2856 /* Call legacy weak Tx Rx Complete Callback */
2857 HAL_USART_TxRxCpltCallback(husart
);
2858 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2868 * @brief Simplex receive an amount of data in non-blocking mode.
2869 * @note Function called under interruption only, once
2870 * interruptions have been enabled by HAL_USART_Receive_IT().
2871 * @note ISR function executed when data word length is less than 9 bits long.
2872 * @param husart USART handle
2875 static void USART_RxISR_8BIT(USART_HandleTypeDef
*husart
)
2877 const HAL_USART_StateTypeDef state
= husart
->State
;
2878 uint16_t txdatacount
;
2879 uint16_t uhMask
= husart
->Mask
;
2881 if ((state
== HAL_USART_STATE_BUSY_RX
) ||
2882 (state
== HAL_USART_STATE_BUSY_TX_RX
))
2884 *husart
->pRxBuffPtr
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)uhMask
);
2885 husart
->pRxBuffPtr
++;
2886 husart
->RxXferCount
--;
2888 if (husart
->RxXferCount
== 0U)
2890 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
2891 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
));
2893 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
2894 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
2896 /* Clear RxISR function pointer */
2897 husart
->RxISR
= NULL
;
2899 /* txdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
2900 txdatacount
= husart
->TxXferCount
;
2902 if (state
== HAL_USART_STATE_BUSY_RX
)
2905 /* Rx process is completed, restore husart->State to Ready */
2906 husart
->State
= HAL_USART_STATE_READY
;
2908 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2909 /* Call registered Rx Complete Callback */
2910 husart
->RxCpltCallback(husart
);
2912 /* Call legacy weak Rx Complete Callback */
2913 HAL_USART_RxCpltCallback(husart
);
2914 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2916 else if ((READ_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
) != USART_CR1_TCIE
) &&
2917 (txdatacount
== 0U))
2919 /* TxRx process is completed, restore husart->State to Ready */
2920 husart
->State
= HAL_USART_STATE_READY
;
2922 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2923 /* Call registered Tx Rx Complete Callback */
2924 husart
->TxRxCpltCallback(husart
);
2926 /* Call legacy weak Tx Rx Complete Callback */
2927 HAL_USART_TxRxCpltCallback(husart
);
2928 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2935 else if (state
== HAL_USART_STATE_BUSY_RX
)
2937 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
2938 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
2948 * @brief Simplex receive an amount of data in non-blocking mode.
2949 * @note Function called under interruption only, once
2950 * interruptions have been enabled by HAL_USART_Receive_IT().
2951 * @note ISR function executed when data word length is 9 bits long.
2952 * @param husart USART handle
2955 static void USART_RxISR_16BIT(USART_HandleTypeDef
*husart
)
2957 const HAL_USART_StateTypeDef state
= husart
->State
;
2958 uint16_t txdatacount
;
2960 uint16_t uhMask
= husart
->Mask
;
2962 if ((state
== HAL_USART_STATE_BUSY_RX
) ||
2963 (state
== HAL_USART_STATE_BUSY_TX_RX
))
2965 tmp
= (uint16_t *) husart
->pRxBuffPtr
;
2966 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
2967 husart
->pRxBuffPtr
+= 2U;
2968 husart
->RxXferCount
--;
2970 if (husart
->RxXferCount
== 0U)
2972 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
2973 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
));
2975 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
2976 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
2978 /* Clear RxISR function pointer */
2979 husart
->RxISR
= NULL
;
2981 /* txdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
2982 txdatacount
= husart
->TxXferCount
;
2984 if (state
== HAL_USART_STATE_BUSY_RX
)
2987 /* Rx process is completed, restore husart->State to Ready */
2988 husart
->State
= HAL_USART_STATE_READY
;
2990 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2991 /* Call registered Rx Complete Callback */
2992 husart
->RxCpltCallback(husart
);
2994 /* Call legacy weak Rx Complete Callback */
2995 HAL_USART_RxCpltCallback(husart
);
2996 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2998 else if ((READ_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
) != USART_CR1_TCIE
) &&
2999 (txdatacount
== 0U))
3001 /* TxRx process is completed, restore husart->State to Ready */
3002 husart
->State
= HAL_USART_STATE_READY
;
3004 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3005 /* Call registered Tx Rx Complete Callback */
3006 husart
->TxRxCpltCallback(husart
);
3008 /* Call legacy weak Tx Rx Complete Callback */
3009 HAL_USART_TxRxCpltCallback(husart
);
3010 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3017 else if (state
== HAL_USART_STATE_BUSY_RX
)
3019 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3020 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3034 #endif /* HAL_USART_MODULE_ENABLED */
3043 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/