cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 USART6 DMA not receiving data

LPetr.1
Senior

I have configured 2 UARTS both are configured to using HAL_UARTEx_ReceiveToIdle_DMA.

My init functions:

HAL_UARTEx_ReceiveToIdle_DMA(&huart3,aRxBuffer, RXBUFFERSIZE);
 
 __HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
 
 
 
 
 
 HAL_UARTEx_ReceiveToIdle_DMA(&huart6,aRxBuffer6, RXBUFFERSIZE);
 
 __HAL_DMA_DISABLE_IT(&hdma_usart6_rx,DMA_IT_HT);

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
 
{
 
	if(huart->Instance == USART3)
 
	{
 
 memset(aMainBuffer, 0, sizeof(aMainBuffer));
 
 memcpy(aMainBuffer,aRxBuffer,Size);
 
 Command_parser(aMainBuffer,Size);
 
 HAL_UARTEx_ReceiveToIdle_DMA(&huart3, aRxBuffer, RXBUFFERSIZE);
 
 __HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
 
	}
 
 
 
	if(huart->Instance == USART6)
 
	{
 
 memset(aMainBuffer6, 0, sizeof(aMainBuffer6));
 
 memcpy(aMainBuffer6,aRxBuffer6,Size);
 
 Command_parser_uart6(aMainBuffer6,Size);
 
 HAL_UARTEx_ReceiveToIdle_DMA(&huart6, aRxBuffer6, RXBUFFERSIZE);
 
 __HAL_DMA_DISABLE_IT(&hdma_usart6_rx,DMA_IT_HT);
 
	}
 
 
}

0693W00000NpHt7QAF.png 

I am sending some data from amother device via the USART6. I have even connected the logic analyzer and I can see the data go through, but for some reason the dma interrupt does not fire for usart6. Can someone help me understand what is happening and what is the best way to debug this?

UPDATE

I have tested it with UART receive polling method in while loop and it works without any issues. All I did was disable UART RX DMA and did the following in main while loop:

  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
 
	  if(HAL_UART_Receive(&huart6, testReceiveData, 5, 1000) == HAL_OK)
	  	  {
		  for(int i = 0 ;i<5;i++){
			  printf("received data[%i] =%u\n",i,testReceiveData[i]);
		  }
 
	   }
 
 
  }

And I can see the data that I am sending without any issues:

received data[0] =112
 
received data[1] =111
 
received data[2] =110
 
received data[3] =103
 
received data[4] =10

So that proves that my other device is sending data and the problem is most likely with the DMA.

13 REPLIES 13
LPetr.1
Senior

UPDATE

I have found out why this framing error happens. The USART6 lines are connected to another microcontroller UART( ESP32 ) . Another device starts up after STM32 is already started and initialised. When my another device starts up, it is initializing its own USART which causes the USART state to change during the initialisation hence the error occurs. When this error happens, the USART stops working.

I have made an experiment where I power both device at the same time using 1 power supply for both devices and the communication works as expected!

Can someone suggest me a way to clear this flag because for my application, my device that is sending the commands to the STM32 will always power up later than the STM32 itself. When my ESP32 device initialises it will cause this error to happen but I need a way to clear it so the USART still works.

I have found a way how to detect if this error is set:

void USART6_IRQHandler(void)
{
  /* USER CODE BEGIN USART6_IRQn 0 */
	if(huart6.Instance->SR & USART_SR_FE ){
		printf("frame error is set \n");
	}
 
  /* USER CODE END USART6_IRQn 0 */
  HAL_UART_IRQHandler(&huart6);
  /* USER CODE BEGIN USART6_IRQn 1 */
 
  /* USER CODE END USART6_IRQn 1 */
}

But I cannot find any documentation or information on how this error can be cleared. I have looked at various STM32 documentations but I was not able to find one where UART is documented in detail

0693W00000NpKb6QAF.pngMaybe Cube handles it already.

But FE won't prevent SPI from working, overrun will.

Read out and check/post UART and relevant DMA registers content.

JW

I have tried as suggested by this documentation:

void USART6_IRQHandler(void)
{
  /* USER CODE BEGIN USART6_IRQn 0 */
 
	if(READ_REG(huart6.Instance->SR) & USART_SR_FE ){
		printf("frame error is set \n");
		READ_REG(huart6.Instance->DR);
	}
  /* USER CODE END USART6_IRQn 0 */
  HAL_UART_IRQHandler(&huart6);
 
  /* USER CODE BEGIN USART6_IRQn 1 */
 
  /* USER CODE END USART6_IRQn 1 */
}

After doing this. I cannot believe but the communication now works without any issues. When my ESP32 microcontroller starts, it causes the STM32 USART to go into the Frame error state but I read the SR and DR registers and it clears itself. After that, I can communicate between 2 devices without any issues!

Guenael Cadier
ST Employee

If the FE flag just occurs once, due to other initialisations impacting RX line, you could also try to call the macro for resetting FE flag, just prior starting your reception (i.e. prior calling HAL_UARTEx_ReceiveToIdle_DMA(&huart6,aRxBuffer6, RXBUFFERSIZE);

=> See __HAL_UART_CLEAR_FEFLAG(__HANDLE__) in hal_uart.h

(does basically what you added into your IRQ handler).