cancel
Showing results for 
Search instead for 
Did you mean: 

HAL-Driver UART-receiving via interrupt issue: RXNE-flag is cleared too soon.

Marco Trick
Associate
Posted on May 24, 2018 at 09:32

Hello ST Community,

I'm trying to get started with the HAL-Library using CubeMX on an STM32F4-Discovery board. I'm using the UART interface USART2 and try to receive data via interrupts. The interrupts are fired as usual (so i think my configuration works).

But when the HAL-Driver calls HAL_UART_IRQHandler(&huart2) in stm32f4xx_it.c, the RXNE-flag is cleared, and the processing of the flag inside HAL_UART_IRQHandler(&huart) fails. I know, that the RXNE flag is cleared by hardware, when the SR-register is read. But in my case, the RXNE-flag is cleared right at the moment of the function-call.

As a result, the function UART_Receive_IT() is never called; same with the callback-function. Has anyone any idea what I am doing wrong? Or is there a bug in the HAL-library?

I've tried to use the example of the library for UART on an STM32F4-Discovery, but there is the same problem.

Thank you very much in advance!

#stm32f4-stm32f4-discovery-hal_uart-stm32f4xx_it.c
2 REPLIES 2
T J
Lead
Posted on May 24, 2018 at 10:38

Many aspects of HAL work very well and some do not.

The Uart DMA interaction is flawless.

if you need an interrupt for every byte, then set the DMA circular buffer to size 2 bytes, you will get the two callbacks half Full and Full.

then only enable the Rx interrupt at startup.

if you don't need an interrupt for every byte, then using the DMA buffer size of 1K makes for flawless reception.

I use a foreground process to peek into the DMA buffer, returning length and processing within a state machine as required.

            U1RxBufferPtrIN =  U1RxBufSize - huart1.hdmarx->Instance->CNDTR;

            return U1RxBufferPtrIN - U1RxBufferPtrOUT;

            char readByte = Usart1RxDMABuffer[U1RxBufferPtrOUT++];

void initUart1RxDMABuffer(void) {

    if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)

    {

        // Transfer error in reception process

        //_Error_Handler(__FILE__, __LINE__);

        printf('initUart1RxDMABuffer Failed\n');

    }

    else

        printf('initUart1RxDMABuffer OK!\n');

}
Posted on May 24, 2018 at 23:50

Thank you very much for your help! While implementing your solution (which seems to be even better than the approach I tried to implement), I found out that I misunderstood, how the HAL Drivers are working. It seems to be alright that the flag is cleared, when the handler is called, assuming everything is configured in the right way.

Now both approaches work in my setup.