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

Thanks for the reply. My code is almost identical to the second example that you have shown.

LPetr.1
Senior

I have a feeling that his has got something to do with DMA error handling. II havent implemented any error handling for the DMA, so if the error happens the DMA will stop working. Is that correct?

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

Do you handle UART errors (namely overrun)?

JW

LPetr.1
Senior

Currently I do not handle any errors. I am now looking into how to do this correctly.

I think the correct way is to do the following:

void DMA2_Stream1_IRQHandler (void)
{
  // check errors here
 
 
 
}

Is this correct?

If you use DMA2 Stream1 for USART6 RX access, I guess you should have some code here in order to handle DMA2 Stream1 IRQ that will happen at end of reception.

Something like :

HAL_DMA_IRQHandler(&hdma_usart6_rx);

The handler is enabled in MX_DMA_init function:

static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
  /* DMA2_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
 
}

So I only need to handle specific errors inside the DMA IRQ handler?

I can see that in my stm32f4xx_it.c file I have bunch of IRQ handlers such as:

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
 
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
 
  /* USER CODE END USART3_IRQn 1 */
}
 
/**
  * @brief This function handles DMA2 stream1 global interrupt.
  */
void DMA2_Stream1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */
 
  /* USER CODE END DMA2_Stream1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart6_rx);
  /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */
 
  /* USER CODE END DMA2_Stream1_IRQn 1 */
}
 
/**
  * @brief This function handles USART6 global interrupt.
  */
void USART6_IRQHandler(void)
{
  /* USER CODE BEGIN USART6_IRQn 0 */
 
  /* USER CODE END USART6_IRQn 0 */
  HAL_UART_IRQHandler(&huart6);
  /* USER CODE BEGIN USART6_IRQn 1 */
 
  /* USER CODE END USART6_IRQn 1 */
}
 
/* USER CODE BEGIN 1 */
 
/* USER CODE END 1 *

Sorry, I was not clear enough.

If you generate your project using CubeMx, I would have expected seeing following code in your stm32...xx_it.c file (where IRQ handlers are implemented). Goal is to map IRQ to their HAL handlers. For DMA2_Stream1 case :

void DMA2_Stream1_IRQHandler (void)
{
  /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */
 
  /* USER CODE END DMA2_Stream1_IRQn 0 */
 
  HAL_DMA_IRQHandler(&hdma_usart6_rx);
 
  /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */
 
  /* USER CODE END DMA2_Stream1_IRQn 1 */
}

Hope it is more clear 😉

I have put a breakpoint on:

HAL_UART_IRQHandler

And I can see that the following error happends when I am sending the data:

0693W00000NpJ3mQAF.png