2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_usart.c
\r
4 * @author MCD Application Team
\r
7 * @brief USART HAL module driver.
\r
9 * This file provides firmware functions to manage the following
\r
10 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
\r
11 * Peripheral (USART).
\r
12 * + Initialization and de-initialization functions
\r
13 * + IO operation functions
\r
14 * + Peripheral Control functions
\r
17 ===============================================================================
\r
18 ##### How to use this driver #####
\r
19 ===============================================================================
\r
21 The USART HAL driver can be used as follows:
\r
23 (#) Declare a USART_HandleTypeDef handle structure.
\r
24 (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API:
\r
25 (##) Enable the USARTx interface clock.
\r
26 (##) USART pins configuration:
\r
27 (+) Enable the clock for the USART GPIOs.
\r
28 (+) Configure these USART pins as alternate function pull-up.
\r
29 (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
\r
30 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
\r
31 (+) Configure the USARTx interrupt priority.
\r
32 (+) Enable the NVIC USART IRQ handle.
\r
33 (@) The specific USART interrupts (Transmission complete interrupt,
\r
34 RXNE interrupt and Error Interrupts) will be managed using the macros
\r
35 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
\r
36 (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
\r
37 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
\r
38 (+) Declare a DMA handle structure for the Tx/Rx stream.
\r
39 (+) Enable the DMAx interface clock.
\r
40 (+) Configure the declared DMA handle structure with the required Tx/Rx parameters.
\r
41 (+) Configure the DMA Tx/Rx Stream.
\r
42 (+) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
\r
43 (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
\r
45 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
\r
46 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
\r
48 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
\r
49 (+) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
\r
50 by calling the customed HAL_USART_MspInit(&husart) API.
\r
53 ******************************************************************************
\r
56 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
58 * Redistribution and use in source and binary forms, with or without modification,
\r
59 * are permitted provided that the following conditions are met:
\r
60 * 1. Redistributions of source code must retain the above copyright notice,
\r
61 * this list of conditions and the following disclaimer.
\r
62 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
63 * this list of conditions and the following disclaimer in the documentation
\r
64 * and/or other materials provided with the distribution.
\r
65 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
66 * may be used to endorse or promote products derived from this software
\r
67 * without specific prior written permission.
\r
69 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
70 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
71 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
72 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
73 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
74 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
75 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
76 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
77 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
78 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
80 ******************************************************************************
\r
83 /* Includes ------------------------------------------------------------------*/
\r
84 #include "stm32f7xx_hal.h"
\r
86 /** @addtogroup STM32F7xx_HAL_Driver
\r
90 /** @defgroup USART USART
\r
91 * @brief HAL USART Synchronous module driver
\r
95 #ifdef HAL_USART_MODULE_ENABLED
\r
97 /* Private typedef -----------------------------------------------------------*/
\r
98 /* Private define ------------------------------------------------------------*/
\r
99 /** @addtogroup USART_Private_Constants
\r
102 #define DUMMY_DATA ((uint16_t) 0xFFFF)
\r
103 #define TEACK_REACK_TIMEOUT ((uint32_t) 1000)
\r
104 #define USART_TXDMA_TIMEOUTVALUE 22000
\r
105 #define USART_TIMEOUT_VALUE 22000
\r
106 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
\r
107 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
\r
108 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
\r
109 USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP))
\r
113 /* Private macro -------------------------------------------------------------*/
\r
114 /* Private variables ---------------------------------------------------------*/
\r
115 /* Private function prototypes -----------------------------------------------*/
\r
116 /* Private functions ---------------------------------------------------------*/
\r
117 /** @addtogroup USART_Private_Functions
\r
120 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
\r
121 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
\r
122 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
\r
123 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
\r
124 static void USART_DMAError(DMA_HandleTypeDef *hdma);
\r
125 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
\r
126 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
\r
127 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
\r
128 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
\r
129 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
\r
130 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
\r
131 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
\r
136 /* Exported functions --------------------------------------------------------*/
\r
138 /** @defgroup USART_Exported_Functions USART Exported Functions
\r
142 /** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
\r
143 * @brief Initialization and Configuration functions
\r
146 ===============================================================================
\r
147 ##### Initialization and Configuration functions #####
\r
148 ===============================================================================
\r
150 This subsection provides a set of functions allowing to initialize the USART
\r
151 in asynchronous and in synchronous modes.
\r
152 (+) For the asynchronous mode only these parameters can be configured:
\r
156 (++) Parity: If the parity is enabled, then the MSB bit of the data written
\r
157 in the data register is transmitted but is changed by the parity bit.
\r
158 Depending on the frame length defined by the M1 and M0 bits (7-bit,
\r
159 8-bit or 9-bit), the possible USART frame formats are as listed in the
\r
162 +---------------------------------------------------------------+
\r
163 | M1M0 bits | PCE bit | USART frame |
\r
164 |-----------------------|---------------------------------------|
\r
165 | 10 | 0 | | SB | 7-bit data | STB | |
\r
166 |-----------|-----------|---------------------------------------|
\r
167 | 10 | 1 | | SB | 6-bit data | PB | STB | |
\r
168 +---------------------------------------------------------------+
\r
169 (++) USART polarity
\r
172 (++) Receiver/transmitter modes
\r
175 The HAL_USART_Init() function follows the USART synchronous configuration
\r
176 procedure (details for the procedure are available in reference manual).
\r
183 * @brief Initializes the USART mode according to the specified
\r
184 * parameters in the USART_InitTypeDef and create the associated handle.
\r
185 * @param husart: USART handle
\r
186 * @retval HAL status
\r
188 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
\r
190 /* Check the USART handle allocation */
\r
196 /* Check the parameters */
\r
197 assert_param(IS_USART_INSTANCE(husart->Instance));
\r
199 if(husart->State == HAL_USART_STATE_RESET)
\r
201 /* Allocate lock resource and initialize it */
\r
202 husart->Lock = HAL_UNLOCKED;
\r
203 /* Init the low level hardware : GPIO, CLOCK */
\r
204 HAL_USART_MspInit(husart);
\r
207 husart->State = HAL_USART_STATE_BUSY;
\r
209 /* Disable the Peripheral */
\r
210 __HAL_USART_DISABLE(husart);
\r
212 /* Set the Usart Communication parameters */
\r
213 if (USART_SetConfig(husart) == HAL_ERROR)
\r
218 /* In Synchronous mode, the following bits must be kept cleared:
\r
219 - LINEN bit in the USART_CR2 register
\r
220 - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
\r
221 husart->Instance->CR2 &= ~USART_CR2_LINEN;
\r
222 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
\r
224 /* Enable the Peripheral */
\r
225 __HAL_USART_ENABLE(husart);
\r
227 /* TEACK and/or REACK to check before moving husart->State to Ready */
\r
228 return (USART_CheckIdleState(husart));
\r
232 * @brief DeInitializes the USART peripheral
\r
233 * @param husart: USART handle
\r
234 * @retval HAL status
\r
236 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
\r
238 /* Check the USART handle allocation */
\r
244 /* Check the parameters */
\r
245 assert_param(IS_USART_INSTANCE(husart->Instance));
\r
247 husart->State = HAL_USART_STATE_BUSY;
\r
249 husart->Instance->CR1 = 0x0;
\r
250 husart->Instance->CR2 = 0x0;
\r
251 husart->Instance->CR3 = 0x0;
\r
253 /* DeInit the low level hardware */
\r
254 HAL_USART_MspDeInit(husart);
\r
256 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
257 husart->State = HAL_USART_STATE_RESET;
\r
259 /* Process Unlock */
\r
260 __HAL_UNLOCK(husart);
\r
266 * @brief USART MSP Init
\r
267 * @param husart: USART handle
\r
270 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
\r
272 /* NOTE : This function should not be modified, when the callback is needed,
\r
273 the HAL_USART_MspInit can be implemented in the user file
\r
278 * @brief USART MSP DeInit
\r
279 * @param husart: USART handle
\r
282 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
\r
284 /* NOTE : This function should not be modified, when the callback is needed,
\r
285 the HAL_USART_MspDeInit can be implemented in the user file
\r
293 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
\r
294 * @brief USART Transmit and Receive functions
\r
297 ===============================================================================
\r
298 ##### IO operation functions #####
\r
299 ===============================================================================
\r
300 This subsection provides a set of functions allowing to manage the USART synchronous
\r
303 [..] The USART supports master mode only: it cannot receive or send data related to an input
\r
304 clock (SCLK is always an output).
\r
306 (#) There are two mode of transfer:
\r
307 (+) Blocking mode: The communication is performed in polling mode.
\r
308 The HAL status of all data processing is returned by the same function
\r
309 after finishing transfer.
\r
310 (+) No-Blocking mode: The communication is performed using Interrupts
\r
311 or DMA, These API's return the HAL status.
\r
312 The end of the data processing will be indicated through the
\r
313 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
\r
315 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
\r
316 will be executed respectively at the end of the transmit or Receive process
\r
317 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
\r
319 (#) Blocking mode API's are :
\r
320 (+) HAL_USART_Transmit()in simplex mode
\r
321 (+) HAL_USART_Receive() in full duplex receive only
\r
322 (+) HAL_USART_TransmitReceive() in full duplex mode
\r
324 (#) Non-Blocking mode API's with Interrupt are :
\r
325 (+) HAL_USART_Transmit_IT()in simplex mode
\r
326 (+) HAL_USART_Receive_IT() in full duplex receive only
\r
327 (+) HAL_USART_TransmitReceive_IT()in full duplex mode
\r
328 (+) HAL_USART_IRQHandler()
\r
330 (#) No-Blocking mode functions with DMA are :
\r
331 (+) HAL_USART_Transmit_DMA()in simplex mode
\r
332 (+) HAL_USART_Receive_DMA() in full duplex receive only
\r
333 (+) HAL_USART_TransmitReceive_DMA() in full duplex mode
\r
334 (+) HAL_USART_DMAPause()
\r
335 (+) HAL_USART_DMAResume()
\r
336 (+) HAL_USART_DMAStop()
\r
338 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
\r
339 (+) HAL_USART_TxCpltCallback()
\r
340 (+) HAL_USART_RxCpltCallback()
\r
341 (+) HAL_USART_TxHalfCpltCallback()
\r
342 (+) HAL_USART_RxHalfCpltCallback()
\r
343 (+) HAL_USART_ErrorCallback()
\r
344 (+) HAL_USART_TxRxCpltCallback()
\r
351 * @brief Simplex Send an amount of data in blocking mode
\r
352 * @param husart: USART handle
\r
353 * @param pTxData: pointer to data buffer
\r
354 * @param Size: amount of data to be sent
\r
355 * @param Timeout : Timeout duration
\r
356 * @retval HAL status
\r
358 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
\r
362 if(husart->State == HAL_USART_STATE_READY)
\r
364 if((pTxData == NULL) || (Size == 0))
\r
369 /* Process Locked */
\r
370 __HAL_LOCK(husart);
\r
372 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
373 husart->State = HAL_USART_STATE_BUSY_TX;
\r
375 husart->TxXferSize = Size;
\r
376 husart->TxXferCount = Size;
\r
378 /* Check the remaining data to be sent */
\r
379 while(husart->TxXferCount > 0)
\r
381 husart->TxXferCount--;
\r
382 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
\r
384 return HAL_TIMEOUT;
\r
386 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
388 tmp = (uint16_t*) pTxData;
\r
389 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
\r
394 husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF);
\r
398 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
\r
400 return HAL_TIMEOUT;
\r
403 husart->State = HAL_USART_STATE_READY;
\r
405 /* Process Unlocked */
\r
406 __HAL_UNLOCK(husart);
\r
417 * @brief Receive an amount of data in blocking mode
\r
418 * @note To receive synchronous data, dummy data are simultaneously transmitted
\r
419 * @param husart: USART handle
\r
420 * @param pRxData: pointer to data buffer
\r
421 * @param Size: amount of data to be received
\r
422 * @param Timeout : Timeout duration
\r
423 * @retval HAL status
\r
425 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
\r
430 if(husart->State == HAL_USART_STATE_READY)
\r
432 if((pRxData == NULL) || (Size == 0))
\r
436 /* Process Locked */
\r
437 __HAL_LOCK(husart);
\r
439 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
440 husart->State = HAL_USART_STATE_BUSY_RX;
\r
442 husart->RxXferSize = Size;
\r
443 husart->RxXferCount = Size;
\r
445 /* Computation of USART mask to apply to RDR register */
\r
446 __HAL_USART_MASK_COMPUTATION(husart);
\r
447 uhMask = husart->Mask;
\r
449 /* as long as data have to be received */
\r
450 while(husart->RxXferCount > 0)
\r
452 husart->RxXferCount--;
\r
454 /* Wait until TC flag is set to send dummy byte in order to generate the
\r
455 * clock for the slave to send data.
\r
456 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
\r
457 * can be written for all the cases. */
\r
458 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
\r
460 return HAL_TIMEOUT;
\r
462 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FF);
\r
464 /* Wait for RXNE Flag */
\r
465 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
\r
467 return HAL_TIMEOUT;
\r
470 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
472 tmp = (uint16_t*) pRxData ;
\r
473 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
\r
478 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
\r
482 husart->State = HAL_USART_STATE_READY;
\r
484 /* Process Unlocked */
\r
485 __HAL_UNLOCK(husart);
\r
496 * @brief Full-Duplex Send and Receive an amount of data in blocking mode
\r
497 * @param husart: USART handle
\r
498 * @param pTxData: pointer to TX data buffer
\r
499 * @param pRxData: pointer to RX data buffer
\r
500 * @param Size: amount of data to be sent (same amount to be received)
\r
501 * @param Timeout : Timeout duration
\r
502 * @retval HAL status
\r
504 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
\r
509 if(husart->State == HAL_USART_STATE_READY)
\r
511 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
\r
515 /* Process Locked */
\r
516 __HAL_LOCK(husart);
\r
518 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
519 husart->State = HAL_USART_STATE_BUSY_RX;
\r
521 husart->RxXferSize = Size;
\r
522 husart->TxXferSize = Size;
\r
523 husart->TxXferCount = Size;
\r
524 husart->RxXferCount = Size;
\r
526 /* Computation of USART mask to apply to RDR register */
\r
527 __HAL_USART_MASK_COMPUTATION(husart);
\r
528 uhMask = husart->Mask;
\r
530 /* Check the remain data to be sent */
\r
531 while(husart->TxXferCount > 0)
\r
533 husart->TxXferCount--;
\r
534 husart->RxXferCount--;
\r
536 /* Wait until TC flag is set to send data */
\r
537 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
\r
539 return HAL_TIMEOUT;
\r
541 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
543 tmp = (uint16_t*) pTxData;
\r
544 husart->Instance->TDR = (*tmp & uhMask);
\r
549 husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask);
\r
552 /* Wait for RXNE Flag */
\r
553 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
\r
555 return HAL_TIMEOUT;
\r
558 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
560 tmp = (uint16_t*) pRxData ;
\r
561 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
\r
566 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
\r
570 husart->State = HAL_USART_STATE_READY;
\r
572 /* Process Unlocked */
\r
573 __HAL_UNLOCK(husart);
\r
584 * @brief Send an amount of data in interrupt mode
\r
585 * @param husart: USART handle
\r
586 * @param pTxData: pointer to data buffer
\r
587 * @param Size: amount of data to be sent
\r
588 * @retval HAL status
\r
590 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
\r
592 if(husart->State == HAL_USART_STATE_READY)
\r
594 if((pTxData == NULL ) || (Size == 0))
\r
599 /* Process Locked */
\r
600 __HAL_LOCK(husart);
\r
602 husart->pTxBuffPtr = pTxData;
\r
603 husart->TxXferSize = Size;
\r
604 husart->TxXferCount = Size;
\r
606 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
607 husart->State = HAL_USART_STATE_BUSY_TX;
\r
609 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
\r
610 are not managed by the USART Transmit Process to avoid the overrun interrupt
\r
611 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
\r
612 to benefit for the frame error and noise interrupts the usart mode should be
\r
613 configured only for transmit "USART_MODE_TX" */
\r
615 /* Process Unlocked */
\r
616 __HAL_UNLOCK(husart);
\r
618 /* Enable the USART Transmit Data Register Empty Interrupt */
\r
619 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
\r
630 * @brief Receive an amount of data in blocking mode
\r
631 * To receive synchronous data, dummy data are simultaneously transmitted
\r
632 * @param husart: USART handle
\r
633 * @param pRxData: pointer to data buffer
\r
634 * @param Size: amount of data to be received
\r
635 * @retval HAL status
\r
637 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
\r
639 if(husart->State == HAL_USART_STATE_READY)
\r
641 if((pRxData == NULL ) || (Size == 0))
\r
645 /* Process Locked */
\r
646 __HAL_LOCK(husart);
\r
648 husart->pRxBuffPtr = pRxData;
\r
649 husart->RxXferSize = Size;
\r
650 husart->RxXferCount = Size;
\r
652 __HAL_USART_MASK_COMPUTATION(husart);
\r
654 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
655 husart->State = HAL_USART_STATE_BUSY_RX;
\r
657 /* Enable the USART Parity Error Interrupt */
\r
658 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
\r
660 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
\r
661 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
\r
663 /* Enable the USART Data Register not empty Interrupt */
\r
664 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
\r
666 /* Process Unlocked */
\r
667 __HAL_UNLOCK(husart);
\r
670 /* Send dummy byte in order to generate the clock for the Slave to send the next data */
\r
671 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
\r
673 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FF);
\r
677 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
\r
689 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode
\r
690 * @param husart: USART handle
\r
691 * @param pTxData: pointer to TX data buffer
\r
692 * @param pRxData: pointer to RX data buffer
\r
693 * @param Size: amount of data to be sent (same amount to be received)
\r
694 * @retval HAL status
\r
696 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
\r
699 if(husart->State == HAL_USART_STATE_READY)
\r
701 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
\r
705 /* Process Locked */
\r
706 __HAL_LOCK(husart);
\r
708 husart->pRxBuffPtr = pRxData;
\r
709 husart->RxXferSize = Size;
\r
710 husart->RxXferCount = Size;
\r
711 husart->pTxBuffPtr = pTxData;
\r
712 husart->TxXferSize = Size;
\r
713 husart->TxXferCount = Size;
\r
715 /* Computation of USART mask to apply to RDR register */
\r
716 __HAL_USART_MASK_COMPUTATION(husart);
\r
718 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
719 husart->State = HAL_USART_STATE_BUSY_TX_RX;
\r
721 /* Enable the USART Data Register not empty Interrupt */
\r
722 __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
\r
724 /* Enable the USART Parity Error Interrupt */
\r
725 __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
\r
727 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
\r
728 __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
\r
730 /* Process Unlocked */
\r
731 __HAL_UNLOCK(husart);
\r
733 /* Enable the USART Transmit Data Register Empty Interrupt */
\r
734 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
\r
746 * @brief Send an amount of data in DMA mode
\r
747 * @param husart: USART handle
\r
748 * @param pTxData: pointer to data buffer
\r
749 * @param Size: amount of data to be sent
\r
750 * @retval HAL status
\r
752 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
\r
756 if(husart->State == HAL_USART_STATE_READY)
\r
758 if((pTxData == NULL ) || (Size == 0))
\r
762 /* Process Locked */
\r
763 __HAL_LOCK(husart);
\r
765 husart->pTxBuffPtr = pTxData;
\r
766 husart->TxXferSize = Size;
\r
767 husart->TxXferCount = Size;
\r
769 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
770 husart->State = HAL_USART_STATE_BUSY_TX;
\r
772 /* Set the USART DMA transfer complete callback */
\r
773 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
\r
775 /* Set the USART DMA Half transfer complete callback */
\r
776 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
\r
778 /* Set the DMA error callback */
\r
779 husart->hdmatx->XferErrorCallback = USART_DMAError;
\r
781 /* Enable the USART transmit DMA channel */
\r
782 tmp = (uint32_t*)&pTxData;
\r
783 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
\r
786 /* Clear the TC flag in the SR register by writing 0 to it */
\r
787 __HAL_USART_CLEAR_IT(husart, USART_FLAG_TC);
\r
789 /* Enable the DMA transfer for transmit request by setting the DMAT bit
\r
790 in the USART CR3 register */
\r
791 husart->Instance->CR3 |= USART_CR3_DMAT;
\r
793 /* Process Unlocked */
\r
794 __HAL_UNLOCK(husart);
\r
805 * @brief Receive an amount of data in DMA mode
\r
806 * @param husart: USART handle
\r
807 * @param pRxData: pointer to data buffer
\r
808 * @param Size: amount of data to be received
\r
809 * @note When the USART parity is enabled (PCE = 1), the received data contain
\r
810 * the parity bit (MSB position)
\r
811 * @retval HAL status
\r
812 * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave.
\r
814 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
\r
818 if(husart->State == HAL_USART_STATE_READY)
\r
820 if((pRxData == NULL ) || (Size == 0))
\r
825 /* Process Locked */
\r
826 __HAL_LOCK(husart);
\r
828 husart->pRxBuffPtr = pRxData;
\r
829 husart->RxXferSize = Size;
\r
830 husart->pTxBuffPtr = pRxData;
\r
831 husart->TxXferSize = Size;
\r
833 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
834 husart->State = HAL_USART_STATE_BUSY_RX;
\r
836 /* Set the USART DMA Rx transfer complete callback */
\r
837 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
\r
839 /* Set the USART DMA Half transfer complete callback */
\r
840 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
\r
842 /* Set the USART DMA Rx transfer error callback */
\r
843 husart->hdmarx->XferErrorCallback = USART_DMAError;
\r
845 /* Enable the USART receive DMA channel */
\r
846 tmp = (uint32_t*)&pRxData;
\r
847 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
\r
849 /* Enable the USART transmit DMA channel: the transmit stream is used in order
\r
850 to generate in the non-blocking mode the clock to the slave device,
\r
851 this mode isn't a simplex receive mode but a full-duplex receive mode */
\r
852 tmp = (uint32_t*)&pRxData;
\r
853 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
\r
855 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
\r
856 in the USART CR3 register */
\r
857 husart->Instance->CR3 |= USART_CR3_DMAR;
\r
859 /* Enable the DMA transfer for transmit request by setting the DMAT bit
\r
860 in the USART CR3 register */
\r
861 husart->Instance->CR3 |= USART_CR3_DMAT;
\r
863 /* Process Unlocked */
\r
864 __HAL_UNLOCK(husart);
\r
875 * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode
\r
876 * @param husart: USART handle
\r
877 * @param pTxData: pointer to TX data buffer
\r
878 * @param pRxData: pointer to RX data buffer
\r
879 * @param Size: amount of data to be received/sent
\r
880 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
\r
881 * @retval HAL status
\r
883 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
\r
887 if(husart->State == HAL_USART_STATE_READY)
\r
889 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
\r
893 /* Process Locked */
\r
894 __HAL_LOCK(husart);
\r
896 husart->pRxBuffPtr = pRxData;
\r
897 husart->RxXferSize = Size;
\r
898 husart->pTxBuffPtr = pTxData;
\r
899 husart->TxXferSize = Size;
\r
901 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
902 husart->State = HAL_USART_STATE_BUSY_TX_RX;
\r
904 /* Set the USART DMA Rx transfer complete callback */
\r
905 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
\r
907 /* Set the USART DMA Half transfer complete callback */
\r
908 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
\r
910 /* Set the USART DMA Tx transfer complete callback */
\r
911 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
\r
913 /* Set the USART DMA Half transfer complete callback */
\r
914 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
\r
916 /* Set the USART DMA Tx transfer error callback */
\r
917 husart->hdmatx->XferErrorCallback = USART_DMAError;
\r
919 /* Set the USART DMA Rx transfer error callback */
\r
920 husart->hdmarx->XferErrorCallback = USART_DMAError;
\r
922 /* Enable the USART receive DMA channel */
\r
923 tmp = (uint32_t*)&pRxData;
\r
924 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
\r
926 /* Enable the USART transmit DMA channel */
\r
927 tmp = (uint32_t*)&pTxData;
\r
928 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
\r
930 /* Clear the TC flag in the SR register by writing 0 to it */
\r
931 __HAL_USART_CLEAR_IT(husart, USART_FLAG_TC);
\r
933 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
\r
934 in the USART CR3 register */
\r
935 husart->Instance->CR3 |= USART_CR3_DMAR;
\r
937 /* Enable the DMA transfer for transmit request by setting the DMAT bit
\r
938 in the USART CR3 register */
\r
939 husart->Instance->CR3 |= USART_CR3_DMAT;
\r
941 /* Process Unlocked */
\r
942 __HAL_UNLOCK(husart);
\r
953 * @brief Pauses the DMA Transfer.
\r
954 * @param husart: USART handle
\r
957 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
\r
959 /* Process Locked */
\r
960 __HAL_LOCK(husart);
\r
962 if(husart->State == HAL_USART_STATE_BUSY_TX)
\r
964 /* Disable the USART DMA Tx request */
\r
965 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
\r
967 else if(husart->State == HAL_USART_STATE_BUSY_RX)
\r
969 /* Disable the USART DMA Rx request */
\r
970 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
\r
972 else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
\r
974 /* Disable the USART DMA Tx request */
\r
975 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
\r
976 /* Disable the USART DMA Rx request */
\r
977 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
\r
980 /* Process Unlocked */
\r
981 __HAL_UNLOCK(husart);
\r
987 * @brief Resumes the DMA Transfer.
\r
988 * @param husart: USART handle
\r
991 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
\r
993 /* Process Locked */
\r
994 __HAL_LOCK(husart);
\r
996 if(husart->State == HAL_USART_STATE_BUSY_TX)
\r
998 /* Enable the USART DMA Tx request */
\r
999 husart->Instance->CR3 |= USART_CR3_DMAT;
\r
1001 else if(husart->State == HAL_USART_STATE_BUSY_RX)
\r
1003 /* Enable the USART DMA Rx request */
\r
1004 husart->Instance->CR3 |= USART_CR3_DMAR;
\r
1006 else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
\r
1008 /* Enable the USART DMA Rx request before the DMA Tx request */
\r
1009 husart->Instance->CR3 |= USART_CR3_DMAR;
\r
1010 /* Enable the USART DMA Tx request */
\r
1011 husart->Instance->CR3 |= USART_CR3_DMAT;
\r
1014 /* If the USART peripheral is still not enabled, enable it */
\r
1015 if((husart->Instance->CR1 & USART_CR1_UE) == 0)
\r
1017 /* Enable USART peripheral */
\r
1018 __HAL_USART_ENABLE(husart);
\r
1021 /* Process Unlocked */
\r
1022 __HAL_UNLOCK(husart);
\r
1028 * @brief Stops the DMA Transfer.
\r
1029 * @param husart: USART handle
\r
1032 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
\r
1034 /* Process Locked */
\r
1035 __HAL_LOCK(husart);
\r
1037 /* Disable the USART Tx/Rx DMA requests */
\r
1038 husart->Instance->CR3 &= ~USART_CR3_DMAT;
\r
1039 husart->Instance->CR3 &= ~USART_CR3_DMAR;
\r
1041 /* Abort the USART DMA tx Stream */
\r
1042 if(husart->hdmatx != NULL)
\r
1044 HAL_DMA_Abort(husart->hdmatx);
\r
1046 /* Abort the USART DMA rx Stream */
\r
1047 if(husart->hdmarx != NULL)
\r
1049 HAL_DMA_Abort(husart->hdmarx);
\r
1052 /* Disable USART peripheral */
\r
1053 __HAL_USART_DISABLE(husart);
\r
1055 husart->State = HAL_USART_STATE_READY;
\r
1057 /* Process Unlocked */
\r
1058 __HAL_UNLOCK(husart);
\r
1064 * @brief This function handles USART interrupt request.
\r
1065 * @param husart: USART handle
\r
1068 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
\r
1071 /* USART parity error interrupt occurred ------------------------------------*/
\r
1072 if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET))
\r
1074 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
\r
1075 husart->ErrorCode |= HAL_USART_ERROR_PE;
\r
1076 /* Set the USART state ready to be able to start again the process */
\r
1077 husart->State = HAL_USART_STATE_READY;
\r
1080 /* USART frame error interrupt occurred -------------------------------------*/
\r
1081 if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
\r
1083 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
\r
1084 husart->ErrorCode |= HAL_USART_ERROR_FE;
\r
1085 /* Set the USART state ready to be able to start again the process */
\r
1086 husart->State = HAL_USART_STATE_READY;
\r
1089 /* USART noise error interrupt occurred -------------------------------------*/
\r
1090 if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
\r
1092 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
\r
1093 husart->ErrorCode |= HAL_USART_ERROR_NE;
\r
1094 /* Set the USART state ready to be able to start again the process */
\r
1095 husart->State = HAL_USART_STATE_READY;
\r
1098 /* USART Over-Run interrupt occurred ----------------------------------------*/
\r
1099 if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
\r
1101 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
\r
1102 husart->ErrorCode |= HAL_USART_ERROR_ORE;
\r
1103 /* Set the USART state ready to be able to start again the process */
\r
1104 husart->State = HAL_USART_STATE_READY;
\r
1107 /* Call USART Error Call back function if need be --------------------------*/
\r
1108 if(husart->ErrorCode != HAL_USART_ERROR_NONE)
\r
1110 HAL_USART_ErrorCallback(husart);
\r
1113 /* USART in mode Receiver --------------------------------------------------*/
\r
1114 if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET))
\r
1116 if(husart->State == HAL_USART_STATE_BUSY_RX)
\r
1118 USART_Receive_IT(husart);
\r
1122 USART_TransmitReceive_IT(husart);
\r
1126 /* USART in mode Transmitter -----------------------------------------------*/
\r
1127 if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET))
\r
1129 if(husart->State == HAL_USART_STATE_BUSY_TX)
\r
1131 USART_Transmit_IT(husart);
\r
1135 USART_TransmitReceive_IT(husart);
\r
1139 /* USART in mode Transmitter (transmission end) -----------------------------*/
\r
1140 if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET))
\r
1142 USART_EndTransmit_IT(husart);
\r
1148 * @brief Tx Transfer completed callbacks
\r
1149 * @param husart: USART handle
\r
1152 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
\r
1154 /* NOTE : This function should not be modified, when the callback is needed,
\r
1155 the HAL_USART_TxCpltCallback can be implemented in the user file
\r
1160 * @brief Tx Half Transfer completed callbacks.
\r
1161 * @param husart: USART handle
\r
1164 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
\r
1166 /* NOTE: This function should not be modified, when the callback is needed,
\r
1167 the HAL_USART_TxHalfCpltCallback can be implemented in the user file
\r
1172 * @brief Rx Transfer completed callbacks.
\r
1173 * @param husart: USART handle
\r
1176 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
\r
1178 /* NOTE: This function should not be modified, when the callback is needed,
\r
1179 the HAL_USART_RxCpltCallback can be implemented in the user file
\r
1184 * @brief Rx Half Transfer completed callbacks
\r
1185 * @param husart: usart handle
\r
1188 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
\r
1190 /* NOTE : This function should not be modified, when the callback is needed,
\r
1191 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
\r
1196 * @brief Tx/Rx Transfers completed callback for the non-blocking process
\r
1197 * @param husart: USART handle
\r
1200 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
\r
1202 /* NOTE : This function should not be modified, when the callback is needed,
\r
1203 the HAL_USART_TxRxCpltCallback can be implemented in the user file
\r
1208 * @brief USART error callbacks
\r
1209 * @param husart: USART handle
\r
1212 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
\r
1214 /* NOTE : This function should not be modified, when the callback is needed,
\r
1215 the HAL_USART_ErrorCallback can be implemented in the user file
\r
1223 /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
\r
1224 * @brief USART State and Errors functions
\r
1227 ==============================================================================
\r
1228 ##### Peripheral State and Errors functions #####
\r
1229 ==============================================================================
\r
1231 This subsection provides a set of functions allowing to return the State of
\r
1232 USART communication
\r
1233 process, return Peripheral Errors occurred during communication process
\r
1234 (+) HAL_USART_GetState() API can be helpful to check in run-time the state
\r
1235 of the USART peripheral.
\r
1236 (+) HAL_USART_GetError() check in run-time errors that could be occurred during
\r
1243 * @brief return the USART state
\r
1244 * @param husart: USART handle
\r
1245 * @retval HAL state
\r
1247 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
\r
1249 return husart->State;
\r
1253 * @brief Return the USART error code
\r
1254 * @param husart : pointer to a USART_HandleTypeDef structure that contains
\r
1255 * the configuration information for the specified USART.
\r
1256 * @retval USART Error Code
\r
1258 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
\r
1260 return husart->ErrorCode;
\r
1269 * @brief Simplex Send an amount of data in non-blocking mode.
\r
1270 * @note Function called under interruption only, once
\r
1271 * interruptions have been enabled by HAL_USART_Transmit_IT().
\r
1272 * @param husart: USART handle
\r
1273 * @retval HAL status
\r
1274 * @note The USART errors are not managed to avoid the overrun error.
\r
1276 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
\r
1280 if(husart->State == HAL_USART_STATE_BUSY_TX)
\r
1283 if(husart->TxXferCount == 0)
\r
1285 /* Disable the USART Transmit Complete Interrupt */
\r
1286 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
\r
1288 /* Enable the USART Transmit Complete Interrupt */
\r
1289 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
\r
1295 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
1297 tmp = (uint16_t*) husart->pTxBuffPtr;
\r
1298 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
\r
1299 husart->pTxBuffPtr += 2;
\r
1303 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF);
\r
1306 husart->TxXferCount--;
\r
1318 * @brief Wraps up transmission in non-blocking mode.
\r
1319 * @param husart: pointer to a USART_HandleTypeDef structure that contains
\r
1320 * the configuration information for the specified USART module.
\r
1321 * @retval HAL status
\r
1323 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
\r
1325 /* Disable the USART Transmit Complete Interrupt */
\r
1326 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
\r
1328 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
\r
1329 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
\r
1331 husart->State = HAL_USART_STATE_READY;
\r
1333 HAL_USART_TxCpltCallback(husart);
\r
1339 * @brief Simplex Receive an amount of data in non-blocking mode.
\r
1340 * Function called under interruption only, once
\r
1341 * interruptions have been enabled by HAL_USART_Receive_IT()
\r
1342 * @param husart: USART handle
\r
1343 * @retval HAL status
\r
1345 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
\r
1348 uint16_t uhMask = husart->Mask;
\r
1350 if(husart->State == HAL_USART_STATE_BUSY_RX)
\r
1353 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
1355 tmp = (uint16_t*) husart->pRxBuffPtr;
\r
1356 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
\r
1357 husart->pRxBuffPtr += 2;
\r
1361 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
\r
1363 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
\r
1364 husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
\r
1366 if(--husart->RxXferCount == 0)
\r
1368 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
\r
1370 /* Disable the USART Parity Error Interrupt */
\r
1371 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
\r
1373 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
\r
1374 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
\r
1376 husart->State = HAL_USART_STATE_READY;
\r
1378 HAL_USART_RxCpltCallback(husart);
\r
1392 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
\r
1393 * Function called under interruption only, once
\r
1394 * interruptions have been enabled by HAL_USART_TransmitReceive_IT()
\r
1395 * @param husart: USART handle
\r
1396 * @retval HAL status
\r
1398 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
\r
1401 uint16_t uhMask = husart->Mask;
\r
1403 if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
\r
1405 if(husart->TxXferCount != 0x00)
\r
1407 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
\r
1409 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
1411 tmp = (uint16_t*) husart->pTxBuffPtr;
\r
1412 husart->Instance->TDR = (uint16_t)(*tmp & uhMask);
\r
1413 husart->pTxBuffPtr += 2;
\r
1417 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask);
\r
1419 husart->TxXferCount--;
\r
1421 /* Check the latest data transmitted */
\r
1422 if(husart->TxXferCount == 0)
\r
1424 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
\r
1429 if(husart->RxXferCount != 0x00)
\r
1431 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
\r
1433 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
\r
1435 tmp = (uint16_t*) husart->pRxBuffPtr;
\r
1436 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
\r
1437 husart->pRxBuffPtr += 2;
\r
1441 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
\r
1443 husart->RxXferCount--;
\r
1447 /* Check the latest data received */
\r
1448 if(husart->RxXferCount == 0)
\r
1450 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
\r
1452 /* Disable the USART Parity Error Interrupt */
\r
1453 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
\r
1455 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
\r
1456 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
\r
1458 husart->State = HAL_USART_STATE_READY;
\r
1460 HAL_USART_TxRxCpltCallback(husart);
\r
1474 * @brief This function handles USART Communication Timeout.
\r
1475 * @param husart: USART handle
\r
1476 * @param Flag: specifies the USART flag to check.
\r
1477 * @param Status: The new Flag status (SET or RESET).
\r
1478 * @param Timeout: Timeout duration
\r
1479 * @retval HAL status
\r
1481 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
\r
1483 uint32_t tickstart = HAL_GetTick();
\r
1485 /* Wait until flag is set */
\r
1486 if(Status == RESET)
\r
1488 while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
\r
1490 /* Check for the Timeout */
\r
1491 if(Timeout != HAL_MAX_DELAY)
\r
1493 if((Timeout == 0)||((HAL_GetTick()-tickstart) >= Timeout))
\r
1495 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
\r
1496 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
\r
1497 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
\r
1498 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
\r
1499 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
\r
1501 husart->State= HAL_USART_STATE_READY;
\r
1503 /* Process Unlocked */
\r
1504 __HAL_UNLOCK(husart);
\r
1506 return HAL_TIMEOUT;
\r
1513 while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
\r
1515 /* Check for the Timeout */
\r
1516 if(Timeout != HAL_MAX_DELAY)
\r
1518 if((Timeout == 0)||((HAL_GetTick()-tickstart) >= Timeout))
\r
1520 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
\r
1521 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
\r
1522 __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
\r
1523 __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
\r
1524 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
\r
1526 husart->State= HAL_USART_STATE_READY;
\r
1528 /* Process Unlocked */
\r
1529 __HAL_UNLOCK(husart);
\r
1531 return HAL_TIMEOUT;
\r
1541 * @brief DMA USART transmit process complete callback
\r
1542 * @param hdma: DMA handle
\r
1545 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
\r
1547 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
1549 /* DMA Normal mode */
\r
1550 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
\r
1552 husart->TxXferCount = 0;
\r
1554 if(husart->State == HAL_USART_STATE_BUSY_TX)
\r
1556 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
\r
1557 in the USART CR3 register */
\r
1558 husart->Instance->CR3 &= ~(USART_CR3_DMAT);
\r
1560 /* Enable the USART Transmit Complete Interrupt */
\r
1561 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
\r
1564 /* DMA Circular mode */
\r
1567 if(husart->State == HAL_USART_STATE_BUSY_TX)
\r
1569 HAL_USART_TxCpltCallback(husart);
\r
1576 * @brief DMA USART transmit process half complete callback
\r
1577 * @param hdma : DMA handle
\r
1580 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
\r
1582 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
\r
1584 HAL_USART_TxHalfCpltCallback(husart);
\r
1588 * @brief DMA USART receive process complete callback
\r
1589 * @param hdma: DMA handle
\r
1592 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
\r
1594 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
1596 /* DMA Normal mode */
\r
1597 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
\r
1599 husart->RxXferCount = 0;
\r
1601 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
\r
1602 in USART CR3 register */
\r
1603 husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
\r
1604 /* similarly, disable the DMA TX transfer that was started to provide the
\r
1605 clock to the slave device */
\r
1606 husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
\r
1608 if(husart->State == HAL_USART_STATE_BUSY_RX)
\r
1610 HAL_USART_RxCpltCallback(husart);
\r
1612 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
\r
1615 HAL_USART_TxRxCpltCallback(husart);
\r
1617 husart->State= HAL_USART_STATE_READY;
\r
1619 /* DMA circular mode */
\r
1622 if(husart->State == HAL_USART_STATE_BUSY_RX)
\r
1624 HAL_USART_RxCpltCallback(husart);
\r
1626 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
\r
1629 HAL_USART_TxRxCpltCallback(husart);
\r
1635 * @brief DMA USART receive process half complete callback
\r
1636 * @param hdma : DMA handle
\r
1639 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
\r
1641 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
\r
1643 HAL_USART_RxHalfCpltCallback(husart);
\r
1647 * @brief DMA USART communication error callback
\r
1648 * @param hdma: DMA handle
\r
1651 static void USART_DMAError(DMA_HandleTypeDef *hdma)
\r
1653 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
1655 husart->RxXferCount = 0;
\r
1656 husart->TxXferCount = 0;
\r
1657 husart->ErrorCode |= HAL_USART_ERROR_DMA;
\r
1658 husart->State= HAL_USART_STATE_READY;
\r
1660 HAL_USART_ErrorCallback(husart);
\r
1664 * @brief Configure the USART peripheral
\r
1665 * @param husart: USART handle
\r
1668 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
\r
1670 uint32_t tmpreg = 0x0;
\r
1671 USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED;
\r
1672 HAL_StatusTypeDef ret = HAL_OK;
\r
1673 uint16_t brrtemp = 0x0000;
\r
1674 uint16_t usartdiv = 0x0000;
\r
1676 /* Check the parameters */
\r
1677 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
\r
1678 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
\r
1679 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
\r
1680 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
\r
1681 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
\r
1682 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
\r
1683 assert_param(IS_USART_PARITY(husart->Init.Parity));
\r
1684 assert_param(IS_USART_MODE(husart->Init.Mode));
\r
1685 assert_param(IS_USART_OVERSAMPLING(husart->Init.OverSampling));
\r
1688 /*-------------------------- USART CR1 Configuration -----------------------*/
\r
1689 /* Clear M, PCE, PS, TE and RE bits and configure
\r
1690 * the USART Word Length, Parity, Mode and OverSampling:
\r
1691 * set the M bits according to husart->Init.WordLength value
\r
1692 * set PCE and PS bits according to husart->Init.Parity value
\r
1693 * set TE and RE bits according to husart->Init.Mode value
\r
1694 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
\r
1695 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
\r
1696 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
\r
1698 /*---------------------------- USART CR2 Configuration ---------------------*/
\r
1699 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
\r
1700 * set CPOL bit according to husart->Init.CLKPolarity value
\r
1701 * set CPHA bit according to husart->Init.CLKPhase value
\r
1702 * set LBCL bit according to husart->Init.CLKLastBit value
\r
1703 * set STOP[13:12] bits according to husart->Init.StopBits value */
\r
1704 tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
\r
1705 tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
\r
1706 tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits);
\r
1707 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
\r
1709 /*-------------------------- USART CR3 Configuration -----------------------*/
\r
1710 /* no CR3 register configuration */
\r
1712 /*-------------------------- USART BRR Configuration -----------------------*/
\r
1713 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
\r
1714 USART_GETCLOCKSOURCE(husart, clocksource);
\r
1715 switch (clocksource)
\r
1717 case USART_CLOCKSOURCE_PCLK1:
\r
1718 usartdiv = (uint16_t)((2*HAL_RCC_GetPCLK1Freq()) / husart->Init.BaudRate);
\r
1720 case USART_CLOCKSOURCE_PCLK2:
\r
1721 usartdiv = (uint16_t)((2*HAL_RCC_GetPCLK2Freq()) / husart->Init.BaudRate);
\r
1723 case USART_CLOCKSOURCE_HSI:
\r
1724 usartdiv = (uint16_t)((2*HSI_VALUE) / husart->Init.BaudRate);
\r
1726 case USART_CLOCKSOURCE_SYSCLK:
\r
1727 usartdiv = (uint16_t)((2*HAL_RCC_GetSysClockFreq()) / husart->Init.BaudRate);
\r
1729 case USART_CLOCKSOURCE_LSE:
\r
1730 usartdiv = (uint16_t)((2*LSE_VALUE) / husart->Init.BaudRate);
\r
1732 case USART_CLOCKSOURCE_UNDEFINED:
\r
1738 brrtemp = usartdiv & 0xFFF0;
\r
1739 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U);
\r
1740 husart->Instance->BRR = brrtemp;
\r
1746 * @brief Check the USART Idle State
\r
1747 * @param husart: USART handle
\r
1748 * @retval HAL status
\r
1750 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
\r
1752 /* Initialize the USART ErrorCode */
\r
1753 husart->ErrorCode = HAL_USART_ERROR_NONE;
\r
1755 /* Check if the Transmitter is enabled */
\r
1756 if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
\r
1758 /* Wait until TEACK flag is set */
\r
1759 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
\r
1761 husart->State= HAL_USART_STATE_TIMEOUT;
\r
1762 return HAL_TIMEOUT;
\r
1765 /* Check if the Receiver is enabled */
\r
1766 if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
\r
1768 /* Wait until REACK flag is set */
\r
1769 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
\r
1771 husart->State= HAL_USART_STATE_TIMEOUT;
\r
1772 return HAL_TIMEOUT;
\r
1776 /* Initialize the USART state*/
\r
1777 husart->State= HAL_USART_STATE_READY;
\r
1779 /* Process Unlocked */
\r
1780 __HAL_UNLOCK(husart);
\r
1789 #endif /* HAL_USART_MODULE_ENABLED */
\r
1798 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r