2026-04-14 8:22 AM
Hi everyone,
I am working on an STM32MP2 platform and facing a persistent issue with LPUART1 in interrupt mode.
When using interrupt mode, the system gets stuck in:
NVIC enabled correctly:
FIFO configuration added:
2026-04-29 12:44 AM
Hello @rutiklunagariya6 ,
If the OverRun Error flag sets but the receive data register is empty (RXNE = 0), HAL_UART_IRQHandler() does not clear ORE and exits immediately.
Since ORE remains set, the interrupt fires again instantly, creating an infinite loop.
Fix: In your LPUART1_IRQHandler, clear error flags before calling HAL_UART_IRQHandler():
void LPUART1_IRQHandler(void)
{
uint32_t isrflags = READ_REG(hlpuart1.Instance->ISR);
/* Clear overrun error if set but no data pending */
if ((isrflags & USART_ISR_ORE) && !(isrflags & USART_ISR_RXNE))
{
__HAL_UART_CLEAR_OREFLAG(&hlpuart1); // Clears ORE via USART_ICR_ORECF
}
HAL_UART_IRQHandler(&hlpuart1);
}Also verify your HAL_UART_ErrorCallback() is implemented. If an overrun or framing error occurs and you have no error callback, HAL may leave the peripheral in a stuck state.
LPUART1 on STM32MP2 does not use the same clock tree as standard UARTs. If the peripheral clock is misconfigured or too slow for 115200 baud, timing violations can cause spurious flags.
Fix: In HAL_UART_MspInit(), explicitly configure the LPUART1 kernel clock:
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
PeriphClkInit.XBAR_Channel = RCC_PERIPHCLK_LPUART1;
PeriphClkInit.XBAR_ClkSrc = RCC_LPUART1CLKSRC_HSI;
PeriphClkInit.Div = 0x01;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { while(1);
}Verify the actual LPUART1 kernel clock frequency in your clock config. An incorrect baud rate divider can cause framing errors that trigger continuous interrupts.
With MAX485, if the DE/RE pin is left HIGH after transmission, the transceiver stays in transmit mode and cannot receive. More subtly, if you toggle DE/RE immediately after HAL_UART_Transmit(), the last byte may not have fully shifted out, causing bus contention or an echo that triggers RX interrupts.
You mentioned disabling FIFO mode, but on STM32MP2 the UART peripheral has a 16-byte FIFO that behaves differently from non-FIFO UARTs. If FIFO threshold interrupts are not handled correctly, they can cause repeated triggering.
Fix: Since you're using HAL_UARTEx_ReceiveToIdle_IT(), you should fully disable FIFO or configure it consistently. Your current approach is valid, but verify:
/* Explicitly disable FIFO before starting reception */
HAL_UARTEx_DisableFifoMode(&hlpuart1);
/* Then start the IT-based reception */
HAL_UARTEx_ReceiveToIdle_IT(&hlpuart1, RxBuf, RX_BUF_SIZE);If you ever enable FIFO, you must use HAL_UARTEx_SetRxFifoThreshold() and handle the RXFF (RX FIFO Full) interrupt, or HAL may miss data and trigger error paths.
HAL_UARTEx_ReceiveToIdle_IT() disables the RX interrupt after each idle event or when the buffer fills. You must re-arm it in the callback, or the next incoming byte may cause an unexpected interrupt state
Check the ISR register: In the debugger, read LPUART1->ISR when stuck. If ORE or FE (Framing Error) is set, that confirms the root cause.
Check hlpuart1.gState and RxState: If RxState is stuck in HAL_UART_STATE_BUSY_RX but no reception is active, the HAL state machine is desynchronized.
Verify LPUART1 clock: Check RCC->LPUART1CKSELR or use HAL_RCCEx_GetPeriphCLKFreq() to confirm the kernel clock.
Scope the A/B lines: Verify the MAX485 is actually releasing the bus (DE/RE goes LOW) and that your sensor's response is clean.
Best Regards,
Zakaria