2 ******************************************************************************
3 * @file stm32l0xx_hal_uart.c
4 * @author MCD Application Team
6 * @date 06-February-2015
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 methods
12 * + IO operation methods
13 * + Peripheral Control methods
16 ===============================================================================
17 ##### How to use this driver #####
18 ===============================================================================
20 The UART HAL driver can be used as follows:
22 (#) 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.
34 (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
35 and HAL_UART_Receive_DMA() APIs):
36 (+++) Declare a DMA handle structure for the Tx/Rx stream.
37 (+++) Enable the DMAx interface clock.
38 (+++) Configure the declared DMA handle structure with the required
40 (+++) Configure the DMA Tx/Rx Stream.
41 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
42 (+++) Configure the priority and enable the NVIC for the transfer complete
43 interrupt on the DMA Tx/Rx Stream.
45 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
46 flow control and Mode(Receiver/Transmitter) in the Init structure.
48 (#) For the UART asynchronous mode, initialize the UART registers by calling
49 the HAL_UART_Init() API.
51 (#) For the UART Half duplex mode, initialize the UART registers by calling
52 the HAL_HalfDuplex_Init() API.
54 (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
56 (#) For the Multi-Processor mode, initialize the UART registers by calling
57 the HAL_MultiProcessor_Init() API.
60 (@) The specific UART interrupts (Transmission complete interrupt,
61 RXNE interrupt and Error Interrupts) will be managed using the macros
62 __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
66 (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
67 low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customed
68 HAL_UART_MspInit() API.
71 Three operation modes are available within this driver :
73 *** Polling mode IO operation ***
74 =================================
76 (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
77 (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
80 *** Interrupt mode IO operation ***
81 ===================================
83 (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
84 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
85 add his own code by customization of function pointer HAL_UART_TxCpltCallback
86 (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
87 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
88 add his own code by customization of function pointer HAL_UART_RxCpltCallback
89 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
90 add his own code by customization of function pointer HAL_UART_ErrorCallback
92 *** DMA mode IO operation ***
93 ==============================
95 (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
96 (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
97 add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
98 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
99 add his own code by customization of function pointer HAL_UART_TxCpltCallback
100 (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
101 (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
102 add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
103 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
104 add his own code by customization of function pointer HAL_UART_RxCpltCallback
105 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
106 add his own code by customization of function pointer HAL_UART_ErrorCallback
107 (+) Pause the DMA Transfer using HAL_UART_DMAPause()
108 (+) Resume the DMA Transfer using HAL_UART_DMAResume()
109 (+) Stop the DMA Transfer using HAL_UART_DMAStop()
111 *** UART HAL driver macros list ***
112 =============================================
114 Below the list of most used macros in UART HAL driver.
116 (+) __HAL_UART_ENABLE: Enable the UART peripheral
117 (+) __HAL_UART_DISABLE: Disable the UART peripheral
118 (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
119 (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
120 (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
121 (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
124 (@) You can refer to the UART HAL driver header file for more useful macros
126 ******************************************************************************
129 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
131 * Redistribution and use in source and binary forms, with or without modification,
132 * are permitted provided that the following conditions are met:
133 * 1. Redistributions of source code must retain the above copyright notice,
134 * this list of conditions and the following disclaimer.
135 * 2. Redistributions in binary form must reproduce the above copyright notice,
136 * this list of conditions and the following disclaimer in the documentation
137 * and/or other materials provided with the distribution.
138 * 3. Neither the name of STMicroelectronics nor the names of its contributors
139 * may be used to endorse or promote products derived from this software
140 * without specific prior written permission.
142 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
143 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
144 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
146 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
147 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
148 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
149 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
150 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
151 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153 ******************************************************************************
156 /* Includes ------------------------------------------------------------------*/
157 #include "stm32l0xx_hal.h"
159 /** @addtogroup STM32L0xx_HAL_Driver
164 * @brief UART module driver
167 #ifdef HAL_UART_MODULE_ENABLED
169 /* Private typedef -----------------------------------------------------------*/
170 /* Private define ------------------------------------------------------------*/
171 #define UART_TIMEOUT_VALUE ((uint32_t) 22000)
172 #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
173 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
174 /* Private macro -------------------------------------------------------------*/
175 /* Private variables ---------------------------------------------------------*/
176 /* Private function prototypes -----------------------------------------------*/
177 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
178 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
179 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
180 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
181 static void UART_DMAError(DMA_HandleTypeDef *hdma);
182 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
183 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
184 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
188 /* Private functions ---------------------------------------------------------*/
190 /** @addtogroup UART_Exported_Functions UART Exported Functions
194 /** @addtogroup UART_Exported_Functions_Group1
195 * @brief Initialization and Configuration functions
198 ===============================================================================
199 ##### Initialization and Configuration functions #####
200 ===============================================================================
202 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
203 in asynchronous mode.
204 (+) For the asynchronous mode only these parameters can be configured:
208 (++) Parity: If the parity is enabled, then the MSB bit of the data written
209 in the data register is transmitted but is changed by the parity bit.
210 Depending on the frame length defined by the M bit (8-bits or 9-bits),
211 the possible UART frame formats are as listed in the following table:
212 +-----------------------------------------------------------------------+
213 | M1 bit | M0 bit | PCE bit | USART frame |
214 |---------|---------|-----------|---------------------------------------|
215 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
216 |---------|---------|-----------|---------------------------------------|
217 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
218 |---------|---------|-----------|---------------------------------------|
219 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
220 |---------|---------|-----------|---------------------------------------|
221 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
222 |---------|---------|-----------|---------------------------------------|
223 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
224 |---------|---------|-----------|---------------------------------------|
225 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
226 +-----------------------------------------------------------------------+
227 (++) Hardware flow control
228 (++) Receiver/transmitter modes
229 (++) Over Sampling Method
230 (++) One-Bit Sampling Method
231 (+) For the asynchronous mode, the following advanced features can be configured as well:
232 (++) TX and/or RX pin level inversion
233 (++) data logical level inversion
234 (++) RX and TX pins swap
235 (++) RX overrun detection disabling
236 (++) DMA disabling on RX error
237 (++) MSB first on communication line
238 (++) auto Baud rate detection
240 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessorEx_Init()API
241 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
242 and UART multiprocessor mode mode configuration procedures (details for the procedures
243 are available in reference manual).
250 * @brief Initializes the UART mode according to the specified
251 * parameters in the UART_InitTypeDef and creates the associated handle .
252 * @param huart: uart handle
255 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
257 /* Check the UART handle allocation */
263 if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
265 /* Check the parameters */
266 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
270 /* Check the parameters */
271 assert_param(IS_UART_INSTANCE(huart->Instance));
274 if(huart->State == HAL_UART_STATE_RESET)
276 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
277 HAL_UART_MspInit(huart);
280 huart->State = HAL_UART_STATE_BUSY;
282 /* Disable the Peripheral */
283 __HAL_UART_DISABLE(huart);
285 /* Set the UART Communication parameters */
286 UART_SetConfig(huart);
288 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
290 UART_AdvFeatureConfig(huart);
293 /* In asynchronous mode, the following bits must be kept cleared:
294 - LINEN and CLKEN bits in the USART_CR2 register,
295 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
296 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
297 huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
299 /* Enable the Peripheral */
300 __HAL_UART_ENABLE(huart);
302 /* TEACK and/or REACK to check before moving huart->State to Ready */
303 return (UART_CheckIdleState(huart));
307 * @brief Initializes the half-duplex mode according to the specified
308 * parameters in the UART_InitTypeDef and creates the associated handle .
309 * @param huart: uart handle
312 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
314 /* Check the UART handle allocation */
320 /* Check UART instance */
321 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
324 if(huart->State == HAL_UART_STATE_RESET)
326 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
327 HAL_UART_MspInit(huart);
330 /* Disable the Peripheral */
331 __HAL_UART_DISABLE(huart);
333 /* Set the UART Communication parameters */
334 UART_SetConfig(huart);
336 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
338 UART_AdvFeatureConfig(huart);
341 /* In half-duplex mode, the following bits must be kept cleared:
342 - LINEN and CLKEN bits in the USART_CR2 register,
343 - SCEN and IREN bits in the USART_CR3 register.*/
344 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
345 huart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN);
347 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
348 huart->Instance->CR3 |= USART_CR3_HDSEL;
350 /* Enable the Peripheral */
351 __HAL_UART_ENABLE(huart);
353 /* TEACK and/or REACK to check before moving huart->State to Ready */
354 return (UART_CheckIdleState(huart));
358 * @brief Initializes the LIN mode according to the specified
359 * parameters in the UART_InitTypeDef and creates the associated handle .
360 * @param huart: uart handle
361 * @param BreakDetectLength: specifies the LIN break detection length.
362 * This parameter can be one of the following values:
363 * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
364 * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
367 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
369 /* Check the UART handle allocation */
374 /* Check the LIN UART instance */
375 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
377 /* Check the Break detection length parameter */
378 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
380 /* LIN mode limited to 16-bit oversampling only */
381 if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
386 /* in LIN mode limited, data length limited to 8-bit only */
387 if(huart->Init.WordLength!= UART_WORDLENGTH_8B)
392 if(huart->State == HAL_UART_STATE_RESET)
394 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
395 HAL_UART_MspInit(huart);
398 /* Disable the Peripheral */
399 __HAL_UART_DISABLE(huart);
401 /* Set the UART Communication parameters */
402 UART_SetConfig(huart);
404 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
406 UART_AdvFeatureConfig(huart);
409 /* In LIN mode, the following bits must be kept cleared:
410 - LINEN and CLKEN bits in the USART_CR2 register,
411 - SCEN and IREN bits in the USART_CR3 register.*/
412 huart->Instance->CR2 &= ~(USART_CR2_CLKEN);
413 huart->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN);
415 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
416 huart->Instance->CR2 |= USART_CR2_LINEN;
418 /* Set the USART LIN Break detection length. */
419 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
421 /* Enable the Peripheral */
422 __HAL_UART_ENABLE(huart);
424 /* TEACK and/or REACK to check before moving huart->State to Ready */
425 return (UART_CheckIdleState(huart));
429 * @brief Initializes the multiprocessor mode according to the specified
430 * parameters in the UART_InitTypeDef and creates the associated handle.
431 * @param huart: UART handle
432 * @param Address: UART node address (4-, 6-, 7- or 8-bit long)
433 * @param WakeUpMethod: specifies the UART wakeup method.
434 * This parameter can be one of the following values:
435 * @arg UART_WAKEUPMETHOD_IDLELINE: WakeUp by an idle line detection
436 * @arg UART_WAKEUPMETHOD_ADDRESSMARK: WakeUp by an address mark
437 * @note If the user resorts to idle line detection wake up, the Address parameter
438 * is useless and ignored by the initialization function.
439 * @note If the user resorts to address mark wake up, the address length detection
440 * is configured by default to 4 bits only. For the UART to be able to
441 * manage 6-, 7- or 8-bit long addresses detection, the API
442 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
443 * HAL_MultiProcessor_Init().
446 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
448 /* Check the UART handle allocation */
454 /* Check the wake up method parameter */
455 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
457 if(huart->State == HAL_UART_STATE_RESET)
459 /* Init the low level hardware : GPIO, CLOCK */
460 HAL_UART_MspInit(huart);
463 huart->State = HAL_UART_STATE_BUSY;
465 /* Disable the Peripheral */
466 __HAL_UART_DISABLE(huart);
468 /* Set the UART Communication parameters */
469 UART_SetConfig(huart);
471 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
473 UART_AdvFeatureConfig(huart);
476 /* In multiprocessor mode, the following bits must be kept cleared:
477 - LINEN and CLKEN bits in the USART_CR2 register,
478 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
479 huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
480 huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
482 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
484 /* If address mark wake up method is chosen, set the USART address node */
485 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
488 /* Set the wake up method by setting the WAKE bit in the CR1 register */
489 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
491 /* Enable the Peripheral */
492 __HAL_UART_ENABLE(huart);
494 /* TEACK and/or REACK to check before moving huart->State to Ready */
495 return (UART_CheckIdleState(huart));
499 * @brief DeInitializes the UART peripheral
500 * @param huart: uart handle
503 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
505 /* Check the UART handle allocation */
511 /* Check the parameters */
512 assert_param(IS_UART_INSTANCE(huart->Instance));
514 huart->State = HAL_UART_STATE_BUSY;
516 /* Disable the Peripheral */
517 __HAL_UART_DISABLE(huart);
519 huart->Instance->CR1 = 0x0;
520 huart->Instance->CR2 = 0x0;
521 huart->Instance->CR3 = 0x0;
523 /* DeInit the low level hardware */
524 HAL_UART_MspDeInit(huart);
526 huart->ErrorCode = HAL_UART_ERROR_NONE;
527 huart->State = HAL_UART_STATE_RESET;
536 * @brief UART MSP Init
537 * @param huart: uart handle
540 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
542 /* NOTE : This function should not be modified, when the callback is needed,
543 the HAL_UART_MspInit can be implemented in the user file
548 * @brief UART MSP DeInit
549 * @param huart: uart handle
552 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
554 /* NOTE : This function should not be modified, when the callback is needed,
555 the HAL_UART_MspDeInit can be implemented in the user file
563 /** @addtogroup UART_Exported_Functions_Group2
564 * @brief UART Transmit/Receive functions
567 ===============================================================================
568 ##### IO operation functions #####
569 ===============================================================================
570 This subsection provides a set of functions allowing to manage the UART asynchronous
571 and Half duplex data transfers.
573 (#) There are two mode of transfer:
574 (+) Blocking mode: The communication is performed in polling mode.
575 The HAL status of all data processing is returned by the same function
576 after finishing transfer.
577 (+) No-Blocking mode: The communication is performed using Interrupts
578 or DMA, These API's return the HAL status.
579 The end of the data processing will be indicated through the
580 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
582 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
583 will be executed respectivelly at the end of the transmit or Receive process
584 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
586 (#) Blocking mode API's are :
587 (+) HAL_UART_Transmit()
588 (+) HAL_UART_Receive()
590 (#) Non-Blocking mode API's with Interrupt are :
591 (+) HAL_UART_Transmit_IT()
592 (+) HAL_UART_Receive_IT()
593 (+) HAL_UART_IRQHandler()
594 (+) UART_Transmit_IT()
595 (+) UART_Receive_IT()
597 (#) No-Blocking mode API's with DMA are :
598 (+) HAL_UART_Transmit_DMA()
599 (+) HAL_UART_Receive_DMA()
600 (+) HAL_UART_DMAPause()
601 (+) HAL_UART_DMAResume()
602 (+) HAL_UART_DMAStop()
604 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
605 (+) HAL_UART_TxHalfCpltCallback()
606 (+) HAL_UART_TxCpltCallback()
607 (+) HAL_UART_RxHalfCpltCallback()
608 (+) HAL_UART_RxCpltCallback()
609 (+) HAL_UART_ErrorCallback()
611 -@- In the Half duplex communication, it is forbidden to run the transmit
612 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
619 * @brief Send an amount of data in blocking mode
620 * @param huart: uart handle
621 * @param pData: pointer to data buffer
622 * @param Size: amount of data to be sent
623 * @param Timeout : Timeout duration
626 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
630 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
632 if((pData == NULL ) || (Size == 0))
640 huart->ErrorCode = HAL_UART_ERROR_NONE;
641 /* Check if a non-blocking receive process is ongoing or not */
642 if(huart->State == HAL_UART_STATE_BUSY_RX)
644 huart->State = HAL_UART_STATE_BUSY_TX_RX;
648 huart->State = HAL_UART_STATE_BUSY_TX;
651 huart->TxXferSize = Size;
652 huart->TxXferCount = Size;
653 while(huart->TxXferCount > 0)
655 huart->TxXferCount--;
656 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)
660 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
662 tmp = (uint16_t*) pData;
663 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
668 huart->Instance->TDR = (*pData++ & (uint8_t)0xFF);
671 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK)
675 /* Check if a non-blocking receive Process is ongoing or not */
676 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
678 huart->State = HAL_UART_STATE_BUSY_RX;
682 huart->State = HAL_UART_STATE_READY;
685 /* Process Unlocked */
697 * @brief Receive an amount of data in blocking mode
698 * @param huart: uart handle
699 * @param pData: pointer to data buffer
700 * @param Size: amount of data to be received
701 * @param Timeout : Timeout duration
704 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
709 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
711 if((pData == NULL ) || (Size == 0))
719 huart->ErrorCode = HAL_UART_ERROR_NONE;
720 /* Check if a non-blocking transmit process is ongoing or not */
721 if(huart->State == HAL_UART_STATE_BUSY_TX)
723 huart->State = HAL_UART_STATE_BUSY_TX_RX;
727 huart->State = HAL_UART_STATE_BUSY_RX;
730 huart->RxXferSize = Size;
731 huart->RxXferCount = Size;
733 /* Computation of UART mask to apply to RDR register */
734 UART_MASK_COMPUTATION(huart);
735 uhMask = huart->Mask;
737 /* as long as data have to be received */
738 while(huart->RxXferCount > 0)
740 huart->RxXferCount--;
741 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
745 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
747 tmp = (uint16_t*) pData ;
748 *tmp = (uint16_t)(huart->Instance->RDR & uhMask);
753 *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
757 /* Check if a non-blocking transmit Process is ongoing or not */
758 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
760 huart->State = HAL_UART_STATE_BUSY_TX;
764 huart->State = HAL_UART_STATE_READY;
766 /* Process Unlocked */
778 * @brief Send an amount of data in interrupt mode
779 * @param huart: uart handle
780 * @param pData: pointer to data buffer
781 * @param Size: amount of data to be sent
784 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
786 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
788 if((pData == NULL ) || (Size == 0))
796 huart->pTxBuffPtr = pData;
797 huart->TxXferSize = Size;
798 huart->TxXferCount = Size;
800 huart->ErrorCode = HAL_UART_ERROR_NONE;
801 /* Check if a receive process is ongoing or not */
802 if(huart->State == HAL_UART_STATE_BUSY_RX)
804 huart->State = HAL_UART_STATE_BUSY_TX_RX;
808 huart->State = HAL_UART_STATE_BUSY_TX;
811 /* Enable the UART Parity Error Interrupt */
812 __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
814 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
815 __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
817 /* Process Unlocked */
820 /* Enable the UART Transmit data register empty Interrupt */
821 __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
832 * @brief Receive an amount of data in interrupt mode
833 * @param huart: uart handle
834 * @param pData: pointer to data buffer
835 * @param Size: amount of data to be received
838 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
840 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
842 if((pData == NULL ) || (Size == 0))
850 huart->pRxBuffPtr = pData;
851 huart->RxXferSize = Size;
852 huart->RxXferCount = Size;
854 /* Computation of UART mask to apply to RDR register */
855 UART_MASK_COMPUTATION(huart);
857 huart->ErrorCode = HAL_UART_ERROR_NONE;
858 /* Check if a transmit process is ongoing or not */
859 if(huart->State == HAL_UART_STATE_BUSY_TX)
861 huart->State = HAL_UART_STATE_BUSY_TX_RX;
865 huart->State = HAL_UART_STATE_BUSY_RX;
868 /* Enable the UART Parity Error Interrupt */
869 __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
871 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
872 __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
874 /* Process Unlocked */
877 /* Enable the UART Data Register not empty Interrupt */
878 __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
889 * @brief Send an amount of data in DMA mode
890 * @param huart: uart handle
891 * @param pData: pointer to data buffer
892 * @param Size: amount of data to be sent
895 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
899 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_RX))
901 if((pData == NULL ) || (Size == 0))
909 huart->pTxBuffPtr = pData;
910 huart->TxXferSize = Size;
911 huart->TxXferCount = Size;
913 huart->ErrorCode = HAL_UART_ERROR_NONE;
914 /* Check if a receive process is ongoing or not */
915 if(huart->State == HAL_UART_STATE_BUSY_RX)
917 huart->State = HAL_UART_STATE_BUSY_TX_RX;
921 huart->State = HAL_UART_STATE_BUSY_TX;
924 /* Set the UART DMA transfert complete callback */
925 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
927 /* Set the UART DMA Half transfer complete callback */
928 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
930 /* Set the DMA error callback */
931 huart->hdmatx->XferErrorCallback = UART_DMAError;
933 /* Enable the UART transmit DMA Stream */
934 tmp = (uint32_t*)&pData;
935 HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, Size);
937 /* Clear the TC flag in the SR register by writing 0 to it */
938 __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
940 /* Enable the DMA transfer for transmit request by setting the DMAT bit
941 in the UART CR3 register */
942 huart->Instance->CR3 |= USART_CR3_DMAT;
944 /* Process Unlocked */
956 * @brief Receive an amount of data in DMA mode
957 * @param huart: uart handle
958 * @param pData: pointer to data buffer
959 * @param Size: amount of data to be received
960 * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit.
963 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
967 if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX))
969 if((pData == NULL ) || (Size == 0))
977 huart->pRxBuffPtr = pData;
978 huart->RxXferSize = Size;
980 huart->ErrorCode = HAL_UART_ERROR_NONE;
981 /* Check if a transmit process is ongoing or not */
982 if(huart->State == HAL_UART_STATE_BUSY_TX)
984 huart->State = HAL_UART_STATE_BUSY_TX_RX;
988 huart->State = HAL_UART_STATE_BUSY_RX;
991 /* Set the UART DMA transfert complete callback */
992 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
994 /* Set the UART DMA Half transfer complete callback */
995 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
997 /* Set the DMA error callback */
998 huart->hdmarx->XferErrorCallback = UART_DMAError;
1000 /* Enable the DMA Stream */
1001 tmp = (uint32_t*)&pData;
1002 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size);
1004 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1005 in the UART CR3 register */
1006 huart->Instance->CR3 |= USART_CR3_DMAR;
1008 /* Process Unlocked */
1009 __HAL_UNLOCK(huart);
1020 * @brief Pauses the DMA Transfer.
1021 * @param huart: UART handle
1024 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1026 /* Process Locked */
1029 if(huart->State == HAL_UART_STATE_BUSY_TX)
1031 /* Disable the UART DMA Tx request */
1032 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
1034 else if(huart->State == HAL_UART_STATE_BUSY_RX)
1036 /* Disable the UART DMA Rx request */
1037 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
1039 else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1041 /* Disable the UART DMA Tx request */
1042 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
1043 /* Disable the UART DMA Rx request */
1044 huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
1046 /* Process Unlocked */
1047 __HAL_UNLOCK(huart);
1053 * @brief Resumes the DMA Transfer.
1054 * @param huart: UART handle
1057 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1059 /* Process Locked */
1062 if(huart->State == HAL_UART_STATE_BUSY_TX)
1064 /* Enable the UART DMA Tx request */
1065 huart->Instance->CR3 |= USART_CR3_DMAT;
1067 else if(huart->State == HAL_UART_STATE_BUSY_RX)
1069 /* Clear the Overrun flag before resumming the Rx transfer*/
1070 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
1072 /* Enable the UART DMA Rx request */
1073 huart->Instance->CR3 |= USART_CR3_DMAR;
1075 else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1077 /* Clear the Overrun flag before resumming the Rx transfer*/
1078 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
1080 /* Enable the UART DMA Rx request before the DMA Tx request */
1081 huart->Instance->CR3 |= USART_CR3_DMAR;
1083 /* Enable the UART DMA Tx request */
1084 huart->Instance->CR3 |= USART_CR3_DMAT;
1087 /* Process Unlocked */
1088 __HAL_UNLOCK(huart);
1094 * @brief Stops the DMA Transfer.
1095 * @param huart: UART handle
1098 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1100 /* The Lock is not implemented on this API to allow the user application
1101 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
1102 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1103 and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
1106 /* Disable the UART Tx/Rx DMA requests */
1107 huart->Instance->CR3 &= ~USART_CR3_DMAT;
1108 huart->Instance->CR3 &= ~USART_CR3_DMAR;
1110 /* Abort the UART DMA tx channel */
1111 if(huart->hdmatx != NULL)
1113 HAL_DMA_Abort(huart->hdmatx);
1115 /* Abort the UART DMA rx channel */
1116 if(huart->hdmarx != NULL)
1118 HAL_DMA_Abort(huart->hdmarx);
1121 huart->State = HAL_UART_STATE_READY;
1127 * @brief This function handles UART interrupt request.
1128 * @param huart: uart handle
1131 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
1133 /* UART parity error interrupt occurred ------------------------------------*/
1135 if((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE) != RESET))
1137 __HAL_UART_CLEAR_PEFLAG(huart);
1139 huart->ErrorCode |= HAL_UART_ERROR_PE;
1140 /* Set the UART state ready to be able to start again the process */
1141 huart->State = HAL_UART_STATE_READY;
1144 /* UART frame error interrupt occured --------------------------------------*/
1145 if((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
1147 __HAL_UART_CLEAR_FEFLAG(huart);
1149 huart->ErrorCode |= HAL_UART_ERROR_FE;
1150 /* Set the UART state ready to be able to start again the process */
1151 huart->State = HAL_UART_STATE_READY;
1154 /* UART noise error interrupt occured --------------------------------------*/
1155 if((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
1157 __HAL_UART_CLEAR_NEFLAG(huart);
1159 huart->ErrorCode |= HAL_UART_ERROR_NE;
1160 /* Set the UART state ready to be able to start again the process */
1161 huart->State = HAL_UART_STATE_READY;
1164 /* UART Over-Run interrupt occured -----------------------------------------*/
1165 if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
1167 __HAL_UART_CLEAR_OREFLAG(huart);
1169 huart->ErrorCode |= HAL_UART_ERROR_ORE;
1170 /* Set the UART state ready to be able to start again the process */
1171 huart->State = HAL_UART_STATE_READY;
1174 /* Call UART Error Call back function if need be --------------------------*/
1175 if(huart->ErrorCode != HAL_UART_ERROR_NONE)
1177 HAL_UART_ErrorCallback(huart);
1180 /* UART Wake Up interrupt occured ------------------------------------------*/
1181 if((__HAL_UART_GET_IT(huart, UART_IT_WUF) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_WUF) != RESET))
1183 __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
1184 /* Set the UART state ready to be able to start again the process */
1185 huart->State = HAL_UART_STATE_READY;
1186 HAL_UARTEx_WakeupCallback(huart);
1189 /* UART in mode Receiver ---------------------------------------------------*/
1190 if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET))
1192 UART_Receive_IT(huart);
1195 /* UART in mode Transmitter ------------------------------------------------*/
1196 if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET))
1198 UART_Transmit_IT(huart);
1201 /* UART in mode Transmitter -- TC ------------------------------------------*/
1202 if((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET))
1204 UART_EndTransmit_IT(huart);
1207 if(huart->ErrorCode != HAL_UART_ERROR_NONE)
1209 HAL_UART_ErrorCallback(huart);
1214 * @brief Tx Transfer completed callbacks
1215 * @param huart: uart handle
1218 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
1220 /* NOTE : This function Should not be modified, when the callback is needed,
1221 the HAL_UART_TxCpltCallback could be implemented in the user file
1226 * @brief Tx Half Transfer completed callbacks.
1227 * @param huart: UART handle
1230 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
1232 /* NOTE: This function Should not be modified, when the callback is needed,
1233 the HAL_UART_TxCpltCallback could be implemented in the user file
1238 * @brief Rx Transfer completed callbacks
1239 * @param huart: uart handle
1242 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
1244 /* NOTE : This function Should not be modified, when the callback is needed,
1245 the HAL_UART_TxCpltCallback could be implemented in the user file
1250 * @brief Rx Half Transfer completed callbacks.
1251 * @param huart: UART handle
1254 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
1256 /* NOTE: This function Should not be modified, when the callback is needed,
1257 the HAL_UART_TxCpltCallback could be implemented in the user file
1262 * @brief UART error callbacks
1263 * @param huart: uart handle
1266 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
1268 /* NOTE : This function should not be modified, when the callback is needed,
1269 the HAL_UART_ErrorCallback can be implemented in the user file
1278 /** @addtogroup UART_Exported_Functions_Group3
1279 * @brief UART control functions
1282 ===============================================================================
1283 ##### Peripheral Control functions #####
1284 ===============================================================================
1286 This subsection provides a set of functions allowing to control the UART.
1287 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
1288 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
1289 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
1290 (+) HAL_HalfDuplex_EnableTransmitter() API enables the transmitter
1291 (+) HAL_HalfDuplex_EnableReceiver() API enables the receiver
1292 (+) HAL_UART_GetState() API is helpful to check in run-time the state of the UART peripheral
1293 (+) HAL_UART_GetError()API is helpful to check in run-time the error state of the UART peripheral
1299 * @brief Enable UART in mute mode (doesn't mean UART enters mute mode;
1300 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called)
1301 * @param huart: uart handle
1302 * @retval HAL status
1304 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
1306 /* Process Locked */
1309 huart->State = HAL_UART_STATE_BUSY;
1311 /* Enable USART mute mode by setting the MME bit in the CR1 register */
1312 huart->Instance->CR1 |= USART_CR1_MME;
1314 huart->State = HAL_UART_STATE_READY;
1316 return (UART_CheckIdleState(huart));
1320 * @brief Disable UART mute mode (doesn't mean it actually wakes up the software,
1321 * as it may not have been in mute mode at this very moment).
1322 * @param huart: uart handle
1323 * @retval HAL status
1325 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
1327 /* Process Locked */
1330 huart->State = HAL_UART_STATE_BUSY;
1332 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
1333 huart->Instance->CR1 &= ~(USART_CR1_MME);
1335 huart->State = HAL_UART_STATE_READY;
1337 return (UART_CheckIdleState(huart));
1341 * @brief Enter UART mute mode (means UART actually enters mute mode).
1342 * To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
1343 * @param huart: uart handle
1344 * @retval HAL status
1346 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
1348 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
1352 * @brief Enables the UART transmitter and disables the UART receiver.
1353 * @param huart: UART handle
1354 * @retval HAL status
1357 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
1359 /* Process Locked */
1361 huart->State = HAL_UART_STATE_BUSY;
1363 /* Clear TE and RE bits */
1364 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
1365 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
1366 SET_BIT(huart->Instance->CR1, USART_CR1_TE);
1368 huart->State = HAL_UART_STATE_READY;
1369 /* Process Unlocked */
1370 __HAL_UNLOCK(huart);
1376 * @brief Enables the UART receiver and disables the UART transmitter.
1377 * @param huart: UART handle
1378 * @retval HAL status
1380 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
1382 /* Process Locked */
1384 huart->State = HAL_UART_STATE_BUSY;
1386 /* Clear TE and RE bits */
1387 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
1388 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
1389 SET_BIT(huart->Instance->CR1, USART_CR1_RE);
1391 huart->State = HAL_UART_STATE_READY;
1392 /* Process Unlocked */
1393 __HAL_UNLOCK(huart);
1399 * @brief Transmits break characters.
1400 * @param huart: pointer to a UART_HandleTypeDef structure that contains
1401 * the configuration information for the specified UART module.
1402 * @retval HAL status
1404 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
1406 /* Check the parameters */
1407 assert_param(IS_UART_INSTANCE(huart->Instance));
1409 /* Process Locked */
1412 huart->State = HAL_UART_STATE_BUSY;
1414 /* Send break characters */
1415 huart->Instance->RQR |= USART_RQR_SBKRQ;
1417 huart->State = HAL_UART_STATE_READY;
1419 /* Process Unlocked */
1420 __HAL_UNLOCK(huart);
1426 * @brief return the UART state
1427 * @param huart: uart handle
1430 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
1432 return huart->State;
1436 * @brief Return the UART error code
1437 * @param huart : pointer to a UART_HandleTypeDef structure that contains
1438 * the configuration information for the specified UART.
1439 * @retval UART Error Code
1441 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
1443 return huart->ErrorCode;
1450 /***************************************************************
1451 * Private functions...
1453 ***************************************************************/
1455 * @brief DMA UART transmit process complete callback
1456 * @param hdma: DMA handle
1459 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1461 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1462 huart->TxXferCount = 0;
1464 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1465 in the UART CR3 register */
1466 huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
1468 /* Enable the UART Transmit Complete Interrupt */
1469 __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
1474 * @brief DMA UART transmit process half complete callback
1475 * @param hdma : DMA handle
1478 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1480 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1482 HAL_UART_TxHalfCpltCallback(huart);
1486 * @brief DMA UART receive process complete callback
1487 * @param hdma: DMA handle
1490 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1492 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1494 /* DMA Normal mode*/
1495 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
1497 huart->RxXferCount = 0;
1499 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1500 in the UART CR3 register */
1501 huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
1503 /* Check if a transmit Process is ongoing or not */
1504 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1506 huart->State = HAL_UART_STATE_BUSY_TX;
1510 huart->State = HAL_UART_STATE_READY;
1513 HAL_UART_RxCpltCallback(huart);
1517 * @brief DMA UART receive process half complete callback
1518 * @param hdma : DMA handle
1521 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1523 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1525 HAL_UART_RxHalfCpltCallback(huart);
1529 * @brief DMA UART communication error callback
1530 * @param hdma: DMA handle
1533 static void UART_DMAError(DMA_HandleTypeDef *hdma)
1535 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1536 huart->RxXferCount = 0;
1537 huart->TxXferCount = 0;
1538 huart->State= HAL_UART_STATE_READY;
1539 huart->ErrorCode |= HAL_UART_ERROR_DMA;
1540 HAL_UART_ErrorCallback(huart);
1544 * @brief Send an amount of data in interrupt mode
1545 * Function called under interruption only, once
1546 * interruptions have been enabled by HAL_UART_Transmit_IT()
1547 * @param huart: UART handle
1548 * @retval HAL status
1550 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
1554 if ((huart->State == HAL_UART_STATE_BUSY_TX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX))
1556 if(huart->TxXferCount == 0)
1558 /* Disable the UART TXE Interrupt */
1559 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1561 /* Enable the UART Transmit Complete Interrupt */
1562 __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
1569 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1571 tmp = (uint16_t*) huart->pTxBuffPtr;
1572 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1573 huart->pTxBuffPtr += 2;
1577 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF);
1580 huart->TxXferCount--;
1592 * @brief Wraps up transmission in non blocking mode.
1593 * @param huart: pointer to a UART_HandleTypeDef structure that contains
1594 * the configuration information for the specified UART module.
1595 * @retval HAL status
1597 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
1599 /* Disable the UART Transmit Complete Interrupt */
1600 __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
1602 /* Check if a receive process is ongoing or not */
1603 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1605 huart->State = HAL_UART_STATE_BUSY_RX;
1609 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1610 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1612 huart->State = HAL_UART_STATE_READY;
1615 HAL_UART_TxCpltCallback(huart);
1622 * @brief Receive an amount of data in interrupt mode
1623 * Function called under interruption only, once
1624 * interruptions have been enabled by HAL_UART_Receive_IT()
1625 * @param huart: UART handle
1626 * @retval HAL status
1628 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
1631 uint16_t uhMask = huart->Mask;
1633 if((huart->State == HAL_UART_STATE_BUSY_RX) || (huart->State == HAL_UART_STATE_BUSY_TX_RX))
1635 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1637 tmp = (uint16_t*) huart->pRxBuffPtr ;
1638 *tmp = (uint16_t)(huart->Instance->RDR & uhMask);
1639 huart->pRxBuffPtr +=2;
1643 *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1646 if(--huart->RxXferCount == 0)
1648 while(HAL_IS_BIT_SET(huart->Instance->ISR, UART_FLAG_RXNE))
1651 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1653 /* Check if a transmit Process is ongoing or not */
1654 if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1656 huart->State = HAL_UART_STATE_BUSY_TX;
1660 /* Disable the UART Parity Error Interrupt */
1661 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1663 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1664 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1666 huart->State = HAL_UART_STATE_READY;
1668 HAL_UART_RxCpltCallback(huart);
1680 * @brief Configure the UART peripheral
1681 * @param huart: uart handle
1684 void UART_SetConfig(UART_HandleTypeDef *huart)
1686 uint32_t tmpreg = 0x00000000;
1687 uint32_t clocksource = 0x00000000;
1688 uint16_t brrtemp = 0x0000;
1689 uint16_t usartdiv = 0x0000;
1691 /* Check the parameters */
1692 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
1693 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
1694 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
1695 assert_param(IS_UART_PARITY(huart->Init.Parity));
1696 assert_param(IS_UART_MODE(huart->Init.Mode));
1697 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
1698 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
1699 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
1701 /*-------------------------- USART CR1 Configuration -----------------------*/
1702 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
1703 * the UART Word Length, Parity, Mode and oversampling:
1704 * set the M bits according to huart->Init.WordLength value
1705 * set PCE and PS bits according to huart->Init.Parity value
1706 * set TE and RE bits according to huart->Init.Mode value
1707 * set OVER8 bit according to huart->Init.OverSampling value */
1708 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
1709 MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg);
1711 /*-------------------------- USART CR2 Configuration -----------------------*/
1712 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
1713 * to huart->Init.StopBits value */
1714 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
1716 /*-------------------------- USART CR3 Configuration -----------------------*/
1718 * - UART HardWare Flow Control: set CTSE and RTSE bits according
1719 * to huart->Init.HwFlowCtl value
1720 * - one-bit sampling method versus three samples' majority rule according
1721 * to huart->Init.OneBitSampling */
1722 tmpreg = (uint32_t)huart->Init.HwFlowCtl | huart->Init.OneBitSampling ;
1723 MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT), tmpreg);
1725 /*-------------------------- USART BRR Configuration -----------------------*/
1726 UART_GETCLOCKSOURCE(huart, clocksource);
1728 /* Check LPUART instace */
1729 if(huart->Instance == LPUART1)
1731 switch (clocksource)
1733 case UART_CLOCKSOURCE_PCLK1:
1734 huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
1736 case UART_CLOCKSOURCE_HSI:
1737 huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HSI_VALUE, huart->Init.BaudRate));
1739 case UART_CLOCKSOURCE_SYSCLK:
1740 huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
1742 case UART_CLOCKSOURCE_LSE:
1743 huart->Instance->BRR = (uint32_t)(__DIV_LPUART(LSE_VALUE, huart->Init.BaudRate));
1749 /* Check the UART Over Sampling 8 to set Baud Rate Register */
1750 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
1752 switch (clocksource)
1754 case UART_CLOCKSOURCE_PCLK1:
1755 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
1757 case UART_CLOCKSOURCE_PCLK2:
1758 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
1760 case UART_CLOCKSOURCE_HSI:
1761 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
1763 case UART_CLOCKSOURCE_SYSCLK:
1764 huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
1766 case UART_CLOCKSOURCE_LSE:
1767 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate));
1773 brrtemp = usartdiv & 0xFFF0;
1774 brrtemp |= (uint16_t)((uint16_t)(usartdiv & (uint16_t)0x000F) >> (uint16_t)1);
1775 huart->Instance->BRR = brrtemp;
1779 switch (clocksource)
1781 case UART_CLOCKSOURCE_PCLK1:
1782 huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
1784 case UART_CLOCKSOURCE_PCLK2:
1785 huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
1787 case UART_CLOCKSOURCE_HSI:
1788 huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
1790 case UART_CLOCKSOURCE_SYSCLK:
1791 huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
1793 case UART_CLOCKSOURCE_LSE:
1794 huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate));
1803 * @brief Check the UART Idle State
1804 * @param huart: uart handle
1805 * @retval HAL status
1807 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
1809 /* Check if the Transmitter is enabled */
1810 if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1812 /* Wait until TEACK flag is set */
1813 if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, UART_TIMEOUT_VALUE) != HAL_OK)
1818 /* Check if the Receiver is enabled */
1819 if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1821 /* Wait until REACK flag is set */
1822 if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, UART_TIMEOUT_VALUE) != HAL_OK)
1828 /* Process Unlocked */
1829 __HAL_UNLOCK(huart);
1831 /* Initialize the UART state*/
1832 huart->ErrorCode = HAL_UART_ERROR_NONE;
1833 huart->State= HAL_UART_STATE_READY;
1839 * @brief Configure the UART peripheral advanced feautures
1840 * @param huart: uart handle
1843 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
1845 /* Check whether the set of advanced features to configure is properly set */
1846 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
1848 /* if required, configure TX pin active level inversion */
1849 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
1851 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
1852 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
1855 /* if required, configure RX pin active level inversion */
1856 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
1858 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
1859 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
1862 /* if required, configure data inversion */
1863 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
1865 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
1866 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
1869 /* if required, configure RX/TX pins swap */
1870 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
1872 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
1873 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
1876 /* if required, configure RX overrun detection disabling */
1877 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
1879 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
1880 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
1883 /* if required, configure DMA disabling on reception error */
1884 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
1886 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
1887 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
1890 /* if required, configure auto Baud rate detection scheme */
1891 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
1893 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
1894 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
1895 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
1896 /* set auto Baudrate detection parameters if detection is enabled */
1897 if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
1899 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
1900 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
1904 /* if required, configure MSB first on communication line */
1905 if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
1907 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
1908 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
1913 * @brief This function handles UART Communication Timeout.
1914 * @param huart: UART handle
1915 * @param Flag: specifies the UART flag to check.
1916 * @param Status: The new Flag status (SET or RESET).
1917 * @param Timeout: Timeout duration
1918 * @retval HAL status
1920 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1922 uint32_t tickstart = 0x00;
1923 tickstart = HAL_GetTick();
1925 /* Wait until flag is set */
1928 while(__HAL_UART_GET_FLAG(huart, Flag) == RESET)
1930 /* Check for the Timeout */
1931 if(Timeout != HAL_MAX_DELAY)
1933 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1935 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1936 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1937 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1938 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1939 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1941 huart->State= HAL_UART_STATE_READY;
1943 /* Process Unlocked */
1944 __HAL_UNLOCK(huart);
1953 while(__HAL_UART_GET_FLAG(huart, Flag) != RESET)
1955 /* Check for the Timeout */
1956 if(Timeout != HAL_MAX_DELAY)
1958 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1960 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1961 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1962 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1963 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1964 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1966 huart->State= HAL_UART_STATE_READY;
1968 /* Process Unlocked */
1969 __HAL_UNLOCK(huart);
1983 #endif /* HAL_UART_MODULE_ENABLED */
1992 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/