2 ******************************************************************************
3 * @file stm32l0xx_hal_usart.c
4 * @author MCD Application Team
6 * @date 06-February-2015
7 * @brief USART HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
12 * + Initialization and de-initialization functions
13 * + IO operation functions
14 * + Peripheral Control functions
17 ===============================================================================
18 ##### How to use this driver #####
19 ===============================================================================
21 The USART HAL driver can be used as follows:
23 (#) Declare a USART_HandleTypeDef handle structure.
24 (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API:
25 (##) Enable the USARTx interface clock.
26 (##) USART pins configuration:
27 (+++) Enable the clock for the USART GPIOs.
28 (+++) Configure these USART pins as alternate function pull-up.
29 (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
30 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
31 (+++) Configure the USARTx interrupt priority.
32 (+++) Enable the NVIC USART IRQ handle.
33 (@) The specific USART interrupts (Transmission complete interrupt,
34 RXNE interrupt and Error Interrupts) will be managed using the macros
35 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
36 (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
37 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
38 (+++) Declare a DMA handle structure for the Tx/Rx stream.
39 (+++) Enable the DMAx interface clock.
40 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
41 (+++) Configure the DMA Tx/Rx Stream.
42 (+++) Associate the initilalized DMA handle to the USART DMA Tx/Rx handle.
43 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
45 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
46 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
48 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
49 (+) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
50 by calling the customed HAL_USART_MspInit(&husart) API.
53 ******************************************************************************
56 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
58 * Redistribution and use in source and binary forms, with or without modification,
59 * are permitted provided that the following conditions are met:
60 * 1. Redistributions of source code must retain the above copyright notice,
61 * this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright notice,
63 * this list of conditions and the following disclaimer in the documentation
64 * and/or other materials provided with the distribution.
65 * 3. Neither the name of STMicroelectronics nor the names of its contributors
66 * may be used to endorse or promote products derived from this software
67 * without specific prior written permission.
69 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
70 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
73 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
75 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
76 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
77 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
78 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80 ******************************************************************************
83 /* Includes ------------------------------------------------------------------*/
84 #include "stm32l0xx_hal.h"
86 /** @addtogroup STM32L0xx_HAL_Driver
91 * @brief USART Synchronous module driver
94 #ifdef HAL_USART_MODULE_ENABLED
95 /* Private typedef -----------------------------------------------------------*/
96 /* Private define ------------------------------------------------------------*/
97 #define DUMMY_DATA ((uint16_t) 0xFFFF)
98 #define TEACK_REACK_TIMEOUT ((uint32_t) 1000)
99 #define HAL_USART_TXDMA_TIMEOUTVALUE ((uint32_t) 22000)
102 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | \
103 USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
104 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
105 USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP))
106 /* Private macro -------------------------------------------------------------*/
107 /* Private variables ---------------------------------------------------------*/
108 /* Private function prototypes -----------------------------------------------*/
109 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
110 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
111 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
112 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
113 static void USART_DMAError(DMA_HandleTypeDef *hdma);
114 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
115 static void USART_SetConfig (USART_HandleTypeDef *husart);
116 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
117 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
118 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
119 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
120 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
121 /* Private functions ---------------------------------------------------------*/
124 /** @addtogroup USART_Exported_Functions
128 /** @addtogroup USART_Exported_Functions_Group1
129 * @brief Initialization and Configuration functions
132 ===============================================================================
133 ##### Initialization and Configuration functions #####
134 ===============================================================================
136 This subsection provides a set of functions allowing to initialize the USART
137 in asynchronous and in synchronous modes.
138 (+) For the asynchronous mode only these parameters can be configured:
142 (++) Parity: If the parity is enabled, then the MSB bit of the data written
143 in the data register is transmitted but is changed by the parity bit.
144 Depending on the frame length defined by the M bit (8-bits or 9-bits),
145 the possible USART frame formats are as listed in the following table:
146 +-------------------------------------------------------------+
147 | M0 bit | PCE bit | USART frame |
148 |---------------------|---------------------------------------|
149 | 0 | 0 | | SB | 8 bit data | STB | |
150 |---------|-----------|---------------------------------------|
151 | 0 | 1 | | SB | 7 bit data | PB | STB | |
152 |---------|-----------|---------------------------------------|
153 | 1 | 0 | | SB | 9 bit data | STB | |
154 |---------|-----------|---------------------------------------|
155 | 1 | 1 | | SB | 8 bit data | PB | STB | |
156 +-------------------------------------------------------------+
160 (++) Receiver/transmitter modes
163 The HAL_USART_Init() function follows the USART synchronous configuration
164 procedure (details for the procedure are available in reference manual (RM0329)).
171 * @brief Initializes the USART mode according to the specified
172 * parameters in the USART_InitTypeDef and create the associated handle.
173 * @param husart: USART handle
176 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
178 /* Check the USART handle allocation */
184 /* Check the parameters */
185 assert_param(IS_USART_INSTANCE(husart->Instance));
187 if(husart->State == HAL_USART_STATE_RESET)
189 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
190 HAL_USART_MspInit(husart);
193 husart->State = HAL_USART_STATE_BUSY;
195 /* Disable the Peripheral */
196 __HAL_USART_DISABLE(husart);
198 /* Set the Usart Communication parameters */
199 USART_SetConfig(husart);
201 /* In Synchronous mode, the following bits must be kept cleared:
202 - LINEN bit in the USART_CR2 register
203 - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
204 husart->Instance->CR2 &= ~USART_CR2_LINEN;
205 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
207 /* Enable the Peripharal */
208 __HAL_USART_ENABLE(husart);
210 /* TEACK and/or REACK to check before moving husart->State to Ready */
211 return (USART_CheckIdleState(husart));
215 * @brief DeInitializes the USART peripheral.
216 * @param husart: USART handle
219 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
221 /* Check the USART handle allocation */
227 /* Check the parameters */
228 assert_param(IS_USART_INSTANCE(husart->Instance));
230 husart->State = HAL_USART_STATE_BUSY;
232 husart->Instance->CR1 = 0x0;
233 husart->Instance->CR2 = 0x0;
234 husart->Instance->CR3 = 0x0;
236 /* DeInit the low level hardware */
237 HAL_USART_MspDeInit(husart);
239 husart->ErrorCode = HAL_USART_ERROR_NONE;
240 husart->State = HAL_USART_STATE_RESET;
243 __HAL_UNLOCK(husart);
249 * @brief USART MSP Init.
250 * @param husart: USART handle
253 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
255 /* NOTE: This function Should not be modified, when the callback is needed,
256 the HAL_USART_MspInit could be implenetd in the user file
261 * @brief USART MSP DeInit.
262 * @param husart: USART handle
265 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
267 /* NOTE: This function Should not be modified, when the callback is needed,
268 the HAL_USART_MspDeInit could be implenetd in the user file
276 /** @addtogroup USART_Exported_Functions_Group2
277 * @brief USART Transmit and Receive functions
280 ===============================================================================
281 ##### IO operation functions #####
282 ===============================================================================
284 This subsection provides a set of functions allowing to manage the USART synchronous
287 [..] The USART supports master mode only: it cannot receive or send data related to an input
288 clock (SCLK is always an output).
290 (#) There are two modes of transfer:
291 (++) Blocking mode: The communication is performed in polling mode.
292 The HAL status of all data processing is returned by the same function
293 after finishing transfer.
294 (++) No-Blocking mode: The communication is performed using Interrupts
295 or DMA, These API's return the HAL status.
296 The end of the data processing will be indicated through the
297 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
299 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
300 will be executed respectivelly at the end of the transmit or Receive process
301 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected.
303 (#) Blocking mode API's are :
304 (++) HAL_USART_Transmit()in simplex mode
305 (++) HAL_USART_Receive() in full duplex receive only
306 (++) HAL_USART_TransmitReceive() in full duplex mode
308 (#) Non-Blocking mode API's with Interrupt are :
309 (++) HAL_USART_Transmit_IT()in simplex mode
310 (++) HAL_USART_Receive_IT() in full duplex receive only
311 (++) HAL_USART_TransmitReceive_IT()in full duplex mode
312 (++) HAL_USART_IRQHandler()
314 (#) No-Blocking mode functions with DMA are :
315 (++) HAL_USART_Transmit_DMA()in simplex mode
316 (++) HAL_USART_Receive_DMA() in full duplex receive only
317 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
318 (++) HAL_USART_DMAPause()
319 (++) HAL_USART_DMAResume()
320 (++) HAL_USART_DMAStop()
322 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
323 (++) HAL_USART_TxCpltCallback()
324 (++) HAL_USART_RxCpltCallback()
325 (++) HAL_USART_TxHalfCpltCallback()
326 (++) HAL_USART_RxHalfCpltCallback()
327 (++) HAL_USART_ErrorCallback()
328 (++) HAL_USART_TxRxCpltCallback()
335 * @brief Simplex Send an amount of data in blocking mode
336 * @param husart: USART handle
337 * @param pTxData: Pointer to data buffer
338 * @param Size: Amount of data to be sent
339 * @param Timeout : Timeout duration
342 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
346 if(husart->State == HAL_USART_STATE_READY)
348 if((pTxData == NULL) || (Size == 0))
356 husart->ErrorCode = HAL_USART_ERROR_NONE;
357 husart->State = HAL_USART_STATE_BUSY_TX;
359 husart->TxXferSize = Size;
360 husart->TxXferCount = Size;
362 /* Check the remaining data to be sent */
363 while(husart->TxXferCount > 0)
365 husart->TxXferCount--;
366 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
370 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
372 tmp = (uint16_t*) pTxData;
373 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
378 husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF);
382 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
387 husart->State = HAL_USART_STATE_READY;
389 /* Process Unlocked */
390 __HAL_UNLOCK(husart);
401 * @brief Receive an amount of data in blocking mode
402 * To receive synchronous data, dummy data are simultaneously transmitted
403 * @param husart: USART handle
404 * @param pRxData: pointer to data buffer
405 * @param Size: amount of data to be received
406 * @param Timeout : Timeout duration
409 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
414 if(husart->State == HAL_USART_STATE_READY)
416 if((pRxData == NULL) || (Size == 0))
423 husart->ErrorCode = HAL_USART_ERROR_NONE;
424 husart->State = HAL_USART_STATE_BUSY_RX;
426 husart->RxXferSize = Size;
427 husart->RxXferCount = Size;
429 /* Computation of USART mask to apply to RDR register */
430 USART_MASK_COMPUTATION(husart);
431 uhMask = husart->Mask;
433 /* as long as data have to be received */
434 while(husart->RxXferCount > 0)
436 husart->RxXferCount--;
438 /* Wait until TXE flag is set to send dummy byte in order to generate the
439 * clock for the slave to send data.
440 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
441 * can be written for all the cases. */
442 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
446 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FF);
448 /* Wait for RXNE Flag */
449 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
454 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
456 tmp = (uint16_t*) pRxData ;
457 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
462 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
466 husart->State = HAL_USART_STATE_READY;
468 /* Process Unlocked */
469 __HAL_UNLOCK(husart);
480 * @brief Full-Duplex Send and Receive an amount of data in blocking mode
481 * @param husart: USART handle
482 * @param pTxData: pointer to TX data buffer
483 * @param pRxData: pointer to RX data buffer
484 * @param Size: amount of data to be sent (same amount to be received)
485 * @param Timeout : Timeout duration
488 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
493 if(husart->State == HAL_USART_STATE_READY)
495 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
502 husart->ErrorCode = HAL_USART_ERROR_NONE;
503 husart->State = HAL_USART_STATE_BUSY_RX;
505 husart->RxXferSize = Size;
506 husart->TxXferSize = Size;
507 husart->TxXferCount = Size;
508 husart->RxXferCount = Size;
510 /* Computation of USART mask to apply to RDR register */
511 USART_MASK_COMPUTATION(husart);
512 uhMask = husart->Mask;
514 /* Check the remain data to be sent */
515 while(husart->TxXferCount > 0)
517 husart->TxXferCount--;
518 husart->RxXferCount--;
520 /* Wait until TXE flag is set to send data */
521 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
525 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
527 tmp = (uint16_t*) pTxData;
528 husart->Instance->TDR = (*tmp & uhMask);
533 husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask);
536 /* Wait for RXNE Flag */
537 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
542 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
544 tmp = (uint16_t*) pRxData ;
545 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
550 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
554 husart->State = HAL_USART_STATE_READY;
556 /* Process Unlocked */
557 __HAL_UNLOCK(husart);
568 * @brief Send an amount of data in interrupt mode
569 * @param husart: USART handle
570 * @param pTxData: Pointer to data buffer
571 * @param Size: Amount of data to be sent
574 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
576 if(husart->State == HAL_USART_STATE_READY)
578 if((pTxData == NULL ) || (Size == 0))
586 husart->pTxBuffPtr = pTxData;
587 husart->TxXferSize = Size;
588 husart->TxXferCount = Size;
590 husart->ErrorCode = HAL_USART_ERROR_NONE;
591 husart->State = HAL_USART_STATE_BUSY_TX;
593 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
594 are not managed by the USART Transmit Process to avoid the overrun interrupt
595 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
596 to benefit for the frame error and noise interrupts the usart mode should be
597 configured only for transmit "USART_MODE_TX" */
599 /* Process Unlocked */
600 __HAL_UNLOCK(husart);
602 /* Enable the USART Transmit Complete Interrupt */
603 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
614 * @brief Receive an amount of data in blocking mode
615 * To receive synchronous data, dummy data are simultaneously transmitted
616 * @param husart: usart handle
617 * @param pRxData: pointer to data buffer
618 * @param Size: amount of data to be received
621 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
623 if(husart->State == HAL_USART_STATE_READY)
625 if((pRxData == NULL ) || (Size == 0))
632 husart->pRxBuffPtr = pRxData;
633 husart->RxXferSize = Size;
634 husart->RxXferCount = Size;
636 USART_MASK_COMPUTATION(husart);
638 husart->ErrorCode = HAL_USART_ERROR_NONE;
639 husart->State = HAL_USART_STATE_BUSY_RX;
641 /* Enable the USART Parity Error Interrupt */
642 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
644 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
645 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
647 /* Enable the USART Data Register not empty Interrupt */
648 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
650 /* Process Unlocked */
651 __HAL_UNLOCK(husart);
653 /* Send dummy byte in order to generate the clock for the Slave to send the next data */
654 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
656 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FF);
660 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
672 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode
673 * @param husart: USART handle
674 * @param pTxData: pointer to TX data buffer
675 * @param pRxData: pointer to RX data buffer
676 * @param Size: amount of data to be sent (same amount to be received)
679 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
681 if(husart->State == HAL_USART_STATE_READY)
683 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
690 husart->pRxBuffPtr = pRxData;
691 husart->RxXferSize = Size;
692 husart->RxXferCount = Size;
693 husart->pTxBuffPtr = pTxData;
694 husart->TxXferSize = Size;
695 husart->TxXferCount = Size;
697 /* Computation of USART mask to apply to RDR register */
698 USART_MASK_COMPUTATION(husart);
700 husart->ErrorCode = HAL_USART_ERROR_NONE;
701 husart->State = HAL_USART_STATE_BUSY_TX_RX;
703 /* Enable the USART Data Register not empty Interrupt */
704 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
706 /* Enable the USART Parity Error Interrupt */
707 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
709 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
710 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
712 /* Process Unlocked */
713 __HAL_UNLOCK(husart);
715 /* Enable the USART Transmit Complete Interrupt */
716 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
727 * @brief Send an amount of data in DMA mode
728 * @param husart: USART handle
729 * @param pTxData: pointer to data buffer
730 * @param Size: amount of data to be sent
733 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
737 if(husart->State == HAL_USART_STATE_READY)
739 if((pTxData == NULL ) || (Size == 0))
746 husart->pTxBuffPtr = pTxData;
747 husart->TxXferSize = Size;
748 husart->TxXferCount = Size;
750 husart->ErrorCode = HAL_USART_ERROR_NONE;
751 husart->State = HAL_USART_STATE_BUSY_TX;
753 /* Set the USART DMA transfer complete callback */
754 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
756 /* Set the USART DMA Half transfer complete callback */
757 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
759 /* Set the DMA error callback */
760 husart->hdmatx->XferErrorCallback = USART_DMAError;
762 /* Enable the USART transmit DMA channel */
763 tmp = (uint32_t*)&pTxData;
764 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
766 /* Clear the TC flag in the SR register by writing 0 to it */
767 __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
769 /* Enable the DMA transfer for transmit request by setting the DMAT bit
770 in the USART CR3 register */
771 husart->Instance->CR3 |= USART_CR3_DMAT;
773 /* Process Unlocked */
774 __HAL_UNLOCK(husart);
785 * @brief Receive an amount of data in DMA mode
786 * @param husart: USART handle
787 * @param pRxData: pointer to data buffer
788 * @param Size: amount of data to be received
789 * @note When the USART parity is enabled (PCE = 1), the received data contain
790 * the parity bit (MSB position)
792 * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave.
794 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
798 if(husart->State == HAL_USART_STATE_READY)
800 if((pRxData == NULL ) || (Size == 0))
808 husart->pRxBuffPtr = pRxData;
809 husart->RxXferSize = Size;
810 husart->pTxBuffPtr = pRxData;
811 husart->TxXferSize = Size;
813 husart->ErrorCode = HAL_USART_ERROR_NONE;
814 husart->State = HAL_USART_STATE_BUSY_RX;
816 /* Set the USART DMA Rx transfer complete callback */
817 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
819 /* Set the USART DMA Half transfer complete callback */
820 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
822 /* Set the USART DMA Rx transfer error callback */
823 husart->hdmarx->XferErrorCallback = USART_DMAError;
825 /* Enable the USART receive DMA Stream */
826 tmp = (uint32_t*)&pRxData;
827 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
829 /* Enable the USART transmit DMA channel: the transmit channel is used in order
830 to generate in the non-blocking mode the clock to the slave device,
831 this mode isn't a simplex receive mode but a full-duplex receive mode */
832 tmp = (uint32_t*)&pRxData;
833 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
835 /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer
836 when using the USART in circular mode */
837 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
839 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
840 in the USART CR3 register */
841 husart->Instance->CR3 |= USART_CR3_DMAR;
843 /* Enable the DMA transfer for transmit request by setting the DMAT bit
844 in the USART CR3 register */
845 husart->Instance->CR3 |= USART_CR3_DMAT;
847 /* Process Unlocked */
848 __HAL_UNLOCK(husart);
859 * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode
860 * @param husart: usart handle
861 * @param pTxData: pointer to TX data buffer
862 * @param pRxData: pointer to RX data buffer
863 * @param Size: amount of data to be received/sent
864 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
867 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
871 if(husart->State == HAL_USART_STATE_READY)
873 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
880 husart->pRxBuffPtr = pRxData;
881 husart->RxXferSize = Size;
882 husart->pTxBuffPtr = pTxData;
883 husart->TxXferSize = Size;
885 husart->ErrorCode = HAL_USART_ERROR_NONE;
886 husart->State = HAL_USART_STATE_BUSY_TX_RX;
888 /* Set the USART DMA Rx transfer complete callback */
889 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
891 /* Set the USART DMA Half transfer complete callback */
892 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
894 /* Set the USART DMA Tx transfer complete callback */
895 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
897 /* Set the USART DMA Half transfer complete callback */
898 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
900 /* Set the USART DMA Tx transfer error callback */
901 husart->hdmatx->XferErrorCallback = USART_DMAError;
903 /* Set the USART DMA Rx transfer error callback */
904 husart->hdmarx->XferErrorCallback = USART_DMAError;
906 /* Enable the USART receive DMA Stream */
907 tmp = (uint32_t*)&pRxData;
908 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
910 /* Enable the USART transmit DMA Stream */
911 tmp = (uint32_t*)&pTxData;
912 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
914 /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
915 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
917 /* Clear the TC flag in the SR register by writing 0 to it */
918 __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
920 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
921 in the USART CR3 register */
922 husart->Instance->CR3 |= USART_CR3_DMAR;
924 /* Enable the DMA transfer for transmit request by setting the DMAT bit
925 in the USART CR3 register */
926 husart->Instance->CR3 |= USART_CR3_DMAT;
928 /* Process Unlocked */
929 __HAL_UNLOCK(husart);
940 * @brief Pauses the DMA Transfer.
941 * @param husart: USART handle
944 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
949 /* Disable the USART DMA Tx request */
950 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
952 /* Process Unlocked */
953 __HAL_UNLOCK(husart);
959 * @brief Resumes the DMA Transfer.
960 * @param husart: USART handle
963 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
968 /* Enable the USART DMA Tx request */
969 husart->Instance->CR3 |= USART_CR3_DMAT;
971 /* Process Unlocked */
972 __HAL_UNLOCK(husart);
978 * @brief Stops the DMA Transfer.
979 * @param husart: USART handle
982 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
984 /* The Lock is not implemented on this API to allow the user application
985 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
986 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
987 and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
990 /* Abort the USART DMA tx Stream */
991 if(husart->hdmatx != NULL)
993 HAL_DMA_Abort(husart->hdmatx);
995 /* Abort the USART DMA rx Stream */
996 if(husart->hdmarx != NULL)
998 HAL_DMA_Abort(husart->hdmarx);
1001 /* Disable the USART Tx/Rx DMA requests */
1002 husart->Instance->CR3 &= ~USART_CR3_DMAT;
1003 husart->Instance->CR3 &= ~USART_CR3_DMAR;
1005 husart->State = HAL_USART_STATE_READY;
1011 * @brief This function handles USART interrupt request.
1012 * @param husart: USART handle
1015 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1018 /* USART parity error interrupt occured ------------------------------------*/
1019 if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET))
1021 __HAL_USART_CLEAR_PEFLAG(husart);
1022 husart->ErrorCode |= HAL_USART_ERROR_PE;
1023 /* Set the USART state ready to be able to start again the process */
1024 husart->State = HAL_USART_STATE_READY;
1027 /* USART frame error interrupt occured -------------------------------------*/
1028 if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1030 __HAL_USART_CLEAR_FEFLAG(husart);
1031 husart->ErrorCode |= HAL_USART_ERROR_FE;
1032 /* Set the USART state ready to be able to start again the process */
1033 husart->State = HAL_USART_STATE_READY;
1036 /* USART noise error interrupt occured -------------------------------------*/
1037 if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1039 __HAL_USART_CLEAR_NEFLAG(husart);
1040 husart->ErrorCode |= HAL_USART_ERROR_NE;
1041 /* Set the USART state ready to be able to start again the process */
1042 husart->State = HAL_USART_STATE_READY;
1045 /* USART Over-Run interrupt occured ----------------------------------------*/
1046 if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1048 __HAL_USART_CLEAR_OREFLAG(husart);
1049 husart->ErrorCode |= HAL_USART_ERROR_ORE;
1050 /* Set the USART state ready to be able to start again the process */
1051 husart->State = HAL_USART_STATE_READY;
1054 /* Call USART Error Call back function if need be --------------------------*/
1055 if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1057 HAL_USART_ErrorCallback(husart);
1060 /* USART in mode Receiver --------------------------------------------------*/
1061 if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET))
1063 if(husart->State == HAL_USART_STATE_BUSY_RX)
1065 USART_Receive_IT(husart);
1069 USART_TransmitReceive_IT(husart);
1073 /* USART in mode Transmitter -----------------------------------------------*/
1074 if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET))
1076 if(husart->State == HAL_USART_STATE_BUSY_TX)
1078 USART_Transmit_IT(husart);
1082 USART_TransmitReceive_IT(husart);
1086 /* USART in mode Transmitter (transmission end) -----------------------------*/
1087 if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET))
1089 USART_EndTransmit_IT(husart);
1094 * @brief Tx Transfer completed callbacks.
1095 * @param husart: USART handle
1098 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1100 /* NOTE: This function Should not be modified, when the callback is needed,
1101 the HAL_USART_TxCpltCallback could be implemented in the user file
1106 * @brief Tx Half Transfer completed callbacks.
1107 * @param husart: USART handle
1110 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1112 /* NOTE: This function Should not be modified, when the callback is needed,
1113 the HAL_USART_TxCpltCallback could be implemented in the user file
1118 * @brief Rx Transfer completed callbacks.
1119 * @param husart: USART handle
1122 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1124 /* NOTE: This function Should not be modified, when the callback is needed,
1125 the HAL_USART_TxCpltCallback could be implemented in the user file
1130 * @brief Rx Half Transfer completed callbacks.
1131 * @param husart: USART handle
1134 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1136 /* NOTE: This function Should not be modified, when the callback is needed,
1137 the HAL_USART_TxCpltCallback could be implemented in the user file
1142 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
1143 * @param husart: USART handle
1146 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1148 /* NOTE: This function Should not be modified, when the callback is needed,
1149 the HAL_USART_TxCpltCallback could be implemented in the user file
1154 * @brief USART error callbacks.
1155 * @param husart: USART handle
1158 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1160 /* NOTE: This function Should not be modified, when the callback is needed,
1161 the HAL_USART_ErrorCallback could be implemented in the user file
1169 /** @addtogroup USART_Exported_Functions_Group3
1170 * @brief USART State functions
1173 ===============================================================================
1174 ##### Peripheral State functions #####
1175 ===============================================================================
1177 This subsection provides a set of functions allowing to control the USART.
1178 (+) HAL_USART_GetState() API can be helpful to check in run-time the state of the USART peripheral.
1179 (+) HAL_USART_GetError() API can be helpful to check in run-time the Error Code of the USART peripheral.
1180 (+) USART_SetConfig() API is used to set the USART communication parameters.
1181 (+) USART_CheckIdleState() APi ensures that TEACK and/or REACK bits are set after initialization
1188 * @brief Returns the USART state.
1189 * @param husart: USART handle
1192 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1194 return husart->State;
1198 * @brief Return the USART error code
1199 * @param husart : pointer to a USART_HandleTypeDef structure that contains
1200 * the configuration information for the specified USART.
1201 * @retval USART Error Code
1203 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1205 return husart->ErrorCode;
1213 * @brief This function handles USART Communication Timeout.
1214 * @param husart: USART handle
1215 * @param Flag: specifies the USART flag to check.
1216 * @param Status: The new Flag status (SET or RESET).
1217 * @param Timeout: Timeout duration
1218 * @retval HAL status
1220 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1222 uint32_t tickstart = 0x00;
1223 tickstart = HAL_GetTick();
1225 /* Wait until flag is set */
1228 while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
1230 /* Check for the Timeout */
1231 if(Timeout != HAL_MAX_DELAY)
1233 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1235 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1236 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1237 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1238 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1239 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1241 husart->State= HAL_USART_STATE_READY;
1243 /* Process Unlocked */
1244 __HAL_UNLOCK(husart);
1253 while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
1255 /* Check for the Timeout */
1256 if(Timeout != HAL_MAX_DELAY)
1258 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1260 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1261 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1262 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1263 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1264 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1266 husart->State= HAL_USART_STATE_READY;
1268 /* Process Unlocked */
1269 __HAL_UNLOCK(husart);
1280 * @brief DMA USART transmit process complete callback.
1281 * @param hdma: DMA handle
1284 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1286 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1288 husart->TxXferCount = 0;
1290 if(husart->State == HAL_USART_STATE_BUSY_TX)
1292 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1293 in the USART CR3 register */
1294 husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1296 /* Enable the USART Transmit Complete Interrupt */
1297 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1299 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1302 husart->State= HAL_USART_STATE_BUSY_RX;
1303 HAL_USART_TxCpltCallback(husart);
1308 * @brief DMA USART transmit process half complete callback
1309 * @param hdma : DMA handle
1312 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1314 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1316 HAL_USART_TxHalfCpltCallback(husart);
1320 * @brief DMA USART receive process complete callback.
1321 * @param hdma: DMA handle
1324 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1326 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1327 /* DMA Normal mode */
1328 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
1330 husart->RxXferCount = 0;
1332 if(husart->State == HAL_USART_STATE_BUSY_RX)
1334 /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
1335 in the USART CR3 register */
1336 husart->Instance->CR3 &= ~(USART_CR3_DMAR);
1338 husart->State= HAL_USART_STATE_READY;
1339 HAL_USART_RxCpltCallback(husart);
1341 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1344 /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
1345 in the USART CR3 register */
1346 husart->Instance->CR3 &= ~(USART_CR3_DMAR);
1347 husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1349 husart->State= HAL_USART_STATE_READY;
1350 HAL_USART_TxRxCpltCallback(husart);
1353 /* DMA circular mode */
1356 if(husart->State == HAL_USART_STATE_BUSY_RX)
1358 HAL_USART_RxCpltCallback(husart);
1360 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1363 HAL_USART_TxRxCpltCallback(husart);
1369 * @brief DMA USART receive process half complete callback
1370 * @param hdma : DMA handle
1373 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1375 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1377 HAL_USART_RxHalfCpltCallback(husart);
1381 * @brief DMA USART communication error callback.
1382 * @param hdma: DMA handle
1385 static void USART_DMAError(DMA_HandleTypeDef *hdma)
1387 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1389 husart->RxXferCount = 0;
1390 husart->TxXferCount = 0;
1391 husart->ErrorCode |= HAL_USART_ERROR_DMA;
1392 husart->State= HAL_USART_STATE_READY;
1394 HAL_USART_ErrorCallback(husart);
1398 * @brief Simplex Send an amount of data in non-blocking mode.
1399 * Function called under interruption only, once
1400 * interruptions have been enabled by HAL_USART_Transmit_IT()
1401 * @param husart: USART handle
1402 * @retval HAL status
1403 * @note The USART errors are not managed to avoid the overrun error.
1405 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1409 if(husart->State == HAL_USART_STATE_BUSY_TX)
1411 if(husart->TxXferCount == 0)
1413 /* Disable the USART Transmit Complete Interrupt */
1414 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1416 /* Enable the USART Transmit Complete Interrupt */
1417 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1423 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1425 tmp = (uint16_t*) husart->pTxBuffPtr;
1426 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1427 husart->pTxBuffPtr += 2;
1431 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF);
1434 husart->TxXferCount--;
1446 * @brief Wraps up transmission in non blocking mode.
1447 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1448 * the configuration information for the specified USART module.
1449 * @retval HAL status
1451 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
1453 /* Disable the USART Transmit Complete Interrupt */
1454 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
1456 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1457 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1459 husart->State = HAL_USART_STATE_READY;
1461 HAL_USART_TxCpltCallback(husart);
1467 * @brief Simplex Receive an amount of data in non-blocking mode.
1468 * Function called under interruption only, once
1469 * interruptions have been enabled by HAL_USART_Receive_IT()
1470 * @param husart: USART handle
1471 * @retval HAL status
1473 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
1476 uint16_t uhMask = husart->Mask;
1478 if(husart->State == HAL_USART_STATE_BUSY_RX)
1481 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1483 tmp = (uint16_t*) husart->pRxBuffPtr;
1484 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1485 husart->pRxBuffPtr += 2;
1489 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
1491 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
1492 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
1494 if(--husart->RxXferCount == 0)
1496 /* Wait for RXNE Flag */
1497 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, HAL_USART_TXDMA_TIMEOUTVALUE) != HAL_OK)
1502 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1504 /* Disable the USART Parity Error Interrupt */
1505 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1507 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1508 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1510 husart->State = HAL_USART_STATE_READY;
1513 HAL_USART_RxCpltCallback(husart);
1528 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1529 * Function called under interruption only, once
1530 * interruptions have been enabled by HAL_USART_TransmitReceive_IT()
1531 * @param husart: USART handle
1532 * @retval HAL status
1534 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
1537 uint16_t uhMask = husart->Mask;
1539 if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1541 if(husart->TxXferCount != 0x00)
1543 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TC) != RESET)
1545 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1547 tmp = (uint16_t*) husart->pTxBuffPtr;
1548 husart->Instance->TDR = (uint16_t)(*tmp & uhMask);
1549 husart->pTxBuffPtr += 2;
1553 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask);
1555 husart->TxXferCount--;
1557 /* Check the latest data transmitted */
1558 if(husart->TxXferCount == 0)
1560 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1565 if(husart->RxXferCount != 0x00)
1567 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
1569 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1571 tmp = (uint16_t*) husart->pRxBuffPtr;
1572 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1573 husart->pRxBuffPtr += 2;
1577 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
1579 husart->RxXferCount--;
1583 /* Check the latest data received */
1584 if(husart->RxXferCount == 0)
1586 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1588 /* Disable the USART Parity Error Interrupt */
1589 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1591 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1592 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1594 husart->State = HAL_USART_STATE_READY;
1596 HAL_USART_TxRxCpltCallback(husart);
1601 /* Process Unlocked */
1602 __HAL_UNLOCK(husart);
1613 * @brief Configure the USART peripheral
1614 * @param husart: USART handle
1617 static void USART_SetConfig(USART_HandleTypeDef *husart)
1619 uint32_t tmpreg = 0x0;
1620 uint32_t clocksource = 0x0;
1622 /* Check the parameters */
1623 assert_param(IS_USART_INSTANCE(husart->Instance));
1624 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
1625 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
1626 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
1627 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
1628 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
1629 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
1630 assert_param(IS_USART_PARITY(husart->Init.Parity));
1631 assert_param(IS_USART_MODE(husart->Init.Mode));
1633 /*-------------------------- USART CR1 Configuration -----------------------*/
1634 /* Clear M, PCE, PS, TE and RE bits and configure
1635 * the USART Word Length, Parity, Mode and oversampling:
1636 * set the M bits according to husart->Init.WordLength value
1637 * set PCE and PS bits according to husart->Init.Parity value
1638 * set TE and RE bits according to husart->Init.Mode value
1639 * Force OVER8 bit to 1 in order to reach the max USART frequencies */
1640 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
1641 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
1643 /*---------------------------- USART CR2 Configuration ---------------------*/
1644 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
1645 * set CPOL bit according to husart->Init.CLKPolarity value
1646 * set CPHA bit according to husart->Init.CLKPhase value
1647 * set LBCL bit according to husart->Init.CLKLastBit value
1648 * set STOP[13:12] bits according to husart->Init.StopBits value */
1649 tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
1650 tmpreg |= (uint32_t)(husart->Init.CLKPolarity | husart->Init.CLKPhase);
1651 tmpreg |= (uint32_t)(husart->Init.CLKLastBit | husart->Init.StopBits);
1652 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
1654 /*-------------------------- USART CR3 Configuration -----------------------*/
1655 /* no CR3 register configuration */
1657 /*-------------------------- USART BRR Configuration -----------------------*/
1658 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
1659 USART_GETCLOCKSOURCE(husart, clocksource);
1660 switch (clocksource)
1662 case USART_CLOCKSOURCE_PCLK1:
1663 husart->Instance->BRR = (uint16_t)((2 * HAL_RCC_GetPCLK1Freq())/ husart->Init.BaudRate);
1665 case USART_CLOCKSOURCE_PCLK2:
1666 husart->Instance->BRR = (uint16_t)((2 * HAL_RCC_GetPCLK2Freq()) / husart->Init.BaudRate);
1668 case USART_CLOCKSOURCE_HSI:
1669 husart->Instance->BRR = (uint16_t)((2 * HSI_VALUE) / husart->Init.BaudRate);
1671 case USART_CLOCKSOURCE_SYSCLK:
1672 husart->Instance->BRR = (uint16_t)(( 2 * HAL_RCC_GetSysClockFreq()) / husart->Init.BaudRate);
1674 case USART_CLOCKSOURCE_LSE:
1675 husart->Instance->BRR = (uint16_t)((2 * LSE_VALUE) / husart->Init.BaudRate);
1683 * @brief Check the USART Idle State
1684 * @param husart: USART handle
1685 * @retval HAL status
1687 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
1689 /* Initialize the USART ErrorCode */
1690 husart->ErrorCode = HAL_USART_ERROR_NONE;
1692 /* Check if the Transmitter is enabled */
1693 if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1695 /* Wait until TEACK flag is set */
1696 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1698 husart->State= HAL_USART_STATE_TIMEOUT;
1702 /* Check if the Receiver is enabled */
1703 if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1705 /* Wait until REACK flag is set */
1706 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1708 husart->State= HAL_USART_STATE_TIMEOUT;
1713 /* Process Unlocked */
1714 __HAL_UNLOCK(husart);
1716 /* Initialize the USART state*/
1717 husart->State= HAL_USART_STATE_READY;
1726 #endif /* HAL_USART_MODULE_ENABLED */
1735 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/