cancel
Showing results for 
Search instead for 
Did you mean: 

Ping Pong UART DMA

Wleon.1
Associate II

Hi,

I fove the following code:

void EXTI9_5_IRQHandler(void)
{
  
...
 if(GPSDMAStart == 1){
  if(currentPing == 0 && currentPingProcessed == 1){
     /* currently pong, switch to ping */ 
     hdma_uart7_rx.Instance->CR &= ~(1 << 0);
     hdma_uart7_rx.Instance->NDTR = 1000-1;
     hdma_uart7_rx.Instance->M0AR = uartbufPing;
     hdma_uart7_rx.Instance->CR = hdma_uart7_rx.Instance->CR|0x0011;
      huart7.Instance->CR3 = 0x00000041;
     currentPing = 1;
     currentPongProcessed = 0;
 
   
  }else if(currentPing == 1 && currentPongProcessed == 1){
     /* currently ping,  switch to pong */
     hdma_uart7_rx.Instance->CR &= ~(1 << 0);
     hdma_uart7_rx.Instance->NDTR = 1000-1;
     hdma_uart7_rx.Instance->M0AR = uartbufPong;
     hdma_uart7_rx.Instance->CR = hdma_uart7_rx.Instance->CR|0x0011;
     huart7.Instance->CR3 = 0x00000041;
     currentPing = 0;
     currentPingProcessed = 0;
   }
  }
 
...
} 
 
main(){
...
  Uartret = HAL_UART_Receive_DMA(&huart7, uartbuf, 300);
  memset(uartbufPing,0xCC, 1000); <--- fill ping and pong with 0xCC
  memset(uartbufPong,0xCC, 1000);
  GPSDMAStart = 1;
  while(1){
    uint8_t rret = 0;
    if(currentPing == 0 && currentPingProcessed == 0) {
        currentPingProcessed = 1;
    }
    else if (currentPing == 1 && currentPongProcessed == 0){
        currentPongProcessed = 1;
    }      
  } 
...
}

The EXTI9_5_IRQHandler interrupt handler comes very sec, Running the program give me the following output from both memory:

Pong:0693W000001stZ3QAI.png

ping:

0693W000001stYtQAI.png

My question is why is the ping does not start from the top ? and it consistently starts with the same offset, am I doing anything wrong here ?

4 REPLIES 4
hs2
Senior

Checking and setting 2 (volatile ?) flags (currentPing and currentPing/PongProcessed) In main is not atomic i.e. is a race condition.

An interrupt can kick in e.g. right after the 1st part of the expression and might break the check.

You should wrap the check by disable/enable EXTI9_5_IRQ or even better rewrite the code to handle the ISR state variables only in the ISR.

Should be doable for your ping/pong test.

What STM32 is being used here? Do you ​manage cache coherency?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Its stm32F733, how do I manage that ?

currentPing/PongProcessed are separated, I think even if it kick in right afer the 1st part if the expression it will also work right ?