2 ******************************************************************************
3 * @file stm32l1xx_hal_usart.c
4 * @author MCD Application Team
6 * @date 5-September-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 these USART pins as alternate function pull-up.
27 (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
28 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
29 (+++) Configure the USARTx interrupt priority.
30 (+++) Enable the NVIC USART IRQ handle.
31 (##) 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.
40 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
41 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
43 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
44 (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
45 by calling the customed HAL_USART_MspInit(&husart) API.
47 -@@- The specific USART interrupts (Transmission complete interrupt,
48 RXNE interrupt and Error Interrupts) will be managed using the macros
49 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
51 (#) Three operation modes are available within this driver :
53 *** Polling mode IO operation ***
54 =================================
56 (+) Send an amount of data in blocking mode using HAL_USART_Transmit()
57 (+) Receive an amount of data in blocking mode using HAL_USART_Receive()
59 *** Interrupt mode IO operation ***
60 ===================================
62 (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
63 (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
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 half transfer HAL_USART_RxHalfCpltCallback is executed and user can
69 add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
70 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
71 add his own code by customization of function pointer HAL_USART_RxCpltCallback
72 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
73 add his own code by customization of function pointer HAL_USART_ErrorCallback
75 *** DMA mode IO operation ***
76 ==============================
78 (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
79 (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
80 add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
81 (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
82 add his own code by customization of function pointer HAL_USART_TxCpltCallback
83 (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
84 (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
85 add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
86 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
87 add his own code by customization of function pointer HAL_USART_RxCpltCallback
88 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
89 add his own code by customization of function pointer HAL_USART_ErrorCallback
90 (+) Pause the DMA Transfer using HAL_USART_DMAPause()
91 (+) Resume the DMA Transfer using HAL_USART_DMAResume()
92 (+) Stop the DMA Transfer using HAL_USART_DMAStop()
94 *** USART HAL driver macros list ***
95 =============================================
97 Below the list of most used macros in USART HAL driver.
99 (+) __HAL_USART_ENABLE: Enable the USART peripheral
100 (+) __HAL_USART_DISABLE: Disable the USART peripheral
101 (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
102 (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
103 (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
104 (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
107 (@) You can refer to the USART HAL driver header file for more useful macros
110 ******************************************************************************
113 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
115 * Redistribution and use in source and binary forms, with or without modification,
116 * are permitted provided that the following conditions are met:
117 * 1. Redistributions of source code must retain the above copyright notice,
118 * this list of conditions and the following disclaimer.
119 * 2. Redistributions in binary form must reproduce the above copyright notice,
120 * this list of conditions and the following disclaimer in the documentation
121 * and/or other materials provided with the distribution.
122 * 3. Neither the name of STMicroelectronics nor the names of its contributors
123 * may be used to endorse or promote products derived from this software
124 * without specific prior written permission.
126 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
127 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
128 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
130 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
131 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
132 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
133 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
134 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
135 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
137 ******************************************************************************
140 /* Includes ------------------------------------------------------------------*/
141 #include "stm32l1xx_hal.h"
143 /** @addtogroup STM32L1xx_HAL_Driver
147 /** @defgroup USART USART
148 * @brief HAL USART Synchronous module driver
151 #ifdef HAL_USART_MODULE_ENABLED
152 /* Private typedef -----------------------------------------------------------*/
153 /* Private define ------------------------------------------------------------*/
154 /** @defgroup USART_Private_Constants USART Private Constants
157 #define DUMMY_DATA 0xFFFF
158 #define USART_TIMEOUT_VALUE 22000
163 /* Private macro -------------------------------------------------------------*/
164 /* Private variables ---------------------------------------------------------*/
165 /* Private function prototypes -----------------------------------------------*/
166 /** @addtogroup USART_Private_Functions USART Private Functions
169 static HAL_StatusTypeDef
USART_Transmit_IT(USART_HandleTypeDef
*husart
);
170 static HAL_StatusTypeDef
USART_EndTransmit_IT(USART_HandleTypeDef
*husart
);
171 static HAL_StatusTypeDef
USART_Receive_IT(USART_HandleTypeDef
*husart
);
172 static HAL_StatusTypeDef
USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
);
173 static void USART_SetConfig (USART_HandleTypeDef
*husart
);
174 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
);
175 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
);
176 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
);
177 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
);
178 static void USART_DMAError(DMA_HandleTypeDef
*hdma
);
179 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
, uint32_t Timeout
);
184 /* Exported functions ---------------------------------------------------------*/
187 /** @defgroup USART_Exported_Functions USART Exported Functions
191 /** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
192 * @brief Initialization and Configuration functions
195 ==============================================================================
196 ##### Initialization and Configuration functions #####
197 ==============================================================================
199 This subsection provides a set of functions allowing to initialize the USART
200 in asynchronous and in synchronous modes.
201 (+) For the asynchronous mode only these parameters can be configured:
205 (++) Parity: If the parity is enabled, then the MSB bit of the data written
206 in the data register is transmitted but is changed by the parity bit.
207 Depending on the frame length defined by the M bit (8-bits or 9-bits),
208 the possible USART frame formats are as listed in the following table:
209 +-------------------------------------------------------------+
210 | M bit | PCE bit | USART frame |
211 |---------------------|---------------------------------------|
212 | 0 | 0 | | SB | 8 bit data | STB | |
213 |---------|-----------|---------------------------------------|
214 | 0 | 1 | | SB | 7 bit data | PB | STB | |
215 |---------|-----------|---------------------------------------|
216 | 1 | 0 | | SB | 9 bit data | STB | |
217 |---------|-----------|---------------------------------------|
218 | 1 | 1 | | SB | 8 bit data | PB | STB | |
219 +-------------------------------------------------------------+
223 (++) Receiver/transmitter modes
226 The HAL_USART_Init() function follows the USART synchronous configuration
227 procedure (details for the procedure are available in reference manual (RM0038)).
234 * @brief Initializes the USART mode according to the specified
235 * parameters in the USART_InitTypeDef and create the associated handle.
236 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
237 * the configuration information for the specified USART module.
240 HAL_StatusTypeDef
HAL_USART_Init(USART_HandleTypeDef
*husart
)
242 /* Check the USART handle allocation */
243 if(husart
== HAL_NULL
)
248 /* Check the parameters */
249 assert_param(IS_USART_INSTANCE(husart
->Instance
));
251 if(husart
->State
== HAL_USART_STATE_RESET
)
253 /* Init the low level hardware */
254 HAL_USART_MspInit(husart
);
257 husart
->State
= HAL_USART_STATE_BUSY
;
259 /* Set the USART Communication parameters */
260 USART_SetConfig(husart
);
262 /* In USART mode, the following bits must be kept cleared:
263 - LINEN bit in the USART_CR2 register
264 - HDSEL, SCEN and IREN bits in the USART_CR3 register */
265 CLEAR_BIT(husart
->Instance
->CR2
, USART_CR2_LINEN
);
266 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_IREN
| USART_CR3_SCEN
| USART_CR3_HDSEL
));
268 /* Enable the Peripheral */
269 __HAL_USART_ENABLE(husart
);
271 /* Initialize the USART state */
272 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
273 husart
->State
= HAL_USART_STATE_READY
;
279 * @brief DeInitializes the USART peripheral.
280 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
281 * the configuration information for the specified USART module.
284 HAL_StatusTypeDef
HAL_USART_DeInit(USART_HandleTypeDef
*husart
)
286 /* Check the USART handle allocation */
287 if(husart
== HAL_NULL
)
292 /* Check the parameters */
293 assert_param(IS_USART_INSTANCE(husart
->Instance
));
295 husart
->State
= HAL_USART_STATE_BUSY
;
297 /* Disable the Peripheral */
298 __HAL_USART_DISABLE(husart
);
300 /* DeInit the low level hardware */
301 HAL_USART_MspDeInit(husart
);
303 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
304 husart
->State
= HAL_USART_STATE_RESET
;
307 __HAL_UNLOCK(husart
);
313 * @brief USART MSP Init.
314 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
315 * the configuration information for the specified USART module.
318 __weak
void HAL_USART_MspInit(USART_HandleTypeDef
*husart
)
320 /* NOTE: This function Should not be modified, when the callback is needed,
321 the HAL_USART_MspInit could be implemented in the user file
326 * @brief USART MSP DeInit.
327 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
328 * the configuration information for the specified USART module.
331 __weak
void HAL_USART_MspDeInit(USART_HandleTypeDef
*husart
)
333 /* NOTE: This function Should not be modified, when the callback is needed,
334 the HAL_USART_MspDeInit could be implemented in the user file
342 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
343 * @brief USART Transmit and Receive functions
346 ==============================================================================
347 ##### IO operation functions #####
348 ==============================================================================
350 This subsection provides a set of functions allowing to manage the USART synchronous
354 The USART supports master mode only: it cannot receive or send data related to an input
355 clock (SCLK is always an output).
357 (#) There are two modes of transfer:
358 (++) Blocking mode: The communication is performed in polling mode.
359 The HAL status of all data processing is returned by the same function
360 after finishing transfer.
361 (++) No-Blocking mode: The communication is performed using Interrupts
362 or DMA, These API's return the HAL status.
363 The end of the data processing will be indicated through the
364 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
366 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
368 will be executed respectivelly at the end of the transmit or Receive process
369 The HAL_USART_ErrorCallback() user callback will be executed when a communication
372 (#) Blocking mode APIs are :
373 (++) HAL_USART_Transmit() in simplex mode
374 (++) HAL_USART_Receive() in full duplex receive only
375 (++) HAL_USART_TransmitReceive() in full duplex mode
377 (#) Non Blocking mode APIs with Interrupt are :
378 (++) HAL_USART_Transmit_IT()in simplex mode
379 (++) HAL_USART_Receive_IT() in full duplex receive only
380 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
381 (++) HAL_USART_IRQHandler()
383 (#) Non Blocking mode functions with DMA are :
384 (++) HAL_USART_Transmit_DMA()in simplex mode
385 (++) HAL_USART_Receive_DMA() in full duplex receive only
386 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
387 (++) HAL_USART_DMAPause()
388 (++) HAL_USART_DMAResume()
389 (++) HAL_USART_DMAStop()
391 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
392 (++) HAL_USART_TxHalfCpltCallback()
393 (++) HAL_USART_TxCpltCallback()
394 (++) HAL_USART_RxHalfCpltCallback()
395 (++) HAL_USART_RxCpltCallback()
396 (++) HAL_USART_ErrorCallback()
397 (++) HAL_USART_TxRxCpltCallback()
404 * @brief Simplex Send an amount of data in blocking mode.
405 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
406 * the configuration information for the specified USART module.
407 * @param pTxData: Pointer to data buffer
408 * @param Size: Amount of data to be sent
409 * @param Timeout: Timeout duration
412 HAL_StatusTypeDef
HAL_USART_Transmit(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
, uint32_t Timeout
)
416 if(husart
->State
== HAL_USART_STATE_READY
)
418 if((pTxData
== HAL_NULL
) || (Size
== 0))
426 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
427 husart
->State
= HAL_USART_STATE_BUSY_TX
;
429 husart
->TxXferSize
= Size
;
430 husart
->TxXferCount
= Size
;
431 while(husart
->TxXferCount
> 0)
433 husart
->TxXferCount
--;
434 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
436 /* Wait for TC flag in order to write data in DR */
437 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
441 tmp
= (uint16_t*) pTxData
;
442 WRITE_REG(husart
->Instance
->DR
, (*tmp
& (uint16_t)0x01FF));
443 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
454 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
458 WRITE_REG(husart
->Instance
->DR
, (*pTxData
++ & (uint8_t)0xFF));
462 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, Timeout
) != HAL_OK
)
467 husart
->State
= HAL_USART_STATE_READY
;
469 /* Process Unlocked */
470 __HAL_UNLOCK(husart
);
481 * @brief Full-Duplex Receive an amount of data in blocking mode.
482 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
483 * the configuration information for the specified USART module.
484 * @param pRxData: Pointer to data buffer
485 * @param Size: Amount of data to be received
486 * @param Timeout: Timeout duration
489 HAL_StatusTypeDef
HAL_USART_Receive(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
493 if(husart
->State
== HAL_USART_STATE_READY
)
495 if((pRxData
== HAL_NULL
) || (Size
== 0))
503 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
504 husart
->State
= HAL_USART_STATE_BUSY_RX
;
506 husart
->RxXferSize
= Size
;
507 husart
->RxXferCount
= Size
;
508 /* Check the remain data to be received */
509 while(husart
->RxXferCount
> 0)
511 husart
->RxXferCount
--;
512 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
514 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
515 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
519 /* Send dummy byte in order to generate clock */
520 WRITE_REG(husart
->Instance
->DR
, (DUMMY_DATA
& (uint16_t)0x01FF));
522 /* Wait for RXNE Flag */
523 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, Timeout
) != HAL_OK
)
527 tmp
= (uint16_t*) pRxData
;
528 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
530 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x01FF);
535 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x00FF);
541 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
542 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
547 /* Send Dummy Byte in order to generate clock */
548 WRITE_REG(husart
->Instance
->DR
, (DUMMY_DATA
& (uint16_t)0x00FF));
550 /* Wait until RXNE flag is set to receive the byte */
551 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, Timeout
) != HAL_OK
)
555 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
558 *pRxData
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x00FF);
563 *pRxData
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x007F);
569 husart
->State
= HAL_USART_STATE_READY
;
571 /* Process Unlocked */
572 __HAL_UNLOCK(husart
);
583 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode).
584 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
585 * the configuration information for the specified USART module.
586 * @param pTxData: Pointer to data transmitted buffer
587 * @param pRxData: Pointer to data received buffer
588 * @param Size: Amount of data to be sent
589 * @param Timeout: Timeout duration
592 HAL_StatusTypeDef
HAL_USART_TransmitReceive(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
596 if(husart
->State
== HAL_USART_STATE_READY
)
598 if((pTxData
== HAL_NULL
) || (pRxData
== HAL_NULL
) || (Size
== 0))
605 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
606 husart
->State
= HAL_USART_STATE_BUSY_RX
;
608 husart
->RxXferSize
= Size
;
609 husart
->TxXferSize
= Size
;
610 husart
->TxXferCount
= Size
;
611 husart
->RxXferCount
= Size
;
613 /* Check the remain data to be received */
614 while(husart
->TxXferCount
> 0)
616 husart
->TxXferCount
--;
617 husart
->RxXferCount
--;
618 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
620 /* Wait for TC flag in order to write data in DR */
621 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
625 tmp
= (uint16_t*) pTxData
;
626 WRITE_REG(husart
->Instance
->DR
, (*tmp
& (uint16_t)0x01FF));
627 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
636 /* Wait for RXNE Flag */
637 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, Timeout
) != HAL_OK
)
641 tmp
= (uint16_t*) pRxData
;
642 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
644 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x01FF);
649 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x00FF);
655 /* Wait for TC flag in order to write data in DR */
656 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
660 WRITE_REG(husart
->Instance
->DR
, (*pTxData
++ & (uint8_t)0x00FF));
662 /* Wait for RXNE Flag */
663 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, Timeout
) != HAL_OK
)
667 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
670 *pRxData
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x00FF);
675 *pRxData
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x007F);
680 husart
->State
= HAL_USART_STATE_READY
;
682 /* Process Unlocked */
683 __HAL_UNLOCK(husart
);
694 * @brief Simplex Send an amount of data in non-blocking mode.
695 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
696 * the configuration information for the specified USART module.
697 * @param pTxData: Pointer to data buffer
698 * @param Size: Amount of data to be sent
700 * @note The USART errors are not managed to avoid the overrun error.
702 HAL_StatusTypeDef
HAL_USART_Transmit_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
704 if(husart
->State
== HAL_USART_STATE_READY
)
706 if((pTxData
== HAL_NULL
) || (Size
== 0))
714 husart
->pTxBuffPtr
= pTxData
;
715 husart
->TxXferSize
= Size
;
716 husart
->TxXferCount
= Size
;
718 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
719 husart
->State
= HAL_USART_STATE_BUSY_TX
;
721 /* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
722 are not managed by the USART transmit process to avoid the overrun interrupt
723 when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
724 to benefit for the frame error and noise interrupts the USART mode should be
725 configured only for transmit "USART_MODE_TX"
726 The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
727 Noise error interrupt */
729 /* Process Unlocked */
730 __HAL_UNLOCK(husart
);
732 /* Enable the USART Transmit Data Register Empty Interrupt */
733 __HAL_USART_ENABLE_IT(husart
, USART_IT_TXE
);
744 * @brief Simplex Receive an amount of data in non-blocking mode.
745 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
746 * the configuration information for the specified USART module.
747 * @param pRxData: Pointer to data buffer
748 * @param Size: Amount of data to be received
751 HAL_StatusTypeDef
HAL_USART_Receive_IT(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
753 if(husart
->State
== HAL_USART_STATE_READY
)
755 if((pRxData
== HAL_NULL
) || (Size
== 0))
762 husart
->pRxBuffPtr
= pRxData
;
763 husart
->RxXferSize
= Size
;
764 husart
->RxXferCount
= Size
;
766 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
767 husart
->State
= HAL_USART_STATE_BUSY_RX
;
769 /* Enable the USART Data Register not empty Interrupt */
770 __HAL_USART_ENABLE_IT(husart
, USART_IT_RXNE
);
772 /* Enable the USART Parity Error Interrupt */
773 __HAL_USART_ENABLE_IT(husart
, USART_IT_PE
);
775 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
776 __HAL_USART_ENABLE_IT(husart
, USART_IT_ERR
);
778 /* Process Unlocked */
779 __HAL_UNLOCK(husart
);
781 /* Send dummy byte in order to generate the clock for the slave to send data */
782 WRITE_REG(husart
->Instance
->DR
, (DUMMY_DATA
& (uint16_t)0x01FF));
793 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
794 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
795 * the configuration information for the specified USART module.
796 * @param pTxData: Pointer to data transmitted buffer
797 * @param pRxData: Pointer to data received buffer
798 * @param Size: Amount of data to be received
801 HAL_StatusTypeDef
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
)
803 if(husart
->State
== HAL_USART_STATE_READY
)
805 if((pTxData
== HAL_NULL
) || (pRxData
== HAL_NULL
) || (Size
== 0))
812 husart
->pRxBuffPtr
= pRxData
;
813 husart
->RxXferSize
= Size
;
814 husart
->RxXferCount
= Size
;
815 husart
->pTxBuffPtr
= pTxData
;
816 husart
->TxXferSize
= Size
;
817 husart
->TxXferCount
= Size
;
819 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
820 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
822 /* Enable the USART Data Register not empty Interrupt */
823 __HAL_USART_ENABLE_IT(husart
, USART_IT_RXNE
);
825 /* Enable the USART Parity Error Interrupt */
826 __HAL_USART_ENABLE_IT(husart
, USART_IT_PE
);
828 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
829 __HAL_USART_ENABLE_IT(husart
, USART_IT_ERR
);
831 /* Process Unlocked */
832 __HAL_UNLOCK(husart
);
834 /* Enable the USART Transmit Data Register Empty Interrupt */
835 __HAL_USART_ENABLE_IT(husart
, USART_IT_TXE
);
846 * @brief Simplex Send an amount of data in non-blocking mode.
847 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
848 * the configuration information for the specified USART module.
849 * @param pTxData: Pointer to data buffer
850 * @param Size: Amount of data to be sent
853 HAL_StatusTypeDef
HAL_USART_Transmit_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
857 if(husart
->State
== HAL_USART_STATE_READY
)
859 if((pTxData
== HAL_NULL
) || (Size
== 0))
866 husart
->pTxBuffPtr
= pTxData
;
867 husart
->TxXferSize
= Size
;
868 husart
->TxXferCount
= Size
;
870 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
871 husart
->State
= HAL_USART_STATE_BUSY_TX
;
873 /* Set the USART DMA transfer complete callback */
874 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
876 /* Set the USART DMA Half transfer complete callback */
877 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
879 /* Set the DMA error callback */
880 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
882 /* Enable the USART transmit DMA channel */
883 tmp
= (uint32_t*)&pTxData
;
884 HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&husart
->Instance
->DR
, Size
);
886 /* Enable the DMA transfer for transmit request by setting the DMAT bit
887 in the USART CR3 register */
888 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
890 /* Process Unlocked */
891 __HAL_UNLOCK(husart
);
902 * @brief Full-Duplex Receive an amount of data in non-blocking mode.
903 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
904 * the configuration information for the specified USART module.
905 * @param pRxData: Pointer to data buffer
906 * @param Size: Amount of data to be received
908 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
909 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
911 HAL_StatusTypeDef
HAL_USART_Receive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
915 if(husart
->State
== HAL_USART_STATE_READY
)
917 if((pRxData
== HAL_NULL
) || (Size
== 0))
925 husart
->pRxBuffPtr
= pRxData
;
926 husart
->RxXferSize
= Size
;
927 husart
->pTxBuffPtr
= pRxData
;
928 husart
->TxXferSize
= Size
;
930 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
931 husart
->State
= HAL_USART_STATE_BUSY_RX
;
933 /* Set the USART DMA Rx transfer complete callback */
934 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
936 /* Set the USART DMA Half transfer complete callback */
937 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
939 /* Set the USART DMA Rx transfer error callback */
940 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
942 /* Enable the USART receive DMA channel */
943 tmp
= (uint32_t*)&pRxData
;
944 HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->DR
, *(uint32_t*)tmp
, Size
);
946 /* Enable the USART transmit DMA channel: the transmit channel is used in order
947 to generate in the non-blocking mode the clock to the slave device,
948 this mode isn't a simplex receive mode but a full-duplex receive one */
949 HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&husart
->Instance
->DR
, Size
);
951 /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer
952 when using the USART in circular mode */
953 __HAL_USART_CLEAR_OREFLAG(husart
);
955 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
956 in the USART CR3 register */
957 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
959 /* Enable the DMA transfer for transmit request by setting the DMAT bit
960 in the USART CR3 register */
961 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
963 /* Process Unlocked */
964 __HAL_UNLOCK(husart
);
975 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
976 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
977 * the configuration information for the specified USART module.
978 * @param pTxData: Pointer to data transmitted buffer
979 * @param pRxData: Pointer to data received buffer
980 * @param Size: Amount of data to be received
981 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
984 HAL_StatusTypeDef
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
, uint16_t Size
)
988 if(husart
->State
== HAL_USART_STATE_READY
)
990 if((pTxData
== HAL_NULL
) || (pRxData
== HAL_NULL
) || (Size
== 0))
997 husart
->pRxBuffPtr
= pRxData
;
998 husart
->RxXferSize
= Size
;
999 husart
->pTxBuffPtr
= pTxData
;
1000 husart
->TxXferSize
= Size
;
1002 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1003 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
1005 /* Set the USART DMA Rx transfer complete callback */
1006 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
1008 /* Set the USART DMA Half transfer complete callback */
1009 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
1011 /* Set the USART DMA Tx transfer complete callback */
1012 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
1014 /* Set the USART DMA Half transfer complete callback */
1015 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
1017 /* Set the USART DMA Tx transfer error callback */
1018 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
1020 /* Set the USART DMA Rx transfer error callback */
1021 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
1023 /* Enable the USART receive DMA channel */
1024 tmp
= (uint32_t*)&pRxData
;
1025 HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->DR
, *(uint32_t*)tmp
, Size
);
1027 /* Enable the USART transmit DMA channel */
1028 tmp
= (uint32_t*)&pTxData
;
1029 HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&husart
->Instance
->DR
, Size
);
1031 /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
1032 __HAL_USART_CLEAR_OREFLAG(husart
);
1034 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1035 in the USART CR3 register */
1036 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1038 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1039 in the USART CR3 register */
1040 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1042 /* Process Unlocked */
1043 __HAL_UNLOCK(husart
);
1054 * @brief Pauses the DMA Transfer.
1055 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1056 * the configuration information for the specified USART module.
1057 * @retval HAL status
1059 HAL_StatusTypeDef
HAL_USART_DMAPause(USART_HandleTypeDef
*husart
)
1061 /* Process Locked */
1064 /* Disable the USART DMA Tx request */
1065 CLEAR_BIT(husart
->Instance
->CR3
, (uint32_t)(USART_CR3_DMAT
));
1067 /* Process Unlocked */
1068 __HAL_UNLOCK(husart
);
1074 * @brief Resumes the DMA Transfer.
1075 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1076 * the configuration information for the specified USART module.
1077 * @retval HAL status
1079 HAL_StatusTypeDef
HAL_USART_DMAResume(USART_HandleTypeDef
*husart
)
1081 /* Process Locked */
1084 /* Enable the USART DMA Tx request */
1085 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1087 /* Process Unlocked */
1088 __HAL_UNLOCK(husart
);
1094 * @brief Stops the DMA Transfer.
1095 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1096 * the configuration information for the specified USART module.
1097 * @retval HAL status
1099 HAL_StatusTypeDef
HAL_USART_DMAStop(USART_HandleTypeDef
*husart
)
1101 /* The Lock is not implemented on this API to allow the user application
1102 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
1103 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1104 and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
1107 /* Abort the USART DMA Tx channel */
1108 if(husart
->hdmatx
!= HAL_NULL
)
1110 HAL_DMA_Abort(husart
->hdmatx
);
1112 /* Abort the USART DMA Rx channel */
1113 if(husart
->hdmarx
!= HAL_NULL
)
1115 HAL_DMA_Abort(husart
->hdmarx
);
1118 /* Disable the USART Tx/Rx DMA requests */
1119 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1120 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1122 husart
->State
= HAL_USART_STATE_READY
;
1128 * @brief This function handles USART interrupt request.
1129 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1130 * the configuration information for the specified USART module.
1133 void HAL_USART_IRQHandler(USART_HandleTypeDef
*husart
)
1135 uint32_t tmp1
= 0, tmp2
= 0;
1137 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_PE
);
1138 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_PE
);
1139 /* USART parity error interrupt occurred -----------------------------------*/
1140 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1142 __HAL_USART_CLEAR_PEFLAG(husart
);
1143 husart
->ErrorCode
|= HAL_USART_ERROR_PE
;
1146 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_FE
);
1147 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_ERR
);
1148 /* USART frame error interrupt occurred ------------------------------------*/
1149 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1151 __HAL_USART_CLEAR_FEFLAG(husart
);
1152 husart
->ErrorCode
|= HAL_USART_ERROR_FE
;
1155 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_NE
);
1156 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_ERR
);
1157 /* USART noise error interrupt occurred ------------------------------------*/
1158 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1160 __HAL_USART_CLEAR_NEFLAG(husart
);
1161 husart
->ErrorCode
|= HAL_USART_ERROR_NE
;
1164 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_ORE
);
1165 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_ERR
);
1166 /* USART Over-Run interrupt occurred ---------------------------------------*/
1167 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1169 __HAL_USART_CLEAR_OREFLAG(husart
);
1170 husart
->ErrorCode
|= HAL_USART_ERROR_ORE
;
1173 if(husart
->ErrorCode
!= HAL_USART_ERROR_NONE
)
1175 /* Set the USART state ready to be able to start again the process */
1176 husart
->State
= HAL_USART_STATE_READY
;
1178 HAL_USART_ErrorCallback(husart
);
1181 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_RXNE
);
1182 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_RXNE
);
1183 /* USART in mode Receiver --------------------------------------------------*/
1184 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1186 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1188 USART_Receive_IT(husart
);
1192 USART_TransmitReceive_IT(husart
);
1196 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_TXE
);
1197 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_TXE
);
1198 /* USART in mode Transmitter -----------------------------------------------*/
1199 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1201 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1203 USART_Transmit_IT(husart
);
1207 USART_TransmitReceive_IT(husart
);
1211 tmp1
= __HAL_USART_GET_FLAG(husart
, USART_FLAG_TC
);
1212 tmp2
= __HAL_USART_GET_IT_SOURCE(husart
, USART_IT_TC
);
1213 /* USART in mode Transmitter (transmission end) -----------------------------*/
1214 if((tmp1
!= RESET
) && (tmp2
!= RESET
))
1216 USART_EndTransmit_IT(husart
);
1223 * @brief Tx Transfer completed callbacks.
1224 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1225 * the configuration information for the specified USART module.
1228 __weak
void HAL_USART_TxCpltCallback(USART_HandleTypeDef
*husart
)
1230 /* NOTE: This function Should not be modified, when the callback is needed,
1231 the HAL_USART_TxCpltCallback could be implemented in the user file
1236 * @brief Tx Half Transfer completed callbacks.
1237 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1238 * the configuration information for the specified USART module.
1241 __weak
void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef
*husart
)
1243 /* NOTE: This function Should not be modified, when the callback is needed,
1244 the HAL_USART_TxHalfCpltCallback could be implemented in the user file
1249 * @brief Rx Transfer completed callbacks.
1250 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1251 * the configuration information for the specified USART module.
1254 __weak
void HAL_USART_RxCpltCallback(USART_HandleTypeDef
*husart
)
1256 /* NOTE: This function Should not be modified, when the callback is needed,
1257 the HAL_USART_RxCpltCallback could be implemented in the user file
1262 * @brief Rx Half Transfer completed callbacks.
1263 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1264 * the configuration information for the specified USART module.
1267 __weak
void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef
*husart
)
1269 /* NOTE: This function Should not be modified, when the callback is needed,
1270 the HAL_USART_RxHalfCpltCallback could be implemented in the user file
1275 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
1276 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1277 * the configuration information for the specified USART module.
1280 __weak
void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef
*husart
)
1282 /* NOTE: This function Should not be modified, when the callback is needed,
1283 the HAL_USART_TxRxCpltCallback could be implemented in the user file
1288 * @brief USART error callbacks.
1289 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1290 * the configuration information for the specified USART module.
1293 __weak
void HAL_USART_ErrorCallback(USART_HandleTypeDef
*husart
)
1295 /* NOTE: This function Should not be modified, when the callback is needed,
1296 the HAL_USART_ErrorCallback could be implemented in the user file
1304 /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
1305 * @brief USART State and Errors functions
1308 ==============================================================================
1309 ##### Peripheral State and Errors functions #####
1310 ==============================================================================
1312 This subsection provides a set of functions allowing to return the State of
1314 process, return Peripheral Errors occurred during communication process
1315 (+) HAL_USART_GetState() API can be helpful to check in run-time the state
1316 of the USART peripheral.
1317 (+) HAL_USART_GetError() check in run-time errors that could be occurred during
1324 * @brief Returns the USART state.
1325 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1326 * the configuration information for the specified USART module.
1329 HAL_USART_StateTypeDef
HAL_USART_GetState(USART_HandleTypeDef
*husart
)
1331 return husart
->State
;
1335 * @brief Return the USART error code
1336 * @param husart : pointer to a USART_HandleTypeDef structure that contains
1337 * the configuration information for the specified USART.
1338 * @retval USART Error Code
1340 uint32_t HAL_USART_GetError(USART_HandleTypeDef
*husart
)
1342 return husart
->ErrorCode
;
1353 /** @defgroup USART_Private_Functions USART Private Functions
1354 * @brief USART Private functions
1358 * @brief DMA USART transmit process complete callback.
1359 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1360 * the configuration information for the specified DMA module.
1363 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
)
1365 USART_HandleTypeDef
* husart
= ( USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1367 /* DMA Normal mode */
1368 if((hdma
->Instance
->CCR
& DMA_CCR_CIRC
) == 0)
1370 husart
->TxXferCount
= 0;
1371 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1373 /* Wait for USART TC Flag */
1374 if(USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, USART_TIMEOUT_VALUE
) != HAL_OK
)
1376 /* Timeout occurred */
1377 husart
->State
= HAL_USART_STATE_TIMEOUT
;
1378 HAL_USART_ErrorCallback(husart
);
1383 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1384 in the USART CR3 register */
1385 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1386 husart
->State
= HAL_USART_STATE_READY
;
1387 HAL_USART_TxCpltCallback(husart
);
1391 /* DMA Circular mode */
1394 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1396 HAL_USART_TxCpltCallback(husart
);
1402 * @brief DMA USART transmit process half complete callback
1403 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1404 * the configuration information for the specified DMA module.
1407 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
)
1409 USART_HandleTypeDef
* husart
= (USART_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
1411 HAL_USART_TxHalfCpltCallback(husart
);
1415 * @brief DMA USART receive process complete callback.
1416 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1417 * the configuration information for the specified DMA module.
1420 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
)
1422 USART_HandleTypeDef
* husart
= ( USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1424 /* DMA Normal mode */
1425 if((hdma
->Instance
->CCR
& DMA_CCR_CIRC
) == 0)
1427 husart
->RxXferCount
= 0;
1428 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1430 /* Disable the DMA transfer for the receiver requests by setting the DMAR bit
1431 in the USART CR3 register */
1432 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1434 HAL_USART_RxCpltCallback(husart
);
1436 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1439 /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
1440 in the USART CR3 register */
1441 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1442 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1444 HAL_USART_TxRxCpltCallback(husart
);
1446 husart
->State
= HAL_USART_STATE_READY
;
1448 /* DMA circular mode */
1451 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1453 HAL_USART_RxCpltCallback(husart
);
1455 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1458 HAL_USART_TxRxCpltCallback(husart
);
1464 * @brief DMA USART receive process half complete callback
1465 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1466 * the configuration information for the specified DMA module.
1469 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
)
1471 USART_HandleTypeDef
* husart
= (USART_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
1473 HAL_USART_RxHalfCpltCallback(husart
);
1477 * @brief DMA USART communication error callback.
1478 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
1479 * the configuration information for the specified DMA module.
1482 static void USART_DMAError(DMA_HandleTypeDef
*hdma
)
1484 USART_HandleTypeDef
* husart
= ( USART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1486 husart
->RxXferCount
= 0;
1487 husart
->TxXferCount
= 0;
1488 husart
->ErrorCode
|= HAL_USART_ERROR_DMA
;
1489 husart
->State
= HAL_USART_STATE_READY
;
1491 HAL_USART_ErrorCallback(husart
);
1495 * @brief This function handles USART Communication Timeout.
1496 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1497 * the configuration information for the specified USART module.
1498 * @param Flag: specifies the USART flag to check.
1499 * @param Status: The new Flag status (SET or RESET).
1500 * @param Timeout: Timeout duration
1501 * @retval HAL status
1503 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
, uint32_t Timeout
)
1505 uint32_t tickstart
= 0;
1508 tickstart
= HAL_GetTick();
1510 /* Wait until flag is set */
1513 while(__HAL_USART_GET_FLAG(husart
, Flag
) == RESET
)
1515 /* Check for the Timeout */
1516 if(Timeout
!= HAL_MAX_DELAY
)
1518 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1520 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1521 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
1522 __HAL_USART_DISABLE_IT(husart
, USART_IT_RXNE
);
1523 __HAL_USART_DISABLE_IT(husart
, USART_IT_PE
);
1524 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
1526 husart
->State
= HAL_USART_STATE_READY
;
1528 /* Process Unlocked */
1529 __HAL_UNLOCK(husart
);
1538 while(__HAL_USART_GET_FLAG(husart
, Flag
) != RESET
)
1540 /* Check for the Timeout */
1541 if(Timeout
!= HAL_MAX_DELAY
)
1543 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1545 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1546 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
1547 __HAL_USART_DISABLE_IT(husart
, USART_IT_RXNE
);
1548 __HAL_USART_DISABLE_IT(husart
, USART_IT_PE
);
1549 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
1551 husart
->State
= HAL_USART_STATE_READY
;
1553 /* Process Unlocked */
1554 __HAL_UNLOCK(husart
);
1565 * @brief Simplex Send an amount of data in non-blocking mode.
1566 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1567 * the configuration information for the specified USART module.
1568 * @retval HAL status
1569 * @note The USART errors are not managed to avoid the overrun error.
1571 static HAL_StatusTypeDef
USART_Transmit_IT(USART_HandleTypeDef
*husart
)
1575 if(husart
->State
== HAL_USART_STATE_BUSY_TX
)
1577 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
1579 tmp
= (uint16_t*) husart
->pTxBuffPtr
;
1580 WRITE_REG(husart
->Instance
->DR
, (uint16_t)(*tmp
& (uint16_t)0x01FF));
1581 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
1583 husart
->pTxBuffPtr
+= 2;
1587 husart
->pTxBuffPtr
+= 1;
1592 WRITE_REG(husart
->Instance
->DR
, (uint8_t)(*husart
->pTxBuffPtr
++ & (uint8_t)0x00FF));
1595 if(--husart
->TxXferCount
== 0)
1597 /* Disable the USART Transmit data register empty Interrupt */
1598 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
1600 /* Enable the USART Transmit Complete Interrupt */
1601 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
1613 * @brief Wraps up transmission in non blocking mode.
1614 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1615 * the configuration information for the specified USART module.
1616 * @retval HAL status
1618 static HAL_StatusTypeDef
USART_EndTransmit_IT(USART_HandleTypeDef
*husart
)
1620 /* Disable the USART Transmit Complete Interrupt */
1621 __HAL_USART_DISABLE_IT(husart
, USART_IT_TC
);
1623 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1624 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
1626 husart
->State
= HAL_USART_STATE_READY
;
1628 HAL_USART_TxCpltCallback(husart
);
1635 * @brief Simplex Receive an amount of data in non-blocking mode.
1636 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1637 * the configuration information for the specified USART module.
1638 * @retval HAL status
1640 static HAL_StatusTypeDef
USART_Receive_IT(USART_HandleTypeDef
*husart
)
1643 if(husart
->State
== HAL_USART_STATE_BUSY_RX
)
1645 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
1647 tmp
= (uint16_t*) husart
->pRxBuffPtr
;
1648 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
1650 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x01FF);
1651 husart
->pRxBuffPtr
+= 2;
1655 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x00FF);
1656 husart
->pRxBuffPtr
+= 1;
1658 if(--husart
->RxXferCount
!= 0x00)
1660 /* Send dummy byte in order to generate the clock for the slave to send the next data */
1661 WRITE_REG(husart
->Instance
->DR
, (DUMMY_DATA
& (uint16_t)0x01FF));
1666 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
1668 *husart
->pRxBuffPtr
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x00FF);
1672 *husart
->pRxBuffPtr
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x007F);
1675 if(--husart
->RxXferCount
!= 0x00)
1677 /* Send dummy byte in order to generate the clock for the slave to send the next data */
1678 WRITE_REG(husart
->Instance
->DR
, (DUMMY_DATA
& (uint16_t)0x00FF));
1682 if(husart
->RxXferCount
== 0)
1684 /* Disable the USART RXNE Interrupt */
1685 __HAL_USART_DISABLE_IT(husart
, USART_IT_RXNE
);
1687 /* Disable the USART Parity Error Interrupt */
1688 __HAL_USART_DISABLE_IT(husart
, USART_IT_PE
);
1690 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1691 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
1693 husart
->State
= HAL_USART_STATE_READY
;
1694 HAL_USART_RxCpltCallback(husart
);
1707 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1708 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1709 * the configuration information for the specified USART module.
1710 * @retval HAL status
1712 static HAL_StatusTypeDef
USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
)
1716 if(husart
->State
== HAL_USART_STATE_BUSY_TX_RX
)
1718 if(husart
->TxXferCount
!= 0x00)
1720 if(__HAL_USART_GET_FLAG(husart
, USART_FLAG_TXE
) != RESET
)
1722 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
1724 tmp
= (uint16_t*) husart
->pTxBuffPtr
;
1725 WRITE_REG(husart
->Instance
->DR
, (uint16_t)(*tmp
& (uint16_t)0x01FF));
1726 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
1728 husart
->pTxBuffPtr
+= 2;
1732 husart
->pTxBuffPtr
+= 1;
1737 WRITE_REG(husart
->Instance
->DR
, (uint8_t)(*husart
->pTxBuffPtr
++ & (uint8_t)0x00FF));
1739 husart
->TxXferCount
--;
1741 /* Check the latest data transmitted */
1742 if(husart
->TxXferCount
== 0)
1744 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
1749 if(husart
->RxXferCount
!= 0x00)
1751 if(__HAL_USART_GET_FLAG(husart
, USART_FLAG_RXNE
) != RESET
)
1753 if(husart
->Init
.WordLength
== USART_WORDLENGTH_9B
)
1755 tmp
= (uint16_t*) husart
->pRxBuffPtr
;
1756 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
1758 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x01FF);
1759 husart
->pRxBuffPtr
+= 2;
1763 *tmp
= (uint16_t)(husart
->Instance
->DR
& (uint16_t)0x00FF);
1764 husart
->pRxBuffPtr
+= 1;
1769 if(husart
->Init
.Parity
== USART_PARITY_NONE
)
1771 *husart
->pRxBuffPtr
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x00FF);
1775 *husart
->pRxBuffPtr
++ = (uint8_t)(husart
->Instance
->DR
& (uint8_t)0x007F);
1778 husart
->RxXferCount
--;
1782 /* Check the latest data received */
1783 if(husart
->RxXferCount
== 0)
1785 __HAL_USART_DISABLE_IT(husart
, USART_IT_RXNE
);
1787 /* Disable the USART Parity Error Interrupt */
1788 __HAL_USART_DISABLE_IT(husart
, USART_IT_PE
);
1790 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1791 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
1793 husart
->State
= HAL_USART_STATE_READY
;
1795 HAL_USART_TxRxCpltCallback(husart
);
1809 * @brief Configures the USART peripheral.
1810 * @param husart: Pointer to a USART_HandleTypeDef structure that contains
1811 * the configuration information for the specified USART module.
1814 static void USART_SetConfig(USART_HandleTypeDef
*husart
)
1816 /* Check the parameters */
1817 assert_param(IS_USART_INSTANCE(husart
->Instance
));
1818 assert_param(IS_USART_POLARITY(husart
->Init
.CLKPolarity
));
1819 assert_param(IS_USART_PHASE(husart
->Init
.CLKPhase
));
1820 assert_param(IS_USART_LASTBIT(husart
->Init
.CLKLastBit
));
1821 assert_param(IS_USART_BAUDRATE(husart
->Init
.BaudRate
));
1822 assert_param(IS_USART_WORD_LENGTH(husart
->Init
.WordLength
));
1823 assert_param(IS_USART_STOPBITS(husart
->Init
.StopBits
));
1824 assert_param(IS_USART_PARITY(husart
->Init
.Parity
));
1825 assert_param(IS_USART_MODE(husart
->Init
.Mode
));
1827 /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
1828 receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
1829 CLEAR_BIT(husart
->Instance
->CR1
, ((uint32_t)(USART_CR1_TE
| USART_CR1_RE
)));
1831 /*---------------------------- USART CR2 Configuration ---------------------*/
1832 /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
1833 /* Set CPOL bit according to husart->Init.CLKPolarity value */
1834 /* Set CPHA bit according to husart->Init.CLKPhase value */
1835 /* Set LBCL bit according to husart->Init.CLKLastBit value */
1836 /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
1837 /* Write to USART CR2 */
1838 MODIFY_REG(husart
->Instance
->CR2
,
1839 (uint32_t)(USART_CR2_CPHA
| USART_CR2_CPOL
| USART_CR2_CLKEN
| USART_CR2_LBCL
| USART_CR2_STOP
),
1840 ((uint32_t)(USART_CLOCK_ENABLED
| husart
->Init
.CLKPolarity
| husart
->Init
.CLKPhase
| husart
->Init
.CLKLastBit
| husart
->Init
.StopBits
)));
1842 /*-------------------------- USART CR1 Configuration -----------------------*/
1843 /* Configure the USART Word Length, Parity and mode:
1844 Set the M bits according to husart->Init.WordLength value
1845 Set PCE and PS bits according to husart->Init.Parity value
1846 Set TE and RE bits according to husart->Init.Mode value */
1847 MODIFY_REG(husart
->Instance
->CR1
,
1848 (uint32_t)(USART_CR1_M
| USART_CR1_PCE
| USART_CR1_PS
| USART_CR1_TE
| USART_CR1_RE
),
1849 (uint32_t)husart
->Init
.WordLength
| husart
->Init
.Parity
| husart
->Init
.Mode
);
1851 /*-------------------------- USART CR3 Configuration -----------------------*/
1852 /* Clear CTSE and RTSE bits */
1853 CLEAR_BIT(husart
->Instance
->CR3
, (uint32_t)(USART_CR3_RTSE
| USART_CR3_CTSE
));
1855 /*-------------------------- USART BRR Configuration -----------------------*/
1856 if((husart
->Instance
== USART1
))
1858 husart
->Instance
->BRR
= USART_BRR(HAL_RCC_GetPCLK2Freq(), husart
->Init
.BaudRate
);
1862 husart
->Instance
->BRR
= USART_BRR(HAL_RCC_GetPCLK1Freq(), husart
->Init
.BaudRate
);
1870 #endif /* HAL_USART_MODULE_ENABLED */
1879 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/