cancel
Showing results for 
Search instead for 
Did you mean: 

UART Overrun Error (ORE) on STM32H563 Without Hardware Flow Control in Communication with Raspberry Pi

NavaneethanN
Associate II

I am working on UART communication between an STM32H563 and a Raspberry Pi CM4.

Currently, I am using UART without hardware flow control (RTS/CTS disabled). During continuous communication, I am frequently getting ORE (Overrun Error) on the STM32 side.

Configuration details:

  • MCU: STM32H563
  • Communication: UART
  • Flow control: Disabled
  • UART mode: Interrupt
  • Peer device: Raspberry Pi


I would like to know:

1. What is the best workaround to avoid ORE errors without enabling hardware flow control?
2. Is it reliable to use UART communication continuously without RTS/CTS?
3. What are the recommended UART settings or software handling methods for STM32H5 series?
4. How should ORE recovery be handled properly in STM32H563?

Currently, once ORE occurs, The data became lost.

3 REPLIES 3
Ozone
Principal III

> 1. What is the best workaround to avoid ORE errors without enabling hardware flow control?

I suppose you talk about Cube/HAL generated code here.
Go through your source code, and check what you do in interrupt context.
Mind you, all callback functions run in interrupt context, and block further Rx interrupts until they finish.

The best option is to reorganize the code, only copy received data to another buffer in the Rx interrupt, and process them in the main application / loop.

Second, there are "semantic" start/stop mechanisms for serial communication. Look up "Xon / Xoff".

And third, you can change the Raspberry code to go slower.

EThom.3
Senior III

I've been using UARTs for about a quarter of a century, much of the time using small 8-bit microcontrollers, running with a very moderate clock frequency. Mostly, I've used RS485, where hardware flow contrrol isn't an option. Even with relatively small 8-bit microcontrollers, a bit rate of 115200 hasn't been an issue. Your microcontroller is hellishly fast, compared to most of what I've used.

To answer your four questions:

1. Use either interrups (my primary choice) or DMA to receive data.

2. Absolutely, if you do it right. If you want to communicate over long distances, I'll recommend using RS422 or RS485, rather than RS232.

3. I haven't exactly used an ST32H5. But on the H7 I've used ordinary receive interrupts.

4. That I cannot answer. But in general, if you get an ORE flag, data will be lost.

Unless you run the serial interface at a ludicrous speed, the microcontroller should easily be done handling one byte, long before the next byte has been received. A few advices for you:

As @Ozone mentions, keep the receive interrupt code as short as possible. I general, I do only a few things in the interrupt:

A. Check if the incoming byte is a "start of transmission" byte (only if relevant in the protocol you are using)

B. Copy the received byte to a buffer. I typically use a global array for this.

C. If the received byte is an "end of transmission" byte (such as <CR> or <LF>), set a flag (boolean variable) to indicate to the main code that a full transmission is waiting in the buffer.

I always handle what has been received in the main code, so I don't spend loads of time in an interrupt. In case of duplex communication (i.e. not RS485), I may copy the receive buffer to a work buffer, so a new transmission can tick in while I handle the present one. Or I may use a ring buffer.

You also need to make sure that other code doesn't block your receive interrupt for a long time. ("A long time" here is the time it takes to fill the microcontroller's receive buffer / FIFO.)

Yes XON / XOFF flow control may be an option, if your connection permits it. But in my opinion, it is better to figure out why you are getting overrun errors in the first place. Suggestion: if you have an available output pin and an oscilloscope, connect the scope to that output pin and the UART receive pin. Then, in the receive interrupt, set the output pin high in the beginning of the interrupt, and low in the end. Using the oscilloscope, this can tell you how quickly the microcontroller responds to the received data, and how much time it spends in the interrupt. This may, in turn, help you figure out where your problem is.

In general, with a fast microcontroller, you shouldn't get overrun errors at all.

> Unless you run the serial interface at a ludicrous speed, the microcontroller should easily be done handling one byte, long before the next byte has been received. A few advices for you: ...

It's often hard to judge the level of experience of posters, like it is the case here.

But I have seen similiar threads with long evaluation routines implemented within interrupt callbacks, often even calling printf() functionality.
I suspect it might be the case here as well.

NavaneethanN, posting your implementation of the UART handler routines, especially the callbacks, would be helpful.
And communication parameters like baudrate, and specifics of the transmission (packet size, rate, idle times).