cancel
Showing results for 
Search instead for 
Did you mean: 

UART DMA Transmit and receive not working

VTOL_Aviations
Associate II

I'm using Atollic True Studio V 9.0 , CubeMx v5.1.0, STM32F407VG-DISC1 board and enabled DMA for UART2.

My code:

int main(void)
{
  
int i = 0;
 
  HAL_Init();
for(i = 0; i<10; i++)
  	rx_arr[i] = 0;
for(i = 0; i<10; i++)
	tx_arr[i] = i*2;
 
 SystemClock_Config();
 MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART6_UART_Init();
  MX_USART2_UART_Init();
 
  while (1)
  {
          
	  if( HAL_UART_Transmit_DMA(&huart2, (uint8_t*)tx_arr, 10)!= HAL_OK )
	  {
	   	  Error_Handler();
	  }
          while(UartReady != SET)
          {
 
	  }
	  UartReady  = RESET;
          if( HAL_UART_Receive_DMA(&huart2, (uint8_t*)rx_arr, 10)!= HAL_OK )
	 {
	    Error_Handler();
	 }
         while(UartReady != SET)
	 {
 
	 }
	 UartReady  = RESET;
 
 
}
  
}
 
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	UartReady = SET;
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	UartReady = SET;
}

What I'm trying to do is fairly simple. Transmit through DMA and wait till it gets transmitted. And then receive and wait till it is received.

When I comment out the receive part(including the call back), it is going into the transmit complete call back function. But when I un-comment the receive portion, it is not going into the tx cplt call back and it is directly going into the receive cplt callback. And when I check the receive buffer I'm not getting what I expected(obviously). What could have gone wrong?

My clock settings:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

Even though the external clock frequency is 8MHz(selected that in cubeMX too), it is showing

#if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */

in system_stm32f4xx.c

7 REPLIES 7
Bob S
Principal

Where is your declaration for UartReady? Is it declared as "volatile"?

Yes. I've declared __IO ITStatus UartReady = RESET;

Sorry for not mentioning it.

S.Ma
Principal

...

OK. And just to be thorough, how are tx_arr and rx_arr declared? Specifically, as arrays of at least 10 elements?

What do you have connected to the other end of the serial port? Is it some program that waits to receive 10 bytes and then sends 10 bytes back? Or do you have the Tx line shorted to the Rx line for loop-back?

And just to be thorough, how are tx_arr and rx_arr declared? Specifically, as arrays of at least 10 elements?

Yes. They are declared as uint8_t data type array with exactly 10 elements each.

What do you have connected to the other end of the serial port? Is it some program that waits to receive 10 bytes and then sends 10 bytes back? Or do you have the Tx line shorted to the Rx line for loop-back?

It's the latter. I'm trying do a loop-back test.

-Aditya

OK, so you say that with both the TX and RX code enabled (i.e. rx code un-commented)

> "it is not going into the tx cplt call back and it is directly going into the receive cplt callback".

Does it NEVER get to the tx complete callback? Or does it just get to the rx complete callback first? There are two options here:

(1) At least in the 32L4xx HAL code, the HAL_UART_IRQHandler() calls the "receive complete" callback before if calls the "transmit complete" callback. So if it gets a UART interrupt and BOTH the TC and RXNE interrupts are pending, it will handle the RX interrupt first, then the TX interrupt.

or...

(2) I am totally guessing here, but it MAY be possible that there is a slightly longer delay in the TX hardware before setting the TC flag, which allows the RX hardware to assert RXNE just before the TX TC flag. Again, I'm guessing here, and I like answer (1) better than this one.

alouni bargougui
Associate II

i've the same problme but i used the Keil uvision 5 with Cube Mx

please give me the terminal can be used to verified the communication carte- PC via USART

thanks a lot