2 ******************************************************************************
3 * @file stm32f0xx_hal_uart.c
4 * @author MCD Application Team
6 * @date 11-December-2014
7 * @brief UART HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral Control functions
13 * + Peripheral State and Errors functions
15 ===============================================================================
16 ##### How to use this driver #####
17 ================================================================================
19 The UART HAL driver can be used as follows:
21 (#) Declare a UART_HandleTypeDef handle structure.
23 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit ()API:
24 (##) Enable the USARTx interface clock.
25 (##) UART pins configuration:
26 (+++) Enable the clock for the UART GPIOs.
27 (+++) Configure these UART pins as alternate function pull-up.
28 (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
29 and HAL_UART_Receive_IT() APIs):
30 (+++) Configure the USARTx interrupt priority.
31 (+++) Enable the NVIC USART IRQ handle.
32 (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
33 and HAL_UART_Receive_DMA() APIs):
34 (+++) Declare a DMA handle structure for the Tx/Rx channel.
35 (+++) Enable the DMAx interface clock.
36 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
37 (+++) Configure the DMA Tx/Rx channel.
38 (+++) Associate the initilalized DMA handle to the UART DMA Tx/Rx handle.
39 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
41 (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware
42 flow control and Mode(Receiver/Transmitter) in the huart Init structure.
44 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
45 in the huart AdvancedInit structure.
47 (#) For the UART asynchronous mode, initialize the UART registers by calling
48 the HAL_UART_Init() API.
50 (#) For the UART Half duplex mode, initialize the UART registers by calling
51 the HAL_HalfDuplex_Init() API.
53 (#) For the UART Multiprocessor mode, initialize the UART registers
54 by calling the HAL_MultiProcessor_Init() API.
56 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
57 by calling the HAL_RS485Ex_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 and receive process.
65 (@) These APIs(HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_MultiProcessor_Init(),
66 also configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) by
67 calling the customed HAL_UART_MspInit() API.
69 Three operation modes are available within this driver :
71 *** Polling mode IO operation ***
72 =================================
74 (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
75 (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
77 *** Interrupt mode IO operation ***
78 ===================================
80 (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
81 (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
82 add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
83 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
84 add his own code by customization of function pointer HAL_UART_TxCpltCallback
85 (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
86 (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
87 add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
88 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
89 add his own code by customization of function pointer HAL_UART_RxCpltCallback
90 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
91 add his own code by customization of function pointer HAL_UART_ErrorCallback
93 *** DMA mode IO operation ***
94 ==============================
96 (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
97 (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
98 add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
99 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
100 add his own code by customization of function pointer HAL_UART_TxCpltCallback
101 (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
102 (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
103 add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
104 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
105 add his own code by customization of function pointer HAL_UART_RxCpltCallback
106 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
107 add his own code by customization of function pointer HAL_UART_ErrorCallback
108 (+) Pause the DMA Transfer using HAL_UART_DMAPause()
109 (+) Resume the DMA Transfer using HAL_UART_DMAResume()
110 (+) Stop the DMA Transfer using HAL_UART_DMAStop()
112 *** UART HAL driver macros list ***
113 =============================================
115 Below the list of most used macros in UART HAL driver.
117 (+) __HAL_UART_ENABLE: Enable the UART peripheral
118 (+) __HAL_UART_DISABLE: Disable the UART peripheral
119 (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
120 (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
121 (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
122 (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
125 (@) You can refer to the UART HAL driver header file for more useful macros
128 ******************************************************************************
131 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
133 * Redistribution and use in source and binary forms, with or without modification,
134 * are permitted provided that the following conditions are met:
135 * 1. Redistributions of source code must retain the above copyright notice,
136 * this list of conditions and the following disclaimer.
137 * 2. Redistributions in binary form must reproduce the above copyright notice,
138 * this list of conditions and the following disclaimer in the documentation
139 * and/or other materials provided with the distribution.
140 * 3. Neither the name of STMicroelectronics nor the names of its contributors
141 * may be used to endorse or promote products derived from this software
142 * without specific prior written permission.
144 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
145 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
146 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
147 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
148 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
149 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
150 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
151 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
152 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
153 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155 ******************************************************************************
158 /* Includes ------------------------------------------------------------------*/
159 #include "stm32f0xx_hal.h"
161 /** @addtogroup STM32F0xx_HAL_Driver
165 /** @defgroup UART UART HAL module driver
166 * @brief HAL UART module driver
169 #ifdef HAL_UART_MODULE_ENABLED
171 /* Private typedef -----------------------------------------------------------*/
172 /* Private define ------------------------------------------------------------*/
173 /** @defgroup UART_Private_Constants UART Private Constants
176 #define HAL_UART_TXDMA_TIMEOUTVALUE 22000
177 #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
178 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
183 /* Private macro -------------------------------------------------------------*/
184 /* Private variables ---------------------------------------------------------*/
185 /* Private function prototypes -----------------------------------------------*/
186 /** @addtogroup UART_Private_Functions UART Private Functions
189 static void UART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
);
190 static void UART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
);
191 static void UART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
);
192 static void UART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
);
193 static void UART_DMAError(DMA_HandleTypeDef
*hdma
);
198 /* Exported functions ---------------------------------------------------------*/
200 /** @defgroup UART_Exported_Functions UART Exported Functions
204 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
205 * @brief Initialization and Configuration functions
208 ===============================================================================
209 ##### Initialization and Configuration functions #####
210 ===============================================================================
212 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
213 in asynchronous mode.
214 (+) For the asynchronous mode only these parameters can be configured:
218 (++) Parity: If the parity is enabled, then the MSB bit of the data written
219 in the data register is transmitted but is changed by the parity bit.
220 Depending on the frame length defined by the M bit (8-bits or 9-bits),
221 the possible UART frame formats are as listed in the following table:
222 |-----------|-----------|---------------------------------------|
223 | M1M0 bits | PCE bit | UART frame |
224 |-----------------------|---------------------------------------|
225 | 00 | 0 | | SB | 8-bit data | STB | |
226 |-----------|-----------|---------------------------------------|
227 | 00 | 1 | | SB | 7-bit data | PB | STB | |
228 |-----------|-----------|---------------------------------------|
229 | 01 | 0 | | SB | 9-bit data | STB | |
230 |-----------|-----------|---------------------------------------|
231 | 01 | 1 | | SB | 8-bit data | PB | STB | |
232 +---------------------------------------------------------------+
233 | 10 | 0 | | SB | 7-bit data | STB | |
234 |-----------|-----------|---------------------------------------|
235 | 10 | 1 | | SB | 6-bit data | PB | STB | |
236 +---------------------------------------------------------------+
237 (++) Hardware flow control
238 (++) Receiver/transmitter modes
239 (++) Over Sampling Method
240 (++) One-Bit Sampling Method
241 (+) For the asynchronous mode, the following advanced features can be configured as well:
242 (++) TX and/or RX pin level inversion
243 (++) data logical level inversion
244 (++) RX and TX pins swap
245 (++) RX overrun detection disabling
246 (++) DMA disabling on RX error
247 (++) MSB first on communication line
248 (++) auto Baud rate detection
250 The HAL_UART_Init(), HAL_HalfDuplex_Init() and HAL_MultiProcessor_Init()
251 API follow respectively the UART asynchronous, UART Half duplex and multiprocessor
252 configuration procedures (details for the procedures are available in reference manual).
259 * @brief Initializes the UART mode according to the specified
260 * parameters in the UART_InitTypeDef and creates the associated handle .
261 * @param huart: uart handle
264 HAL_StatusTypeDef
HAL_UART_Init(UART_HandleTypeDef
*huart
)
266 /* Check the UART handle allocation */
272 if(huart
->Init
.HwFlowCtl
!= UART_HWCONTROL_NONE
)
274 /* Check the parameters */
275 assert_param(IS_UART_HWFLOW_INSTANCE(huart
->Instance
));
279 /* Check the parameters */
280 assert_param(IS_UART_INSTANCE(huart
->Instance
));
283 if(huart
->State
== HAL_UART_STATE_RESET
)
285 /* Init the low level hardware : GPIO, CLOCK */
286 HAL_UART_MspInit(huart
);
289 huart
->State
= HAL_UART_STATE_BUSY
;
291 /* Disable the Peripheral */
292 __HAL_UART_DISABLE(huart
);
294 /* Set the UART Communication parameters */
295 if (UART_SetConfig(huart
) == HAL_ERROR
)
300 if (huart
->AdvancedInit
.AdvFeatureInit
!= UART_ADVFEATURE_NO_INIT
)
302 UART_AdvFeatureConfig(huart
);
305 /* In asynchronous mode, the following bits must be kept cleared:
306 - LINEN and CLKEN bits in the USART_CR2 register,
307 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
308 huart
->Instance
->CR2
&= ~(USART_CR2_LINEN
| USART_CR2_CLKEN
);
309 huart
->Instance
->CR3
&= ~(USART_CR3_SCEN
| USART_CR3_HDSEL
| USART_CR3_IREN
);
311 /* Enable the Peripheral */
312 __HAL_UART_ENABLE(huart
);
314 /* TEACK and/or REACK to check before moving huart->State to Ready */
315 return (UART_CheckIdleState(huart
));
319 * @brief Initializes the half-duplex mode according to the specified
320 * parameters in the UART_InitTypeDef and creates the associated handle .
321 * @param huart: uart handle
324 HAL_StatusTypeDef
HAL_HalfDuplex_Init(UART_HandleTypeDef
*huart
)
326 /* Check the UART handle allocation */
332 /* Check UART instance */
333 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart
->Instance
));
335 if(huart
->State
== HAL_UART_STATE_RESET
)
337 /* Init the low level hardware : GPIO, CLOCK */
338 HAL_UART_MspInit(huart
);
341 huart
->State
= HAL_UART_STATE_BUSY
;
343 /* Disable the Peripheral */
344 __HAL_UART_DISABLE(huart
);
346 /* Set the UART Communication parameters */
347 if (UART_SetConfig(huart
) == HAL_ERROR
)
352 if (huart
->AdvancedInit
.AdvFeatureInit
!= UART_ADVFEATURE_NO_INIT
)
354 UART_AdvFeatureConfig(huart
);
357 /* In half-duplex mode, the following bits must be kept cleared:
358 - LINEN and CLKEN bits in the USART_CR2 register,
359 - SCEN and IREN bits in the USART_CR3 register.*/
360 huart
->Instance
->CR2
&= ~(USART_CR2_LINEN
| USART_CR2_CLKEN
);
361 huart
->Instance
->CR3
&= ~(USART_CR3_IREN
| USART_CR3_SCEN
);
363 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
364 huart
->Instance
->CR3
|= USART_CR3_HDSEL
;
366 /* Enable the Peripheral */
367 __HAL_UART_ENABLE(huart
);
369 /* TEACK and/or REACK to check before moving huart->State to Ready */
370 return (UART_CheckIdleState(huart
));
375 * @brief Initializes the multiprocessor mode according to the specified
376 * parameters in the UART_InitTypeDef and creates the associated handle.
377 * @param huart: UART handle
378 * @param Address: UART node address (4-, 6-, 7- or 8-bit long)
379 * @param WakeUpMethod: specifies the UART wakeup method.
380 * This parameter can be one of the following values:
381 * @arg UART_WAKEUPMETHOD_IDLELINE: WakeUp by an idle line detection
382 * @arg UART_WAKEUPMETHOD_ADDRESSMARK: WakeUp by an address mark
383 * @note If the user resorts to idle line detection wake up, the Address parameter
384 * is useless and ignored by the initialization function.
385 * @note If the user resorts to address mark wake up, the address length detection
386 * is configured by default to 4 bits only. For the UART to be able to
387 * manage 6-, 7- or 8-bit long addresses detection, the API
388 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
389 * HAL_MultiProcessor_Init().
392 HAL_StatusTypeDef
HAL_MultiProcessor_Init(UART_HandleTypeDef
*huart
, uint8_t Address
, uint32_t WakeUpMethod
)
394 /* Check the UART handle allocation */
400 /* Check the wake up method parameter */
401 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod
));
403 if(huart
->State
== HAL_UART_STATE_RESET
)
405 /* Init the low level hardware : GPIO, CLOCK */
406 HAL_UART_MspInit(huart
);
409 huart
->State
= HAL_UART_STATE_BUSY
;
411 /* Disable the Peripheral */
412 __HAL_UART_DISABLE(huart
);
414 /* Set the UART Communication parameters */
415 if (UART_SetConfig(huart
) == HAL_ERROR
)
420 if (huart
->AdvancedInit
.AdvFeatureInit
!= UART_ADVFEATURE_NO_INIT
)
422 UART_AdvFeatureConfig(huart
);
425 /* In multiprocessor mode, the following bits must be kept cleared:
426 - LINEN and CLKEN bits in the USART_CR2 register,
427 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
428 huart
->Instance
->CR2
&= ~(USART_CR2_LINEN
| USART_CR2_CLKEN
);
429 huart
->Instance
->CR3
&= ~(USART_CR3_SCEN
| USART_CR3_HDSEL
| USART_CR3_IREN
);
431 if (WakeUpMethod
== UART_WAKEUPMETHOD_ADDRESSMARK
)
433 /* If address mark wake up method is chosen, set the USART address node */
434 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_ADD
, ((uint32_t)Address
<< UART_CR2_ADDRESS_LSB_POS
));
437 /* Set the wake up method by setting the WAKE bit in the CR1 register */
438 MODIFY_REG(huart
->Instance
->CR1
, USART_CR1_WAKE
, WakeUpMethod
);
440 /* Enable the Peripheral */
441 __HAL_UART_ENABLE(huart
);
443 /* TEACK and/or REACK to check before moving huart->State to Ready */
444 return (UART_CheckIdleState(huart
));
448 * @brief DeInitializes the UART peripheral
449 * @param huart: uart handle
452 HAL_StatusTypeDef
HAL_UART_DeInit(UART_HandleTypeDef
*huart
)
454 /* Check the UART handle allocation */
460 /* Check the parameters */
461 assert_param(IS_UART_INSTANCE(huart
->Instance
));
463 huart
->State
= HAL_UART_STATE_BUSY
;
465 /* Disable the Peripheral */
466 __HAL_UART_DISABLE(huart
);
468 huart
->Instance
->CR1
= 0x0;
469 huart
->Instance
->CR2
= 0x0;
470 huart
->Instance
->CR3
= 0x0;
472 /* DeInit the low level hardware */
473 HAL_UART_MspDeInit(huart
);
475 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
476 huart
->State
= HAL_UART_STATE_RESET
;
485 * @brief UART MSP Init
486 * @param huart: uart handle
489 __weak
void HAL_UART_MspInit(UART_HandleTypeDef
*huart
)
491 /* NOTE : This function should not be modified, when the callback is needed,
492 the HAL_UART_MspInit can be implemented in the user file
497 * @brief UART MSP DeInit
498 * @param huart: uart handle
501 __weak
void HAL_UART_MspDeInit(UART_HandleTypeDef
*huart
)
503 /* NOTE : This function should not be modified, when the callback is needed,
504 the HAL_UART_MspDeInit could be implemented in the user file
512 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
513 * @brief UART Transmit and Receive functions
516 ==============================================================================
517 ##### IO operation functions #####
518 ==============================================================================
520 This subsection provides a set of functions allowing to manage the UART asynchronous
521 and Half duplex data transfers.
523 (#) There are two mode of transfer:
524 (++) Blocking mode: The communication is performed in polling mode.
525 The HAL status of all data processing is returned by the same function
526 after finishing transfer.
527 (++) No-Blocking mode: The communication is performed using Interrupts
528 or DMA, These APIs return the HAL status.
529 The end of the data processing will be indicated through the
530 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
532 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
533 will be executed respectivelly at the end of the transmit or Receive process
534 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
536 (#) Blocking mode APIs are :
537 (++) HAL_UART_Transmit()
538 (++) HAL_UART_Receive()
540 (#) Non Blocking mode APIs with Interrupt are :
541 (++) HAL_UART_Transmit_IT()
542 (++) HAL_UART_Receive_IT()
543 (++) HAL_UART_IRQHandler()
544 (++) UART_Transmit_IT()
545 (++) UART_Receive_IT()
547 (#) Non Blocking mode APIs with DMA are :
548 (++) HAL_UART_Transmit_DMA()
549 (++) HAL_UART_Receive_DMA()
550 (++) HAL_UART_DMAPause()
551 (++) HAL_UART_DMAResume()
552 (++) HAL_UART_DMAStop()
554 (#) A set of Transfer Complete Callbacks are provided in non blocking mode:
555 (++) HAL_UART_TxHalfCpltCallback()
556 (++) HAL_UART_TxCpltCallback()
557 (++) HAL_UART_RxHalfCpltCallback()
558 (++) HAL_UART_RxCpltCallback()
559 (++) HAL_UART_ErrorCallback()
562 (@) In the Half duplex communication, it is forbidden to run the transmit
563 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
570 * @brief Send an amount of data in blocking mode
571 * @param huart: uart handle
572 * @param pData: pointer to data buffer
573 * @param Size: amount of data to be sent
574 * @param Timeout : Timeout duration
577 HAL_StatusTypeDef
HAL_UART_Transmit(UART_HandleTypeDef
*huart
, uint8_t *pData
, uint16_t Size
, uint32_t Timeout
)
581 if((huart
->State
== HAL_UART_STATE_READY
) || (huart
->State
== HAL_UART_STATE_BUSY_RX
))
583 if((pData
== NULL
) || (Size
== 0))
591 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
592 /* Check if a non-blocking receive process is ongoing or not */
593 if(huart
->State
== HAL_UART_STATE_BUSY_RX
)
595 huart
->State
= HAL_UART_STATE_BUSY_TX_RX
;
599 huart
->State
= HAL_UART_STATE_BUSY_TX
;
602 huart
->TxXferSize
= Size
;
603 huart
->TxXferCount
= Size
;
604 while(huart
->TxXferCount
> 0)
606 huart
->TxXferCount
--;
607 if(UART_WaitOnFlagUntilTimeout(huart
, UART_FLAG_TXE
, RESET
, Timeout
) != HAL_OK
)
611 if ((huart
->Init
.WordLength
== UART_WORDLENGTH_9B
) && (huart
->Init
.Parity
== UART_PARITY_NONE
))
613 tmp
= (uint16_t*) pData
;
614 huart
->Instance
->TDR
= (*tmp
& (uint16_t)0x01FF);
619 huart
->Instance
->TDR
= (*pData
++ & (uint8_t)0xFF);
622 if(UART_WaitOnFlagUntilTimeout(huart
, UART_FLAG_TC
, RESET
, Timeout
) != HAL_OK
)
626 /* Check if a non-blocking receive Process is ongoing or not */
627 if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
629 huart
->State
= HAL_UART_STATE_BUSY_RX
;
633 huart
->State
= HAL_UART_STATE_READY
;
636 /* Process Unlocked */
648 * @brief Receive an amount of data in blocking mode
649 * @param huart: uart handle
650 * @param pData: pointer to data buffer
651 * @param Size: amount of data to be received
652 * @param Timeout : Timeout duration
655 HAL_StatusTypeDef
HAL_UART_Receive(UART_HandleTypeDef
*huart
, uint8_t *pData
, uint16_t Size
, uint32_t Timeout
)
660 if((huart
->State
== HAL_UART_STATE_READY
) || (huart
->State
== HAL_UART_STATE_BUSY_TX
))
662 if((pData
== NULL
) || (Size
== 0))
670 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
671 /* Check if a non-blocking transmit process is ongoing or not */
672 if(huart
->State
== HAL_UART_STATE_BUSY_TX
)
674 huart
->State
= HAL_UART_STATE_BUSY_TX_RX
;
678 huart
->State
= HAL_UART_STATE_BUSY_RX
;
681 huart
->RxXferSize
= Size
;
682 huart
->RxXferCount
= Size
;
684 /* Computation of UART mask to apply to RDR register */
685 __HAL_UART_MASK_COMPUTATION(huart
);
686 uhMask
= huart
->Mask
;
688 /* as long as data have to be received */
689 while(huart
->RxXferCount
> 0)
691 huart
->RxXferCount
--;
692 if(UART_WaitOnFlagUntilTimeout(huart
, UART_FLAG_RXNE
, RESET
, Timeout
) != HAL_OK
)
696 if ((huart
->Init
.WordLength
== UART_WORDLENGTH_9B
) && (huart
->Init
.Parity
== UART_PARITY_NONE
))
698 tmp
= (uint16_t*) pData
;
699 *tmp
= (uint16_t)(huart
->Instance
->RDR
& uhMask
);
704 *pData
++ = (uint8_t)(huart
->Instance
->RDR
& (uint8_t)uhMask
);
708 /* Check if a non-blocking transmit Process is ongoing or not */
709 if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
711 huart
->State
= HAL_UART_STATE_BUSY_TX
;
715 huart
->State
= HAL_UART_STATE_READY
;
717 /* Process Unlocked */
729 * @brief Send an amount of data in interrupt mode
730 * @param huart: uart handle
731 * @param pData: pointer to data buffer
732 * @param Size: amount of data to be sent
735 HAL_StatusTypeDef
HAL_UART_Transmit_IT(UART_HandleTypeDef
*huart
, uint8_t *pData
, uint16_t Size
)
737 if((huart
->State
== HAL_UART_STATE_READY
) || (huart
->State
== HAL_UART_STATE_BUSY_RX
))
739 if((pData
== NULL
) || (Size
== 0))
747 huart
->pTxBuffPtr
= pData
;
748 huart
->TxXferSize
= Size
;
749 huart
->TxXferCount
= Size
;
751 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
752 /* Check if a receive process is ongoing or not */
753 if(huart
->State
== HAL_UART_STATE_BUSY_RX
)
755 huart
->State
= HAL_UART_STATE_BUSY_TX_RX
;
759 huart
->State
= HAL_UART_STATE_BUSY_TX
;
762 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
763 __HAL_UART_ENABLE_IT(huart
, UART_IT_ERR
);
765 /* Process Unlocked */
768 /* Enable the UART Transmit Data Register Empty Interrupt */
769 __HAL_UART_ENABLE_IT(huart
, UART_IT_TXE
);
780 * @brief Receive an amount of data in interrupt mode
781 * @param huart: uart handle
782 * @param pData: pointer to data buffer
783 * @param Size: amount of data to be received
786 HAL_StatusTypeDef
HAL_UART_Receive_IT(UART_HandleTypeDef
*huart
, uint8_t *pData
, uint16_t Size
)
788 if((huart
->State
== HAL_UART_STATE_READY
) || (huart
->State
== HAL_UART_STATE_BUSY_TX
))
790 if((pData
== NULL
) || (Size
== 0))
798 huart
->pRxBuffPtr
= pData
;
799 huart
->RxXferSize
= Size
;
800 huart
->RxXferCount
= Size
;
802 /* Computation of UART mask to apply to RDR register */
803 __HAL_UART_MASK_COMPUTATION(huart
);
805 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
806 /* Check if a transmit process is ongoing or not */
807 if(huart
->State
== HAL_UART_STATE_BUSY_TX
)
809 huart
->State
= HAL_UART_STATE_BUSY_TX_RX
;
813 huart
->State
= HAL_UART_STATE_BUSY_RX
;
816 /* Enable the UART Parity Error Interrupt */
817 __HAL_UART_ENABLE_IT(huart
, UART_IT_PE
);
819 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
820 __HAL_UART_ENABLE_IT(huart
, UART_IT_ERR
);
822 /* Process Unlocked */
825 /* Enable the UART Data Register not empty Interrupt */
826 __HAL_UART_ENABLE_IT(huart
, UART_IT_RXNE
);
837 * @brief Send an amount of data in DMA mode
838 * @param huart: uart handle
839 * @param pData: pointer to data buffer
840 * @param Size: amount of data to be sent
843 HAL_StatusTypeDef
HAL_UART_Transmit_DMA(UART_HandleTypeDef
*huart
, uint8_t *pData
, uint16_t Size
)
847 if((huart
->State
== HAL_UART_STATE_READY
) || (huart
->State
== HAL_UART_STATE_BUSY_RX
))
849 if((pData
== NULL
) || (Size
== 0))
857 huart
->pTxBuffPtr
= pData
;
858 huart
->TxXferSize
= Size
;
859 huart
->TxXferCount
= Size
;
861 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
862 /* Check if a receive process is ongoing or not */
863 if(huart
->State
== HAL_UART_STATE_BUSY_RX
)
865 huart
->State
= HAL_UART_STATE_BUSY_TX_RX
;
869 huart
->State
= HAL_UART_STATE_BUSY_TX
;
872 /* Set the UART DMA transfer complete callback */
873 huart
->hdmatx
->XferCpltCallback
= UART_DMATransmitCplt
;
875 /* Set the UART DMA Half transfer complete callback */
876 huart
->hdmatx
->XferHalfCpltCallback
= UART_DMATxHalfCplt
;
878 /* Set the DMA error callback */
879 huart
->hdmatx
->XferErrorCallback
= UART_DMAError
;
881 /* Enable the UART transmit DMA channel */
882 tmp
= (uint32_t*)&pData
;
883 HAL_DMA_Start_IT(huart
->hdmatx
, *(uint32_t*)tmp
, (uint32_t)&huart
->Instance
->TDR
, Size
);
885 /* Enable the DMA transfer for transmit request by setting the DMAT bit
886 in the UART CR3 register */
887 huart
->Instance
->CR3
|= USART_CR3_DMAT
;
889 /* Process Unlocked */
901 * @brief Receive an amount of data in DMA mode
902 * @param huart: uart handle
903 * @param pData: pointer to data buffer
904 * @param Size: amount of data to be received
905 * @note When the UART parity is enabled (PCE = 1), the received data contain
906 * the parity bit (MSB position)
909 HAL_StatusTypeDef
HAL_UART_Receive_DMA(UART_HandleTypeDef
*huart
, uint8_t *pData
, uint16_t Size
)
913 if((huart
->State
== HAL_UART_STATE_READY
) || (huart
->State
== HAL_UART_STATE_BUSY_TX
))
915 if((pData
== NULL
) || (Size
== 0))
923 huart
->pRxBuffPtr
= pData
;
924 huart
->RxXferSize
= Size
;
926 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
927 /* Check if a transmit process is ongoing or not */
928 if(huart
->State
== HAL_UART_STATE_BUSY_TX
)
930 huart
->State
= HAL_UART_STATE_BUSY_TX_RX
;
934 huart
->State
= HAL_UART_STATE_BUSY_RX
;
937 /* Set the UART DMA transfer complete callback */
938 huart
->hdmarx
->XferCpltCallback
= UART_DMAReceiveCplt
;
940 /* Set the UART DMA Half transfer complete callback */
941 huart
->hdmarx
->XferHalfCpltCallback
= UART_DMARxHalfCplt
;
943 /* Set the DMA error callback */
944 huart
->hdmarx
->XferErrorCallback
= UART_DMAError
;
946 /* Enable the DMA channel */
947 tmp
= (uint32_t*)&pData
;
948 HAL_DMA_Start_IT(huart
->hdmarx
, (uint32_t)&huart
->Instance
->RDR
, *(uint32_t*)tmp
, Size
);
950 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
951 in the UART CR3 register */
952 huart
->Instance
->CR3
|= USART_CR3_DMAR
;
954 /* Process Unlocked */
966 * @brief Pauses the DMA Transfer.
967 * @param huart: UART handle
970 HAL_StatusTypeDef
HAL_UART_DMAPause(UART_HandleTypeDef
*huart
)
975 if(huart
->State
== HAL_UART_STATE_BUSY_TX
)
977 /* Disable the UART DMA Tx request */
978 huart
->Instance
->CR3
&= (uint32_t)(~USART_CR3_DMAT
);
980 else if(huart
->State
== HAL_UART_STATE_BUSY_RX
)
982 /* Disable the UART DMA Rx request */
983 huart
->Instance
->CR3
&= (uint32_t)(~USART_CR3_DMAR
);
985 else if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
987 /* Disable the UART DMA Tx request */
988 huart
->Instance
->CR3
&= (uint32_t)(~USART_CR3_DMAT
);
989 /* Disable the UART DMA Rx request */
990 huart
->Instance
->CR3
&= (uint32_t)(~USART_CR3_DMAR
);
993 /* Process Unlocked */
1000 * @brief Resumes the DMA Transfer.
1001 * @param huart: UART handle
1004 HAL_StatusTypeDef
HAL_UART_DMAResume(UART_HandleTypeDef
*huart
)
1006 /* Process Locked */
1009 if(huart
->State
== HAL_UART_STATE_BUSY_TX
)
1011 /* Enable the UART DMA Tx request */
1012 huart
->Instance
->CR3
|= USART_CR3_DMAT
;
1014 else if(huart
->State
== HAL_UART_STATE_BUSY_RX
)
1016 /* Enable the UART DMA Rx request */
1017 huart
->Instance
->CR3
|= USART_CR3_DMAR
;
1019 else if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
1021 /* Enable the UART DMA Rx request before the DMA Tx request */
1022 huart
->Instance
->CR3
|= USART_CR3_DMAR
;
1023 /* Enable the UART DMA Tx request */
1024 huart
->Instance
->CR3
|= USART_CR3_DMAT
;
1027 /* If the UART peripheral is still not enabled, enable it */
1028 if ((huart
->Instance
->CR1
& USART_CR1_UE
) == 0)
1030 /* Enable UART peripheral */
1031 __HAL_UART_ENABLE(huart
);
1034 /* TEACK and/or REACK to check before moving huart->State to Ready */
1035 return (UART_CheckIdleState(huart
));
1039 * @brief Stops the DMA Transfer.
1040 * @param huart: UART handle
1043 HAL_StatusTypeDef
HAL_UART_DMAStop(UART_HandleTypeDef
*huart
)
1045 /* Process Locked */
1048 /* Disable the UART Tx/Rx DMA requests */
1049 huart
->Instance
->CR3
&= ~USART_CR3_DMAT
;
1050 huart
->Instance
->CR3
&= ~USART_CR3_DMAR
;
1052 /* Abort the UART DMA tx channel */
1053 if(huart
->hdmatx
!= NULL
)
1055 HAL_DMA_Abort(huart
->hdmatx
);
1057 /* Abort the UART DMA rx channel */
1058 if(huart
->hdmarx
!= NULL
)
1060 HAL_DMA_Abort(huart
->hdmarx
);
1063 /* Disable UART peripheral */
1064 __HAL_UART_DISABLE(huart
);
1066 huart
->State
= HAL_UART_STATE_READY
;
1068 /* Process Unlocked */
1069 __HAL_UNLOCK(huart
);
1075 * @brief Tx Transfer completed callbacks
1076 * @param huart: uart handle
1079 __weak
void HAL_UART_TxCpltCallback(UART_HandleTypeDef
*huart
)
1081 /* NOTE : This function should not be modified, when the callback is needed,
1082 the HAL_UART_TxCpltCallback can be implemented in the user file
1087 * @brief Tx Half Transfer completed callbacks.
1088 * @param huart: UART handle
1091 __weak
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef
*huart
)
1093 /* NOTE: This function should not be modified, when the callback is needed,
1094 the HAL_UART_TxHalfCpltCallback can be implemented in the user file
1099 * @brief Rx Transfer completed callbacks
1100 * @param huart: uart handle
1103 __weak
void HAL_UART_RxCpltCallback(UART_HandleTypeDef
*huart
)
1105 /* NOTE : This function should not be modified, when the callback is needed,
1106 the HAL_UART_RxCpltCallback can be implemented in the user file
1111 * @brief Rx Half Transfer completed callbacks.
1112 * @param huart: UART handle
1115 __weak
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef
*huart
)
1117 /* NOTE: This function should not be modified, when the callback is needed,
1118 the HAL_UART_RxHalfCpltCallback can be implemented in the user file
1123 * @brief UART error callbacks
1124 * @param huart: uart handle
1127 __weak
void HAL_UART_ErrorCallback(UART_HandleTypeDef
*huart
)
1129 /* NOTE : This function should not be modified, when the callback is needed,
1130 the HAL_UART_ErrorCallback can be implemented in the user file
1138 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
1139 * @brief UART control functions
1142 ===============================================================================
1143 ##### Peripheral Control functions #####
1144 ===============================================================================
1146 This subsection provides a set of functions allowing to control the UART.
1147 (+) HAL_UART_GetState() API is helpful to check in run-time the state of the UART peripheral.
1148 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
1149 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
1150 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
1151 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
1152 (+) HAL_UART_EnableStopMode() API enables the UART to wake up the MCU from stop mode
1153 (+) HAL_UART_DisableStopMode() API disables the above functionality
1154 (+) UART_SetConfig() API configures the UART peripheral
1155 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
1156 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
1157 (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters
1158 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
1159 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
1165 * @brief Enable UART in mute mode (doesn't mean UART enters mute mode;
1166 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called)
1167 * @param huart: UART handle
1168 * @retval HAL status
1170 HAL_StatusTypeDef
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef
*huart
)
1172 /* Process Locked */
1175 huart
->State
= HAL_UART_STATE_BUSY
;
1177 /* Enable USART mute mode by setting the MME bit in the CR1 register */
1178 huart
->Instance
->CR1
|= USART_CR1_MME
;
1180 huart
->State
= HAL_UART_STATE_READY
;
1182 return (UART_CheckIdleState(huart
));
1186 * @brief Disable UART mute mode (doesn't mean it actually wakes up the software,
1187 * as it may not have been in mute mode at this very moment).
1188 * @param huart: uart handle
1189 * @retval HAL status
1191 HAL_StatusTypeDef
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef
*huart
)
1193 /* Process Locked */
1196 huart
->State
= HAL_UART_STATE_BUSY
;
1198 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
1199 huart
->Instance
->CR1
&= ~(USART_CR1_MME
);
1201 huart
->State
= HAL_UART_STATE_READY
;
1203 return (UART_CheckIdleState(huart
));
1207 * @brief Enter UART mute mode (means UART actually enters mute mode).
1208 * To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
1209 * @param huart: uart handle
1210 * @retval HAL status
1212 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef
*huart
)
1214 __HAL_UART_SEND_REQ(huart
, UART_MUTE_MODE_REQUEST
);
1218 * @brief Enables the UART transmitter and disables the UART receiver.
1219 * @param huart: UART handle
1220 * @retval HAL status
1223 HAL_StatusTypeDef
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef
*huart
)
1225 /* Process Locked */
1227 huart
->State
= HAL_UART_STATE_BUSY
;
1229 /* Clear TE and RE bits */
1230 CLEAR_BIT(huart
->Instance
->CR1
, (USART_CR1_TE
| USART_CR1_RE
));
1231 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
1232 SET_BIT(huart
->Instance
->CR1
, USART_CR1_TE
);
1234 huart
->State
= HAL_UART_STATE_READY
;
1235 /* Process Unlocked */
1236 __HAL_UNLOCK(huart
);
1242 * @brief Enables the UART receiver and disables the UART transmitter.
1243 * @param huart: UART handle
1244 * @retval HAL status
1246 HAL_StatusTypeDef
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef
*huart
)
1248 /* Process Locked */
1250 huart
->State
= HAL_UART_STATE_BUSY
;
1252 /* Clear TE and RE bits */
1253 CLEAR_BIT(huart
->Instance
->CR1
, (USART_CR1_TE
| USART_CR1_RE
));
1254 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
1255 SET_BIT(huart
->Instance
->CR1
, USART_CR1_RE
);
1257 huart
->State
= HAL_UART_STATE_READY
;
1258 /* Process Unlocked */
1259 __HAL_UNLOCK(huart
);
1268 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
1273 * @brief return the UART state
1274 * @param huart: uart handle
1277 HAL_UART_StateTypeDef
HAL_UART_GetState(UART_HandleTypeDef
*huart
)
1279 return huart
->State
;
1283 * @brief Return the UART error code
1284 * @param huart : pointer to a UART_HandleTypeDef structure that contains
1285 * the configuration information for the specified UART.
1286 * @retval UART Error Code
1288 uint32_t HAL_UART_GetError(UART_HandleTypeDef
*huart
)
1290 return huart
->ErrorCode
;
1301 /** @defgroup UART_Private_Functions UART Private Functions
1306 * @brief Send an amount of data in interrupt mode
1307 * Function called under interruption only, once
1308 * interruptions have been enabled by HAL_UART_Transmit_IT()
1309 * @param huart: UART handle
1310 * @retval HAL status
1312 HAL_StatusTypeDef
UART_Transmit_IT(UART_HandleTypeDef
*huart
)
1316 if ((huart
->State
== HAL_UART_STATE_BUSY_TX
) || (huart
->State
== HAL_UART_STATE_BUSY_TX_RX
))
1319 if(huart
->TxXferCount
== 0)
1321 /* Disable the UART Transmit Data Register Empty Interrupt */
1322 __HAL_UART_DISABLE_IT(huart
, UART_IT_TXE
);
1324 /* Enable the UART Transmit Complete Interrupt */
1325 __HAL_UART_ENABLE_IT(huart
, UART_IT_TC
);
1331 if ((huart
->Init
.WordLength
== UART_WORDLENGTH_9B
) && (huart
->Init
.Parity
== UART_PARITY_NONE
))
1333 tmp
= (uint16_t*) huart
->pTxBuffPtr
;
1334 huart
->Instance
->TDR
= (*tmp
& (uint16_t)0x01FF);
1335 huart
->pTxBuffPtr
+= 2;
1339 huart
->Instance
->TDR
= (uint8_t)(*huart
->pTxBuffPtr
++ & (uint8_t)0xFF);
1342 huart
->TxXferCount
--;
1354 * @brief Receive an amount of data in interrupt mode
1355 * Function called under interruption only, once
1356 * interruptions have been enabled by HAL_UART_Receive_IT()
1357 * @param huart: UART handle
1358 * @retval HAL status
1360 HAL_StatusTypeDef
UART_Receive_IT(UART_HandleTypeDef
*huart
)
1363 uint16_t uhMask
= huart
->Mask
;
1365 if((huart
->State
== HAL_UART_STATE_BUSY_RX
) || (huart
->State
== HAL_UART_STATE_BUSY_TX_RX
))
1368 if ((huart
->Init
.WordLength
== UART_WORDLENGTH_9B
) && (huart
->Init
.Parity
== UART_PARITY_NONE
))
1370 tmp
= (uint16_t*) huart
->pRxBuffPtr
;
1371 *tmp
= (uint16_t)(huart
->Instance
->RDR
& uhMask
);
1372 huart
->pRxBuffPtr
+=2;
1376 *huart
->pRxBuffPtr
++ = (uint8_t)(huart
->Instance
->RDR
& (uint8_t)uhMask
);
1379 if(--huart
->RxXferCount
== 0)
1381 __HAL_UART_DISABLE_IT(huart
, UART_IT_RXNE
);
1383 /* Check if a transmit Process is ongoing or not */
1384 if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
1386 huart
->State
= HAL_UART_STATE_BUSY_TX
;
1390 /* Disable the UART Parity Error Interrupt */
1391 __HAL_UART_DISABLE_IT(huart
, UART_IT_PE
);
1393 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1394 __HAL_UART_DISABLE_IT(huart
, UART_IT_ERR
);
1396 huart
->State
= HAL_UART_STATE_READY
;
1399 HAL_UART_RxCpltCallback(huart
);
1413 * @brief Check the UART Idle State
1414 * @param huart: uart handle
1415 * @retval HAL status
1417 HAL_StatusTypeDef
UART_CheckIdleState(UART_HandleTypeDef
*huart
)
1419 /* Initialize the UART ErrorCode */
1420 huart
->ErrorCode
= HAL_UART_ERROR_NONE
;
1422 /* Check if the Transmitter is enabled */
1423 if((huart
->Instance
->CR1
& USART_CR1_TE
) == USART_CR1_TE
)
1425 /* Wait until TEACK flag is set */
1426 if(UART_WaitOnFlagUntilTimeout(huart
, USART_ISR_TEACK
, RESET
, HAL_UART_TIMEOUT_VALUE
) != HAL_OK
)
1428 /* Timeout Occured */
1432 /* Check if the Receiver is enabled */
1433 if((huart
->Instance
->CR1
& USART_CR1_RE
) == USART_CR1_RE
)
1435 /* Wait until REACK flag is set */
1436 if(UART_WaitOnFlagUntilTimeout(huart
, USART_ISR_REACK
, RESET
, HAL_UART_TIMEOUT_VALUE
) != HAL_OK
)
1438 /* Timeout Occured */
1443 /* Initialize the UART State */
1444 huart
->State
= HAL_UART_STATE_READY
;
1446 /* Process Unlocked */
1447 __HAL_UNLOCK(huart
);
1453 * @brief This function handles UART Communication Timeout.
1454 * @param huart: UART handle
1455 * @param Flag: specifies the UART flag to check.
1456 * @param Status: The new Flag status (SET or RESET).
1457 * @param Timeout: Timeout duration
1458 * @retval HAL status
1460 HAL_StatusTypeDef
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef
*huart
, uint32_t Flag
, FlagStatus Status
, uint32_t Timeout
)
1462 uint32_t tickstart
= HAL_GetTick();
1464 /* Wait until flag is set */
1467 while(__HAL_UART_GET_FLAG(huart
, Flag
) == RESET
)
1469 /* Check for the Timeout */
1470 if(Timeout
!= HAL_MAX_DELAY
)
1472 if((Timeout
== 0) || ((HAL_GetTick() - tickstart
) > Timeout
))
1474 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1475 __HAL_UART_DISABLE_IT(huart
, UART_IT_TXE
);
1476 __HAL_UART_DISABLE_IT(huart
, UART_IT_RXNE
);
1477 __HAL_UART_DISABLE_IT(huart
, UART_IT_PE
);
1478 __HAL_UART_DISABLE_IT(huart
, UART_IT_ERR
);
1480 huart
->State
= HAL_UART_STATE_READY
;
1482 /* Process Unlocked */
1483 __HAL_UNLOCK(huart
);
1492 while(__HAL_UART_GET_FLAG(huart
, Flag
) != RESET
)
1494 /* Check for the Timeout */
1495 if(Timeout
!= HAL_MAX_DELAY
)
1497 if((Timeout
== 0) || ((HAL_GetTick() - tickstart
) > Timeout
))
1499 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1500 __HAL_UART_DISABLE_IT(huart
, UART_IT_TXE
);
1501 __HAL_UART_DISABLE_IT(huart
, UART_IT_RXNE
);
1502 __HAL_UART_DISABLE_IT(huart
, UART_IT_PE
);
1503 __HAL_UART_DISABLE_IT(huart
, UART_IT_ERR
);
1505 huart
->State
= HAL_UART_STATE_READY
;
1507 /* Process Unlocked */
1508 __HAL_UNLOCK(huart
);
1519 * @brief DMA UART transmit process complete callback
1520 * @param hdma: DMA handle
1523 static void UART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
)
1525 UART_HandleTypeDef
* huart
= ( UART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1526 huart
->TxXferCount
= 0;
1528 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1529 in the UART CR3 register */
1530 huart
->Instance
->CR3
&= (uint32_t)~((uint32_t)USART_CR3_DMAT
);
1532 /* Wait for UART TC Flag */
1533 if(UART_WaitOnFlagUntilTimeout(huart
, UART_FLAG_TC
, RESET
, HAL_UART_TXDMA_TIMEOUTVALUE
) != HAL_OK
)
1535 /* Timeout Occured */
1536 huart
->State
= HAL_UART_STATE_TIMEOUT
;
1537 HAL_UART_ErrorCallback(huart
);
1542 /* Check if a receive process is ongoing or not */
1543 if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
1545 huart
->State
= HAL_UART_STATE_BUSY_RX
;
1549 huart
->State
= HAL_UART_STATE_READY
;
1551 HAL_UART_TxCpltCallback(huart
);
1556 * @brief DMA UART transmit process half complete callback
1557 * @param hdma : DMA handle
1560 static void UART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
)
1562 UART_HandleTypeDef
* huart
= (UART_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
1564 HAL_UART_TxHalfCpltCallback(huart
);
1568 * @brief DMA UART receive process complete callback
1569 * @param hdma: DMA handle
1572 static void UART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
)
1574 UART_HandleTypeDef
* huart
= ( UART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1575 huart
->RxXferCount
= 0;
1577 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1578 in the UART CR3 register */
1579 huart
->Instance
->CR3
&= (uint32_t)~((uint32_t)USART_CR3_DMAR
);
1581 /* Check if a transmit Process is ongoing or not */
1582 if(huart
->State
== HAL_UART_STATE_BUSY_TX_RX
)
1584 huart
->State
= HAL_UART_STATE_BUSY_TX
;
1588 huart
->State
= HAL_UART_STATE_READY
;
1590 HAL_UART_RxCpltCallback(huart
);
1594 * @brief DMA UART receive process half complete callback
1595 * @param hdma : DMA handle
1598 static void UART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
)
1600 UART_HandleTypeDef
* huart
= (UART_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
1602 HAL_UART_RxHalfCpltCallback(huart
);
1606 * @brief DMA UART communication error callback
1607 * @param hdma: DMA handle
1610 static void UART_DMAError(DMA_HandleTypeDef
*hdma
)
1612 UART_HandleTypeDef
* huart
= ( UART_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
1613 huart
->RxXferCount
= 0;
1614 huart
->TxXferCount
= 0;
1615 huart
->State
= HAL_UART_STATE_READY
;
1616 huart
->ErrorCode
|= HAL_UART_ERROR_DMA
;
1617 HAL_UART_ErrorCallback(huart
);
1621 * @brief Configure the UART peripheral
1622 * @param huart: uart handle
1625 HAL_StatusTypeDef
UART_SetConfig(UART_HandleTypeDef
*huart
)
1627 uint32_t tmpreg
= 0x00000000;
1628 UART_ClockSourceTypeDef clocksource
= UART_CLOCKSOURCE_UNDEFINED
;
1629 uint16_t brrtemp
= 0x0000;
1630 uint16_t usartdiv
= 0x0000;
1631 HAL_StatusTypeDef ret
= HAL_OK
;
1633 /* Check the parameters */
1634 assert_param(IS_UART_BAUDRATE(huart
->Init
.BaudRate
));
1635 assert_param(IS_UART_WORD_LENGTH(huart
->Init
.WordLength
));
1636 assert_param(IS_UART_STOPBITS(huart
->Init
.StopBits
));
1637 assert_param(IS_UART_PARITY(huart
->Init
.Parity
));
1638 assert_param(IS_UART_MODE(huart
->Init
.Mode
));
1639 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart
->Init
.HwFlowCtl
));
1640 assert_param(IS_UART_ONEBIT_SAMPLING(huart
->Init
.OneBitSampling
));
1643 /*-------------------------- USART CR1 Configuration -----------------------*/
1644 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
1645 * the UART Word Length, Parity, Mode and oversampling:
1646 * set the M bits according to huart->Init.WordLength value
1647 * set PCE and PS bits according to huart->Init.Parity value
1648 * set TE and RE bits according to huart->Init.Mode value
1649 * set OVER8 bit according to huart->Init.OverSampling value */
1650 tmpreg
= (uint32_t)huart
->Init
.WordLength
| huart
->Init
.Parity
| huart
->Init
.Mode
| huart
->Init
.OverSampling
;
1651 MODIFY_REG(huart
->Instance
->CR1
, UART_CR1_FIELDS
, tmpreg
);
1653 /*-------------------------- USART CR2 Configuration -----------------------*/
1654 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
1655 * to huart->Init.StopBits value */
1656 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_STOP
, huart
->Init
.StopBits
);
1658 /*-------------------------- USART CR3 Configuration -----------------------*/
1660 * - UART HardWare Flow Control: set CTSE and RTSE bits according
1661 * to huart->Init.HwFlowCtl value
1662 * - one-bit sampling method versus three samples' majority rule according
1663 * to huart->Init.OneBitSampling */
1664 tmpreg
= (uint32_t)huart
->Init
.HwFlowCtl
| huart
->Init
.OneBitSampling
;
1665 MODIFY_REG(huart
->Instance
->CR3
, (USART_CR3_RTSE
| USART_CR3_CTSE
| USART_CR3_ONEBIT
), tmpreg
);
1667 /*-------------------------- USART BRR Configuration -----------------------*/
1668 __HAL_UART_GETCLOCKSOURCE(huart
, clocksource
);
1670 /* Check the Over Sampling to set Baud Rate Register */
1671 if (huart
->Init
.OverSampling
== UART_OVERSAMPLING_8
)
1673 switch (clocksource
)
1675 case UART_CLOCKSOURCE_PCLK1
:
1676 usartdiv
= (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart
->Init
.BaudRate
));
1678 case UART_CLOCKSOURCE_HSI
:
1679 usartdiv
= (uint16_t)(__DIV_SAMPLING8(HSI_VALUE
, huart
->Init
.BaudRate
));
1681 case UART_CLOCKSOURCE_SYSCLK
:
1682 usartdiv
= (uint16_t)(__DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart
->Init
.BaudRate
));
1684 case UART_CLOCKSOURCE_LSE
:
1685 usartdiv
= (uint16_t)(__DIV_SAMPLING8(LSE_VALUE
, huart
->Init
.BaudRate
));
1687 case UART_CLOCKSOURCE_UNDEFINED
:
1693 brrtemp
= usartdiv
& 0xFFF0;
1694 brrtemp
|= (uint16_t) ((usartdiv
& (uint16_t)0x000F) >> 1U);
1695 huart
->Instance
->BRR
= brrtemp
;
1699 switch (clocksource
)
1701 case UART_CLOCKSOURCE_PCLK1
:
1702 huart
->Instance
->BRR
= (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart
->Init
.BaudRate
));
1704 case UART_CLOCKSOURCE_HSI
:
1705 huart
->Instance
->BRR
= (uint16_t)(__DIV_SAMPLING16(HSI_VALUE
, huart
->Init
.BaudRate
));
1707 case UART_CLOCKSOURCE_SYSCLK
:
1708 huart
->Instance
->BRR
= (uint16_t)(__DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart
->Init
.BaudRate
));
1710 case UART_CLOCKSOURCE_LSE
:
1711 huart
->Instance
->BRR
= (uint16_t)(__DIV_SAMPLING16(LSE_VALUE
, huart
->Init
.BaudRate
));
1713 case UART_CLOCKSOURCE_UNDEFINED
:
1725 * @brief Configure the UART peripheral advanced feautures
1726 * @param huart: uart handle
1729 void UART_AdvFeatureConfig(UART_HandleTypeDef
*huart
)
1731 /* Check whether the set of advanced features to configure is properly set */
1732 assert_param(IS_UART_ADVFEATURE_INIT(huart
->AdvancedInit
.AdvFeatureInit
));
1734 /* if required, configure TX pin active level inversion */
1735 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_TXINVERT_INIT
))
1737 assert_param(IS_UART_ADVFEATURE_TXINV(huart
->AdvancedInit
.TxPinLevelInvert
));
1738 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_TXINV
, huart
->AdvancedInit
.TxPinLevelInvert
);
1741 /* if required, configure RX pin active level inversion */
1742 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_RXINVERT_INIT
))
1744 assert_param(IS_UART_ADVFEATURE_RXINV(huart
->AdvancedInit
.RxPinLevelInvert
));
1745 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_RXINV
, huart
->AdvancedInit
.RxPinLevelInvert
);
1748 /* if required, configure data inversion */
1749 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_DATAINVERT_INIT
))
1751 assert_param(IS_UART_ADVFEATURE_DATAINV(huart
->AdvancedInit
.DataInvert
));
1752 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_DATAINV
, huart
->AdvancedInit
.DataInvert
);
1755 /* if required, configure RX/TX pins swap */
1756 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_SWAP_INIT
))
1758 assert_param(IS_UART_ADVFEATURE_SWAP(huart
->AdvancedInit
.Swap
));
1759 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_SWAP
, huart
->AdvancedInit
.Swap
);
1762 /* if required, configure RX overrun detection disabling */
1763 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT
))
1765 assert_param(IS_UART_OVERRUN(huart
->AdvancedInit
.OverrunDisable
));
1766 MODIFY_REG(huart
->Instance
->CR3
, USART_CR3_OVRDIS
, huart
->AdvancedInit
.OverrunDisable
);
1769 /* if required, configure DMA disabling on reception error */
1770 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_DMADISABLEONERROR_INIT
))
1772 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart
->AdvancedInit
.DMADisableonRxError
));
1773 MODIFY_REG(huart
->Instance
->CR3
, USART_CR3_DDRE
, huart
->AdvancedInit
.DMADisableonRxError
);
1776 /* if required, configure auto Baud rate detection scheme */
1777 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_AUTOBAUDRATE_INIT
))
1779 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart
->Instance
));
1780 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart
->AdvancedInit
.AutoBaudRateEnable
));
1781 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_ABREN
, huart
->AdvancedInit
.AutoBaudRateEnable
);
1782 /* set auto Baudrate detection parameters if detection is enabled */
1783 if (huart
->AdvancedInit
.AutoBaudRateEnable
== UART_ADVFEATURE_AUTOBAUDRATE_ENABLE
)
1785 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart
->AdvancedInit
.AutoBaudRateMode
));
1786 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_ABRMODE
, huart
->AdvancedInit
.AutoBaudRateMode
);
1790 /* if required, configure MSB first on communication line */
1791 if (HAL_IS_BIT_SET(huart
->AdvancedInit
.AdvFeatureInit
, UART_ADVFEATURE_MSBFIRST_INIT
))
1793 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart
->AdvancedInit
.MSBFirst
));
1794 MODIFY_REG(huart
->Instance
->CR2
, USART_CR2_MSBFIRST
, huart
->AdvancedInit
.MSBFirst
);
1802 #endif /* HAL_UART_MODULE_ENABLED */
1811 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/