2 ******************************************************************************
3 * @file stm32f3xx_hal_uart.c
4 * @author MCD Application Team
7 * @brief UART HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
11 * + Initialization and de-initialization functions
12 * + IO operation functions
13 * + Peripheral Control functions
17 ===============================================================================
18 ##### How to use this driver #####
19 ===============================================================================
21 The UART HAL driver can be used as follows:
23 (#) Declare a UART_HandleTypeDef handle structure.
24 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit ()API:
25 (##) Enable the USARTx interface clock.
26 (##) UART pins configuration:
27 (+) Enable the clock for the UART GPIOs.
28 (+) Configure these UART pins as alternate function pull-up.
29 (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
30 and HAL_UART_Receive_IT() APIs):
31 (+) Configure the USARTx interrupt priority.
32 (+) Enable the NVIC USART IRQ handle.
33 (@) The specific UART interrupts (Transmission complete interrupt,
34 RXNE interrupt and Error Interrupts) will be managed using the macros
35 __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit and receive process.
36 (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
37 and HAL_UART_Receive_DMA() APIs):
38 (+) Declare a DMA handle structure for the Tx/Rx channel.
39 (+) Enable the DMAx interface clock.
40 (+) Configure the declared DMA handle structure with the required Tx/Rx parameters.
41 (+) Configure the DMA Tx/Rx channel.
42 (+) Associate the initilalized DMA handle to the UART DMA Tx/Rx handle.
43 (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
45 (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware
46 flow control and Mode(Receiver/Transmitter) in the huart Init structure.
48 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
49 in the huart AdvancedInit structure.
51 (#) For the UART asynchronous mode, initialize the UART registers by calling
52 the HAL_UART_Init() API.
54 (#) For the UART Half duplex mode, initialize the UART registers by calling
55 the HAL_HalfDuplex_Init() API.
57 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
58 by calling the HAL_LIN_Init() API.
60 (#) For the UART Multiprocessor mode, initialize the UART registers
61 by calling the HAL_MultiProcessor_Init() API.
63 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
64 by calling the HAL_RS485Ex_Init() API.
66 (@) These API's(HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
67 also configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) by
68 calling the customized HAL_UART_MspInit() API.
71 ******************************************************************************
74 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
76 * Redistribution and use in source and binary forms, with or without modification,
77 * are permitted provided that the following conditions are met:
78 * 1. Redistributions of source code must retain the above copyright notice,
79 * this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright notice,
81 * this list of conditions and the following disclaimer in the documentation
82 * and/or other materials provided with the distribution.
83 * 3. Neither the name of STMicroelectronics nor the names of its contributors
84 * may be used to endorse or promote products derived from this software
85 * without specific prior written permission.
87 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
88 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
89 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
91 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
92 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
93 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
94 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
95 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
96 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98 ******************************************************************************
101 /* Includes ------------------------------------------------------------------*/
102 #include "stm32f3xx_hal.h"
104 /** @addtogroup STM32F3xx_HAL_Driver
108 /** @defgroup UART UART HAL module driver
109 * @brief UART HAL module driver
112 #ifdef HAL_UART_MODULE_ENABLED
114 /* Private typedef -----------------------------------------------------------*/
115 /* Private define ------------------------------------------------------------*/
116 /** @defgroup UART_Private_Constants UART Private Constants
119 #define HAL_UART_TXDMA_TIMEOUTVALUE 22000
120 #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
121 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
126 /* Private macro -------------------------------------------------------------*/
127 /* Private variables ---------------------------------------------------------*/
128 /* Private function prototypes -----------------------------------------------*/
129 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
130 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
131 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
132 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
133 static void UART_DMAError(DMA_HandleTypeDef *hdma);
134 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
135 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
136 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
137 /* Exported functions ---------------------------------------------------------*/
139 /** @defgroup UART_Exported_Functions UART Exported Functions
143 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
144 * @brief Initialization and Configuration functions
147 ===============================================================================
148 ##### Initialization and Configuration functions #####
149 ===============================================================================
151 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
152 in asynchronous mode.
153 (+) For the asynchronous mode the parameters below can be configured:
157 (++) Parity: If the parity is enabled, then the MSB bit of the data written
158 in the data register is transmitted but is changed by the parity bit.
159 Depending on the frame length defined by the M bit (8-bits or 9-bits)
160 or by the M1 and M0 bits (7-bit, 8-bit or 9-bit),
161 the possible UART frame formats are as listed in the following table:
162 +---------------------------------------------------------------+
163 | M bit | PCE bit | UART frame |
164 |-----------|-----------|---------------------------------------|
165 | 0 | 0 | | SB | 8-bit data | STB | |
166 |-----------|-----------|---------------------------------------|
167 | 0 | 1 | | SB | 7-bit data | PB | STB | |
168 |-----------|-----------|---------------------------------------|
169 | 1 | 0 | | SB | 9-bit data | STB | |
170 |-----------|-----------|---------------------------------------|
171 | 1 | 1 | | SB | 8-bit data | PB | STB | |
172 +---------------------------------------------------------------+
173 | M1M0 bits | PCE bit | UART frame |
174 |-----------------------|---------------------------------------|
175 | 10 | 0 | | SB | 7-bit data | STB | |
176 |-----------|-----------|---------------------------------------|
177 | 10 | 1 | | SB | 6-bit data | PB | STB | |
178 +---------------------------------------------------------------+
179 (++) Hardware flow control
180 (++) Receiver/transmitter modes
181 (++) Over Sampling Method
182 (++) One-Bit Sampling Method
183 (+) For the asynchronous mode, the following advanced features can be configured as well:
184 (++) TX and/or RX pin level inversion
185 (++) data logical level inversion
186 (++) RX and TX pins swap
187 (++) RX overrun detection disabling
188 (++) DMA disabling on RX error
189 (++) MSB first on communication line
190 (++) auto Baud rate detection
192 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init()
193 API follow respectively the UART asynchronous, UART Half duplex, UART LIN mode and
194 multiprocessor configuration procedures (details for the procedures are available in reference manual).
201 * @brief Initializes the UART mode according to the specified
202 * parameters in the UART_InitTypeDef and creates the associated handle .
203 * @param huart: uart handle
206 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
208 /* Check the UART handle allocation */
209 if(huart == HAL_NULL)
214 if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
216 /* Check the parameters */
217 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
221 /* Check the parameters */
222 assert_param(IS_UART_INSTANCE(huart->Instance));
225 if(huart->State == HAL_UART_STATE_RESET)
227 /* Init the low level hardware : GPIO, CLOCK */
228 HAL_UART_MspInit(huart);
231 huart->State = HAL_UART_STATE_BUSY;
233 /* Disable the Peripheral */
234 __HAL_UART_DISABLE(huart);
236 /* Set the UART Communication parameters */
237 if (UART_SetConfig(huart) == HAL_ERROR)
242 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
244 UART_AdvFeatureConfig(huart);
247 /* In asynchronous mode, the following bits must be kept cleared:
248 - LINEN and CLKEN bits in the USART_CR2 register,
249 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
250 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
251 huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
253 /* Enable the Peripheral */
254 __HAL_UART_ENABLE(huart);
256 /* TEACK and/or REACK to check before moving huart->State to Ready */
257 return (UART_CheckIdleState(huart));
261 * @brief Initializes the half-duplex mode according to the specified
262 * parameters in the UART_InitTypeDef and creates the associated handle .
263 * @param huart: uart handle
266 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
268 /* Check the UART handle allocation */
269 if(huart == HAL_NULL)
274 /* Check UART instance */
275 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
277 if(huart->State == HAL_UART_STATE_RESET)
279 /* Init the low level hardware : GPIO, CLOCK */
280 HAL_UART_MspInit(huart);
283 huart->State = HAL_UART_STATE_BUSY;
285 /* Disable the Peripheral */
286 __HAL_UART_DISABLE(huart);
288 /* Set the UART Communication parameters */
289 if (UART_SetConfig(huart) == HAL_ERROR)
294 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
296 UART_AdvFeatureConfig(huart);
299 /* In half-duplex mode, the following bits must be kept cleared:
300 - LINEN and CLKEN bits in the USART_CR2 register,
301 - SCEN and IREN bits in the USART_CR3 register.*/
302 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
303 huart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN);
305 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
306 huart->Instance->CR3 |= USART_CR3_HDSEL;
308 /* Enable the Peripheral */
309 __HAL_UART_ENABLE(huart);
311 /* TEACK and/or REACK to check before moving huart->State to Ready */
312 return (UART_CheckIdleState(huart));
317 * @brief Initializes the LIN mode according to the specified
318 * parameters in the UART_InitTypeDef and creates the associated handle .
319 * @param huart: uart handle
320 * @param BreakDetectLength: specifies the LIN break detection length.
321 * This parameter can be one of the following values:
322 * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
323 * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
326 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
328 /* Check the UART handle allocation */
329 if(huart == HAL_NULL)
334 /* Check the LIN UART instance */
335 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
336 /* Check the Break detection length parameter */
337 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
339 /* LIN mode limited to 16-bit oversampling only */
340 if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
345 if(huart->State == HAL_UART_STATE_RESET)
347 /* Init the low level hardware : GPIO, CLOCK */
348 HAL_UART_MspInit(huart);
351 huart->State = HAL_UART_STATE_BUSY;
353 /* Disable the Peripheral */
354 __HAL_UART_DISABLE(huart);
356 /* Set the UART Communication parameters */
357 if (UART_SetConfig(huart) == HAL_ERROR)
362 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
364 UART_AdvFeatureConfig(huart);
367 /* In LIN mode, the following bits must be kept cleared:
368 - LINEN and CLKEN bits in the USART_CR2 register,
369 - SCEN and IREN bits in the USART_CR3 register.*/
370 huart->Instance->CR2 &= ~(USART_CR2_CLKEN);
371 huart->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN);
373 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
374 huart->Instance->CR2 |= USART_CR2_LINEN;
376 /* Set the USART LIN Break detection length. */
377 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
379 /* Enable the Peripheral */
380 __HAL_UART_ENABLE(huart);
382 /* TEACK and/or REACK to check before moving huart->State to Ready */
383 return (UART_CheckIdleState(huart));
389 * @brief Initializes the multiprocessor mode according to the specified
390 * parameters in the UART_InitTypeDef and creates the associated handle.
391 * @param huart: UART handle
392 * @param Address: UART node address (4-, 6-, 7- or 8-bit long)
393 * @param WakeUpMethod: specifies the UART wakeup method.
394 * This parameter can be one of the following values:
395 * @arg UART_WAKEUPMETHOD_IDLELINE: WakeUp by an idle line detection
396 * @arg UART_WAKEUPMETHOD_ADDRESSMARK: WakeUp by an address mark
397 * @note If the user resorts to idle line detection wake up, the Address parameter
398 * is useless and ignored by the initialization function.
399 * @note If the user resorts to address mark wake up, the address length detection
400 * is configured by default to 4 bits only. For the UART to be able to
401 * manage 6-, 7- or 8-bit long addresses detection, the API
402 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
403 * HAL_MultiProcessor_Init().
406 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
408 /* Check the UART handle allocation */
409 if(huart == HAL_NULL)
414 /* Check the wake up method parameter */
415 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
417 if(huart->State == HAL_UART_STATE_RESET)
419 /* Init the low level hardware : GPIO, CLOCK */
420 HAL_UART_MspInit(huart);
423 huart->State = HAL_UART_STATE_BUSY;
425 /* Disable the Peripheral */
426 __HAL_UART_DISABLE(huart);
428 /* Set the UART Communication parameters */
429 if (UART_SetConfig(huart) == HAL_ERROR)
434 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
436 UART_AdvFeatureConfig(huart);
439 /* In multiprocessor mode, the following bits must be kept cleared:
440 - LINEN and CLKEN bits in the USART_CR2 register,
441 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
442 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
443 huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
445 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
447 /* If address mark wake up method is chosen, set the USART address node */
448 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
451 /* Set the wake up method by setting the WAKE bit in the CR1 register */
452 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
454 /* Enable the Peripheral */
455 __HAL_UART_ENABLE(huart);
457 /* TEACK and/or REACK to check before moving huart->State to Ready */
458 return (UART_CheckIdleState(huart));
465 * @brief DeInitializes the UART peripheral
466 * @param huart: uart handle
469 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
471 /* Check the UART handle allocation */
472 if(huart == HAL_NULL)
477 /* Check the parameters */
478 assert_param(IS_UART_INSTANCE(huart->Instance));
480 huart->State = HAL_UART_STATE_BUSY;
482 /* Disable the Peripheral */
483 __HAL_UART_DISABLE(huart);
485 huart->Instance->CR1 = 0x0;
486 huart->Instance->CR2 = 0x0;
487 huart->Instance->CR3 = 0x0;
489 /* DeInit the low level hardware */
490 HAL_UART_MspDeInit(huart);
492 huart->ErrorCode = HAL_UART_ERROR_NONE;
493 huart->State = HAL_UART_STATE_RESET;
502 * @brief UART MSP Init
503 * @param huart: uart handle
506 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
508 /* NOTE : This function should not be modified, when the callback is needed,
509 the HAL_UART_MspInit can be implemented in the user file
514 * @brief UART MSP DeInit
515 * @param huart: uart handle
518 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
520 /* NOTE : This function should not be modified, when the callback is needed,
521 the HAL_UART_MspDeInit can be implemented in the user file
529 /** @defgroup UART_Exported_Functions_Group2 Input and Output operation functions
530 * @brief UART Transmit/Receive functions
533 ===============================================================================
534 ##### I/O operation functions #####
535 ===============================================================================
536 This subsection provides a set of functions allowing to manage the UART asynchronous
537 and Half duplex data transfers.
539 (#) There are two mode of transfer:
540 (+) Blocking mode: The communication is performed in polling mode.
541 The HAL status of all data processing is returned by the same function
542 after finishing transfer.
543 (+) No-Blocking mode: The communication is performed using Interrupts
544 or DMA, These API's return the HAL status.
545 The end of the data processing will be indicated through the
546 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
548 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
549 will be executed respectivelly at the end of the transmit or Receive process
550 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
552 (#) Blocking mode API's are :
553 (+) HAL_UART_Transmit()
554 (+) HAL_UART_Receive()
556 (#) Non-Blocking mode API's with Interrupt are :
557 (+) HAL_UART_Transmit_IT()
558 (+) HAL_UART_Receive_IT()
559 (+) HAL_UART_IRQHandler()
561 (#) No-Blocking mode API's with DMA are :
562 (+) HAL_UART_Transmit_DMA()
563 (+) HAL_UART_Receive_DMA()
564 (+) HAL_UART_DMAPause()
565 (+) HAL_UART_DMAResume()
566 (+) HAL_UART_DMAStop()
568 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
569 (+) HAL_UART_TxHalfCpltCallback()
570 (+) HAL_UART_TxCpltCallback()
571 (+) HAL_UART_RxHalfCpltCallback()
572 (+) HAL_UART_RxCpltCallback()
573 (+) HAL_UART_ErrorCallback()
576 -@- In the Half duplex communication, it is forbidden to run the transmit
577 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
584 * @brief Send an amount of data in blocking mode
585 * @param huart: uart handle
586 * @param pData: pointer to data buffer
587 * @param Size: amount of data to be sent
588 * @param Timeout : Timeout duration
591 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
595 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
597 if((pData == HAL_NULL ) || (Size == 0))
605 huart->ErrorCode = HAL_UART_ERROR_NONE;
606 /* Check if a non-blocking receive process is ongoing or not */
607 if(huart->State == HAL_UART_STATE_BUSY_RX)
609 huart->State = HAL_UART_STATE_BUSY_TX_RX;
613 huart->State = HAL_UART_STATE_BUSY_TX;
616 huart->TxXferSize = Size;
617 huart->TxXferCount = Size;
618 while(huart->TxXferCount > 0)
620 huart->TxXferCount--;
621 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)
625 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
627 tmp = (uint16_t*) pData;
628 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
633 huart->Instance->TDR = (*pData++ & (uint8_t)0xFF);
636 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK)
640 /* Check if a non-blocking receive Process is ongoing or not */
641 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
643 huart->State = HAL_UART_STATE_BUSY_RX;
647 huart->State = HAL_UART_STATE_READY;
650 /* Process Unlocked */
662 * @brief Receive an amount of data in blocking mode
663 * @param huart: uart handle
664 * @param pData: pointer to data buffer
665 * @param Size: amount of data to be received
666 * @param Timeout : Timeout duration
669 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
674 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
676 if((pData == HAL_NULL ) || (Size == 0))
684 huart->ErrorCode = HAL_UART_ERROR_NONE;
685 /* Check if a non-blocking transmit process is ongoing or not */
686 if(huart->State == HAL_UART_STATE_BUSY_TX)
688 huart->State = HAL_UART_STATE_BUSY_TX_RX;
692 huart->State = HAL_UART_STATE_BUSY_RX;
695 huart->RxXferSize = Size;
696 huart->RxXferCount = Size;
698 /* Computation of UART mask to apply to RDR register */
699 __HAL_UART_MASK_COMPUTATION(huart);
700 uhMask = huart->Mask;
702 /* as long as data have to be received */
703 while(huart->RxXferCount > 0)
705 huart->RxXferCount--;
706 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
710 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
712 tmp = (uint16_t*) pData ;
713 *tmp = (uint16_t)(huart->Instance->RDR & uhMask);
718 *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
722 /* Check if a non-blocking transmit Process is ongoing or not */
723 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
725 huart->State = HAL_UART_STATE_BUSY_TX;
729 huart->State = HAL_UART_STATE_READY;
731 /* Process Unlocked */
743 * @brief Send an amount of data in interrupt mode
744 * @param huart: uart handle
745 * @param pData: pointer to data buffer
746 * @param Size: amount of data to be sent
749 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
751 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
753 if((pData == HAL_NULL ) || (Size == 0))
761 huart->pTxBuffPtr = pData;
762 huart->TxXferSize = Size;
763 huart->TxXferCount = Size;
765 huart->ErrorCode = HAL_UART_ERROR_NONE;
766 /* Check if a receive process is ongoing or not */
767 if(huart->State == HAL_UART_STATE_BUSY_RX)
769 huart->State = HAL_UART_STATE_BUSY_TX_RX;
773 huart->State = HAL_UART_STATE_BUSY_TX;
776 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
777 __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
779 /* Process Unlocked */
782 /* Enable the UART Transmit Data Register Empty Interrupt */
783 __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
794 * @brief Receive an amount of data in interrupt mode
795 * @param huart: uart handle
796 * @param pData: pointer to data buffer
797 * @param Size: amount of data to be received
800 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
802 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
804 if((pData == HAL_NULL ) || (Size == 0))
812 huart->pRxBuffPtr = pData;
813 huart->RxXferSize = Size;
814 huart->RxXferCount = Size;
816 /* Computation of UART mask to apply to RDR register */
817 __HAL_UART_MASK_COMPUTATION(huart);
819 huart->ErrorCode = HAL_UART_ERROR_NONE;
820 /* Check if a transmit process is ongoing or not */
821 if(huart->State == HAL_UART_STATE_BUSY_TX)
823 huart->State = HAL_UART_STATE_BUSY_TX_RX;
827 huart->State = HAL_UART_STATE_BUSY_RX;
830 /* Enable the UART Parity Error Interrupt */
831 __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
833 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
834 __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
836 /* Process Unlocked */
839 /* Enable the UART Data Register not empty Interrupt */
840 __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
851 * @brief Send an amount of data in DMA mode
852 * @param huart: uart handle
853 * @param pData: pointer to data buffer
854 * @param Size: amount of data to be sent
857 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
861 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
863 if((pData == HAL_NULL ) || (Size == 0))
871 huart->pTxBuffPtr = pData;
872 huart->TxXferSize = Size;
873 huart->TxXferCount = Size;
875 huart->ErrorCode = HAL_UART_ERROR_NONE;
876 /* Check if a receive process is ongoing or not */
877 if(huart->State == HAL_UART_STATE_BUSY_RX)
879 huart->State = HAL_UART_STATE_BUSY_TX_RX;
883 huart->State = HAL_UART_STATE_BUSY_TX;
886 /* Set the UART DMA transfer complete callback */
887 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
889 /* Set the UART DMA Half transfer complete callback */
890 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
892 /* Set the DMA error callback */
893 huart->hdmatx->XferErrorCallback = UART_DMAError;
895 /* Enable the UART transmit DMA channel */
896 tmp = (uint32_t*)&pData;
897 HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, Size);
899 /* Enable the DMA transfer for transmit request by setting the DMAT bit
900 in the UART CR3 register */
901 huart->Instance->CR3 |= USART_CR3_DMAT;
903 /* Process Unlocked */
915 * @brief Receive an amount of data in DMA mode
916 * @param huart: uart handle
917 * @param pData: pointer to data buffer
918 * @param Size: amount of data to be received
919 * @note When the UART parity is enabled (PCE = 1), the received data contain
920 * the parity bit (MSB position)
923 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
927 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
929 if((pData == HAL_NULL ) || (Size == 0))
937 huart->pRxBuffPtr = pData;
938 huart->RxXferSize = Size;
940 huart->ErrorCode = HAL_UART_ERROR_NONE;
941 /* Check if a transmit process is ongoing or not */
942 if(huart->State == HAL_UART_STATE_BUSY_TX)
944 huart->State = HAL_UART_STATE_BUSY_TX_RX;
948 huart->State = HAL_UART_STATE_BUSY_RX;
951 /* Set the UART DMA transfer complete callback */
952 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
954 /* Set the UART DMA Half transfer complete callback */
955 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
957 /* Set the DMA error callback */
958 huart->hdmarx->XferErrorCallback = UART_DMAError;
960 /* Enable the DMA channel */
961 tmp = (uint32_t*)&pData;
962 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size);
964 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
965 in the UART CR3 register */
966 huart->Instance->CR3 |= USART_CR3_DMAR;
968 /* Process Unlocked */
980 * @brief Pauses the DMA Transfer.
981 * @param huart: UART handle
984 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
989 if(huart->State == HAL_UART_STATE_BUSY_TX)
991 /* Disable the UART DMA Tx request */
992 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
994 else if(huart->State == HAL_UART_STATE_BUSY_RX)
996 /* Disable the UART DMA Rx request */
997 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
999 else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1001 /* Disable the UART DMA Tx request */
1002 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
1003 /* Disable the UART DMA Rx request */
1004 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
1007 /* Process Unlocked */
1008 __HAL_UNLOCK(huart);
1014 * @brief Resumes the DMA Transfer.
1015 * @param huart: UART handle
1018 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1020 /* Process Locked */
1023 if(huart->State == HAL_UART_STATE_BUSY_TX)
1025 /* Enable the UART DMA Tx request */
1026 huart->Instance->CR3 |= USART_CR3_DMAT;
1028 else if(huart->State == HAL_UART_STATE_BUSY_RX)
1030 /* Enable the UART DMA Rx request */
1031 huart->Instance->CR3 |= USART_CR3_DMAR;
1033 else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1035 /* Enable the UART DMA Rx request before the DMA Tx request */
1036 huart->Instance->CR3 |= USART_CR3_DMAR;
1037 /* Enable the UART DMA Tx request */
1038 huart->Instance->CR3 |= USART_CR3_DMAT;
1041 /* If the UART peripheral is still not enabled, enable it */
1042 if ((huart->Instance->CR1 & USART_CR1_UE) == 0)
1044 /* Enable UART peripheral */
1045 __HAL_UART_ENABLE(huart);
1048 /* TEACK and/or REACK to check before moving huart->State to Ready */
1049 return (UART_CheckIdleState(huart));
1053 * @brief Stops the DMA Transfer.
1054 * @param huart: UART handle
1057 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1059 /* Process Locked */
1062 /* Disable the UART Tx/Rx DMA requests */
1063 huart->Instance->CR3 &= ~USART_CR3_DMAT;
1064 huart->Instance->CR3 &= ~USART_CR3_DMAR;
1066 /* Abort the UART DMA tx channel */
1067 if(huart->hdmatx != HAL_NULL)
1069 HAL_DMA_Abort(huart->hdmatx);
1071 /* Abort the UART DMA rx channel */
1072 if(huart->hdmarx != HAL_NULL)
1074 HAL_DMA_Abort(huart->hdmarx);
1077 /* Disable UART peripheral */
1078 __HAL_UART_DISABLE(huart);
1080 huart->State = HAL_UART_STATE_READY;
1082 /* Process Unlocked */
1083 __HAL_UNLOCK(huart);
1089 * @brief This function handles UART interrupt request.
1090 * @param huart: uart handle
1093 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
1095 /* UART parity error interrupt occurred -------------------------------------*/
1096 if((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE) != RESET))
1098 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
1100 huart->ErrorCode |= HAL_UART_ERROR_PE;
1101 /* Set the UART state ready to be able to start again the process */
1102 huart->State = HAL_UART_STATE_READY;
1105 /* UART frame error interrupt occured --------------------------------------*/
1106 if((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
1108 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
1110 huart->ErrorCode |= HAL_UART_ERROR_FE;
1111 /* Set the UART state ready to be able to start again the process */
1112 huart->State = HAL_UART_STATE_READY;
1115 /* UART noise error interrupt occured --------------------------------------*/
1116 if((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
1118 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
1120 huart->ErrorCode |= HAL_UART_ERROR_NE;
1121 /* Set the UART state ready to be able to start again the process */
1122 huart->State = HAL_UART_STATE_READY;
1125 /* UART Over-Run interrupt occured -----------------------------------------*/
1126 if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
1128 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
1130 huart->ErrorCode |= HAL_UART_ERROR_ORE;
1131 /* Set the UART state ready to be able to start again the process */
1132 huart->State = HAL_UART_STATE_READY;
1135 /* Call UART Error Call back function if need be --------------------------*/
1136 if(huart->ErrorCode != HAL_UART_ERROR_NONE)
1138 HAL_UART_ErrorCallback(huart);
1141 /* UART wakeup from Stop mode interrupt occurred -------------------------------------*/
1142 if((__HAL_UART_GET_IT(huart, UART_IT_WUF) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_WUF) != RESET))
1144 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
1145 /* Set the UART state ready to be able to start again the process */
1146 huart->State = HAL_UART_STATE_READY;
1147 HAL_UART_WakeupCallback(huart);
1150 /* UART in mode Receiver ---------------------------------------------------*/
1151 if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET))
1153 UART_Receive_IT(huart);
1154 /* Clear RXNE interrupt flag */
1155 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1159 /* UART in mode Transmitter ------------------------------------------------*/
1160 if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET))
1162 UART_Transmit_IT(huart);
1165 /* UART in mode Transmitter (transmission end) -----------------------------*/
1166 if((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET))
1168 UART_EndTransmit_IT(huart);
1175 * @brief This function handles UART Communication Timeout.
1176 * @param huart: UART handle
1177 * @param Flag: specifies the UART flag to check.
1178 * @param Status: The new Flag status (SET or RESET).
1179 * @param Timeout: Timeout duration
1180 * @retval HAL status
1182 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1184 uint32_t tickstart = HAL_GetTick();
1186 /* Wait until flag is set */
1189 while(__HAL_UART_GET_FLAG(huart, Flag) == RESET)
1191 /* Check for the Timeout */
1192 if(Timeout != HAL_MAX_DELAY)
1194 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1196 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1197 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1198 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1199 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1200 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1202 huart->State = HAL_UART_STATE_TIMEOUT;
1204 /* Process Unlocked */
1205 __HAL_UNLOCK(huart);
1214 while(__HAL_UART_GET_FLAG(huart, Flag) != RESET)
1216 /* Check for the Timeout */
1217 if(Timeout != HAL_MAX_DELAY)
1219 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1221 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1222 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1223 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1224 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1225 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1227 huart->State = HAL_UART_STATE_TIMEOUT;
1229 /* Process Unlocked */
1230 __HAL_UNLOCK(huart);
1241 * @brief Tx Transfer completed callbacks
1242 * @param huart: uart handle
1245 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
1247 /* NOTE : This function should not be modified, when the callback is needed,
1248 the HAL_UART_TxCpltCallback can be implemented in the user file
1253 * @brief Tx Half Transfer completed callbacks.
1254 * @param huart: UART handle
1257 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
1259 /* NOTE: This function should not be modified, when the callback is needed,
1260 the HAL_UART_TxHalfCpltCallback can be implemented in the user file
1265 * @brief Rx Transfer completed callbacks
1266 * @param huart: uart handle
1269 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
1271 /* NOTE : This function should not be modified, when the callback is needed,
1272 the HAL_UART_RxCpltCallback can be implemented in the user file
1277 * @brief Rx Half Transfer completed callbacks.
1278 * @param huart: UART handle
1281 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
1283 /* NOTE: This function should not be modified, when the callback is needed,
1284 the HAL_UART_RxHalfCpltCallback can be implemented in the user file
1289 * @brief UART error callbacks
1290 * @param huart: uart handle
1293 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
1295 /* NOTE : This function should not be modified, when the callback is needed,
1296 the HAL_UART_ErrorCallback can be implemented in the user file
1301 * @brief UART wakeup from Stop mode callback
1302 * @param huart: uart handle
1305 __weak void HAL_UART_WakeupCallback(UART_HandleTypeDef *huart)
1307 /* NOTE : This function should not be modified, when the callback is needed,
1308 the HAL_UART_WakeupCallback can be implemented in the user file
1316 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
1317 * @brief UART control functions
1320 ===============================================================================
1321 ##### Peripheral Control functions #####
1322 ===============================================================================
1324 This subsection provides a set of functions allowing to control the UART.
1325 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
1326 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
1327 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
1328 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
1329 (+) UART_SetConfig() API configures the UART peripheral
1330 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
1331 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
1332 (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters
1333 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
1334 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
1335 (+) HAL_LIN_SendBreak() API transmits the break characters
1341 * @brief Enable UART in mute mode (doesn't mean UART enters mute mode;
1342 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called)
1343 * @param huart: UART handle
1344 * @retval HAL status
1346 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
1348 /* Process Locked */
1351 huart->State = HAL_UART_STATE_BUSY;
1353 /* Enable USART mute mode by setting the MME bit in the CR1 register */
1354 huart->Instance->CR1 |= USART_CR1_MME;
1356 huart->State = HAL_UART_STATE_READY;
1358 return (UART_CheckIdleState(huart));
1362 * @brief Disable UART mute mode (doesn't mean it actually wakes up the software,
1363 * as it may not have been in mute mode at this very moment).
1364 * @param huart: uart handle
1365 * @retval HAL status
1367 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
1369 /* Process Locked */
1372 huart->State = HAL_UART_STATE_BUSY;
1374 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
1375 huart->Instance->CR1 &= ~(USART_CR1_MME);
1377 huart->State = HAL_UART_STATE_READY;
1379 return (UART_CheckIdleState(huart));
1383 * @brief Enter UART mute mode (means UART actually enters mute mode).
1384 * To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
1385 * @param huart: uart handle
1386 * @retval HAL status
1388 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
1390 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
1394 * @brief Configure the UART peripheral
1395 * @param huart: uart handle
1398 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
1400 uint32_t tmpreg = 0x00000000;
1401 UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED;
1402 uint16_t brrtemp = 0x0000;
1403 uint16_t usartdiv = 0x0000;
1404 HAL_StatusTypeDef ret = HAL_OK;
1406 /* Check the parameters */
1407 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
1408 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
1409 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
1410 assert_param(IS_UART_PARITY(huart->Init.Parity));
1411 assert_param(IS_UART_MODE(huart->Init.Mode));
1412 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
1413 assert_param(IS_UART_ONEBIT_SAMPLING(huart->Init.OneBitSampling));
1414 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
1417 /*-------------------------- USART CR1 Configuration -----------------------*/
1418 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
1419 * the UART Word Length, Parity, Mode and oversampling:
1420 * set the M bits according to huart->Init.WordLength value
1421 * set PCE and PS bits according to huart->Init.Parity value
1422 * set TE and RE bits according to huart->Init.Mode value
1423 * set OVER8 bit according to huart->Init.OverSampling value */
1424 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
1425 MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg);
1427 /*-------------------------- USART CR2 Configuration -----------------------*/
1428 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
1429 * to huart->Init.StopBits value */
1430 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
1432 /*-------------------------- USART CR3 Configuration -----------------------*/
1434 * - UART HardWare Flow Control: set CTSE and RTSE bits according
1435 * to huart->Init.HwFlowCtl value
1436 * - one-bit sampling method versus three samples' majority rule according
1437 * to huart->Init.OneBitSampling */
1438 tmpreg = (uint32_t)huart->Init.HwFlowCtl | huart->Init.OneBitSampling ;
1439 MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT), tmpreg);
1441 /*-------------------------- USART BRR Configuration -----------------------*/
1442 __HAL_UART_GETCLOCKSOURCE(huart, clocksource);
1444 /* Check the Over Sampling to set Baud Rate Register */
1445 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
1447 switch (clocksource)
1449 case UART_CLOCKSOURCE_PCLK1:
1450 usartdiv = (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
1452 case UART_CLOCKSOURCE_PCLK2:
1453 usartdiv = (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
1455 case UART_CLOCKSOURCE_HSI:
1456 usartdiv = (uint16_t)(__DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
1458 case UART_CLOCKSOURCE_SYSCLK:
1459 usartdiv = (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
1461 case UART_CLOCKSOURCE_LSE:
1462 usartdiv = (uint16_t)(__DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate));
1464 case UART_CLOCKSOURCE_UNDEFINED:
1470 brrtemp = usartdiv & 0xFFF0;
1471 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U);
1472 huart->Instance->BRR = brrtemp;
1476 switch (clocksource)
1478 case UART_CLOCKSOURCE_PCLK1:
1479 huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
1481 case UART_CLOCKSOURCE_PCLK2:
1482 huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
1484 case UART_CLOCKSOURCE_HSI:
1485 huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
1487 case UART_CLOCKSOURCE_SYSCLK:
1488 huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
1490 case UART_CLOCKSOURCE_LSE:
1491 huart->Instance->BRR = (uint16_t)(__DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate));
1493 case UART_CLOCKSOURCE_UNDEFINED:
1506 * @brief Configure the UART peripheral advanced feautures
1507 * @param huart: uart handle
1510 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
1512 /* Check whether the set of advanced features to configure is properly set */
1513 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
1515 /* if required, configure TX pin active level inversion */
1516 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
1518 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
1519 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
1522 /* if required, configure RX pin active level inversion */
1523 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
1525 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
1526 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
1529 /* if required, configure data inversion */
1530 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
1532 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
1533 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
1536 /* if required, configure RX/TX pins swap */
1537 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
1539 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
1540 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
1543 /* if required, configure RX overrun detection disabling */
1544 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
1546 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
1547 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
1550 /* if required, configure DMA disabling on reception error */
1551 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
1553 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
1554 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
1557 /* if required, configure auto Baud rate detection scheme */
1558 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
1560 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
1561 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
1562 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
1563 /* set auto Baudrate detection parameters if detection is enabled */
1564 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
1566 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
1567 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
1571 /* if required, configure MSB first on communication line */
1572 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
1574 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
1575 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
1582 * @brief Check the UART Idle State
1583 * @param huart: uart handle
1584 * @retval HAL status
1586 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
1588 /* Initialize the UART ErrorCode */
1589 huart->ErrorCode = HAL_UART_ERROR_NONE;
1591 /* Check if the Transmitter is enabled */
1592 if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1594 /* Wait until TEACK flag is set */
1595 if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
1597 /* Timeout Occured */
1601 /* Check if the Receiver is enabled */
1602 if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1604 /* Wait until REACK flag is set */
1605 if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
1607 /* Timeout Occured */
1612 /* Initialize the UART State */
1613 huart->State= HAL_UART_STATE_READY;
1615 /* Process Unlocked */
1616 __HAL_UNLOCK(huart);
1625 * @brief Initializes the UART wake-up from stop mode parameters when triggered by address detection.
1626 * @param huart: uart handle
1627 * @param WakeUpSelection: UART wake up from stop mode parameters
1628 * @retval HAL status
1630 void UART_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
1632 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
1634 /* Set the USART address length */
1635 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
1637 /* Set the USART address node */
1638 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
1642 * @brief Enables the UART transmitter and disables the UART receiver.
1643 * @param huart: UART handle
1644 * @retval HAL status
1647 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
1649 /* Process Locked */
1651 huart->State = HAL_UART_STATE_BUSY;
1653 /* Clear TE and RE bits */
1654 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
1655 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
1656 SET_BIT(huart->Instance->CR1, USART_CR1_TE);
1658 huart->State = HAL_UART_STATE_READY;
1659 /* Process Unlocked */
1660 __HAL_UNLOCK(huart);
1666 * @brief Enables the UART receiver and disables the UART transmitter.
1667 * @param huart: UART handle
1668 * @retval HAL status
1670 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
1672 /* Process Locked */
1674 huart->State = HAL_UART_STATE_BUSY;
1676 /* Clear TE and RE bits */
1677 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
1678 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
1679 SET_BIT(huart->Instance->CR1, USART_CR1_RE);
1681 huart->State = HAL_UART_STATE_READY;
1682 /* Process Unlocked */
1683 __HAL_UNLOCK(huart);
1690 * @brief Transmits break characters.
1691 * @param huart: UART handle
1692 * @retval HAL status
1694 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
1696 /* Check the parameters */
1697 assert_param(IS_UART_INSTANCE(huart->Instance));
1699 /* Process Locked */
1702 huart->State = HAL_UART_STATE_BUSY;
1704 /* Send break characters */
1705 huart->Instance->RQR |= UART_SENDBREAK_REQUEST;
1707 huart->State = HAL_UART_STATE_READY;
1709 /* Process Unlocked */
1710 __HAL_UNLOCK(huart);
1720 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
1721 * @brief UART Peripheral State functions
1724 ==============================================================================
1725 ##### Peripheral State and Error functions #####
1726 ==============================================================================
1728 This subsection provides functions allowing to :
1729 (+) Returns the UART state.
1730 (+) Returns the UART error code
1737 * @brief return the UART state
1738 * @param huart: uart handle
1741 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
1743 return huart->State;
1747 * @brief Return the UART error code
1748 * @param huart : pointer to a UART_HandleTypeDef structure that contains
1749 * the configuration information for the specified UART.
1750 * @retval UART Error Code
1752 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
1754 return huart->ErrorCode;
1765 /** @defgroup UART_Private_Functions UART Private Functions
1769 * @brief DMA UART transmit process complete callback
1770 * @param hdma: DMA handle
1773 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1775 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1776 huart->TxXferCount = 0;
1778 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1779 in the UART CR3 register */
1780 huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
1782 /* Wait for UART TC Flag */
1783 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, HAL_UART_TXDMA_TIMEOUTVALUE) != HAL_OK)
1785 /* Timeout Occured */
1786 huart->State = HAL_UART_STATE_TIMEOUT;
1787 HAL_UART_ErrorCallback(huart);
1792 /* Check if a receive process is ongoing or not */
1793 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1795 huart->State = HAL_UART_STATE_BUSY_RX;
1799 huart->State = HAL_UART_STATE_READY;
1801 HAL_UART_TxCpltCallback(huart);
1806 * @brief DMA UART transmit process half complete callback
1807 * @param hdma : DMA handle
1810 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1812 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1814 HAL_UART_TxHalfCpltCallback(huart);
1818 * @brief DMA UART receive process complete callback
1819 * @param hdma: DMA handle
1822 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1824 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1825 huart->RxXferCount = 0;
1827 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1828 in the UART CR3 register */
1829 huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
1831 /* Check if a transmit Process is ongoing or not */
1832 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1834 huart->State = HAL_UART_STATE_BUSY_TX;
1838 huart->State = HAL_UART_STATE_READY;
1840 HAL_UART_RxCpltCallback(huart);
1844 * @brief DMA UART receive process half complete callback
1845 * @param hdma : DMA handle
1848 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1850 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1852 HAL_UART_RxHalfCpltCallback(huart);
1856 * @brief DMA UART communication error callback
1857 * @param hdma: DMA handle
1860 static void UART_DMAError(DMA_HandleTypeDef *hdma)
1862 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1863 huart->RxXferCount = 0;
1864 huart->TxXferCount = 0;
1865 huart->State= HAL_UART_STATE_READY;
1866 huart->ErrorCode |= HAL_UART_ERROR_DMA;
1867 HAL_UART_ErrorCallback(huart);
1871 * @brief Send an amount of data in interrupt mode
1872 * Function called under interruption only, once
1873 * interruptions have been enabled by HAL_UART_Transmit_IT()
1874 * @param huart: UART handle
1875 * @retval HAL status
1877 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
1881 if ((huart->State == HAL_UART_STATE_BUSY_TX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX))
1884 if(huart->TxXferCount == 0)
1886 /* Disable the UART Transmit Data Register Empty Interrupt */
1887 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1889 /* Enable the UART Transmit Complete Interrupt */
1890 __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
1896 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1898 tmp = (uint16_t*) huart->pTxBuffPtr;
1899 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1900 huart->pTxBuffPtr += 2;
1904 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF);
1907 huart->TxXferCount--;
1920 * @brief Wraps up transmission in non blocking mode.
1921 * @param huart: pointer to a UART_HandleTypeDef structure that contains
1922 * the configuration information for the specified UART module.
1923 * @retval HAL status
1925 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
1927 /* Disable the UART Transmit Complete Interrupt */
1928 __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
1930 /* Check if a receive process is ongoing or not */
1931 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1933 huart->State = HAL_UART_STATE_BUSY_RX;
1937 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1938 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1940 huart->State = HAL_UART_STATE_READY;
1943 HAL_UART_TxCpltCallback(huart);
1950 * @brief Receive an amount of data in interrupt mode
1951 * Function called under interruption only, once
1952 * interruptions have been enabled by HAL_UART_Receive_IT()
1953 * @param huart: UART handle
1954 * @retval HAL status
1956 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
1959 uint16_t uhMask = huart->Mask;
1961 if((huart->State == HAL_UART_STATE_BUSY_RX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX))
1964 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1966 tmp = (uint16_t*) huart->pRxBuffPtr ;
1967 *tmp = (uint16_t)(huart->Instance->RDR & uhMask);
1968 huart->pRxBuffPtr +=2;
1972 *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1975 if(--huart->RxXferCount == 0)
1977 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1979 /* Check if a transmit Process is ongoing or not */
1980 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1982 huart->State = HAL_UART_STATE_BUSY_TX;
1986 /* Disable the UART Parity Error Interrupt */
1987 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1989 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1990 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1992 huart->State = HAL_UART_STATE_READY;
1995 HAL_UART_RxCpltCallback(huart);
2012 #endif /* HAL_UART_MODULE_ENABLED */
2021 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/