cancel
Showing results for 
Search instead for 
Did you mean: 

usart DMA interrupt faster than buffer update

CTing.1
Associate II

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

0693W00000WLAjYQAX.pngsecond, data normal after delay

0693W00000WLAnXQAX.png 

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);

0 REPLIES 0