cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 LPUART INTERRUPT IS NOT WORKING

EmirhanOzkan
Associate

Hi,

I am developing on stm32l011 board and I am facing issue about UART interrupt.

 

static uint8_t rxBuffer[32] = { 0 };
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	/* Check if it is start command. */
	if(NULL != strstr((char*) rxBuffer, KEYPAD_START_COMMAND))
	{
		/* Increase received data count. */
		g_ReceivedDataCount++;
		/* Turn flag on. */
		g_devicePlugged = true;
	}
	/* Check if it is stop command. */
	else if(NULL != strstr((char*) rxBuffer, KEYPAD_STOP_COMMAND))
	{
		/* Turn flag off. */
		g_devicePlugged = false;
	}
	if(0 != rxBuffer[sizeof(rxBuffer) - 1])
	{
		memset(rxBuffer, 0, sizeof(rxBuffer));
	}
	/* Start UART RX again. */
    if (HAL_UART_Receive_IT(&hlpuart1, rxBuffer, sizeof(rxBuffer)) != HAL_OK)
    {
        /* Handle error if the UART receive does not start properly */
        Error_Handler();
    }
}

 

 

When I send data less than 32 byte, interrupt works sccesfully but after I send greater than 32 byte data, interrupt firing and never work again. I tried to abort rx data but it didn't work. I tried to use DMA but I have still same problem. How can I fix that?

 

Have a nice day.

3 REPLIES 3
nouirakh
ST Employee

Hello @EmirhanOzkan ,

Welcome to ST Community!


The issue you're facing is likely due to the way the UART interrupt and buffer handling are implemented. When you send more than 32 bytes, the buffer overflows, and the interrupt handling logic doesn't properly reset or handle the overflow condition.
To solve this you can Implement a circular buffer to handle incoming data more efficiently( The circular buffer allows continuous data reception without worrying about buffer overflow. When the buffer is full, the oldest data is discarded).
Another point, I can think of Interrupt Configuration could you please ensure that the UART interrupt is configured correctly to handle continuous data reception.

Could you please check the points I mentioned above?

Karl Yamashita
Lead III

Well you set it to interrupt on every 32 bytes. So if you get a packet that is maybe 40 bytes, you'll get an interrupt on the first 32 bytes. Then you'll receive the next 8 bytes of the 40. But you won't get an interrupt until you receive another 24 bytes. 

 

If you want to receive variable length packet then use idle interrupt.

You can use HAL_UARTEx_ReceiveToIdle_DMA or HAL_UARTEx_ReceiveToIdle_IT

And the callback to use is HAL_UARTEx_RxEventCallback.

 

See this project which explains more https://github.com/karlyamashita/Nucleo-G431RB_Three_UART

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

String functions expect a terminating NULL, if you're filling 32 bytes with data, the array needs to be 33 bytes. Your code looks semi-aware to this, but ultimately fails at it.

Have a functioning HardFault_Handler() that can report memory/pointer failure issues, and doesn't stop quietly in a while(1) loop

If the DMA is malfunctioning, check the status/error flagging in the DMA peripheral. Check the status/error flagging in the USART peripheral, and clear them.

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