2 ******************************************************************************
3 * @file stm32f0xx_hal_usart.c
4 * @author MCD Application Team
6 * @date 11-December-2014
7 * @brief USART HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral Control functions
13 * + Peripheral State and Errors functions
15 ===============================================================================
16 ##### How to use this driver #####
17 ===============================================================================
19 The USART HAL driver can be used as follows:
21 (#) Declare a USART_HandleTypeDef handle structure.
22 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit ()API:
23 (##) Enable the USARTx interface clock.
24 (##) USART pins configuration:
25 (+++) Enable the clock for the USART GPIOs.
26 (+++) Configure 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 "stm32f0xx_hal.h"
143 /** @addtogroup STM32F0xx_HAL_Driver
147 /** @defgroup USART USART HAL module driver
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 ((uint16_t) 0xFFFF)
158 #define TEACK_REACK_TIMEOUT ((uint32_t) 1000)
159 #define USART_TXDMA_TIMEOUTVALUE 22000
160 #define USART_TIMEOUT_VALUE 22000
161 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
162 USART_CR1_TE | USART_CR1_RE))
163 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
164 USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP))
169 /* Private macro -------------------------------------------------------------*/
170 /* Private variables ---------------------------------------------------------*/
171 /* Private function prototypes -----------------------------------------------*/
172 /** @addtogroup USART_Private_Functions USART Private Functions
175 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
176 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
177 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
178 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
179 static void USART_DMAError(DMA_HandleTypeDef *hdma);
180 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
181 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
182 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
183 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
184 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
185 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
186 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
191 /* Exported functions ---------------------------------------------------------*/
194 /** @defgroup USART_Exported_Functions USART Exported Functions
198 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
199 * @brief Initialization and Configuration functions
202 ==============================================================================
203 ##### Initialization and Configuration functions #####
204 ==============================================================================
206 This subsection provides a set of functions allowing to initialize the USART
207 in asynchronous and in synchronous modes.
208 (+) For the asynchronous mode only these parameters can be configured:
212 (++) Parity: If the parity is enabled, then the MSB bit of the data written
213 in the data register is transmitted but is changed by the parity bit.
214 Depending on the frame length defined by the M bit (8-bits or 9-bits)
215 or by the M1 and M0 bits (7-bit, 8-bit or 9-bit),
216 the possible USART frame formats are as listed in the following table:
217 +---------------------------------------------------------------+
218 | M bit | PCE bit | USART frame |
219 |-----------|-----------|---------------------------------------|
220 | 0 | 0 | | SB | 8-bit data | STB | |
221 |-----------|-----------|---------------------------------------|
222 | 0 | 1 | | SB | 7-bit data | PB | STB | |
223 |-----------|-----------|---------------------------------------|
224 | 1 | 0 | | SB | 9-bit data | STB | |
225 |-----------|-----------|---------------------------------------|
226 | 1 | 1 | | SB | 8-bit data | PB | STB | |
227 +---------------------------------------------------------------+
228 | M1M0 bits | PCE bit | USART frame |
229 |-----------------------|---------------------------------------|
230 | 10 | 0 | | SB | 7-bit data | STB | |
231 |-----------|-----------|---------------------------------------|
232 | 10 | 1 | | SB | 6-bit data | PB | STB | |
233 +---------------------------------------------------------------+
237 (++) Receiver/transmitter modes
240 The HAL_USART_Init() function follows the USART synchronous configuration
241 procedure (details for the procedure are available in reference manual).
248 * @brief Initializes the USART mode according to the specified
249 * parameters in the USART_InitTypeDef and create the associated handle .
250 * @param husart: usart handle
253 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
255 /* Check the USART handle allocation */
261 /* Check the parameters */
262 assert_param(IS_USART_INSTANCE(husart->Instance));
264 if(husart->State == HAL_USART_STATE_RESET)
266 /* Init the low level hardware : GPIO, CLOCK */
267 HAL_USART_MspInit(husart);
270 husart->State = HAL_USART_STATE_BUSY;
272 /* Disable the Peripheral */
273 __HAL_USART_DISABLE(husart);
275 /* Set the Usart Communication parameters */
276 if (USART_SetConfig(husart) == HAL_ERROR)
281 /* In Synchronous mode, the following bits must be kept cleared:
282 - LINEN bit in the USART_CR2 register
283 - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
284 husart->Instance->CR2 &= ~USART_CR2_LINEN;
285 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
287 /* Enable the Peripharal */
288 __HAL_USART_ENABLE(husart);
290 /* TEACK and/or REACK to check before moving husart->State to Ready */
291 return (USART_CheckIdleState(husart));
295 * @brief DeInitializes the USART peripheral
296 * @param husart: usart handle
299 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
301 /* Check the USART handle allocation */
307 /* Check the parameters */
308 assert_param(IS_USART_INSTANCE(husart->Instance));
310 husart->State = HAL_USART_STATE_BUSY;
312 husart->Instance->CR1 = 0x0;
313 husart->Instance->CR2 = 0x0;
314 husart->Instance->CR3 = 0x0;
316 /* DeInit the low level hardware */
317 HAL_USART_MspDeInit(husart);
319 husart->ErrorCode = HAL_USART_ERROR_NONE;
320 husart->State = HAL_USART_STATE_RESET;
323 __HAL_UNLOCK(husart);
329 * @brief USART MSP Init
330 * @param husart: usart handle
333 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
335 /* NOTE : This function should not be modified, when the callback is needed,
336 the HAL_USART_MspInit can be implemented in the user file
341 * @brief USART MSP DeInit
342 * @param husart: usart handle
345 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
347 /* NOTE : This function should not be modified, when the callback is needed,
348 the HAL_USART_MspDeInit can be implemented in the user file
356 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
357 * @brief USART Transmit and Receive functions
360 ==============================================================================
361 ##### IO operation functions #####
362 ==============================================================================
364 This subsection provides a set of functions allowing to manage the USART synchronous
368 The USART supports master mode only: it cannot receive or send data related to an input
369 clock (SCLK is always an output).
371 (#) There are two modes of transfer:
372 (++) Blocking mode: The communication is performed in polling mode.
373 The HAL status of all data processing is returned by the same function
374 after finishing transfer.
375 (++) Non Blocking mode: The communication is performed using Interrupts
376 or DMA, These APIs return the HAL status.
377 The end of the data processing will be indicated through the
378 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
380 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
381 will be executed respectivelly at the end of the transmit or Receive process
382 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
384 (#) Blocking mode APIs are :
385 (++) HAL_USART_Transmit()in simplex mode
386 (++) HAL_USART_Receive() in full duplex receive only
387 (++) HAL_USART_TransmitReceive() in full duplex mode
389 (#) Non Blocking mode APIs with Interrupt are :
390 (++) HAL_USART_Transmit_IT()in simplex mode
391 (++) HAL_USART_Receive_IT() in full duplex receive only
392 (++) HAL_USART_TransmitReceive_IT()in full duplex mode
393 (++) HAL_USART_IRQHandler()
395 (#) Non Blocking mode functions with DMA are :
396 (++) HAL_USART_Transmit_DMA()in simplex mode
397 (++) HAL_USART_Receive_DMA() in full duplex receive only
398 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
399 (++) HAL_USART_DMAPause()
400 (++) HAL_USART_DMAResume()
401 (++) HAL_USART_DMAStop()
403 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
404 (++) HAL_USART_TxCpltCallback()
405 (++) HAL_USART_RxCpltCallback()
406 (++) HAL_USART_TxHalfCpltCallback()
407 (++) HAL_USART_RxHalfCpltCallback()
408 (++) HAL_USART_ErrorCallback()
409 (++) HAL_USART_TxRxCpltCallback()
416 * @brief Simplex Send an amount of data in blocking mode
417 * @param husart: USART handle
418 * @param pTxData: pointer to data buffer
419 * @param Size: amount of data to be sent
420 * @param Timeout : Timeout duration
423 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
427 if(husart->State == HAL_USART_STATE_READY)
429 if((pTxData == NULL) || (Size == 0))
437 husart->ErrorCode = HAL_USART_ERROR_NONE;
438 husart->State = HAL_USART_STATE_BUSY_TX;
440 husart->TxXferSize = Size;
441 husart->TxXferCount = Size;
443 /* Check the remaining data to be sent */
444 while(husart->TxXferCount > 0)
446 husart->TxXferCount--;
447 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
451 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
453 tmp = (uint16_t*) pTxData;
454 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
459 husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF);
463 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
468 husart->State = HAL_USART_STATE_READY;
470 /* Process Unlocked */
471 __HAL_UNLOCK(husart);
482 * @brief Receive an amount of data in blocking mode
483 * To receive synchronous data, dummy data are simultaneously transmitted
484 * @param husart: USART handle
485 * @param pRxData: pointer to data buffer
486 * @param Size: amount of data to be received
487 * @param Timeout : Timeout duration
490 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
495 if(husart->State == HAL_USART_STATE_READY)
497 if((pRxData == NULL) || (Size == 0))
504 husart->ErrorCode = HAL_USART_ERROR_NONE;
505 husart->State = HAL_USART_STATE_BUSY_RX;
507 husart->RxXferSize = Size;
508 husart->RxXferCount = Size;
510 /* Computation of USART mask to apply to RDR register */
511 __HAL_USART_MASK_COMPUTATION(husart);
512 uhMask = husart->Mask;
514 /* as long as data have to be received */
515 while(husart->RxXferCount > 0)
517 husart->RxXferCount--;
519 /* Wait until TC flag is set to send dummy byte in order to generate the
520 * clock for the slave to send data.
521 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
522 * can be written for all the cases. */
523 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
527 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FF);
529 /* Wait for RXNE Flag */
530 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
535 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
537 tmp = (uint16_t*) pRxData ;
538 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
543 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
547 husart->State = HAL_USART_STATE_READY;
549 /* Process Unlocked */
550 __HAL_UNLOCK(husart);
561 * @brief Full-Duplex Send and Receive an amount of data in blocking mode
562 * @param husart: USART handle
563 * @param pTxData: pointer to TX data buffer
564 * @param pRxData: pointer to RX data buffer
565 * @param Size: amount of data to be sent (same amount to be received)
566 * @param Timeout : Timeout duration
569 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
574 if(husart->State == HAL_USART_STATE_READY)
576 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
583 husart->ErrorCode = HAL_USART_ERROR_NONE;
584 husart->State = HAL_USART_STATE_BUSY_RX;
586 husart->RxXferSize = Size;
587 husart->TxXferSize = Size;
588 husart->TxXferCount = Size;
589 husart->RxXferCount = Size;
591 /* Computation of USART mask to apply to RDR register */
592 __HAL_USART_MASK_COMPUTATION(husart);
593 uhMask = husart->Mask;
595 /* Check the remain data to be sent */
596 while(husart->TxXferCount > 0)
598 husart->TxXferCount--;
599 husart->RxXferCount--;
601 /* Wait until TC flag is set to send data */
602 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
606 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
608 tmp = (uint16_t*) pTxData;
609 husart->Instance->TDR = (*tmp & uhMask);
614 husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask);
617 /* Wait for RXNE Flag */
618 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
623 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
625 tmp = (uint16_t*) pRxData ;
626 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
631 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
635 husart->State = HAL_USART_STATE_READY;
637 /* Process Unlocked */
638 __HAL_UNLOCK(husart);
649 * @brief Send an amount of data in interrupt mode
650 * @param husart: USART handle
651 * @param pTxData: pointer to data buffer
652 * @param Size: amount of data to be sent
655 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
657 if(husart->State == HAL_USART_STATE_READY)
659 if((pTxData == NULL) || (Size == 0))
667 husart->pTxBuffPtr = pTxData;
668 husart->TxXferSize = Size;
669 husart->TxXferCount = Size;
671 husart->ErrorCode = HAL_USART_ERROR_NONE;
672 husart->State = HAL_USART_STATE_BUSY_TX;
674 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
675 are not managed by the USART Transmit Process to avoid the overrun interrupt
676 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
677 to benefit for the frame error and noise interrupts the usart mode should be
678 configured only for transmit "USART_MODE_TX" */
680 /* Process Unlocked */
681 __HAL_UNLOCK(husart);
683 /* Enable the USART Transmit Data Register Empty Interrupt */
684 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
695 * @brief Receive an amount of data in blocking mode
696 * To receive synchronous data, dummy data are simultaneously transmitted
697 * @param husart: usart handle
698 * @param pRxData: pointer to data buffer
699 * @param Size: amount of data to be received
702 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
704 if(husart->State == HAL_USART_STATE_READY)
706 if((pRxData == NULL) || (Size == 0))
713 husart->pRxBuffPtr = pRxData;
714 husart->RxXferSize = Size;
715 husart->RxXferCount = Size;
717 __HAL_USART_MASK_COMPUTATION(husart);
719 husart->ErrorCode = HAL_USART_ERROR_NONE;
720 husart->State = HAL_USART_STATE_BUSY_RX;
722 /* Enable the USART Parity Error Interrupt */
723 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
725 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
726 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
728 /* Enable the USART Data Register not empty Interrupt */
729 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
731 /* Process Unlocked */
732 __HAL_UNLOCK(husart);
735 /* Send dummy byte in order to generate the clock for the Slave to send the next data */
736 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
738 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FF);
742 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
754 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode
755 * @param husart: USART handle
756 * @param pTxData: pointer to TX data buffer
757 * @param pRxData: pointer to RX data buffer
758 * @param Size: amount of data to be sent (same amount to be received)
761 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
763 if(husart->State == HAL_USART_STATE_READY)
765 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
772 husart->pRxBuffPtr = pRxData;
773 husart->RxXferSize = Size;
774 husart->RxXferCount = Size;
775 husart->pTxBuffPtr = pTxData;
776 husart->TxXferSize = Size;
777 husart->TxXferCount = Size;
779 /* Computation of USART mask to apply to RDR register */
780 __HAL_USART_MASK_COMPUTATION(husart);
782 husart->ErrorCode = HAL_USART_ERROR_NONE;
783 husart->State = HAL_USART_STATE_BUSY_TX_RX;
785 /* Enable the USART Data Register not empty Interrupt */
786 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
788 /* Enable the USART Parity Error Interrupt */
789 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
791 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
792 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
794 /* Process Unlocked */
795 __HAL_UNLOCK(husart);
797 /* Enable the USART Transmit Data Register Empty Interrupt */
798 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
809 * @brief Send an amount of data in DMA mode
810 * @param husart: USART handle
811 * @param pTxData: pointer to data buffer
812 * @param Size: amount of data to be sent
815 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
819 if(husart->State == HAL_USART_STATE_READY)
821 if((pTxData == NULL) || (Size == 0))
828 husart->pTxBuffPtr = pTxData;
829 husart->TxXferSize = Size;
830 husart->TxXferCount = Size;
832 husart->ErrorCode = HAL_USART_ERROR_NONE;
833 husart->State = HAL_USART_STATE_BUSY_TX;
835 /* Set the USART DMA transfer complete callback */
836 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
838 /* Set the USART DMA Half transfer complete callback */
839 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
841 /* Set the DMA error callback */
842 husart->hdmatx->XferErrorCallback = USART_DMAError;
844 /* Enable the USART transmit DMA channel */
845 tmp = (uint32_t*)&pTxData;
846 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
848 /* Enable the DMA transfer for transmit request by setting the DMAT bit
849 in the USART CR3 register */
850 husart->Instance->CR3 |= USART_CR3_DMAT;
852 /* Process Unlocked */
853 __HAL_UNLOCK(husart);
864 * @brief Full-Duplex Receive an amount of data in non-blocking mode
865 * @param husart: USART handle
866 * @param pRxData: pointer to data buffer
867 * @param Size: amount of data to be received
868 * @note When the USART parity is enabled (PCE = 1), the received data contain
869 * the parity bit (MSB position)
871 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
873 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
877 if(husart->State == HAL_USART_STATE_READY)
879 if((pRxData == NULL) || (Size == 0))
887 husart->pRxBuffPtr = pRxData;
888 husart->RxXferSize = Size;
889 husart->pTxBuffPtr = pRxData;
890 husart->TxXferSize = Size;
892 husart->ErrorCode = HAL_USART_ERROR_NONE;
893 husart->State = HAL_USART_STATE_BUSY_RX;
895 /* Set the USART DMA Rx transfer complete callback */
896 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
898 /* Set the USART DMA Half transfer complete callback */
899 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
901 /* Set the USART DMA Rx transfer error callback */
902 husart->hdmarx->XferErrorCallback = USART_DMAError;
904 /* Enable the USART receive DMA channel */
905 tmp = (uint32_t*)&pRxData;
906 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
908 /* Enable the USART transmit DMA channel: the transmit channel is used in order
909 to generate in the non-blocking mode the clock to the slave device,
910 this mode isn't a simplex receive mode but a full-duplex receive mode */
911 tmp = (uint32_t*)&pRxData;
912 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
914 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
915 in the USART CR3 register */
916 husart->Instance->CR3 |= USART_CR3_DMAR;
918 /* Enable the DMA transfer for transmit request by setting the DMAT bit
919 in the USART CR3 register */
920 husart->Instance->CR3 |= USART_CR3_DMAT;
922 /* Process Unlocked */
923 __HAL_UNLOCK(husart);
934 * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode
935 * @param husart: usart handle
936 * @param pTxData: pointer to TX data buffer
937 * @param pRxData: pointer to RX data buffer
938 * @param Size: amount of data to be received/sent
939 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
942 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
946 if(husart->State == HAL_USART_STATE_READY)
948 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
955 husart->pRxBuffPtr = pRxData;
956 husart->RxXferSize = Size;
957 husart->pTxBuffPtr = pTxData;
958 husart->TxXferSize = Size;
960 husart->ErrorCode = HAL_USART_ERROR_NONE;
961 husart->State = HAL_USART_STATE_BUSY_TX_RX;
963 /* Set the USART DMA Rx transfer complete callback */
964 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
966 /* Set the USART DMA Half transfer complete callback */
967 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
969 /* Set the USART DMA Tx transfer complete callback */
970 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
972 /* Set the USART DMA Half transfer complete callback */
973 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
975 /* Set the USART DMA Tx transfer error callback */
976 husart->hdmatx->XferErrorCallback = USART_DMAError;
978 /* Set the USART DMA Rx transfer error callback */
979 husart->hdmarx->XferErrorCallback = USART_DMAError;
981 /* Enable the USART receive DMA channel */
982 tmp = (uint32_t*)&pRxData;
983 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
985 /* Enable the USART transmit DMA channel */
986 tmp = (uint32_t*)&pTxData;
987 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
989 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
990 in the USART CR3 register */
991 husart->Instance->CR3 |= USART_CR3_DMAR;
993 /* Enable the DMA transfer for transmit request by setting the DMAT bit
994 in the USART CR3 register */
995 husart->Instance->CR3 |= USART_CR3_DMAT;
997 /* Process Unlocked */
998 __HAL_UNLOCK(husart);
1009 * @brief Pauses the DMA Transfer.
1010 * @param husart: USART handle
1013 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1015 /* Process Locked */
1018 if(husart->State == HAL_USART_STATE_BUSY_TX)
1020 /* Disable the USART DMA Tx request */
1021 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
1023 else if(husart->State == HAL_USART_STATE_BUSY_RX)
1025 /* Disable the USART DMA Rx request */
1026 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
1028 else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1030 /* Disable the USART DMA Tx request */
1031 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
1032 /* Disable the USART DMA Rx request */
1033 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
1036 /* Process Unlocked */
1037 __HAL_UNLOCK(husart);
1043 * @brief Resumes the DMA Transfer.
1044 * @param husart: USART handle
1047 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1049 /* Process Locked */
1052 if(husart->State == HAL_USART_STATE_BUSY_TX)
1054 /* Enable the USART DMA Tx request */
1055 husart->Instance->CR3 |= USART_CR3_DMAT;
1057 else if(husart->State == HAL_USART_STATE_BUSY_RX)
1059 /* Enable the USART DMA Rx request */
1060 husart->Instance->CR3 |= USART_CR3_DMAR;
1062 else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1064 /* Enable the USART DMA Rx request before the DMA Tx request */
1065 husart->Instance->CR3 |= USART_CR3_DMAR;
1066 /* Enable the USART DMA Tx request */
1067 husart->Instance->CR3 |= USART_CR3_DMAT;
1070 /* If the USART peripheral is still not enabled, enable it */
1071 if ((husart->Instance->CR1 & USART_CR1_UE) == 0)
1073 /* Enable USART peripheral */
1074 __HAL_USART_ENABLE(husart);
1077 /* Process Unlocked */
1078 __HAL_UNLOCK(husart);
1084 * @brief Stops the DMA Transfer.
1085 * @param husart: USART handle
1088 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1090 /* Process Locked */
1093 /* Disable the USART Tx/Rx DMA requests */
1094 husart->Instance->CR3 &= ~USART_CR3_DMAT;
1095 husart->Instance->CR3 &= ~USART_CR3_DMAR;
1097 /* Abort the USART DMA tx Channel */
1098 if(husart->hdmatx != NULL)
1100 HAL_DMA_Abort(husart->hdmatx);
1102 /* Abort the USART DMA rx Channel */
1103 if(husart->hdmarx != NULL)
1105 HAL_DMA_Abort(husart->hdmarx);
1108 /* Disable USART peripheral */
1109 __HAL_USART_DISABLE(husart);
1111 husart->State = HAL_USART_STATE_READY;
1113 /* Process Unlocked */
1114 __HAL_UNLOCK(husart);
1120 * @brief This function handles USART interrupt request.
1121 * @param husart: USART handle
1124 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1127 /* USART parity error interrupt occured ------------------------------------*/
1128 if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET))
1130 __HAL_USART_CLEAR_IT(husart, USART_IT_PE);
1131 husart->ErrorCode |= HAL_USART_ERROR_PE;
1132 /* Set the USART state ready to be able to start again the process */
1133 husart->State = HAL_USART_STATE_READY;
1136 /* USART frame error interrupt occured -------------------------------------*/
1137 if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1139 __HAL_USART_CLEAR_IT(husart, USART_IT_FE);
1140 husart->ErrorCode |= HAL_USART_ERROR_FE;
1141 /* Set the USART state ready to be able to start again the process */
1142 husart->State = HAL_USART_STATE_READY;
1145 /* USART noise error interrupt occured -------------------------------------*/
1146 if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1148 __HAL_USART_CLEAR_IT(husart, USART_IT_NE);
1149 husart->ErrorCode |= HAL_USART_ERROR_NE;
1150 /* Set the USART state ready to be able to start again the process */
1151 husart->State = HAL_USART_STATE_READY;
1154 /* USART Over-Run interrupt occured ----------------------------------------*/
1155 if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1157 __HAL_USART_CLEAR_IT(husart, USART_IT_ORE);
1158 husart->ErrorCode |= HAL_USART_ERROR_ORE;
1159 /* Set the USART state ready to be able to start again the process */
1160 husart->State = HAL_USART_STATE_READY;
1163 /* Call USART Error Call back function if need be --------------------------*/
1164 if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1166 HAL_USART_ErrorCallback(husart);
1169 /* USART in mode Receiver --------------------------------------------------*/
1170 if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET))
1172 if(husart->State == HAL_USART_STATE_BUSY_RX)
1174 USART_Receive_IT(husart);
1178 USART_TransmitReceive_IT(husart);
1182 /* USART in mode Transmitter -----------------------------------------------*/
1183 if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET))
1185 if(husart->State == HAL_USART_STATE_BUSY_TX)
1187 USART_Transmit_IT(husart);
1191 USART_TransmitReceive_IT(husart);
1195 /* USART in mode Transmitter (transmission end) -----------------------------*/
1196 if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET))
1198 USART_EndTransmit_IT(husart);
1205 * @brief Tx Transfer completed callbacks
1206 * @param husart: usart handle
1209 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1211 /* NOTE : This function should not be modified, when the callback is needed,
1212 the HAL_USART_TxCpltCallback can be implemented in the user file
1217 * @brief Tx Half Transfer completed callbacks.
1218 * @param husart: USART handle
1221 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1223 /* NOTE: This function should not be modified, when the callback is needed,
1224 the HAL_USART_TxHalfCpltCallback can be implemented in the user file
1229 * @brief Rx Transfer completed callbacks.
1230 * @param husart: USART handle
1233 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1235 /* NOTE: This function should not be modified, when the callback is needed,
1236 the HAL_USART_RxCpltCallback can be implemented in the user file
1241 * @brief Rx Half Transfer completed callbacks
1242 * @param husart: usart handle
1245 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1247 /* NOTE : This function should not be modified, when the callback is needed,
1248 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
1253 * @brief Tx/Rx Transfers completed callback for the non-blocking process
1254 * @param husart: usart handle
1257 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1259 /* NOTE : This function should not be modified, when the callback is needed,
1260 the HAL_USART_TxRxCpltCallback can be implemented in the user file
1265 * @brief USART error callbacks
1266 * @param husart: usart handle
1269 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1271 /* NOTE : This function should not be modified, when the callback is needed,
1272 the HAL_USART_ErrorCallback can be implemented in the user file
1280 /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
1281 * @brief USART control functions
1284 ===============================================================================
1285 ##### Peripheral Control functions #####
1286 ===============================================================================
1288 This subsection provides a set of functions allowing to control the USART.
1289 (+) HAL_USART_GetState() API can be helpful to check in run-time the state of the USART peripheral.
1290 (+) USART_SetConfig() API is used to set the USART communication parameters.
1291 (+) USART_CheckIdleState() APi ensures that TEACK and/or REACK bits are set after initialization
1298 * @brief return the USART state
1299 * @param husart: USART handle
1302 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1304 return husart->State;
1308 * @brief Return the USART error code
1309 * @param husart : pointer to a USART_HandleTypeDef structure that contains
1310 * the configuration information for the specified USART.
1311 * @retval USART Error Code
1313 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1315 return husart->ErrorCode;
1326 /** @defgroup USART_Private_Functions USART Private Functions
1327 * @brief USART Private functions
1332 * @brief Configure the USART peripheral
1333 * @param husart: USART handle
1336 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
1338 uint32_t tmpreg = 0x0;
1339 USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED;
1340 HAL_StatusTypeDef ret = HAL_OK;
1342 /* Check the parameters */
1343 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
1344 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
1345 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
1346 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
1347 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
1348 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
1349 assert_param(IS_USART_PARITY(husart->Init.Parity));
1350 assert_param(IS_USART_MODE(husart->Init.Mode));
1353 /*-------------------------- USART CR1 Configuration -----------------------*/
1354 /* Clear M, PCE, PS, TE and RE bits and configure
1355 * the USART Word Length, Parity and Mode:
1356 * set the M bits according to husart->Init.WordLength value
1357 * set PCE and PS bits according to husart->Init.Parity value
1358 * set TE and RE bits according to husart->Init.Mode value */
1359 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode;
1360 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
1362 /*---------------------------- USART CR2 Configuration ---------------------*/
1363 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
1364 * set CPOL bit according to husart->Init.CLKPolarity value
1365 * set CPHA bit according to husart->Init.CLKPhase value
1366 * set LBCL bit according to husart->Init.CLKLastBit value
1367 * set STOP[13:12] bits according to husart->Init.StopBits value */
1368 tmpreg = (uint32_t)(USART_CLOCK_ENABLED);
1369 tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
1370 tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits);
1371 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
1373 /*-------------------------- USART CR3 Configuration -----------------------*/
1374 /* no CR3 register configuration */
1376 /*-------------------------- USART BRR Configuration -----------------------*/
1377 __HAL_USART_GETCLOCKSOURCE(husart, clocksource);
1378 switch (clocksource)
1380 case USART_CLOCKSOURCE_PCLK1:
1381 husart->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / husart->Init.BaudRate);
1383 case USART_CLOCKSOURCE_HSI:
1384 husart->Instance->BRR = (uint16_t)(HSI_VALUE / husart->Init.BaudRate);
1386 case USART_CLOCKSOURCE_SYSCLK:
1387 husart->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / husart->Init.BaudRate);
1389 case USART_CLOCKSOURCE_LSE:
1390 husart->Instance->BRR = (uint16_t)(LSE_VALUE / husart->Init.BaudRate);
1392 case USART_CLOCKSOURCE_UNDEFINED:
1402 * @brief Check the USART Idle State
1403 * @param husart: USART handle
1404 * @retval HAL status
1406 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
1408 /* Initialize the USART ErrorCode */
1409 husart->ErrorCode = HAL_USART_ERROR_NONE;
1411 /* Check if the Transmitter is enabled */
1412 if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1414 /* Wait until TEACK flag is set */
1415 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1417 husart->State= HAL_USART_STATE_TIMEOUT;
1421 /* Check if the Receiver is enabled */
1422 if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1424 /* Wait until REACK flag is set */
1425 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1427 husart->State= HAL_USART_STATE_TIMEOUT;
1432 /* Initialize the USART state*/
1433 husart->State= HAL_USART_STATE_READY;
1435 /* Process Unlocked */
1436 __HAL_UNLOCK(husart);
1442 * @brief This function handles USART Communication Timeout.
1443 * @param husart: USART handle
1444 * @param Flag: specifies the USART flag to check.
1445 * @param Status: The new Flag status (SET or RESET).
1446 * @param Timeout: Timeout duration
1447 * @retval HAL status
1449 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1451 uint32_t tickstart = HAL_GetTick();
1453 /* Wait until flag is set */
1456 while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
1458 /* Check for the Timeout */
1459 if(Timeout != HAL_MAX_DELAY)
1461 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1463 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1464 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1465 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1466 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1467 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1469 husart->State= HAL_USART_STATE_READY;
1471 /* Process Unlocked */
1472 __HAL_UNLOCK(husart);
1481 while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
1483 /* Check for the Timeout */
1484 if(Timeout != HAL_MAX_DELAY)
1486 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1488 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1489 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1490 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1491 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1492 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1494 husart->State= HAL_USART_STATE_READY;
1496 /* Process Unlocked */
1497 __HAL_UNLOCK(husart);
1509 * @brief DMA USART transmit process complete callback
1510 * @param hdma : DMA handle
1513 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1515 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1517 husart->TxXferCount = 0;
1519 if(husart->State == HAL_USART_STATE_BUSY_TX)
1521 /* Wait for USART TC Flag */
1522 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, USART_TXDMA_TIMEOUTVALUE) != HAL_OK)
1524 /* Timeout Occured */
1525 husart->State = HAL_USART_STATE_TIMEOUT;
1526 HAL_USART_ErrorCallback(husart);
1531 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1532 in the USART CR3 register */
1533 husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1534 husart->State= HAL_USART_STATE_READY;
1537 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1540 husart->State= HAL_USART_STATE_BUSY_RX;
1541 HAL_USART_TxCpltCallback(husart);
1547 * @brief DMA USART transmit process half complete callback
1548 * @param hdma : DMA handle
1551 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1553 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1555 HAL_USART_TxHalfCpltCallback(husart);
1559 * @brief DMA USART receive process complete callback
1560 * @param hdma : DMA handle
1563 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1565 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1567 husart->RxXferCount = 0;
1569 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
1570 in USART CR3 register */
1571 husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
1572 /* similarly, disable the DMA TX transfer that was started to provide the
1573 clock to the slave device */
1574 husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
1576 husart->State= HAL_USART_STATE_READY;
1578 HAL_USART_RxCpltCallback(husart);
1582 * @brief DMA USART receive process half complete callback
1583 * @param hdma : DMA handle
1586 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1588 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1590 HAL_USART_RxHalfCpltCallback(husart);
1594 * @brief DMA USART communication error callback
1595 * @param hdma : DMA handle
1598 static void USART_DMAError(DMA_HandleTypeDef *hdma)
1600 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1602 husart->RxXferCount = 0;
1603 husart->TxXferCount = 0;
1604 husart->ErrorCode |= HAL_USART_ERROR_DMA;
1605 husart->State= HAL_USART_STATE_READY;
1607 HAL_USART_ErrorCallback(husart);
1611 * @brief Simplex Send an amount of data in non-blocking mode.
1612 * Function called under interruption only, once
1613 * interruptions have been enabled by HAL_USART_Transmit_IT()
1614 * @param husart: USART handle
1615 * @retval HAL status
1616 * @note The USART errors are not managed to avoid the overrun error.
1618 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1622 if (husart->State == HAL_USART_STATE_BUSY_TX)
1625 if(husart->TxXferCount == 0)
1627 /* Disable the USART Transmit Complete Interrupt */
1628 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1630 /* Enable the USART Transmit Complete Interrupt */
1631 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1637 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1639 tmp = (uint16_t*) husart->pTxBuffPtr;
1640 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1641 husart->pTxBuffPtr += 2;
1645 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF);
1648 husart->TxXferCount--;
1661 * @brief Wraps up transmission in non blocking mode.
1662 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1663 * the configuration information for the specified USART module.
1664 * @retval HAL status
1666 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
1668 /* Disable the USART Transmit Complete Interrupt */
1669 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
1671 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1672 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1674 husart->State = HAL_USART_STATE_READY;
1676 HAL_USART_TxCpltCallback(husart);
1683 * @brief Simplex Receive an amount of data in non-blocking mode.
1684 * Function called under interruption only, once
1685 * interruptions have been enabled by HAL_USART_Receive_IT()
1686 * @param husart: USART handle
1687 * @retval HAL status
1689 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
1692 uint16_t uhMask = husart->Mask;
1694 if(husart->State == HAL_USART_STATE_BUSY_RX)
1697 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1699 tmp = (uint16_t*) husart->pRxBuffPtr ;
1700 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1701 husart->pRxBuffPtr += 2;
1705 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
1707 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
1708 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
1710 if(--husart->RxXferCount == 0)
1712 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1714 /* Disable the USART Parity Error Interrupt */
1715 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1717 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1718 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1720 husart->State = HAL_USART_STATE_READY;
1722 HAL_USART_RxCpltCallback(husart);
1736 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1737 * Function called under interruption only, once
1738 * interruptions have been enabled by HAL_USART_TransmitReceive_IT()
1739 * @param husart: USART handle
1740 * @retval HAL status
1742 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
1745 uint16_t uhMask = husart->Mask;
1747 if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1750 if(husart->TxXferCount != 0x00)
1752 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
1754 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1756 tmp = (uint16_t*) husart->pTxBuffPtr;
1757 husart->Instance->TDR = (uint16_t)(*tmp & uhMask);
1758 husart->pTxBuffPtr += 2;
1762 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask);
1764 husart->TxXferCount--;
1766 /* Check the latest data transmitted */
1767 if(husart->TxXferCount == 0)
1769 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1774 if(husart->RxXferCount != 0x00)
1776 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
1778 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1780 tmp = (uint16_t*) husart->pRxBuffPtr ;
1781 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1782 husart->pRxBuffPtr += 2;
1786 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
1788 husart->RxXferCount--;
1792 /* Check the latest data received */
1793 if(husart->RxXferCount == 0)
1795 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1797 /* Disable the USART Parity Error Interrupt */
1798 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1800 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1801 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1803 husart->State = HAL_USART_STATE_READY;
1805 HAL_USART_TxRxCpltCallback(husart);
1822 #endif /* HAL_USART_MODULE_ENABLED */
1831 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/