Skip to main content
Associate III
October 8, 2023
Question

RTOF: Receiver timeout - UART

  • October 8, 2023
  • 10 replies
  • 5323 views

Hi,

HAL Version used - 1.10.0

I am using RTO interrupt to identify if the transmitter has finished sending a packet. 

In the IRQ handler "void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)", this is considered as an error and it is aborting the ongoing DMA transfer from the UART peripheral to the memory. This is causing issues on our side.

 

Luke_abc_1-1696761236413.png

The same is also posted here.

https://community.st.com/t5/stm32-mcus-embedded-software/is-implementation-of-rtof-support-botched-in-hal/m-p/166118

Why is this implemented it in this way ? Are we not supposed to use RTOF to identify if the transmitter has finished transmitting the packet ?

 

 

This topic has been closed for replies.

10 replies

Pavel A.
October 8, 2023

> Are we not supposed to use RTOF to identify if the transmitter has finished transmitting the packet ?

In the error callback you can check huart.ErrorCode & HAL_UART_ERROR_RTO to find the error reason.

Why is this implemented it in this way ?

Short answer - because the RTO event signals end of packet, therefore end of transfer. You can then restart RX, possibly into a new buffer.

Even shorter answer... the UART "HAL" driver is not considered production quality - at least by some people on this forum. OK for a quick test of the hardware.

 

Luke_abcAuthor
Associate III
October 8, 2023

Thank you @Pavel A. for your prompt reply. My concern is that the handler "HAL_UART_IRQHandler" is aborting the ongoing DMA transfer (HAL_DMA_ABORT_IT()) and I am loosing the data. I have configured DMA for my UART. Is there any workaround for this ? 

 

 

Pavel A.
October 8, 2023

Make your own driver, or decrease the RTO timeout, or react faster to the RTO event to minimize the window from the timeout to the next RX byte.

TDK
October 8, 2023

You can use IDLE to detect the end of transmission instead.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Karl Yamashita
Principal
October 9, 2023

Use HAL_UARTEx_ReceiveToIdle_DMA and HAL_UARTEx_RxEventCallback 

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Luke_abcAuthor
Associate III
October 9, 2023

Thank you @Karl Yamashita  and @TDK  for your suggestions.

I do receive variable amount of data on my UART. Let's say, I get an IDLE interrupt after I sent 100 kB of data from my PC. Does this IDLE interrupt mean that the data has already been copied to the DMA buffer ? In the IDLE interrupt handler, how can I verify that the entire data is copied into the DMA buffer. Please note that the RX data size is variable.

Karl Yamashita
Principal
October 9, 2023

@Luke_abc Is that 100KB of data that is streamed at one time? Or is it multiples of packets that add up to 100KB of data? In the data, is there something that indicates the total data size? Is there a checksum? Each type of received data may require a different approach of saving data so knowing a little more about your data helps. 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Luke_abcAuthor
Associate III
October 10, 2023

Thank you @Karl Yamashita  for you reply. Data is streamed all at one time.

That data size will not be more than 64 KB.

Can I use the idle interrupt to confirm all the data (let's say 64 KB) is copied to the dma buffer ?

TDK
October 9, 2023

Data gets shifted to the DMA buffer continuously as it comes in, byte by byte. When the IDLE interrupt, or RX half- or full-complete interrupts happen, the data is already in there.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Piranha
Principal III
October 11, 2023

UART is a stream based interface, not message based. It just sends a stream of bytes. There is no concept of beginning and end of a message. The only thing UART guarantees is the order of bytes. It doesn't guarantee delivery, correctness and generally also the pauses between bytes. Though, if both ends are under your control, then you can force the pauses to be meaningful for message delimiting or something else. Therefore messages, checksums etc. have to be implemented as a higher level protocols and processing layers in software.

And the HAL is a broken bloatware. Use a decent code instead:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx