2 ******************************************************************************
3 * @file stm32f1xx_hal_usart.c
4 * @author MCD Application Team
6 * @date 15-December-2014
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 (USART) peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral Control functions
13 * + Peripheral State and Errors 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.
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 the USART pins (TX as alternate function pull-up, RX as alternate function Input).
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 (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
32 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
33 (+++) Declare a DMA handle structure for the Tx/Rx channel.
34 (+++) Enable the DMAx interface clock.
35 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
36 (+++) Configure the DMA Tx/Rx channel.
37 (+++) Associate the initilalized DMA handle to the USART DMA Tx/Rx handle.
38 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
39 (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
40 (used for last byte sending completion detection in DMA non circular mode)
42 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
43 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
45 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
46 (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
47 by calling the customed HAL_USART_MspInit(&husart) API.
49 -@@- The specific USART interrupts (Transmission complete interrupt,
50 RXNE interrupt and Error Interrupts) will be managed using the macros
51 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
53 (#) Three operation modes are available within this driver :
55 *** Polling mode IO operation ***
56 =================================
58 (+) Send an amount of data in blocking mode using HAL_USART_Transmit()
59 (+) Receive an amount of data in blocking mode using HAL_USART_Receive()
61 *** Interrupt mode IO operation ***
62 ===================================
64 (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
65 (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_USART_TxCpltCallback
67 (+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT()
68 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
69 add his own code by customization of function pointer HAL_USART_RxCpltCallback
70 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
71 add his own code by customization of function pointer HAL_USART_ErrorCallback
73 *** DMA mode IO operation ***
74 ==============================
76 (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
77 (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
78 add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
79 (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
80 add his own code by customization of function pointer HAL_USART_TxCpltCallback
81 (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
82 (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
83 add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
84 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
85 add his own code by customization of function pointer HAL_USART_RxCpltCallback
86 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
87 add his own code by customization of function pointer HAL_USART_ErrorCallback
88 (+) Pause the DMA Transfer using HAL_USART_DMAPause()
89 (+) Resume the DMA Transfer using HAL_USART_DMAResume()
90 (+) Stop the DMA Transfer using HAL_USART_DMAStop()
92 *** USART HAL driver macros list ***
93 =============================================
95 Below the list of most used macros in USART HAL driver.
97 (+) __HAL_USART_ENABLE: Enable the USART peripheral
98 (+) __HAL_USART_DISABLE: Disable the USART peripheral
99 (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
100 (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
101 (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
102 (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
103 (+) __HAL_USART_GET_IT_SOURCE: Check whether the specified USART interrupt has occurred or not
106 (@) You can refer to the USART HAL driver header file for more useful macros
109 ******************************************************************************
112 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
114 * Redistribution and use in source and binary forms, with or without modification,
115 * are permitted provided that the following conditions are met:
116 * 1. Redistributions of source code must retain the above copyright notice,
117 * this list of conditions and the following disclaimer.
118 * 2. Redistributions in binary form must reproduce the above copyright notice,
119 * this list of conditions and the following disclaimer in the documentation
120 * and/or other materials provided with the distribution.
121 * 3. Neither the name of STMicroelectronics nor the names of its contributors
122 * may be used to endorse or promote products derived from this software
123 * without specific prior written permission.
125 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
126 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
127 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
129 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
130 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
131 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
132 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
133 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
134 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
136 ******************************************************************************
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32f1xx_hal.h"
142 /** @addtogroup STM32F1xx_HAL_Driver
146 /** @defgroup USART USART
147 * @brief HAL USART Synchronous module driver
150 #ifdef HAL_USART_MODULE_ENABLED
151 /* Private typedef -----------------------------------------------------------*/
152 /* Private define ------------------------------------------------------------*/
153 /** @defgroup USART_Private_Constants USART Private Constants
156 #define DUMMY_DATA 0xFFFF
161 /* Private macros --------------------------------------------------------*/
162 /* Private variables ---------------------------------------------------------*/
163 /* Private function prototypes -----------------------------------------------*/
164 /** @addtogroup USART_Private_Functions USART Private Functions
167 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
168 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
169 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
170 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
171 static void USART_SetConfig (USART_HandleTypeDef *husart);
172 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
173 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
174 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
175 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
176 static void USART_DMAError(DMA_HandleTypeDef *hdma);
177 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
182 /* Exported functions ---------------------------------------------------------*/
185 /** @defgroup USART_Exported_Functions USART Exported Functions
189 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
190 * @brief Initialization and Configuration functions
193 ==============================================================================
194 ##### Initialization and Configuration functions #####
195 ==============================================================================
197 This subsection provides a set of functions allowing to initialize the USART
198 in asynchronous and in synchronous modes.
199 (+) For the asynchronous mode only these parameters can be configured:
203 (++) Parity: If the parity is enabled, then the MSB bit of the data written
204 in the data register is transmitted but is changed by the parity bit.
205 Depending on the frame length defined by the M bit (8-bits or 9-bits),
206 the possible USART frame formats are as listed in the following table:
207 (+++) +-------------------------------------------------------------+
208 (+++) | M bit | PCE bit | USART frame |
209 (+++) |---------------------|---------------------------------------|
210 (+++) | 0 | 0 | | SB | 8 bit data | STB | |
211 (+++) |---------|-----------|---------------------------------------|
212 (+++) | 0 | 1 | | SB | 7 bit data | PB | STB | |
213 (+++) |---------|-----------|---------------------------------------|
214 (+++) | 1 | 0 | | SB | 9 bit data | STB | |
215 (+++) |---------|-----------|---------------------------------------|
216 (+++) | 1 | 1 | | SB | 8 bit data | PB | STB | |
217 (+++) +-------------------------------------------------------------+
221 (++) Receiver/transmitter modes
224 The HAL_USART_Init() function follows the USART synchronous configuration
225 procedure (details for the procedure are available in reference manuals
226 (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
233 * @brief Initializes the USART mode according to the specified
234 * parameters in the USART_InitTypeDef and create the associated handle.
235 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
236 * the configuration information for the specified USART module.
239 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
241 /* Check the USART handle allocation */
247 /* Check the parameters */
248 assert_param(IS_USART_INSTANCE(husart->Instance));
250 if(husart->State == HAL_USART_STATE_RESET)
252 /* Allocate lock resource and initialize it */
253 husart-> Lock = HAL_UNLOCKED;
255 /* Init the low level hardware */
256 HAL_USART_MspInit(husart);
259 husart->State = HAL_USART_STATE_BUSY;
261 /* Set the USART Communication parameters */
262 USART_SetConfig(husart);
264 /* In USART mode, the following bits must be kept cleared:
265 - LINEN bit in the USART_CR2 register
266 - HDSEL, SCEN and IREN bits in the USART_CR3 register */
267 CLEAR_BIT(husart->Instance->CR2, USART_CR2_LINEN);
268 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL));
270 /* Enable the Peripheral */
271 __HAL_USART_ENABLE(husart);
273 /* Initialize the USART state */
274 husart->ErrorCode = HAL_USART_ERROR_NONE;
275 husart->State= HAL_USART_STATE_READY;
281 * @brief DeInitializes the USART peripheral.
282 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
283 * the configuration information for the specified USART module.
286 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
288 /* Check the USART handle allocation */
294 /* Check the parameters */
295 assert_param(IS_USART_INSTANCE(husart->Instance));
297 husart->State = HAL_USART_STATE_BUSY;
299 /* Disable the Peripheral */
300 __HAL_USART_DISABLE(husart);
302 /* DeInit the low level hardware */
303 HAL_USART_MspDeInit(husart);
305 husart->ErrorCode = HAL_USART_ERROR_NONE;
306 husart->State = HAL_USART_STATE_RESET;
309 __HAL_UNLOCK(husart);
315 * @brief USART MSP Init.
316 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
317 * the configuration information for the specified USART module.
320 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
322 /* NOTE: This function should not be modified, when the callback is needed,
323 the HAL_USART_MspInit can be implemented in the user file
328 * @brief USART MSP DeInit.
329 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
330 * the configuration information for the specified USART module.
333 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
335 /* NOTE: This function should not be modified, when the callback is needed,
336 the HAL_USART_MspDeInit can be implemented in the user file
344 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
345 * @brief USART Transmit and Receive functions
348 ==============================================================================
349 ##### IO operation functions #####
350 ==============================================================================
352 This subsection provides a set of functions allowing to manage the USART synchronous
356 The USART supports master mode only: it cannot receive or send data related to an input
357 clock (SCLK is always an output).
359 (#) There are two modes of transfer:
360 (++) Blocking mode: The communication is performed in polling mode.
361 The HAL status of all data processing is returned by the same function
362 after finishing transfer.
363 (++) No-Blocking mode: The communication is performed using Interrupts
364 or DMA, These API's return the HAL status.
365 The end of the data processing will be indicated through the
366 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
368 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
370 will be executed respectively at the end of the transmit or Receive process
371 The HAL_USART_ErrorCallback() user callback will be executed when a communication
374 (#) Blocking mode APIs are :
375 (++) HAL_USART_Transmit() in simplex mode
376 (++) HAL_USART_Receive() in full duplex receive only
377 (++) HAL_USART_TransmitReceive() in full duplex mode
379 (#) Non Blocking mode APIs with Interrupt are :
380 (++) HAL_USART_Transmit_IT()in simplex mode
381 (++) HAL_USART_Receive_IT() in full duplex receive only
382 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
383 (++) HAL_USART_IRQHandler()
385 (#) Non Blocking mode functions with DMA are :
386 (++) HAL_USART_Transmit_DMA()in simplex mode
387 (++) HAL_USART_Receive_DMA() in full duplex receive only
388 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
389 (++) HAL_USART_DMAPause()
390 (++) HAL_USART_DMAResume()
391 (++) HAL_USART_DMAStop()
393 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
394 (++) HAL_USART_TxHalfCpltCallback()
395 (++) HAL_USART_TxCpltCallback()
396 (++) HAL_USART_RxHalfCpltCallback()
397 (++) HAL_USART_RxCpltCallback()
398 (++) HAL_USART_ErrorCallback()
399 (++) HAL_USART_TxRxCpltCallback()
406 * @brief Simplex Send an amount of data in blocking mode.
407 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
408 * the configuration information for the specified USART module.
409 * @param pTxData: Pointer to data buffer
410 * @param Size: Amount of data to be sent
411 * @param Timeout: Timeout duration
414 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
418 if(husart->State == HAL_USART_STATE_READY)
420 if((pTxData == NULL) || (Size == 0))
428 husart->ErrorCode = HAL_USART_ERROR_NONE;
429 husart->State = HAL_USART_STATE_BUSY_TX;
431 husart->TxXferSize = Size;
432 husart->TxXferCount = Size;
433 while(husart->TxXferCount > 0)
435 husart->TxXferCount--;
436 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
438 /* Wait for TC flag in order to write data in DR */
439 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
443 tmp = (uint16_t*) pTxData;
444 WRITE_REG(husart->Instance->DR, (*tmp & (uint16_t)0x01FF));
445 if(husart->Init.Parity == USART_PARITY_NONE)
456 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
460 WRITE_REG(husart->Instance->DR, (*pTxData++ & (uint8_t)0xFF));
464 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
469 husart->State = HAL_USART_STATE_READY;
471 /* Process Unlocked */
472 __HAL_UNLOCK(husart);
483 * @brief Full-Duplex Receive an amount of data in blocking mode.
484 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
485 * the configuration information for the specified USART module.
486 * @param pRxData: Pointer to data buffer
487 * @param Size: Amount of data to be received
488 * @param Timeout: Timeout duration
491 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
495 if(husart->State == HAL_USART_STATE_READY)
497 if((pRxData == NULL) || (Size == 0))
505 husart->ErrorCode = HAL_USART_ERROR_NONE;
506 husart->State = HAL_USART_STATE_BUSY_RX;
508 husart->RxXferSize = Size;
509 husart->RxXferCount = Size;
510 /* Check the remain data to be received */
511 while(husart->RxXferCount > 0)
513 husart->RxXferCount--;
514 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
516 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
517 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
521 /* Send dummy byte in order to generate clock */
522 WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
524 /* Wait for RXNE Flag */
525 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
529 tmp = (uint16_t*) pRxData ;
530 if(husart->Init.Parity == USART_PARITY_NONE)
532 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
537 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
543 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
544 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
549 /* Send Dummy Byte in order to generate clock */
550 WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x00FF));
552 /* Wait until RXNE flag is set to receive the byte */
553 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
557 if(husart->Init.Parity == USART_PARITY_NONE)
560 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
565 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
571 husart->State = HAL_USART_STATE_READY;
573 /* Process Unlocked */
574 __HAL_UNLOCK(husart);
585 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode).
586 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
587 * the configuration information for the specified USART module.
588 * @param pTxData: Pointer to data transmitted buffer
589 * @param pRxData: Pointer to data received buffer
590 * @param Size: Amount of data to be sent
591 * @param Timeout: Timeout duration
594 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
598 if(husart->State == HAL_USART_STATE_READY)
600 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
607 husart->ErrorCode = HAL_USART_ERROR_NONE;
608 husart->State = HAL_USART_STATE_BUSY_RX;
610 husart->RxXferSize = Size;
611 husart->TxXferSize = Size;
612 husart->TxXferCount = Size;
613 husart->RxXferCount = Size;
615 /* Check the remain data to be received */
616 while(husart->TxXferCount > 0)
618 husart->TxXferCount--;
619 husart->RxXferCount--;
620 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
622 /* Wait for TC flag in order to write data in DR */
623 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
627 tmp = (uint16_t*) pTxData;
628 WRITE_REG(husart->Instance->DR, (*tmp & (uint16_t)0x01FF));
629 if(husart->Init.Parity == USART_PARITY_NONE)
638 /* Wait for RXNE Flag */
639 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
643 tmp = (uint16_t*) pRxData ;
644 if(husart->Init.Parity == USART_PARITY_NONE)
646 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
651 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
657 /* Wait for TC flag in order to write data in DR */
658 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
662 WRITE_REG(husart->Instance->DR, (*pTxData++ & (uint8_t)0x00FF));
664 /* Wait for RXNE Flag */
665 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
669 if(husart->Init.Parity == USART_PARITY_NONE)
672 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
677 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
682 husart->State = HAL_USART_STATE_READY;
684 /* Process Unlocked */
685 __HAL_UNLOCK(husart);
696 * @brief Simplex Send an amount of data in non-blocking mode.
697 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
698 * the configuration information for the specified USART module.
699 * @param pTxData: Pointer to data buffer
700 * @param Size: Amount of data to be sent
702 * @note The USART errors are not managed to avoid the overrun error.
704 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
706 if(husart->State == HAL_USART_STATE_READY)
708 if((pTxData == NULL) || (Size == 0))
716 husart->pTxBuffPtr = pTxData;
717 husart->TxXferSize = Size;
718 husart->TxXferCount = Size;
720 husart->ErrorCode = HAL_USART_ERROR_NONE;
721 husart->State = HAL_USART_STATE_BUSY_TX;
723 /* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
724 are not managed by the USART transmit process to avoid the overrun interrupt
725 when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
726 to benefit for the frame error and noise interrupts the USART mode should be
727 configured only for transmit "USART_MODE_TX"
728 The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
729 Noise error interrupt */
731 /* Process Unlocked */
732 __HAL_UNLOCK(husart);
734 /* Enable the USART Transmit Data Register Empty Interrupt */
735 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
746 * @brief Simplex Receive an amount of data in non-blocking mode.
747 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
748 * the configuration information for the specified USART module.
749 * @param pRxData: Pointer to data buffer
750 * @param Size: Amount of data to be received
753 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
755 if(husart->State == HAL_USART_STATE_READY)
757 if((pRxData == NULL) || (Size == 0))
764 husart->pRxBuffPtr = pRxData;
765 husart->RxXferSize = Size;
766 husart->RxXferCount = Size;
768 husart->ErrorCode = HAL_USART_ERROR_NONE;
769 husart->State = HAL_USART_STATE_BUSY_RX;
771 /* Process Unlocked */
772 __HAL_UNLOCK(husart);
774 /* Enable the USART Data Register not empty Interrupt */
775 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
777 /* Enable the USART Parity Error Interrupt */
778 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
780 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
781 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
783 /* Send dummy byte in order to generate the clock for the slave to send data */
784 WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
795 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
796 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
797 * the configuration information for the specified USART module.
798 * @param pTxData: Pointer to data transmitted buffer
799 * @param pRxData: Pointer to data received buffer
800 * @param Size: Amount of data to be received
803 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
805 if(husart->State == HAL_USART_STATE_READY)
807 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
814 husart->pRxBuffPtr = pRxData;
815 husart->RxXferSize = Size;
816 husart->RxXferCount = Size;
817 husart->pTxBuffPtr = pTxData;
818 husart->TxXferSize = Size;
819 husart->TxXferCount = Size;
821 husart->ErrorCode = HAL_USART_ERROR_NONE;
822 husart->State = HAL_USART_STATE_BUSY_TX_RX;
824 /* Process Unlocked */
825 __HAL_UNLOCK(husart);
827 /* Enable the USART Data Register not empty Interrupt */
828 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
830 /* Enable the USART Parity Error Interrupt */
831 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
833 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
834 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
836 /* Enable the USART Transmit Data Register Empty Interrupt */
837 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
848 * @brief Simplex Send an amount of data in non-blocking mode.
849 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
850 * the configuration information for the specified USART module.
851 * @param pTxData: Pointer to data buffer
852 * @param Size: Amount of data to be sent
855 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
859 if(husart->State == HAL_USART_STATE_READY)
861 if((pTxData == NULL) || (Size == 0))
868 husart->pTxBuffPtr = pTxData;
869 husart->TxXferSize = Size;
870 husart->TxXferCount = Size;
872 husart->ErrorCode = HAL_USART_ERROR_NONE;
873 husart->State = HAL_USART_STATE_BUSY_TX;
875 /* Set the USART DMA transfer complete callback */
876 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
878 /* Set the USART DMA Half transfer complete callback */
879 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
881 /* Set the DMA error callback */
882 husart->hdmatx->XferErrorCallback = USART_DMAError;
884 /* Enable the USART transmit DMA channel */
885 tmp = (uint32_t*)&pTxData;
886 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
888 /* Clear the TC flag in the SR register by writing 0 to it */
889 __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
891 /* Enable the DMA transfer for transmit request by setting the DMAT bit
892 in the USART CR3 register */
893 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
895 /* Process Unlocked */
896 __HAL_UNLOCK(husart);
907 * @brief Full-Duplex Receive an amount of data in non-blocking mode.
908 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
909 * the configuration information for the specified USART module.
910 * @param pRxData: Pointer to data buffer
911 * @param Size: Amount of data to be received
913 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
914 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
916 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
920 if(husart->State == HAL_USART_STATE_READY)
922 if((pRxData == NULL) || (Size == 0))
930 husart->pRxBuffPtr = pRxData;
931 husart->RxXferSize = Size;
932 husart->pTxBuffPtr = pRxData;
933 husart->TxXferSize = Size;
935 husart->ErrorCode = HAL_USART_ERROR_NONE;
936 husart->State = HAL_USART_STATE_BUSY_RX;
938 /* Set the USART DMA Rx transfer complete callback */
939 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
941 /* Set the USART DMA Half transfer complete callback */
942 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
944 /* Set the USART DMA Rx transfer error callback */
945 husart->hdmarx->XferErrorCallback = USART_DMAError;
947 /* Enable the USART receive DMA channel */
948 tmp = (uint32_t*)&pRxData;
949 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
951 /* Enable the USART transmit DMA channel: the transmit channel is used in order
952 to generate in the non-blocking mode the clock to the slave device,
953 this mode isn't a simplex receive mode but a full-duplex receive one */
954 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
956 /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer
957 when using the USART in circular mode */
958 __HAL_USART_CLEAR_OREFLAG(husart);
960 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
961 in the USART CR3 register */
962 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
964 /* Enable the DMA transfer for transmit request by setting the DMAT bit
965 in the USART CR3 register */
966 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
968 /* Process Unlocked */
969 __HAL_UNLOCK(husart);
980 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
981 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
982 * the configuration information for the specified USART module.
983 * @param pTxData: Pointer to data transmitted buffer
984 * @param pRxData: Pointer to data received buffer
985 * @param Size: Amount of data to be received
986 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
989 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
993 if(husart->State == HAL_USART_STATE_READY)
995 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
1002 husart->pRxBuffPtr = pRxData;
1003 husart->RxXferSize = Size;
1004 husart->pTxBuffPtr = pTxData;
1005 husart->TxXferSize = Size;
1007 husart->ErrorCode = HAL_USART_ERROR_NONE;
1008 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1010 /* Set the USART DMA Rx transfer complete callback */
1011 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1013 /* Set the USART DMA Half transfer complete callback */
1014 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1016 /* Set the USART DMA Tx transfer complete callback */
1017 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1019 /* Set the USART DMA Half transfer complete callback */
1020 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1022 /* Set the USART DMA Tx transfer error callback */
1023 husart->hdmatx->XferErrorCallback = USART_DMAError;
1025 /* Set the USART DMA Rx transfer error callback */
1026 husart->hdmarx->XferErrorCallback = USART_DMAError;
1028 /* Enable the USART receive DMA channel */
1029 tmp = (uint32_t*)&pRxData;
1030 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
1032 /* Enable the USART transmit DMA channel */
1033 tmp = (uint32_t*)&pTxData;
1034 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
1036 /* Clear the TC flag in the SR register by writing 0 to it */
1037 __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
1039 /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
1040 __HAL_USART_CLEAR_OREFLAG(husart);
1042 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1043 in the USART CR3 register */
1044 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1046 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1047 in the USART CR3 register */
1048 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1050 /* Process Unlocked */
1051 __HAL_UNLOCK(husart);
1062 * @brief Pauses the DMA Transfer.
1063 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1064 * the configuration information for the specified USART module.
1065 * @retval HAL status
1067 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1069 /* Process Locked */
1072 /* Disable the USART DMA Tx request */
1073 CLEAR_BIT(husart->Instance->CR3, (uint32_t)(USART_CR3_DMAT));
1075 /* Process Unlocked */
1076 __HAL_UNLOCK(husart);
1082 * @brief Resumes the DMA Transfer.
1083 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1084 * the configuration information for the specified USART module.
1085 * @retval HAL status
1087 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1089 /* Process Locked */
1092 /* Enable the USART DMA Tx request */
1093 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1095 /* Process Unlocked */
1096 __HAL_UNLOCK(husart);
1102 * @brief Stops the DMA Transfer.
1103 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1104 * the configuration information for the specified USART module.
1105 * @retval HAL status
1107 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1109 /* The Lock is not implemented on this API to allow the user application
1110 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
1111 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1112 and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
1115 /* Abort the USART DMA Tx channel */
1116 if(husart->hdmatx != NULL)
1118 HAL_DMA_Abort(husart->hdmatx);
1120 /* Abort the USART DMA Rx channel */
1121 if(husart->hdmarx != NULL)
1123 HAL_DMA_Abort(husart->hdmarx);
1126 /* Disable the USART Tx/Rx DMA requests */
1127 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
1129 husart->State = HAL_USART_STATE_READY;
1135 * @brief This function handles USART interrupt request.
1136 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1137 * the configuration information for the specified USART module.
1140 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1142 uint32_t tmp_flag = 0, tmp_it_source = 0;
1144 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_PE);
1145 tmp_it_source = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE);
1146 /* USART parity error interrupt occurred -----------------------------------*/
1147 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1149 __HAL_USART_CLEAR_PEFLAG(husart);
1150 husart->ErrorCode |= HAL_USART_ERROR_PE;
1153 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_FE);
1154 tmp_it_source = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR);
1155 /* USART frame error interrupt occurred ------------------------------------*/
1156 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1158 __HAL_USART_CLEAR_FEFLAG(husart);
1159 husart->ErrorCode |= HAL_USART_ERROR_FE;
1162 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_NE);
1163 /* USART noise error interrupt occurred ------------------------------------*/
1164 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1166 __HAL_USART_CLEAR_NEFLAG(husart);
1167 husart->ErrorCode |= HAL_USART_ERROR_NE;
1170 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_ORE);
1171 /* USART Over-Run interrupt occurred ---------------------------------------*/
1172 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1174 __HAL_USART_CLEAR_OREFLAG(husart);
1175 husart->ErrorCode |= HAL_USART_ERROR_ORE;
1178 if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1180 /* Set the USART state ready to be able to start again the process */
1181 husart->State = HAL_USART_STATE_READY;
1183 HAL_USART_ErrorCallback(husart);
1186 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE);
1187 tmp_it_source = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE);
1188 /* USART in mode Receiver --------------------------------------------------*/
1189 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1191 if(husart->State == HAL_USART_STATE_BUSY_RX)
1193 USART_Receive_IT(husart);
1197 USART_TransmitReceive_IT(husart);
1201 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_TXE);
1202 tmp_it_source = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE);
1203 /* USART in mode Transmitter -----------------------------------------------*/
1204 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1206 if(husart->State == HAL_USART_STATE_BUSY_TX)
1208 USART_Transmit_IT(husart);
1212 USART_TransmitReceive_IT(husart);
1216 tmp_flag = __HAL_USART_GET_FLAG(husart, USART_FLAG_TC);
1217 tmp_it_source = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC);
1218 /* USART in mode Transmitter (transmission end) -----------------------------*/
1219 if((tmp_flag != RESET) && (tmp_it_source != RESET))
1221 USART_EndTransmit_IT(husart);
1228 * @brief Tx Transfer completed callbacks.
1229 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1230 * the configuration information for the specified USART module.
1233 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1235 /* NOTE: This function should not be modified, when the callback is needed,
1236 the HAL_USART_TxCpltCallback can be implemented in the user file
1241 * @brief Tx Half Transfer completed callbacks.
1242 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1243 * the configuration information for the specified USART module.
1246 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1248 /* NOTE: This function should not be modified, when the callback is needed,
1249 the HAL_USART_TxHalfCpltCallback can be implemented in the user file
1254 * @brief Rx Transfer completed callbacks.
1255 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1256 * the configuration information for the specified USART module.
1259 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1261 /* NOTE: This function should not be modified, when the callback is needed,
1262 the HAL_USART_RxCpltCallback can be implemented in the user file
1267 * @brief Rx Half Transfer completed callbacks.
1268 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1269 * the configuration information for the specified USART module.
1272 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1274 /* NOTE: This function should not be modified, when the callback is needed,
1275 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
1280 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
1281 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1282 * the configuration information for the specified USART module.
1285 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1287 /* NOTE: This function should not be modified, when the callback is needed,
1288 the HAL_USART_TxRxCpltCallback can be implemented in the user file
1293 * @brief USART error callbacks.
1294 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1295 * the configuration information for the specified USART module.
1298 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1300 /* NOTE: This function should not be modified, when the callback is needed,
1301 the HAL_USART_ErrorCallback can be implemented in the user file
1309 /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
1310 * @brief USART State and Errors functions
1313 ==============================================================================
1314 ##### Peripheral State and Errors functions #####
1315 ==============================================================================
1317 This subsection provides a set of functions allowing to return the State of
1319 process, return Peripheral Errors occurred during communication process
1320 (+) HAL_USART_GetState() API can be helpful to check in run-time the state
1321 of the USART peripheral.
1322 (+) HAL_USART_GetError() check in run-time errors that could be occurred during
1329 * @brief Returns the USART state.
1330 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1331 * the configuration information for the specified USART module.
1334 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1336 return husart->State;
1340 * @brief Return the USART error code
1341 * @param husart : pointer to a USART_HandleTypeDef structure that contains
1342 * the configuration information for the specified USART.
1343 * @retval USART Error Code
1345 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1347 return husart->ErrorCode;
1358 /** @defgroup USART_Private_Functions USART Private Functions
1359 * @brief USART Private functions
1363 * @brief DMA USART transmit process complete callback.
1364 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1365 * the configuration information for the specified DMA module.
1368 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1370 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1372 /* DMA Normal mode */
1373 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
1375 husart->TxXferCount = 0;
1377 if(husart->State == HAL_USART_STATE_BUSY_TX)
1379 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1380 in the USART CR3 register */
1381 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1383 /* Enable the USART Transmit Complete Interrupt */
1384 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1387 /* DMA Circular mode */
1390 if(husart->State == HAL_USART_STATE_BUSY_TX)
1392 HAL_USART_TxCpltCallback(husart);
1398 * @brief DMA USART transmit process half complete callback
1399 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1400 * the configuration information for the specified DMA module.
1403 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1405 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1407 HAL_USART_TxHalfCpltCallback(husart);
1411 * @brief DMA USART receive process complete callback.
1412 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1413 * the configuration information for the specified DMA module.
1416 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1418 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1420 /* DMA Normal mode */
1421 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
1423 husart->RxXferCount = 0;
1424 if(husart->State == HAL_USART_STATE_BUSY_RX)
1426 /* Disable the DMA transfer for the receiver requests by setting the DMAR bit
1427 in the USART CR3 register */
1428 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1430 husart->State= HAL_USART_STATE_READY;
1431 HAL_USART_RxCpltCallback(husart);
1433 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1436 /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
1437 in the USART CR3 register */
1438 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
1440 husart->State= HAL_USART_STATE_READY;
1441 HAL_USART_TxRxCpltCallback(husart);
1444 /* DMA circular mode */
1447 if(husart->State == HAL_USART_STATE_BUSY_RX)
1449 HAL_USART_RxCpltCallback(husart);
1451 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1454 HAL_USART_TxRxCpltCallback(husart);
1460 * @brief DMA USART receive process half complete callback
1461 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1462 * the configuration information for the specified DMA module.
1465 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1467 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1469 HAL_USART_RxHalfCpltCallback(husart);
1473 * @brief DMA USART communication error callback.
1474 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1475 * the configuration information for the specified DMA module.
1478 static void USART_DMAError(DMA_HandleTypeDef *hdma)
1480 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1482 husart->RxXferCount = 0;
1483 husart->TxXferCount = 0;
1484 husart->ErrorCode |= HAL_USART_ERROR_DMA;
1485 husart->State= HAL_USART_STATE_READY;
1487 HAL_USART_ErrorCallback(husart);
1491 * @brief This function handles USART Communication Timeout.
1492 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1493 * the configuration information for the specified USART module.
1494 * @param Flag: specifies the USART flag to check.
1495 * @param Status: The new Flag status (SET or RESET).
1496 * @param Timeout: Timeout duration
1497 * @retval HAL status
1499 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1501 uint32_t tickstart = 0;
1504 tickstart = HAL_GetTick();
1506 /* Wait until flag is set */
1509 while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
1511 /* Check for the Timeout */
1512 if(Timeout != HAL_MAX_DELAY)
1514 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1516 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1517 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1518 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1519 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1520 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1522 husart->State= HAL_USART_STATE_READY;
1524 /* Process Unlocked */
1525 __HAL_UNLOCK(husart);
1534 while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
1536 /* Check for the Timeout */
1537 if(Timeout != HAL_MAX_DELAY)
1539 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1541 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1542 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1543 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1544 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1545 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1547 husart->State= HAL_USART_STATE_READY;
1549 /* Process Unlocked */
1550 __HAL_UNLOCK(husart);
1561 * @brief Simplex Send an amount of data in non-blocking mode.
1562 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1563 * the configuration information for the specified USART module.
1564 * @retval HAL status
1565 * @note The USART errors are not managed to avoid the overrun error.
1567 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1571 if(husart->State == HAL_USART_STATE_BUSY_TX)
1573 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1575 tmp = (uint16_t*) husart->pTxBuffPtr;
1576 WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
1577 if(husart->Init.Parity == USART_PARITY_NONE)
1579 husart->pTxBuffPtr += 2;
1583 husart->pTxBuffPtr += 1;
1588 WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
1591 if(--husart->TxXferCount == 0)
1593 /* Disable the USART Transmit data register empty Interrupt */
1594 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1596 /* Enable the USART Transmit Complete Interrupt */
1597 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1609 * @brief Wraps up transmission in non blocking mode.
1610 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1611 * the configuration information for the specified USART module.
1612 * @retval HAL status
1614 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
1616 /* Disable the USART Transmit Complete Interrupt */
1617 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
1619 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1620 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1622 husart->State = HAL_USART_STATE_READY;
1624 HAL_USART_TxCpltCallback(husart);
1631 * @brief Simplex Receive an amount of data in non-blocking mode.
1632 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1633 * the configuration information for the specified USART module.
1634 * @retval HAL status
1636 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
1639 if(husart->State == HAL_USART_STATE_BUSY_RX)
1641 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1643 tmp = (uint16_t*) husart->pRxBuffPtr;
1644 if(husart->Init.Parity == USART_PARITY_NONE)
1646 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
1647 husart->pRxBuffPtr += 2;
1651 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
1652 husart->pRxBuffPtr += 1;
1654 if(--husart->RxXferCount != 0x00)
1656 /* Send dummy byte in order to generate the clock for the slave to send the next data */
1657 WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
1662 if(husart->Init.Parity == USART_PARITY_NONE)
1664 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
1668 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
1671 if(--husart->RxXferCount != 0x00)
1673 /* Send dummy byte in order to generate the clock for the slave to send the next data */
1674 WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x00FF));
1678 if(husart->RxXferCount == 0)
1680 /* Disable the USART RXNE Interrupt */
1681 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1683 /* Disable the USART Parity Error Interrupt */
1684 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1686 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1687 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1689 husart->State = HAL_USART_STATE_READY;
1690 HAL_USART_RxCpltCallback(husart);
1703 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1704 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1705 * the configuration information for the specified USART module.
1706 * @retval HAL status
1708 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
1712 if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1714 if(husart->TxXferCount != 0x00)
1716 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
1718 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1720 tmp = (uint16_t*) husart->pTxBuffPtr;
1721 WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
1722 if(husart->Init.Parity == USART_PARITY_NONE)
1724 husart->pTxBuffPtr += 2;
1728 husart->pTxBuffPtr += 1;
1733 WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
1735 husart->TxXferCount--;
1737 /* Check the latest data transmitted */
1738 if(husart->TxXferCount == 0)
1740 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1745 if(husart->RxXferCount != 0x00)
1747 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
1749 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1751 tmp = (uint16_t*) husart->pRxBuffPtr;
1752 if(husart->Init.Parity == USART_PARITY_NONE)
1754 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
1755 husart->pRxBuffPtr += 2;
1759 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
1760 husart->pRxBuffPtr += 1;
1765 if(husart->Init.Parity == USART_PARITY_NONE)
1767 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
1771 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
1774 husart->RxXferCount--;
1778 /* Check the latest data received */
1779 if(husart->RxXferCount == 0)
1781 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1783 /* Disable the USART Parity Error Interrupt */
1784 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1786 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1787 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1789 husart->State = HAL_USART_STATE_READY;
1791 HAL_USART_TxRxCpltCallback(husart);
1805 * @brief Configures the USART peripheral.
1806 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1807 * the configuration information for the specified USART module.
1810 static void USART_SetConfig(USART_HandleTypeDef *husart)
1812 /* Check the parameters */
1813 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
1814 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
1815 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
1816 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
1817 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
1818 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
1819 assert_param(IS_USART_PARITY(husart->Init.Parity));
1820 assert_param(IS_USART_MODE(husart->Init.Mode));
1822 /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
1823 receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
1824 CLEAR_BIT(husart->Instance->CR1, ((uint32_t)(USART_CR1_TE | USART_CR1_RE)));
1826 /*---------------------------- USART CR2 Configuration ---------------------*/
1827 /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
1828 /* Set CPOL bit according to husart->Init.CLKPolarity value */
1829 /* Set CPHA bit according to husart->Init.CLKPhase value */
1830 /* Set LBCL bit according to husart->Init.CLKLastBit value */
1831 /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
1832 /* Write to USART CR2 */
1833 MODIFY_REG(husart->Instance->CR2,
1834 (uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP),
1835 ((uint32_t)(USART_CLOCK_ENABLE| husart->Init.CLKPolarity | husart->Init.CLKPhase| husart->Init.CLKLastBit | husart->Init.StopBits)));
1837 /*-------------------------- USART CR1 Configuration -----------------------*/
1838 /* Configure the USART Word Length, Parity and mode:
1839 Set the M bits according to husart->Init.WordLength value
1840 Set PCE and PS bits according to husart->Init.Parity value
1841 Set TE and RE bits according to husart->Init.Mode value */
1842 MODIFY_REG(husart->Instance->CR1,
1843 (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
1844 (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode);
1846 /*-------------------------- USART CR3 Configuration -----------------------*/
1847 /* Clear CTSE and RTSE bits */
1848 CLEAR_BIT(husart->Instance->CR3, (uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE));
1850 /*-------------------------- USART BRR Configuration -----------------------*/
1851 if((husart->Instance == USART1))
1853 husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate);
1857 husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK1Freq(), husart->Init.BaudRate);
1865 #endif /* HAL_USART_MODULE_ENABLED */
1874 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/