UART+DMA sends data disordered or resends it. Is it a variable type problem?
Hello!
I'm working this UART+DMA with idle detection and ring buffer. My STM32F4707VET6 receives data from a sensor and then sends it by USB, the data received by USB should look like this:
$1651500,-5,-228,-988,-3,-217,-976,-102
$1651510,-4,-228,-987,-3,-216,-975,-105
$1651520,-6,-229,-988,-5,-217,-976,-114
$1651530,-5,-229,-987,-4,-217,-975,-110
$1651540,-6,-227,-987,-5,-215,-975,-129
$1651550,-6,-229,-988,-4,-218,-976,-119
But I receive this:
$1651500,-5,-228,-988,-3,-217,-976,-102
$1651510,-4,-228,-987,-3,-216,-975,-105
$1651520,-6,-229,-988,-5,-217,-976,-114
-987,-3,-216,-975,-105
$1651520,-6,-229,-988,-5,-217,-976,-114
$1651530,-5,-229,-987,-4,-217,-975,-110
$1651510,-4,-228,-987,-3,-216,-975,-105
$1651520,-6,-229,-988,-5,-217,-976,-114
I truncated the data because every sample is around 250-300 characters(variable), 50 samples every second at 115200 baudrate. And I checked that the sensor sends its data properly.
I wonder what may be causing this problem. I think maybe is some type of data I'm using on my code but I can't find it.
This is my ring buffer or callback snippet. I post this code because this is how my STM32 receives(possible the problem is here) and sends data:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
// Timer and RX indicator LEDs
__HAL_TIM_SetCounter(&htim2, 0); // Reset Timer2
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); // Turn on LED 2 - UART Rx LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); // Turn off LED 3 - Timer LED
if(huart->Instance == USART1){ // In USART 1
static uint8_t old_pos1 = 0;
uint8_t *ptemp1;
uint32_t i;
// Ring buffer management
if (Size != old_pos1){ // If buffer changed
if (Size > old_pos1){
ReceivedChars1 = Size - old_pos1;
for (i = 0; i < ReceivedChars1; i++){
pBufferReadyForUser1[i] = RXBufferUser1[old_pos1 + i];
}
}else{ // Buffer overflows
ReceivedChars1 = RX_BUFFER_SIZE - old_pos1;
for (i = 0; i < ReceivedChars1; i++){
pBufferReadyForUser1[i] = RXBufferUser1[old_pos1 + i];
}
if (Size > 0){
for (i = 0; i < Size; i++){
pBufferReadyForUser1[ReceivedChars1 + i] = RXBufferUser1[i];
}
ReceivedChars1 += Size;
}
}
// User data process and buffer & pointers update
UserDataTreatment(huart, pBufferReadyForUser1, ReceivedChars1);
ptemp1 = pBufferReadyForUser1;
pBufferReadyForUser1 = pBufferReadyForReception1;
pBufferReadyForReception1 = ptemp1;
}
// Buffer position(pointer) update
old_pos1 = Size;
}
// Turn off Rx indicator LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); // Turn off LED 2 - UART Rx LED
}And my user data treatment function, once the data is received it sends by USB:
void UserDataTreatment(UART_HandleTypeDef *huart, uint8_t* pData, uint16_t Size){
if(huart->Instance == USART1){ // If USART1
__HAL_TIM_SetCounter(&htim2, 0); // Reset Timer2
CDC_Transmit_FS(pData, Size); // Send USB data
}
}I'm using the example from: https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32446E-Nucleo/Examples/UART/UART_ReceptionToIdle_CircularDMA
I also added some features like activity LEDs and a timer to send a special message if no UART messages are received in a few seconds, but I think they are not relevant in the problem. Anyways, tell me to upload them If you think you need them.
Thank you!