Associate
November 13, 2020
Solved
usart.c
- November 13, 2020
- 3 replies
- 1426 views
I want to use the DMA for receiving data over USART. I have configured the DMA as a circular Buffer. To detect the end of the USART package I use the receiver time out.
My Problem is, that when the receiver time out interrupt is triggered, not all Bytes are copied from the USART to the DMA Buffer. A few random Bytes remain the same as before. I know, that the DMA still increment the address, because I send an image and the rest of the image is not shifted.
Does anybody know what problem this could be?
I use a STM32f MCU and I have generated the basic DMA and USART configuration with the CubeMX software.
My interrupt handler
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* check for receive timeout interrupt */
if( huart3.Instance->ISR & USART_ISR_RTOF ) {
/* clear interrupt */
__HAL_UART_CLEAR_FLAG(&huart3, USART_ICR_RTOCF);
ToF_Rx_Timeout_Callback( );
}
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
}/* UART rx callback */
void ToF_Rx_Timeout_Callback( void ) {
static size_t old_pos;
size_t pos;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Initialised to pdFALSE. */
pos = sizeof(ucDmaRxBuffer) - huart3.hdmarx->Instance->NDTR;
if(pos != old_pos)
{
if(pos > old_pos)
{
uint16_t xBytesSent = xMessageBufferSendFromISR( xRxMessageBuffer,(void*) &ucDmaRxBuffer[old_pos], pos-old_pos, &xHigherPriorityTaskWoken );
}
else
{
memcpy(&ucMsgRxTemp[0],&ucDmaRxBuffer[old_pos],sizeof(ucDmaRxBuffer)-old_pos);
memcpy(&ucMsgRxTemp[sizeof(ucDmaRxBuffer)-old_pos],&ucDmaRxBuffer[0],pos);
uint16_t xBytesSent = xMessageBufferSendFromISR( xRxMessageBuffer,(void*) ucMsgRxTemp, pos+sizeof(ucDmaRxBuffer)-old_pos, &xHigherPriorityTaskWoken );
}
}
old_pos = pos;
if(old_pos == sizeof(ucDmaRxBuffer))
{
old_pos = 0;
}
/* switch context if higher priority task is waiting on data */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}Attached is the USART initialization.
