cancel
Showing results for 
Search instead for 
Did you mean: 

Unexpected IDLE Interrupt with Full Buffer Size Before Any UART Data Received on STM32L433 (HAL_UARTEx_ReceiveToIdle_DMA)

Abhimanyu
Associate

Hello ST Community,

I’d like to report an issue  observed with HAL_UARTEx_ReceiveToIdle_DMA() on STM32L433RCT6P using STM32CubeIDE v1.17.0 and the latest STM32CubeMX code generator (L4 series).

Setup:

  • Board: NUCLEO-L433RC-P

  • IDE: STM32CubeIDE 1.17.0

  • HAL version: STM32CubeL4 latest

  • UART: USART2

  • DMA Mode: Circular

  • Baudrate: 115200

  • Buffer size: 128 or 256

  • Code: Generated with CubeMX

What we do:

  1. Call MX_USART2_UART_Init()

  2. Immediately call HAL_UARTEx_ReceiveToIdle_DMA() without delay

  3. Do not send any UART data to the board

  4. Wait...

What we expect:

  • The callback HAL_UARTEx_RxEventCallback() should not trigger until at least one byte has been received, followed by line idle.

What actually happens:

  • Immediately after startup, without any incoming UART data:

    • The callback fires once

    • Size == RX_BUFFER_SIZE (e.g., 128 or 256)

Additional Observations:

  • The issue doesn't occur at very low system clock frequencies

    • On STM32L4 series: it triggers when running on HSI (16 MHz)

    • When using MSI @ 4 MHz, the issue does not occur

    • On STM32U5 series (e.g., STM32U595), the threshold frequency differs but the pattern is the same

Why this matters:

As part of building high-quality embedded platforms, we aim to avoid:

  • Arbitrary HAL_Delay() or for(__NOP()) hacks

  • Fragile time-based fixes that behave differently across platforms or temperature/voltage conditions

We need a deterministic solution to prevent this false RX interrupt on startup.

Reproduction Snippet: (A simple example code snippet)

#define RX_BUFFER_SIZE 128
uint8_t aRXBufferUser[RX_BUFFER_SIZE];

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();

HAL_UARTEx_ReceiveToIdle_DMA(&huart2, aRXBufferUser, RX_BUFFER_SIZE);

while (1) {}
}


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
//echo back the received size
 uint8_t low = Size & 0xFF;
 while (!(__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE))) {}
 huart->Instance->TDR = low;
}

 

My Questions to ST:

  1. Why does HAL_UARTEx_RxEventCallback() trigger immediately with Size == buffer_size, even though no data was received?

  2. Is there a documented correct sequence or flag to wait for before calling HAL_UARTEx_ReceiveToIdle_DMA()?
  3. What is the correct way to prevent this spurious interrupt from happening without using arbitrary HAL_Delay()?

Attached Video Evidence:

I’ve attached a short video demonstrating the issue:

When using MSI @ 4 MHz, no interrupt is triggered → expected behavior

When switching to HSI @ 16 MHz, the interrupt fires immediately after HAL_UARTEx_ReceiveToIdle_DMA()→ even though no data is received

The video shows a breakpoint inside HAL_UARTEx_RxEventCallback() and proves the size equals the buffer length, with no bytes transferred by DMA.

0 REPLIES 0