Problem with UART Idle Line DMA Reception on STM32H563 Microcontroller
I'm working on a project using the STM32H563RIT6 microcontroller where I need to receive data over UART using DMA with idle line detection. The data is sent from a Python script using 'pyserial'. My setup is as follows:
typedef enum{
IDLE,
SET_FREQUENCY,
SPI_WRITE,
SPI_READ,
SPAM,
TEST_CONN
} UserCommand_t;
typedef struct{
UserCommand_t Command;
uint8_t RegAddr;
uint16_t WriteData;
uint32_t BufferCRC;
} ConfigMsg_t;
#define CRC_SIZE 4U
ConfigMsg_t UART_Rx_MsgBuffer = {0};
ConfigMsg_t ConfigMsg = {0};
uint32_t CRCValue = 0;
uint8_t RxSampleBuffer[20] = {0};
int CallCount = 0;
int SizeBytes = 0;
int CRCFailCount = 0;
int main() {
// Initialization and loop code
printf("RxCount - %u: \t ", RxCount);
for(int i = 0; i<sizeof(RxSampleBuffer); i++){
RxSampleBuffer[i] = 255;
printf("%u \t", RxSampleBuffer[i]);
}
printf("\n");
HAL_UARTEx_ReceiveToIdle_DMA(&huart4, (uint8_t*)&UART_Rx_MsgBuffer, sizeof(ConfigMsg_t));
while(1){
}
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
RxCount++;
SizeBytes = Size;
CRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t*)&UART_Rx_MsgBuffer, sizeof(ConfigMsg_t) - CRC_SIZE);
memcpy(&RxSampleBuffer, &UART_Rx_MsgBuffer, sizeof(ConfigMsg_t));
if(UART_Rx_MsgBuffer.BufferCRC == CRCValue){
memcpy(&ConfigMsg, &UART_Rx_MsgBuffer, sizeof(ConfigMsg_t));
}
else{
CRCFailCount++;
}
printf("RxCount - %u: \t ", RxCount);
for(int i = 0; i<sizeof(RxSampleBuffer); i++){
printf("%u \t", RxSampleBuffer[i]);
RxSampleBuffer[i] = 255;
}
printf("\n");
memset(&UART_Rx_MsgBuffer, '\0', sizeof(ConfigMsg_t));
HAL_UARTEx_ReceiveToIdle_DMA(&huart4, (uint8_t*)&RxSampleBuffer, sizeof(ConfigMsg_t));
}
When I transmit {5, 3, 0, 3, 50, 63, 42, 114} from 'pyserial', I get the following output:
RxCount - 0: 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
RxCount - 1: 5 3 0 3 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255
RxCount - 2: 0 0 0 0 0 0 42 114 255 255 255 255 255 255 255 255 255 255 255 255
The image below shows the Live Expressions window:

I'm experiencing an issue where the UART reception seems to split the incoming data into multiple callbacks, even though the data is being sent in a single transmission. Specifically:
- When I use HAL_UARTEx_ReceiveToIdle_DMA(&huart4, (uint8_t*)&UART_Rx_MsgBuffer, sizeof(UART_Rx_MsgBuffer));, the data appears fragmented, and I observe unexpected zeros in the received buffer.
- When I increase the size of the receive buffer to (sizeof(UART_Rx_MsgBuffer) + 9), the problem seems to resolve, and the data is received correctly in one callback. However, it only works for the the first reception and doesn't work afterwards.
My questions are:
- Why is the data being split across multiple callbacks (RxCount = 2) when using the smaller buffer size?
- What is causing the extra zeros to appear in the received data?
- Why does increasing the buffer size seem to fix the issue, and how can I ensure reliable reception without relying on an oversized buffer?
- Shouldn't an early idle line trigger result in the received data being split differently, with no extra zeros?
Any insights or suggestions on how to properly configure the UART to avoid this issue would be greatly appreciated!
Thank You!
