cancel
Showing results for 
Search instead for 
Did you mean: 

STM32cube's HAL_UART_Receive_DMA() not enabling IRQ to detect overrun or other UART errors, bug?

zygron
Associate
Posted on December 18, 2014 at 17:00

When debugging some code that uses DMA to receive data from an uart i noticed that if for some reason an overrun error happen, it's not taken into account, and that prevents the DMA transfer complete interrupt to ever occur.

The problem shows up if i hit a breakpoint in my program after a DMA receive has been issued. When execution is frozen *if data are sent by the remote side* an overrun error is signaled in the UART register. I figure that is to be expected, but when looking at HAL_UART_Receive_DMA() (in stm32F4xx_hal_uart.c) it turns out the UART error interrupt is never enabled, so there's no code to clear the error flag and call the XferErrorCallback...

Basically, during DMA transfer with HAL_UART_Receive_DMA(), if something goes wrong on the UART that's unrelated to DMA (noise / framing error / overrun), there's no way to know... and all communication stops working.

This looks like a bug to me (or well, something that's been overlooked), but maybe i'm missing something?

#uart-dma-overrun
3 REPLIES 3
Posted on January 12, 2015 at 16:30

Hi,

This is a normal behavior,  you should avoid to set breakpoint in your code.  In addition,  The PPP error interrupts are not supported by HAL PPP_DMA_Process().

Regards,

Heisenberg.

vrouesnel
Associate II
Posted on March 02, 2015 at 13:55

I am having the same issue. `USART1_SR -> ORE` bit is set when `HAL_UART_Receive_DMA` is called.

huart->State = HAL_UART_STATE_BUSY_RX, but is never reset because of the overrun error.

I receive the same overrun error in IT mode, which calls the error callback.

Surely this is a bug?

henry2
Associate II
Posted on January 20, 2016 at 22:15

I had the same issue.  The HAL was stuck in the state

HAL_UART_STATE_BUSY_RX 

with no indication of error.  The problem turned out to be overrun (not an overrun resulting from a breakpoint, by the way).  

To improve the HAL, the overrun condition could be detected in HAL_UART_Receive_DMA() and returned in the status.  

The bit can also be tested and cleared before the Receive call using 

__HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_OREF)

To ignore overruns, I tried initializing with the overrun disable advanced feature 

  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;

That feature its own bug in the HAL. The bug is in stm32f3xx_hal_uart.c  v1.2.0 line 1691.  

The incorrect line is    

MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);

The corrected line is 

MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, UART_ADVFEATURE_OVERRUN_DISABLE);