cancel
Showing results for 
Search instead for 
Did you mean: 

Over-run error on STM32L010RB USART2 using HAL

DPang.1
Associate II

Hi, under what circumstances does HAL_UART_ErrorCallback get called with the USART_ISR_ORE flag set in the ISR register?

We have a simple FreeRTOS project that is experiencing this error. It happens randomly, possibly after running for several minutes, or possibly several hours.

The project currently does nothing more than configure USART2 on two identical targets to echo a 64-byte block of data to each other repeatedly, initially using HAL_UART_Transmit_IT(&huart2, buf1, buf1size); on one of the targets, and then HAL_UART_Receive_IT(&huart2, buf2, buf2size); and HAL_UART_Transmit_IT(&huart2, buf2, buf2size); on both targets to echo back the received data. buf1size and buf2size are both 64. The USART2's are configured for quite slow communication - 9600 baud, 8 data bits, 1 stop bit, no parity, and no hardware flow control.

Interestingly, we can cause the over-run to occur, simply by running one of the targets in the STM32CubeIDE debugger, and toggling a breakpoint at a random line of code. The breakpoint does not actually get triggered, but the action of toggling it causes the over-run error, with huart2.RxXferCount somewhere in the middle of the 64-byte transfer.

Why does the overrun happen? Why especially with such a slow baud rate? Any help to understand this would be much appreciated. Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
DPang.1
Associate II

Thanks, everyone for your suggestions. The problem actually turned out to be the APB1 clock being configured too slow to support the UART.

View solution in original post

7 REPLIES 7
TDK
Guru

> Hi, under what circumstances does HAL_UART_ErrorCallback get called with the USART_ISR_ORE flag set in the ISR register?

From the reference manual:

Bit 3 ORE: Overrun error This bit is set by hardware when the data currently being received in the shift register is ready to be transferred into the RDR register while RXNE=1. It is cleared by a software, writing 1 to the ORECF, in the USART_ICR register.

This can happen if HAL_UART_Receive_IT receives all the data it's looking for and then it receives 2 more bytes. You can receive data via DMA into a circular buffer to avoid this. Or handle incoming data faster such that the device is only in a non-receiving state for less time than it takes to transfer 1 byte.

It could also happen because the USART ISR takes too long to act upon a byte being received, either because a higher priority interrupt is active or interrupts are disabled.

If you feel a post has answered your question, please click "Accept as Solution".
KnarfB
Principal III

How is FreeRTOS involved? What is called in what task? Are there more than one tasks running? Are you using a dedicated timer for FreeRTOS tick? Interrupt priorities?

Thanks, TDK. It doesn't seem like it could be the first case, since the over-run can happen at any point during the transfer, close to the beginning, middle or end. Regarding the second case, we're just leaving it to the HAL to populate our buffer with the received data, but we'll have a closer look for anything that could interfere.

>>Why does the overrun happen? 

You're not servicing the UART quickly enough, or otherwise dilly-dallying in the IRQ Handler or respective callback on unrelated work or tasks. This may be especially true if the data is handed to a higher priority task, or the parsing of the data takes more than one byte time or stalls/blocks.

If the IRQ/callback do not exit promptly it will block the interrupt until it does leave.

If you fail to start a new HAL_UART_Receive_IT() as you leave you may also miss the boat.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I agree. Are you disabling interrupts anywhere? Are all of your interrupts quick to complete? I'd guess the issue is one of those.

If you feel a post has answered your question, please click "Accept as Solution".

Only the defaultTask is running. It makes the initial HAL_UART_Transmit_IT and HAL_UART_Receive_IT calls. In its infinite loop, it calls HAL_UART_Transmit_IT to echo the data after detecting a flag has been set. HAL_UART_RxCpltCallback sets this flag, and calls HAL_UART_Receive_IT to receive the next echo. TIM22 is being used for the HAL 1ms tick. Could that be the cause? No other interrupts are being triggered in stm32l0xx.c.

DPang.1
Associate II

Thanks, everyone for your suggestions. The problem actually turned out to be the APB1 clock being configured too slow to support the UART.