2 ******************************************************************************
3 * @file stm32f7xx_hal_usart.c
4 * @author MCD Application Team
7 * @brief USART HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
11 * + Initialization and de-initialization functions
12 * + IO operation functions
13 * + Peripheral Control functions
16 ===============================================================================
17 ##### How to use this driver #####
18 ===============================================================================
20 The USART HAL driver can be used as follows:
22 (#) Declare a USART_HandleTypeDef handle structure.
23 (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API:
24 (##) Enable the USARTx interface clock.
25 (##) USART pins configuration:
26 (+++) Enable the clock for the USART GPIOs.
27 (+++) Configure these USART pins as alternate function pull-up.
28 (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
29 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
30 (+++) Configure the USARTx interrupt priority.
31 (+++) Enable the NVIC USART IRQ handle.
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_IT() and HAL_USART_TransmitReceive_IT() APIs):
37 (+++) Declare a DMA handle structure for the Tx/Rx stream.
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 Stream.
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 Stream.
44 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
45 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
47 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
48 (++) These API's configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
49 by calling the customed HAL_USART_MspInit(&husart) API.
52 ******************************************************************************
55 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
57 * Redistribution and use in source and binary forms, with or without modification,
58 * are permitted provided that the following conditions are met:
59 * 1. Redistributions of source code must retain the above copyright notice,
60 * this list of conditions and the following disclaimer.
61 * 2. Redistributions in binary form must reproduce the above copyright notice,
62 * this list of conditions and the following disclaimer in the documentation
63 * and/or other materials provided with the distribution.
64 * 3. Neither the name of STMicroelectronics nor the names of its contributors
65 * may be used to endorse or promote products derived from this software
66 * without specific prior written permission.
68 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
69 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
72 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
73 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
74 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
75 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
76 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
77 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79 ******************************************************************************
82 /* Includes ------------------------------------------------------------------*/
83 #include "stm32f7xx_hal.h"
85 /** @addtogroup STM32F7xx_HAL_Driver
89 /** @defgroup USART USART
90 * @brief HAL USART Synchronous module driver
94 #ifdef HAL_USART_MODULE_ENABLED
96 /* Private typedef -----------------------------------------------------------*/
97 /* Private define ------------------------------------------------------------*/
98 /** @addtogroup USART_Private_Constants
101 #define DUMMY_DATA ((uint16_t) 0xFFFFU)
102 #define TEACK_REACK_TIMEOUT ((uint32_t) 1000U)
103 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
104 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
105 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
106 USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP))
110 /* Private macro -------------------------------------------------------------*/
111 /* Private variables ---------------------------------------------------------*/
112 /* Private function prototypes -----------------------------------------------*/
113 /* Private functions ---------------------------------------------------------*/
114 /** @addtogroup USART_Private_Functions
117 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
);
118 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
);
119 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
);
120 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
);
121 static void USART_DMAError(DMA_HandleTypeDef
*hdma
);
122 static void USART_DMAAbortOnError(DMA_HandleTypeDef
*hdma
);
123 static void USART_EndTxTransfer(USART_HandleTypeDef
*husart
);
124 static void USART_EndRxTransfer(USART_HandleTypeDef
*husart
);
125 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
, uint32_t Tickstart
, uint32_t Timeout
);
126 static HAL_StatusTypeDef
USART_SetConfig(USART_HandleTypeDef
*husart
);
127 static HAL_StatusTypeDef
USART_CheckIdleState(USART_HandleTypeDef
*husart
);
128 static HAL_StatusTypeDef
USART_Transmit_IT(USART_HandleTypeDef
*husart
);
129 static HAL_StatusTypeDef
USART_EndTransmit_IT(USART_HandleTypeDef
*husart
);
130 static HAL_StatusTypeDef
USART_Receive_IT(USART_HandleTypeDef
*husart
);
131 static HAL_StatusTypeDef
USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
);
137 /* Exported functions --------------------------------------------------------*/
139 /** @defgroup USART_Exported_Functions USART Exported Functions
143 /** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
144 * @brief Initialization and Configuration functions
147 ===============================================================================
148 ##### Initialization and Configuration functions #####
149 ===============================================================================
151 This subsection provides a set of functions allowing to initialize the USART
152 in asynchronous and in synchronous modes.
153 (+) For the asynchronous mode only these parameters can be configured:
157 (++) Parity: If the parity is enabled, then the MSB bit of the data written
158 in the data register is transmitted but is changed by the parity bit.
162 (++) Receiver/transmitter modes
165 The HAL_USART_Init() function follows the USART synchronous configuration
166 procedure (details for the procedure are available in reference manual).
170 Depending on the frame length defined by the M1 and M0 bits (7-bit,
171 8-bit or 9-bit), the possible USART frame formats are as listed in the
174 +---------------------------------------------------------------+
175 | M1M0 bits | PCE bit | USART frame |
176 |-----------------------|---------------------------------------|
177 | 10 | 0 | | SB | 7-bit data | STB | |
178 |-----------|-----------|---------------------------------------|
179 | 10 | 1 | | SB | 6-bit data | PB | STB | |
180 +---------------------------------------------------------------+
186 * @brief Initializes the USART mode according to the specified
187 * parameters in the USART_InitTypeDef and create the associated handle.
188 * @param husart: USART handle
191 HAL_StatusTypeDef
HAL_USART_Init(USART_HandleTypeDef
*husart
)
193 /* Check the USART handle allocation */
199 /* Check the parameters */
200 assert_param(IS_USART_INSTANCE(husart
->Instance
));
202 if(husart
->State
== HAL_USART_STATE_RESET
)
204 /* Allocate lock resource and initialize it */
205 husart
->Lock
= HAL_UNLOCKED
;
206 /* Init the low level hardware : GPIO, CLOCK */
207 HAL_USART_MspInit(husart
);
210 husart
->State
= HAL_USART_STATE_BUSY
;
212 /* Disable the Peripheral */
213 __HAL_USART_DISABLE(husart
);
215 /* Set the Usart Communication parameters */
216 if (USART_SetConfig(husart
) == HAL_ERROR
)
221 /* In Synchronous mode, the following bits must be kept cleared:
222 - LINEN bit in the USART_CR2 register
223 - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
224 CLEAR_BIT(husart
->Instance
->CR2
, (USART_CR2_LINEN
| USART_CR2_CLKEN
));
225 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_SCEN
| USART_CR3_HDSEL
| USART_CR3_IREN
));
227 /* Enable the Peripheral */
228 __HAL_USART_ENABLE(husart
);
230 /* TEACK and/or REACK to check before moving husart->State to Ready */
231 return (USART_CheckIdleState(husart
));
235 * @brief DeInitializes the USART peripheral
236 * @param husart: USART handle
239 HAL_StatusTypeDef
HAL_USART_DeInit(USART_HandleTypeDef
*husart
)
241 /* Check the USART handle allocation */
247 /* Check the parameters */
248 assert_param(IS_USART_INSTANCE(husart
->Instance
));
250 husart
->State
= HAL_USART_STATE_BUSY
;
252 husart
->Instance
->CR1
= 0x0U
;
253 husart
->Instance
->CR2
= 0x0U
;
254 husart
->Instance
->CR3
= 0x0U
;
256 /* DeInit the low level hardware */
257 HAL_USART_MspDeInit(husart
);
259 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
260 husart
->State
= HAL_USART_STATE_RESET
;
263 __HAL_UNLOCK(husart
);
269 * @brief USART MSP Init
270 * @param husart: USART handle
273 __weak
void HAL_USART_MspInit(USART_HandleTypeDef
*husart
)
275 /* Prevent unused argument(s) compilation warning */
278 /* NOTE : This function should not be modified, when the callback is needed,
279 the HAL_USART_MspInit can be implemented in the user file
284 * @brief USART MSP DeInit
285 * @param husart: USART handle
288 __weak
void HAL_USART_MspDeInit(USART_HandleTypeDef
*husart
)
290 /* Prevent unused argument(s) compilation warning */
293 /* NOTE : This function should not be modified, when the callback is needed,
294 the HAL_USART_MspDeInit can be implemented in the user file
302 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
303 * @brief USART Transmit and Receive functions
306 ===============================================================================
307 ##### IO operation functions #####
308 ===============================================================================
309 This subsection provides a set of functions allowing to manage the USART synchronous
312 [..] The USART supports master mode only: it cannot receive or send data related to an input
313 clock (SCLK is always an output).
315 (#) There are two mode of transfer:
316 (++) Blocking mode: The communication is performed in polling mode.
317 The HAL status of all data processing is returned by the same function
318 after finishing transfer.
319 (++) No-Blocking mode: The communication is performed using Interrupts
320 or DMA, These API's return the HAL status.
321 The end of the data processing will be indicated through the
322 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
324 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
325 will be executed respectively at the end of the transmit or Receive process
326 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
328 (#) Blocking mode API's are :
329 (++) HAL_USART_Transmit()in simplex mode
330 (++) HAL_USART_Receive() in full duplex receive only
331 (++) HAL_USART_TransmitReceive() in full duplex mode
333 (#) Non-Blocking mode API's with Interrupt are :
334 (++) HAL_USART_Transmit_IT()in simplex mode
335 (++) HAL_USART_Receive_IT() in full duplex receive only
336 (++) HAL_USART_TransmitReceive_IT()in full duplex mode
337 (++) HAL_USART_IRQHandler()
339 (#) No-Blocking mode functions with DMA are :
340 (++) HAL_USART_Transmit_DMA()in simplex mode
341 (++) HAL_USART_Receive_DMA() in full duplex receive only
342 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
343 (++) HAL_USART_DMAPause()
344 (++) HAL_USART_DMAResume()
345 (++) HAL_USART_DMAStop()
347 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
348 (++) HAL_USART_TxCpltCallback()
349 (++) HAL_USART_RxCpltCallback()
350 (++) HAL_USART_TxHalfCpltCallback()
351 (++) HAL_USART_RxHalfCpltCallback()
352 (++) HAL_USART_ErrorCallback()
353 (++) HAL_USART_TxRxCpltCallback()
360 * @brief Simplex Send an amount of data in blocking mode
361 * @param husart: USART handle
362 * @param pTxData: pointer to data buffer
363 * @param Size: amount of data to be sent
364 * @param Timeout : Timeout duration
367 HAL_StatusTypeDef
HAL_USART_Transmit(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
, uint32_t Timeout
)
370 uint32_t tickstart
= 0U;
372 if(husart
->State
== HAL_USART_STATE_READY
)
374 if((pTxData
== NULL
) || (Size
== 0U))
382 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
383 husart
->State
= HAL_USART_STATE_BUSY_TX
;
385 /* Init tickstart for timeout managment*/
386 tickstart
= HAL_GetTick();
388 husart
->TxXferSize
= Size
;
389 husart
->TxXferCount
= Size
;
391 /* Check the remaining data to be sent */
392 while(husart
->TxXferCount
> 0U)
394 husart
->TxXferCount
--;
395 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, tickstart
, Timeout
) != HAL_OK
)
399 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
401 tmp
= (uint16_t*) pTxData
;
402 husart
->Instance
->TDR
= (*tmp
& (uint16_t)0x01FFU
);
407 husart
->Instance
->TDR
= (*pTxData
++ & (uint8_t)0xFFU
);
411 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, tickstart
, Timeout
) != HAL_OK
)
416 husart
->State
= HAL_USART_STATE_READY
;
418 /* Process Unlocked */
419 __HAL_UNLOCK(husart
);
430 * @brief Receive an amount of data in blocking mode
431 * @note To receive synchronous data, dummy data are simultaneously transmitted
432 * @param husart: USART handle
433 * @param pRxData: pointer to data buffer
434 * @param Size: amount of data to be received
435 * @param Timeout : Timeout duration
438 HAL_StatusTypeDef
HAL_USART_Receive(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
442 uint32_t tickstart
= 0U;
444 if(husart
->State
== HAL_USART_STATE_READY
)
446 if((pRxData
== NULL
) || (Size
== 0U))
453 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
454 husart
->State
= HAL_USART_STATE_BUSY_RX
;
456 /* Init tickstart for timeout managment*/
457 tickstart
= HAL_GetTick();
459 husart
->RxXferSize
= Size
;
460 husart
->RxXferCount
= Size
;
462 /* Computation of USART mask to apply to RDR register */
463 __HAL_USART_MASK_COMPUTATION(husart
);
464 uhMask
= husart
->Mask
;
466 /* as long as data have to be received */
467 while(husart
->RxXferCount
> 0U)
469 husart
->RxXferCount
--;
471 /* Wait until TC flag is set to send dummy byte in order to generate the
472 * clock for the slave to send data.
473 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
474 * can be written for all the cases. */
475 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, tickstart
, Timeout
) != HAL_OK
)
479 husart
->Instance
->TDR
= (DUMMY_DATA
& (uint16_t)0x0FFU
);
481 /* Wait for RXNE Flag */
482 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
487 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
489 tmp
= (uint16_t*) pRxData
;
490 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
495 *pRxData
++ = (uint8_t)(husart
->Instance
->RDR
& (uint8_t)uhMask
);
499 husart
->State
= HAL_USART_STATE_READY
;
501 /* Process Unlocked */
502 __HAL_UNLOCK(husart
);
513 * @brief Full-Duplex Send and Receive an amount of data in blocking mode
514 * @param husart: USART handle
515 * @param pTxData: pointer to TX data buffer
516 * @param pRxData: pointer to RX data buffer
517 * @param Size: amount of data to be sent (same amount to be received)
518 * @param Timeout : Timeout duration
521 HAL_StatusTypeDef
HAL_USART_TransmitReceive(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
525 uint32_t tickstart
= 0U;
527 if(husart
->State
== HAL_USART_STATE_READY
)
529 if((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
536 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
537 husart
->State
= HAL_USART_STATE_BUSY_RX
;
539 /* Init tickstart for timeout managment*/
540 tickstart
= HAL_GetTick();
542 husart
->RxXferSize
= Size
;
543 husart
->TxXferSize
= Size
;
544 husart
->TxXferCount
= Size
;
545 husart
->RxXferCount
= Size
;
547 /* Computation of USART mask to apply to RDR register */
548 __HAL_USART_MASK_COMPUTATION(husart
);
549 uhMask
= husart
->Mask
;
551 /* Check the remain data to be sent */
552 while(husart
->TxXferCount
> 0)
554 husart
->TxXferCount
--;
555 husart
->RxXferCount
--;
557 /* Wait until TC flag is set to send data */
558 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, tickstart
, Timeout
) != HAL_OK
)
562 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
564 tmp
= (uint16_t*) pTxData
;
565 husart
->Instance
->TDR
= (*tmp
& uhMask
);
570 husart
->Instance
->TDR
= (*pTxData
++ & (uint8_t)uhMask
);
573 /* Wait for RXNE Flag */
574 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
579 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
581 tmp
= (uint16_t*) pRxData
;
582 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
587 *pRxData
++ = (uint8_t)(husart
->Instance
->RDR
& (uint8_t)uhMask
);
591 husart
->State
= HAL_USART_STATE_READY
;
593 /* Process Unlocked */
594 __HAL_UNLOCK(husart
);
605 * @brief Send an amount of data in interrupt mode
606 * @param husart: USART handle
607 * @param pTxData: pointer to data buffer
608 * @param Size: amount of data to be sent
611 HAL_StatusTypeDef
HAL_USART_Transmit_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
613 if(husart
->State
== HAL_USART_STATE_READY
)
615 if((pTxData
== NULL
) || (Size
== 0U))
623 husart
->pTxBuffPtr
= pTxData
;
624 husart
->TxXferSize
= Size
;
625 husart
->TxXferCount
= Size
;
627 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
628 husart
->State
= HAL_USART_STATE_BUSY_TX
;
630 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
631 are not managed by the USART Transmit Process to avoid the overrun interrupt
632 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
633 to benefit for the frame error and noise interrupts the usart mode should be
634 configured only for transmit "USART_MODE_TX" */
636 /* Process Unlocked */
637 __HAL_UNLOCK(husart
);
639 /* Enable the USART Transmit Data Register Empty Interrupt */
640 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
651 * @brief Receive an amount of data in blocking mode
652 * To receive synchronous data, dummy data are simultaneously transmitted
653 * @param husart: USART handle
654 * @param pRxData: pointer to data buffer
655 * @param Size: amount of data to be received
658 HAL_StatusTypeDef
HAL_USART_Receive_IT(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
660 if(husart
->State
== HAL_USART_STATE_READY
)
662 if((pRxData
== NULL
) || (Size
== 0U))
669 husart
->pRxBuffPtr
= pRxData
;
670 husart
->RxXferSize
= Size
;
671 husart
->RxXferCount
= Size
;
673 __HAL_USART_MASK_COMPUTATION(husart
);
675 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
676 husart
->State
= HAL_USART_STATE_BUSY_RX
;
678 /* Enable the USART Parity Error Interrupt */
679 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
681 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
682 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
684 /* Enable the USART Data Register not empty Interrupt */
685 SET_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE
);
687 /* Process Unlocked */
688 __HAL_UNLOCK(husart
);
691 /* Send dummy byte in order to generate the clock for the Slave to send the next data */
692 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
694 husart
->Instance
->TDR
= (DUMMY_DATA
& (uint16_t)0x01FFU
);
698 husart
->Instance
->TDR
= (DUMMY_DATA
& (uint16_t)0x00FFU
);
710 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode
711 * @param husart: USART handle
712 * @param pTxData: pointer to TX data buffer
713 * @param pRxData: pointer to RX data buffer
714 * @param Size: amount of data to be sent (same amount to be received)
717 HAL_StatusTypeDef
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
)
720 if(husart
->State
== HAL_USART_STATE_READY
)
722 if((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
729 husart
->pRxBuffPtr
= pRxData
;
730 husart
->RxXferSize
= Size
;
731 husart
->RxXferCount
= Size
;
732 husart
->pTxBuffPtr
= pTxData
;
733 husart
->TxXferSize
= Size
;
734 husart
->TxXferCount
= Size
;
736 /* Computation of USART mask to apply to RDR register */
737 __HAL_USART_MASK_COMPUTATION(husart
);
739 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
740 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
742 /* Enable the USART Data Register not empty Interrupt */
743 SET_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE
);
745 /* Enable the USART Parity Error Interrupt */
746 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
748 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
749 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
751 /* Process Unlocked */
752 __HAL_UNLOCK(husart
);
754 /* Enable the USART Transmit Data Register Empty Interrupt */
755 __HAL_USART_ENABLE_IT(husart
, USART_IT_TXE
);
766 * @brief Send an amount of data in DMA mode
767 * @param husart: USART handle
768 * @param pTxData: pointer to data buffer
769 * @param Size: amount of data to be sent
772 HAL_StatusTypeDef
HAL_USART_Transmit_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
776 if(husart
->State
== HAL_USART_STATE_READY
)
778 if((pTxData
== NULL
) || (Size
== 0U))
785 husart
->pTxBuffPtr
= pTxData
;
786 husart
->TxXferSize
= Size
;
787 husart
->TxXferCount
= Size
;
789 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
790 husart
->State
= HAL_USART_STATE_BUSY_TX
;
792 /* Set the USART DMA transfer complete callback */
793 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
795 /* Set the USART DMA Half transfer complete callback */
796 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
798 /* Set the DMA error callback */
799 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
801 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
802 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
803 SET_BIT(husart
->Instance
->ISR
, (USART_ISR_PE
| USART_ISR_FE
| USART_ISR_NE
| USART_ISR_ORE
));
805 /* Enable the USART transmit DMA channel */
806 tmp
= (uint32_t*)&pTxData
;
807 HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
809 /* Clear the TC flag in the SR register by writing 0 to it */
810 __HAL_USART_CLEAR_IT(husart
, USART_FLAG_TC
);
812 /* Process Unlocked */
813 __HAL_UNLOCK(husart
);
815 /* Enable the DMA transfer for transmit request by setting the DMAT bit
816 in the USART CR3 register */
817 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
828 * @brief Receive an amount of data in DMA mode
829 * @param husart: USART handle
830 * @param pRxData: pointer to data buffer
831 * @param Size: amount of data to be received
832 * @note When the USART parity is enabled (PCE = 1), the received data contain
833 * the parity bit (MSB position)
835 * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave.
837 HAL_StatusTypeDef
HAL_USART_Receive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
841 if(husart
->State
== HAL_USART_STATE_READY
)
843 if((pRxData
== NULL
) || (Size
== 0U))
851 husart
->pRxBuffPtr
= pRxData
;
852 husart
->RxXferSize
= Size
;
853 husart
->pTxBuffPtr
= pRxData
;
854 husart
->TxXferSize
= Size
;
856 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
857 husart
->State
= HAL_USART_STATE_BUSY_RX
;
859 /* Set the USART DMA Rx transfer complete callback */
860 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
862 /* Set the USART DMA Half transfer complete callback */
863 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
865 /* Set the USART DMA Rx transfer error callback */
866 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
868 /* Set the DMA abort callback */
869 husart
->hdmatx
->XferAbortCallback
= NULL
;
871 /* Set the USART Tx DMA transfer complete callback as NULL because the communication closing
872 is performed in DMA reception complete callback */
873 husart
->hdmatx
->XferHalfCpltCallback
= NULL
;
874 husart
->hdmatx
->XferCpltCallback
= NULL
;
876 /* Set the DMA error callback */
877 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
879 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
880 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
881 SET_BIT(husart
->Instance
->ISR
, (USART_ISR_PE
| USART_ISR_FE
| USART_ISR_NE
| USART_ISR_ORE
));
883 /* Enable the USART receive DMA channel */
884 tmp
= (uint32_t*)&pRxData
;
885 HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->RDR
, *(uint32_t*)tmp
, Size
);
887 /* Enable the USART transmit DMA channel: the transmit stream is used in order
888 to generate in the non-blocking mode the clock to the slave device,
889 this mode isn't a simplex receive mode but a full-duplex receive mode */
890 HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
892 /* Process Unlocked */
893 __HAL_UNLOCK(husart
);
895 /* Enable the USART Parity Error Interrupt */
896 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
898 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
899 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
901 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
902 in the USART CR3 register */
903 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
905 /* Enable the DMA transfer for transmit request by setting the DMAT bit
906 in the USART CR3 register */
907 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
919 * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode
920 * @param husart: USART handle
921 * @param pTxData: pointer to TX data buffer
922 * @param pRxData: pointer to RX data buffer
923 * @param Size: amount of data to be received/sent
924 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
927 HAL_StatusTypeDef
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
)
931 if(husart
->State
== HAL_USART_STATE_READY
)
933 if((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
940 husart
->pRxBuffPtr
= pRxData
;
941 husart
->RxXferSize
= Size
;
942 husart
->pTxBuffPtr
= pTxData
;
943 husart
->TxXferSize
= Size
;
945 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
946 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
948 /* Set the USART DMA Rx transfer complete callback */
949 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
951 /* Set the USART DMA Half transfer complete callback */
952 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
954 /* Set the USART DMA Tx transfer complete callback */
955 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
957 /* Set the USART DMA Half transfer complete callback */
958 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
960 /* Set the USART DMA Tx transfer error callback */
961 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
963 /* Set the USART DMA Rx transfer error callback */
964 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
966 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
967 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
968 SET_BIT(husart
->Instance
->ISR
, (USART_ISR_PE
| USART_ISR_FE
| USART_ISR_NE
| USART_ISR_ORE
));
970 /* Enable the USART receive DMA channel */
971 tmp
= (uint32_t*)&pRxData
;
972 HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->RDR
, *(uint32_t*)tmp
, Size
);
974 /* Enable the USART transmit DMA channel */
975 tmp
= (uint32_t*)&pTxData
;
976 HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
978 /* Clear the TC flag in the SR register by writing 0 to it */
979 __HAL_USART_CLEAR_IT(husart
, USART_FLAG_TC
);
981 /* Process Unlocked */
982 __HAL_UNLOCK(husart
);
984 /* Enable the USART Parity Error Interrupt */
985 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
987 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
988 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
990 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
991 in the USART CR3 register */
992 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
994 /* Enable the DMA transfer for transmit request by setting the DMAT bit
995 in the USART CR3 register */
996 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1007 * @brief Pauses the DMA Transfer.
1008 * @param husart: USART handle
1011 HAL_StatusTypeDef
HAL_USART_DMAPause(USART_HandleTypeDef
*husart
)
1013 /* Process Locked */
1016 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1018 /* Disable the USART DMA Tx request */
1019 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1021 else if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1023 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1024 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
));
1025 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1026 /* Disable the USART DMA Rx request */
1027 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1029 else if(husart
->State
== HAL_USART_STATE_BUSY_TX_RX
)
1031 /* Disable the USART DMA Tx request */
1032 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1033 /* Disable the USART DMA Rx request */
1034 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1037 /* Process Unlocked */
1038 __HAL_UNLOCK(husart
);
1044 * @brief Resumes the DMA Transfer.
1045 * @param husart: USART handle
1048 HAL_StatusTypeDef
HAL_USART_DMAResume(USART_HandleTypeDef
*husart
)
1050 /* Process Locked */
1053 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1055 /* Enable the USART DMA Tx request */
1056 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1058 else if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1060 /* Clear the Overrun flag before resuming the Rx transfer*/
1061 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_OREF
);
1063 /* Reenable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1064 SET_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
));
1065 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1067 /* Enable the USART DMA Rx request */
1068 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1070 else if(husart
->State
== HAL_USART_STATE_BUSY_TX_RX
)
1072 /* Clear the Overrun flag before resuming the Rx transfer*/
1073 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_OREF
);
1075 /* Enable the USART DMA Rx request before the DMA Tx request */
1076 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1078 /* Enable the USART DMA Tx request */
1079 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1082 /* Process Unlocked */
1083 __HAL_UNLOCK(husart
);
1089 * @brief Stops the DMA Transfer.
1090 * @param husart: USART handle
1093 HAL_StatusTypeDef
HAL_USART_DMAStop(USART_HandleTypeDef
*husart
)
1095 /* The Lock is not implemented on this API to allow the user application
1096 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1097 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1098 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1099 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1100 the stream and the corresponding call back is executed. */
1102 /* Stop USART DMA Tx request if ongoing */
1103 if ((husart
->State
== HAL_USART_STATE_BUSY_TX
) &&
1104 (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
)))
1106 USART_EndTxTransfer(husart
);
1108 /* Abort the USART DMA Tx channel */
1109 if(husart
->hdmatx
!= NULL
)
1111 HAL_DMA_Abort(husart
->hdmatx
);
1114 /* Disable the USART Tx DMA request */
1115 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1118 /* Stop USART DMA Rx request if ongoing */
1119 if ((husart
->State
== HAL_USART_STATE_BUSY_RX
) &&
1120 (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
)))
1122 USART_EndRxTransfer(husart
);
1124 /* Abort the USART DMA Rx channel */
1125 if(husart
->hdmarx
!= NULL
)
1127 HAL_DMA_Abort(husart
->hdmarx
);
1130 /* Disable the USART Rx DMA request */
1131 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1138 * @brief This function handles USART interrupt request.
1139 * @param husart: USART handle
1142 void HAL_USART_IRQHandler(USART_HandleTypeDef
*husart
)
1144 uint32_t isrflags
= READ_REG(husart
->Instance
->ISR
);
1145 uint32_t cr1its
= READ_REG(husart
->Instance
->CR1
);
1146 uint32_t cr3its
= READ_REG(husart
->Instance
->CR3
);
1147 uint32_t errorflags
;
1149 /* If no error occurs */
1150 errorflags
= (isrflags
& (uint32_t)(USART_ISR_PE
| USART_ISR_FE
| USART_ISR_ORE
| USART_ISR_NE
));
1151 if (errorflags
== RESET
)
1153 /* USART in mode Receiver --------------------------------------------------*/
1154 if(((isrflags
& USART_ISR_RXNE
) != RESET
) && ((cr1its
& USART_CR1_RXNEIE
) != RESET
))
1156 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1158 USART_Receive_IT(husart
);
1162 USART_TransmitReceive_IT(husart
);
1167 /* If some errors occur */
1168 if((errorflags
!= RESET
) && ((cr3its
& (USART_CR3_EIE
| USART_CR1_PEIE
)) != RESET
))
1171 /* USART parity error interrupt occurred ------------------------------------*/
1172 if(((isrflags
& USART_ISR_PE
) != RESET
) && ((cr1its
& USART_CR1_PEIE
) != RESET
))
1174 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_PEF
);
1175 husart
->ErrorCode
|= HAL_USART_ERROR_PE
;
1178 /* USART frame error interrupt occurred -------------------------------------*/
1179 if(((isrflags
& USART_ISR_FE
) != RESET
) && ((cr3its
& USART_CR3_EIE
) != RESET
))
1181 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_FEF
);
1182 husart
->ErrorCode
|= HAL_USART_ERROR_FE
;
1185 /* USART noise error interrupt occurred -------------------------------------*/
1186 if(((isrflags
& USART_ISR_NE
) != RESET
) && ((cr3its
& USART_CR3_EIE
) != RESET
))
1188 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_NEF
);
1189 husart
->ErrorCode
|= HAL_USART_ERROR_NE
;
1192 /* USART Over-Run interrupt occurred ----------------------------------------*/
1193 if(((isrflags
& USART_ISR_ORE
) != RESET
) && ((cr3its
& USART_CR3_EIE
) != RESET
))
1195 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_OREF
);
1196 husart
->ErrorCode
|= HAL_USART_ERROR_ORE
;
1199 /* Call USART Error Call back function if need be --------------------------*/
1200 if(husart
->ErrorCode
!= HAL_USART_ERROR_NONE
)
1202 /* USART in mode Receiver ---------------------------------------------------*/
1203 if(((isrflags
& USART_ISR_RXNE
) != RESET
) && ((cr1its
& USART_CR1_RXNEIE
) != RESET
))
1205 USART_Receive_IT(husart
);
1208 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1209 consider error as blocking */
1210 if (((husart
->ErrorCode
& HAL_USART_ERROR_ORE
) != RESET
) ||
1211 (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
)))
1213 /* Blocking error : transfer is aborted
1214 Set the USART state ready to be able to start again the process,
1215 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
1216 USART_EndRxTransfer(husart
);
1218 /* Disable the USART DMA Rx request if enabled */
1219 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1221 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1223 /* Abort the USART DMA Rx channel */
1224 if(husart
->hdmarx
!= NULL
)
1226 /* Set the USART DMA Abort callback :
1227 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
1228 husart
->hdmarx
->XferAbortCallback
= USART_DMAAbortOnError
;
1231 if(HAL_DMA_Abort_IT(husart
->hdmarx
) != HAL_OK
)
1233 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
1234 husart
->hdmarx
->XferAbortCallback(husart
->hdmarx
);
1239 /* Call user error callback */
1240 HAL_USART_ErrorCallback(husart
);
1245 /* Call user error callback */
1246 HAL_USART_ErrorCallback(husart
);
1251 /* Non Blocking error : transfer could go on.
1252 Error is notified to user through user error callback */
1253 HAL_USART_ErrorCallback(husart
);
1254 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1259 } /* End if some error occurs */
1261 /* USART in mode Transmitter -----------------------------------------------*/
1262 if(((isrflags
& USART_ISR_TXE
) != RESET
) && ((cr1its
& USART_CR1_TXEIE
) != RESET
))
1264 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1266 USART_Transmit_IT(husart
);
1270 USART_TransmitReceive_IT(husart
);
1275 /* USART in mode Transmitter (transmission end) -----------------------------*/
1276 if(((isrflags
& USART_ISR_TC
) != RESET
) && ((cr1its
& USART_CR1_TCIE
) != RESET
))
1278 USART_EndTransmit_IT(husart
);
1284 * @brief Tx Transfer completed callbacks
1285 * @param husart: USART handle
1288 __weak
void HAL_USART_TxCpltCallback(USART_HandleTypeDef
*husart
)
1290 /* Prevent unused argument(s) compilation warning */
1293 /* NOTE : This function should not be modified, when the callback is needed,
1294 the HAL_USART_TxCpltCallback can be implemented in the user file
1299 * @brief Tx Half Transfer completed callbacks.
1300 * @param husart: USART handle
1303 __weak
void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef
*husart
)
1305 /* Prevent unused argument(s) compilation warning */
1308 /* NOTE: This function should not be modified, when the callback is needed,
1309 the HAL_USART_TxHalfCpltCallback can be implemented in the user file
1314 * @brief Rx Transfer completed callbacks.
1315 * @param husart: USART handle
1318 __weak
void HAL_USART_RxCpltCallback(USART_HandleTypeDef
*husart
)
1320 /* Prevent unused argument(s) compilation warning */
1323 /* NOTE: This function should not be modified, when the callback is needed,
1324 the HAL_USART_RxCpltCallback can be implemented in the user file
1329 * @brief Rx Half Transfer completed callbacks
1330 * @param husart: usart handle
1333 __weak
void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef
*husart
)
1335 /* Prevent unused argument(s) compilation warning */
1338 /* NOTE : This function should not be modified, when the callback is needed,
1339 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
1344 * @brief Tx/Rx Transfers completed callback for the non-blocking process
1345 * @param husart: USART handle
1348 __weak
void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef
*husart
)
1350 /* Prevent unused argument(s) compilation warning */
1353 /* NOTE : This function should not be modified, when the callback is needed,
1354 the HAL_USART_TxRxCpltCallback can be implemented in the user file
1359 * @brief USART error callbacks
1360 * @param husart: USART handle
1363 __weak
void HAL_USART_ErrorCallback(USART_HandleTypeDef
*husart
)
1365 /* Prevent unused argument(s) compilation warning */
1368 /* NOTE : This function should not be modified, when the callback is needed,
1369 the HAL_USART_ErrorCallback can be implemented in the user file
1377 /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
1378 * @brief USART State and Errors functions
1381 ==============================================================================
1382 ##### Peripheral State and Errors functions #####
1383 ==============================================================================
1385 This subsection provides a set of functions allowing to return the State of
1387 process, return Peripheral Errors occurred during communication process
1388 (+) HAL_USART_GetState() API can be helpful to check in run-time the state
1389 of the USART peripheral.
1390 (+) HAL_USART_GetError() check in run-time errors that could be occurred during
1397 * @brief return the USART state
1398 * @param husart: USART handle
1401 HAL_USART_StateTypeDef
HAL_USART_GetState(USART_HandleTypeDef
*husart
)
1403 return husart
->State
;
1407 * @brief Return the USART error code
1408 * @param husart : pointer to a USART_HandleTypeDef structure that contains
1409 * the configuration information for the specified USART.
1410 * @retval USART Error Code
1412 uint32_t HAL_USART_GetError(USART_HandleTypeDef
*husart
)
1414 return husart
->ErrorCode
;
1423 * @brief Simplex Send an amount of data in non-blocking mode.
1424 * @note Function called under interruption only, once
1425 * interruptions have been enabled by HAL_USART_Transmit_IT().
1426 * @param husart: USART handle
1427 * @retval HAL status
1428 * @note The USART errors are not managed to avoid the overrun error.
1430 static HAL_StatusTypeDef
USART_Transmit_IT(USART_HandleTypeDef
*husart
)
1434 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1437 if(husart
->TxXferCount
== 0U)
1439 /* Disable the USART Transmit data register empty interrupt */
1440 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
1442 /* Enable the USART Transmit Complete Interrupt */
1443 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
1449 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1451 tmp
= (uint16_t*) husart
->pTxBuffPtr
;
1452 husart
->Instance
->TDR
= (*tmp
& (uint16_t)0x01FFU
);
1453 husart
->pTxBuffPtr
+= 2U;
1457 husart
->Instance
->TDR
= (uint8_t)(*husart
->pTxBuffPtr
++ & (uint8_t)0xFF);
1460 husart
->TxXferCount
--;
1472 * @brief Wraps up transmission in non-blocking mode.
1473 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1474 * the configuration information for the specified USART module.
1475 * @retval HAL status
1477 static HAL_StatusTypeDef
USART_EndTransmit_IT(USART_HandleTypeDef
*husart
)
1479 /* Disable the USART Transmit Complete Interrupt */
1480 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
);
1482 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1483 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1485 husart
->State
= HAL_USART_STATE_READY
;
1487 HAL_USART_TxCpltCallback(husart
);
1493 * @brief Simplex Receive an amount of data in non-blocking mode.
1494 * Function called under interruption only, once
1495 * interruptions have been enabled by HAL_USART_Receive_IT()
1496 * @param husart: USART handle
1497 * @retval HAL status
1499 static HAL_StatusTypeDef
USART_Receive_IT(USART_HandleTypeDef
*husart
)
1502 uint16_t uhMask
= husart
->Mask
;
1504 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1507 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1509 tmp
= (uint16_t*) husart
->pRxBuffPtr
;
1510 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
1511 husart
->pRxBuffPtr
+= 2U;
1515 *husart
->pRxBuffPtr
++ = (uint8_t)(husart
->Instance
->RDR
& (uint8_t)uhMask
);
1517 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
1518 husart
->Instance
->TDR
= (DUMMY_DATA
& (uint16_t)0x00FFU
);
1520 if(--husart
->RxXferCount
== 0U)
1522 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE
);
1524 /* Disable the USART Parity Error Interrupt */
1525 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1527 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1528 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1530 husart
->State
= HAL_USART_STATE_READY
;
1532 HAL_USART_RxCpltCallback(husart
);
1546 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1547 * Function called under interruption only, once
1548 * interruptions have been enabled by HAL_USART_TransmitReceive_IT()
1549 * @param husart: USART handle
1550 * @retval HAL status
1552 static HAL_StatusTypeDef
USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
)
1555 uint16_t uhMask
= husart
->Mask
;
1557 if(husart
->State
== HAL_USART_STATE_BUSY_TX_RX
)
1559 if(husart
->TxXferCount
!= 0x00U
)
1561 if(__HAL_USART_GET_FLAG(husart
, USART_FLAG_TXE
) != RESET
)
1563 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1565 tmp
= (uint16_t*) husart
->pTxBuffPtr
;
1566 husart
->Instance
->TDR
= (uint16_t)(*tmp
& uhMask
);
1567 husart
->pTxBuffPtr
+= 2U;
1571 husart
->Instance
->TDR
= (uint8_t)(*husart
->pTxBuffPtr
++ & (uint8_t)uhMask
);
1573 husart
->TxXferCount
--;
1575 /* Check the latest data transmitted */
1576 if(husart
->TxXferCount
== 0U)
1578 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_TXEIE
);
1583 if(husart
->RxXferCount
!= 0x00U
)
1585 if(__HAL_USART_GET_FLAG(husart
, USART_FLAG_RXNE
) != RESET
)
1587 if((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1589 tmp
= (uint16_t*) husart
->pRxBuffPtr
;
1590 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
1591 husart
->pRxBuffPtr
+= 2U;
1595 *husart
->pRxBuffPtr
++ = (uint8_t)(husart
->Instance
->RDR
& (uint8_t)uhMask
);
1597 husart
->RxXferCount
--;
1601 /* Check the latest data received */
1602 if(husart
->RxXferCount
== 0U)
1604 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE
);
1606 /* Disable the USART Parity Error Interrupt */
1607 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1609 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1610 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1612 husart
->State
= HAL_USART_STATE_READY
;
1614 HAL_USART_TxRxCpltCallback(husart
);
1628 * @brief This function handles USART Communication Timeout.
1629 * @param husart USART handle
1630 * @param Flag specifies the USART flag to check.
1631 * @param Status The new Flag status (SET or RESET).
1632 * @param Tickstart Tick start value
1633 * @param Timeout Timeout duration
1634 * @retval HAL status
1636 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
, uint32_t Tickstart
, uint32_t Timeout
)
1638 /* Wait until flag is set */
1639 while((__HAL_USART_GET_FLAG(husart
, Flag
) ? SET
: RESET
) == Status
)
1641 /* Check for the Timeout */
1642 if(Timeout
!= HAL_MAX_DELAY
)
1644 if((Timeout
== 0U)||((HAL_GetTick()-Tickstart
) >= Timeout
))
1646 /* Disable the USART Transmit Complete Interrupt */
1647 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_TXEIE
);
1649 /* Disable the USART RXNE Interrupt */
1650 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE
);
1652 /* Disable the USART Parity Error Interrupt */
1653 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1655 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1656 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1658 husart
->State
= HAL_USART_STATE_READY
;
1660 /* Process Unlocked */
1661 __HAL_UNLOCK(husart
);
1672 * @brief DMA USART transmit process complete callback
1673 * @param hdma: DMA handle
1676 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
)
1678 USART_HandleTypeDef
* husart
= ( USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1680 /* DMA Normal mode */
1681 if((hdma
->Instance
->CR
& DMA_SxCR_CIRC
) == 0U)
1683 husart
->TxXferCount
= 0U;
1685 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1687 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1688 in the USART CR3 register */
1689 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1691 /* Enable the USART Transmit Complete Interrupt */
1692 SET_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
);
1695 /* DMA Circular mode */
1698 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1700 HAL_USART_TxCpltCallback(husart
);
1707 * @brief DMA USART transmit process half complete callback
1708 * @param hdma : DMA handle
1711 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
)
1713 USART_HandleTypeDef
* husart
= (USART_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
1715 HAL_USART_TxHalfCpltCallback(husart
);
1719 * @brief DMA USART receive process complete callback
1720 * @param hdma: DMA handle
1723 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
)
1725 USART_HandleTypeDef
* husart
= ( USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1727 /* DMA Normal mode */
1728 if((hdma
->Instance
->CR
& DMA_SxCR_CIRC
) == 0U)
1730 husart
->RxXferCount
= 0U;
1732 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1733 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
));
1734 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1736 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
1737 in USART CR3 register */
1738 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1739 /* similarly, disable the DMA TX transfer that was started to provide the
1740 clock to the slave device */
1741 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1743 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1745 HAL_USART_RxCpltCallback(husart
);
1747 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
1750 HAL_USART_TxRxCpltCallback(husart
);
1752 husart
->State
= HAL_USART_STATE_READY
;
1754 /* DMA circular mode */
1757 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1759 HAL_USART_RxCpltCallback(husart
);
1761 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
1764 HAL_USART_TxRxCpltCallback(husart
);
1770 * @brief DMA USART receive process half complete callback
1771 * @param hdma : DMA handle
1774 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
)
1776 USART_HandleTypeDef
* husart
= (USART_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
1778 HAL_USART_RxHalfCpltCallback(husart
);
1782 * @brief DMA USART communication error callback
1783 * @param hdma: DMA handle
1786 static void USART_DMAError(DMA_HandleTypeDef
*hdma
)
1788 USART_HandleTypeDef
* husart
= ( USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1790 husart
->RxXferCount
= 0U;
1791 husart
->TxXferCount
= 0U;
1793 /* Stop USART DMA Tx request if ongoing */
1794 if((husart
->State
== HAL_USART_STATE_BUSY_TX
)
1795 &&(HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
)))
1797 USART_EndTxTransfer(husart
);
1800 /* Stop USART DMA Rx request if ongoing */
1801 if((husart
->State
== HAL_USART_STATE_BUSY_RX
)
1802 &&(HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
)))
1804 USART_EndRxTransfer(husart
);
1807 husart
->ErrorCode
|= HAL_USART_ERROR_DMA
;
1808 husart
->State
= HAL_USART_STATE_READY
;
1810 HAL_USART_ErrorCallback(husart
);
1814 * @brief DMA USART communication abort callback
1815 * (To be called at end of DMA Abort procedure).
1816 * @param hdma: DMA handle.
1819 static void USART_DMAAbortOnError(DMA_HandleTypeDef
*hdma
)
1821 USART_HandleTypeDef
* husart
= (USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1822 husart
->RxXferCount
= 0U;
1823 husart
->TxXferCount
= 0U;
1825 HAL_USART_ErrorCallback(husart
);
1829 * @brief End ongoing Tx transfer on USART peripheral (following error detection or Transmit completion).
1830 * @param husart: USART handle.
1833 static void USART_EndTxTransfer(USART_HandleTypeDef
*husart
)
1835 /* At end of Tx process, restore husart->State to Ready */
1836 husart
->State
= HAL_USART_STATE_READY
;
1838 /* Disable TXEIE and TCIE interrupts */
1839 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_TXEIE
| USART_CR1_TCIE
));
1843 * @brief End ongoing Rx transfer on USART peripheral (following error detection or Reception completion).
1844 * @param husart: USART handle.
1847 static void USART_EndRxTransfer(USART_HandleTypeDef
*husart
)
1849 /* At end of Rx process, restore husart->RxState to Ready */
1850 husart
->State
= HAL_USART_STATE_READY
;
1852 /* Disable RXNE, PE and ERR interrupts */
1853 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE
| USART_CR1_PEIE
));
1854 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1858 * @brief Configure the USART peripheral
1859 * @param husart: USART handle
1862 static HAL_StatusTypeDef
USART_SetConfig(USART_HandleTypeDef
*husart
)
1864 uint32_t tmpreg
= 0x0U
;
1865 USART_ClockSourceTypeDef clocksource
= USART_CLOCKSOURCE_UNDEFINED
;
1866 HAL_StatusTypeDef ret
= HAL_OK
;
1867 uint16_t brrtemp
= 0x0000U
;
1868 uint16_t usartdiv
= 0x0000U
;
1870 /* Check the parameters */
1871 assert_param(IS_USART_POLARITY(husart
->Init
.CLKPolarity
));
1872 assert_param(IS_USART_PHASE(husart
->Init
.CLKPhase
));
1873 assert_param(IS_USART_LASTBIT(husart
->Init
.CLKLastBit
));
1874 assert_param(IS_USART_BAUDRATE(husart
->Init
.BaudRate
));
1875 assert_param(IS_USART_WORD_LENGTH(husart
->Init
.WordLength
));
1876 assert_param(IS_USART_STOPBITS(husart
->Init
.StopBits
));
1877 assert_param(IS_USART_PARITY(husart
->Init
.Parity
));
1878 assert_param(IS_USART_MODE(husart
->Init
.Mode
));
1879 assert_param(IS_USART_OVERSAMPLING(husart
->Init
.OverSampling
));
1882 /*-------------------------- USART CR1 Configuration -----------------------*/
1883 /* Clear M, PCE, PS, TE and RE bits and configure
1884 * the USART Word Length, Parity, Mode and OverSampling:
1885 * set the M bits according to husart->Init.WordLength value
1886 * set PCE and PS bits according to husart->Init.Parity value
1887 * set TE and RE bits according to husart->Init.Mode value
1888 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
1889 tmpreg
= (uint32_t)husart
->Init
.WordLength
| husart
->Init
.Parity
| husart
->Init
.Mode
| USART_CR1_OVER8
;
1890 MODIFY_REG(husart
->Instance
->CR1
, USART_CR1_FIELDS
, tmpreg
);
1892 /*---------------------------- USART CR2 Configuration ---------------------*/
1893 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
1894 * set CPOL bit according to husart->Init.CLKPolarity value
1895 * set CPHA bit according to husart->Init.CLKPhase value
1896 * set LBCL bit according to husart->Init.CLKLastBit value
1897 * set STOP[13:12] bits according to husart->Init.StopBits value */
1898 tmpreg
= (uint32_t)(USART_CLOCK_ENABLE
);
1899 tmpreg
|= ((uint32_t)husart
->Init
.CLKPolarity
| (uint32_t)husart
->Init
.CLKPhase
);
1900 tmpreg
|= ((uint32_t)husart
->Init
.CLKLastBit
| (uint32_t)husart
->Init
.StopBits
);
1901 MODIFY_REG(husart
->Instance
->CR2
, USART_CR2_FIELDS
, tmpreg
);
1903 /*-------------------------- USART CR3 Configuration -----------------------*/
1904 /* no CR3 register configuration */
1906 /*-------------------------- USART BRR Configuration -----------------------*/
1907 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
1908 USART_GETCLOCKSOURCE(husart
, clocksource
);
1909 switch (clocksource
)
1911 case USART_CLOCKSOURCE_PCLK1
:
1912 usartdiv
= (uint16_t)(((2*HAL_RCC_GetPCLK1Freq()) + (husart
->Init
.BaudRate
/2))/ husart
->Init
.BaudRate
);
1914 case USART_CLOCKSOURCE_PCLK2
:
1915 usartdiv
= (uint16_t)(((2*HAL_RCC_GetPCLK2Freq()) + (husart
->Init
.BaudRate
/2))/ husart
->Init
.BaudRate
);
1917 case USART_CLOCKSOURCE_HSI
:
1918 usartdiv
= (uint16_t)(((2*HSI_VALUE
) + (husart
->Init
.BaudRate
/2))/ husart
->Init
.BaudRate
);
1920 case USART_CLOCKSOURCE_SYSCLK
:
1921 usartdiv
= (uint16_t)(((2*HAL_RCC_GetSysClockFreq()) + (husart
->Init
.BaudRate
/2))/ husart
->Init
.BaudRate
);
1923 case USART_CLOCKSOURCE_LSE
:
1924 usartdiv
= (uint16_t)(((2*LSE_VALUE
) + (husart
->Init
.BaudRate
/2))/ husart
->Init
.BaudRate
);
1926 case USART_CLOCKSOURCE_UNDEFINED
:
1932 brrtemp
= usartdiv
& 0xFFF0U
;
1933 brrtemp
|= (uint16_t)((usartdiv
& (uint16_t)0x000FU
) >> 1U);
1934 husart
->Instance
->BRR
= brrtemp
;
1940 * @brief Check the USART Idle State
1941 * @param husart: USART handle
1942 * @retval HAL status
1944 static HAL_StatusTypeDef
USART_CheckIdleState(USART_HandleTypeDef
*husart
)
1946 uint32_t tickstart
= 0U;
1948 /* Initialize the USART ErrorCode */
1949 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1951 /* Init tickstart for timeout managment*/
1952 tickstart
= HAL_GetTick();
1954 /* Check if the Transmitter is enabled */
1955 if((husart
->Instance
->CR1
& USART_CR1_TE
) == USART_CR1_TE
)
1957 /* Wait until TEACK flag is set */
1958 if(USART_WaitOnFlagUntilTimeout(husart
, USART_ISR_TEACK
, RESET
, tickstart
, TEACK_REACK_TIMEOUT
) != HAL_OK
)
1960 husart
->State
= HAL_USART_STATE_TIMEOUT
;
1964 /* Check if the Receiver is enabled */
1965 if((husart
->Instance
->CR1
& USART_CR1_RE
) == USART_CR1_RE
)
1967 /* Wait until REACK flag is set */
1968 if(USART_WaitOnFlagUntilTimeout(husart
, USART_ISR_REACK
, RESET
, tickstart
, TEACK_REACK_TIMEOUT
) != HAL_OK
)
1970 husart
->State
= HAL_USART_STATE_TIMEOUT
;
1975 /* Initialize the USART state*/
1976 husart
->State
= HAL_USART_STATE_READY
;
1978 /* Process Unlocked */
1979 __HAL_UNLOCK(husart
);
1988 #endif /* HAL_USART_MODULE_ENABLED */
1997 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/