cancel
Showing results for 
Search instead for 
Did you mean: 

FAQ: STM32 HAL UART driver - API and Callbacks

Christophe VRIGNAUD
ST Employee

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)
    • An interrupt service routine (ISR) is executed for every received/transmitted character.
    • The application code is executed in a callback function called by the ISR.
  • 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.
 
81.png

 

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.
82.png

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.

84.png 

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.

85.png

Tricks:

  • In transmit direction, the DMA TC event is triggered when the last data has been written to the UART data register but not yet fully transmitted out of the UART (The TC event is triggered by the DMA).

    • In circular buffer mode, the HAL_UART_TxCpltCallback is called from the HAL_DMA_IRQHandler.

    • In normal buffer mode, the HAL_UART_TxCpltCallback is not called from the HAL_DMA_IRQHandler. Instead, the UART transmit complete (UART TC) interrupt is enabled.
      In this case, the HAL_UART_TxCpltCallback will be called from the HAL_UART_IRQHandler when the last data is fully transmitted.
       

                       86.png

  • When STM32CubeMX is used to generate the project, the  DMA interrupt is enabled by default.
  • When STM32CubeMX is used to generate the project, the  UART interrupt is not enabled by default. If HAL_UART_TxCpltCallback is used in normal buffer mode, the UART interrupt must be enabled.
  • In any case, if the DMA IRQ doesn't fire, please verify that it has been enabled. In the specific case of  STM32CubeMX, the checkmark should be there in the NVIC settings to validate the default behavior as shown on the screenshot below.
  • In any case, if the HAL_UART_TxCpltCallback is not called and normal buffer mode is used, please verify that the UART interrupt has been enabled and that the UART_IRQHandler has been implemented. In the specific case of  STM32CubeMX, the checkmark should be there in the NVIC settings to validate the UART interrupts as shown on the screenshot below.
87.png

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()

88.png


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

89.png


Finally, specifically when a DMA is used, the transfer can be paused, resumed or stopped (aborted) using:
 

  • HAL_UART_DMAPause() / HAL_UART_DMAResume() / HAL_UART_DMAStop()

6. To go further:

 

Comments
Ahmet Yasin CİVAN
Associate III

Thank you for sharing.

Version history
Last update:
‎2021-07-22 10:02 AM
Updated by: