2022-12-16 01:41 AM
Hi All,
I use DMA IDLE Idle line and circular mode to receive usart buffer, and process data in rtos,
but when I get an Idle event, sometimes RTOS read buffer will get some empty data, but wait a little bit times, the buffer will be updated, so when I read empty, I delay 500ms and read again in the task, the buffer can read data normally, have anybody know what problem is? any help will be very useful.
thanks.
first, read get \0 23 times
second, data normal after delay
refer
https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
HAL_UARTEx_ReceiveToIdle_DMA(&huart6, (uint8_t*) u6_RxBuffer, BufferSize);
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
if (huart->Instance == USART6) {
MaxWifiSize = Size; // if Size updated, the @task will be read
}
}
rtos task
void usart_protocol(void) {
static uint16_t old_pos = 0;
uint16_t i;
/* Check if number of received data in recpetion buffer has changed */
if (MaxWifiSize != old_pos) {
/* Check if position of index in reception buffer has simply be increased
of if end of buffer has been reached */
if (MaxWifiSize > old_pos) {
/* Current position is higher than previous one */
uwNbReceivedChars = MaxWifiSize - old_pos;
/* Copy received data in "User" buffer for evacuation */
for (i = 0; i < uwNbReceivedChars; i++) {
pBufferReadyForUser[i] = u6_RxBuffer[old_pos + i];
}
if (u6_RxBuffer[old_pos] == 0 && u6_RxBuffer[old_pos + 1] == 0) {
isData0 += 1;
osDelay(500);
for (i = 0; i < uwNbReceivedChars; i++) {
pBufferReadyForUser[i] = u6_RxBuffer[old_pos + i];
}
}
old_pos = MaxWifiSize;
} else {
/* Current position is lower than previous one : end of buffer has been reached */
/* First copy data from current position till end of buffer */
uwNbReceivedChars = ATWSBufferSize - old_pos;
/* Copy received data in "User" buffer for evacuation */
for (i = 0; i < uwNbReceivedChars; i++) {
pBufferReadyForUser[i] = u6_RxBuffer[old_pos + i];
}
if (u6_RxBuffer[old_pos] == 0 && u6_RxBuffer[old_pos + 1] == 0) {
isData0 += 1;
osDelay(500);
for (i = 0; i < uwNbReceivedChars; i++) {
pBufferReadyForUser[i] = u6_RxBuffer[old_pos + i];
}
}
if (MaxWifiSize > 0) {
for (i = 0; i < MaxWifiSize; i++) {
pBufferReadyForUser[uwNbReceivedChars + i] = u6_RxBuffer[i];
}
if (u6_RxBuffer[old_pos] == 0 && u6_RxBuffer[old_pos + 1] == 0) {
isData0 += 1;
osDelay(500);
for (i = 0; i < MaxWifiSize; i++) {
pBufferReadyForUser[uwNbReceivedChars + i] =
u6_RxBuffer[i];
}
}
uwNbReceivedChars += MaxWifiSize;
}
old_pos = MaxWifiSize;
}
chyold_pos = old_pos;
}
}
here is my configuration
void MX_USART6_UART_Init(void)
{
/* USER CODE BEGIN USART6_Init 0 */
/* USER CODE END USART6_Init 0 */
/* USER CODE BEGIN USART6_Init 1 */
/* USER CODE END USART6_Init 1 */
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
huart6.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart6.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart6.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart6, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart6, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart6) != HAL_OK)
{
Error_Handler();
}
}
hdma_usart6_rx.Instance = DMA1_Stream2;
hdma_usart6_rx.Init.Request = DMA_REQUEST_USART6_RX;
hdma_usart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart6_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart6_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart6_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart6_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart6_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart6_rx);
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);