How to use STM32 HAL UART driver API and Callbacks ?
- What are the callbacks involved in UART TX / RX?
- How are these callbacks called?
- Why is the callback not called?
1. STM32 HAL UART supports 3 modes for transmitter (TX) / receiver (RX):
- Polling mode (no DMA, no IRQ)
- only possible for low baud rates, blocking
- Interrupt mode (no DMA)
- DMA mode
- Transfer from UART to memory is done by the DMA without CPU interaction.
- Ideal in case of high baud rate to avoid stalling the CPU and in low power mode.
- An interrupt service routine (ISR) can be executed when a certain amount of characters have been received/transmitted.
- Half Transfer - optional
- Transfer Complete
- The application code is executed in callback functions called by the ISR.
2. Polling mode
- Transmit / Receive functions
- HAL_UART_Transmit() / HAL_UART_Receive()
- with parameters:
- Pointer to data buffer
- Amount of data elements to transmit / receive
- Timeout duration
The data processing is handled internally in a loop. A timeout (expressed in ms) is used to prevent process hanging.
The operation is considered complete when the function returns the HAL_OK status, otherwise an error status is returned.
3. Interrupt mode
- Transmit / Receive functions
- HAL_UART_Transmit_IT() / HAL_UART_Receive_IT()
- with parameters:
- Pointer to data buffer
- Amount of data elements to transmit / receive
- Interrupt Service Routines and Callback functions
- UART_IRQHandler()
- HAL_UART_IRQHandler()
- HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
The HAL function returns the process status after starting the data processing and enabling the appropriate interruption.
The end of the operation is indicated by a callback function: either transmit / receive complete or error.
The callback functions are declared as weak functions in the driver, with no code to execute. This means that the user can declare the Tx / Rx callback again in the application and customize it to be informed in real-time about the process completion and to execute some application code.
Tricks:
- When STM32CubeMX is used to generate the project, the UART interrupt is not enabled by default.
- In any case, if the UART IRQ doesn't fire, please verify that it has been enabled. In the specific case of STM32CubeMX, verify that the checkmark is there in the NVIC settings to validate the interrupts as shown on the screenshot below.
4. DMA mode
- Transmit / Receive functions
- HAL_UART_Transmit_DMA() / HAL_UART_Receive_DMA()
- with parameters:
- Pointer to data buffer
- Amount of data elements to transmit / receive
- Interrupt Service Routines and Callback functions
- DMA_IRQHandler()
- HAL_DMA_IRQHandler()
- HAL_UART_TxHalfCpltCallback() / HAL_UART_RxHalfCpltCallback()
- HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
The principle is the same as in interrupt mode except that the DMA manages the data buffer transmission entirely. It continuously uses the data buffer to copy data to / from the USART data register until the DMA counter reaches 0.
When the DMA HT (half transfer) or TC (transfer complete) interrupt occurs, the UART half transfer callback or the transfer complete callback is called. Like in interrupt mode, the weak default callback executes no code. It can be declared and customized in the application.
Tricks:
5. How to stop an on-going transfer?
Stopping an on-going transfer is possible only in non-blocking modes, interrupt or DMA.
Either both transfers (TX and RX) are aborted or the transmit or receive channel can be selected.
- Basic Abort functions
- HAL_UART_Abort() / HAL_UART_AbortTransmit() / HAL_UART_AbortReceive()
If necessary, a callback can be called to execute some user application code.
- Abort functions with callbacks
- HAL_UART_Abort_IT() / HAL_UART_AbortTransmit_IT() / HAL_UART_AbortReceive_IT()
- Callback functions
- HAL_UART_AbortCpltCallback / HAL_UART_AbortTransmitCpltCallback / HAL_UART_AbortReceiveCpltCallback
Finally, specifically when a DMA is used, the transfer can be paused, resumed or stopped (aborted) using:
6. To go further:
- Examples are given for each of STM32 series in the STM32Cube MCU firmware package.
- e.g. C:\<user name>\STM32Cube\Repository\STM32Cube_FW_H7_V1.9.0\Projects\NUCLEO-H723ZG\Examples\UART
- User Manuals
- MOOCS
- FAQ