2024-07-09 04:02 AM
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.
2024-07-09 06:32 AM
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?
2024-07-09 12:17 PM
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
2024-07-09 12:55 PM
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.