0

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?

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

I've tried sending char buffer through UART DMA and receive it. It seems it is not transmitting at all as it is not going into txCplt call back. And it is directly going into Rxcplt call back.

uint8_t tx_arr[10], rx_arr[10];
__IO ITStatus UartReady = RESET;

int main(void)
{
  int i = 0;
  for(i = 0; i<10; i++)
      rx_arr[i] = 0;

  for(i = 0; i<10; i++)
tx_arr[i] = i*2;

 HAL_Init();
 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;
}

I expect the rx_arr will get filled by 0,2,4,6,...18 but it is getting filled with junk

HelpingHand
  • 1,294
  • 11
  • 27
Venu Aditya
  • 11
  • 1
  • 4

1 Answers1

0

As this looks to me, the reason is that you are using the same flag variable from both ISRs, both times doing busy waiting in your main loop.

If you uncomment both handler actions, you will sooner or later end up with a race condition where both handlers put their "SET" value quickly one by one - before the main loop waits for it. Then, the main loop "consumes" this flag by setting the variable back to "RESET". A few lines later, the other waiting loop comes and isn't served (because both ISRs ran earlier and only left a single "SET" value, one overwriting the other). Then, your main loop is stuck.

In order to verify my assumption, you can activate a one-sided watchdog before entering into the main loop, and trigger it every main loop cycle. If the main loop gets stuck as I assume, you will detect that the reset cause points to the watchdog afterwards.

HelpingHand
  • 1,294
  • 11
  • 27