AnsweredAssumed Answered

Kwikstik audioscope demo question

Question asked by Cesar Rabak on Nov 26, 2014
Latest reply on Dec 2, 2014 by Hui_Ma

I'm studying the Kinetis KwikStik board (K40) and specially the audioscope demo.

 

After an analysis of the producer consumer role of PE_ISR(DMA_ADC_DoneInterrupt) (in Events.c) and ShowData() (in ProcessorExpert.c), I think the implementation in this demo has a race condition where the display function reads the data pointed to be written by the ADC thus turning useless the intended double buffer mechanism:

This is the code for the interrupt service routine:

 

PE_ISR(DMA_ADC_DoneInterrupt)

{

  /* Write your interrupt code here ... */

  // Clear all DMA interrupt flags

  DMA_CINT = 0x40;

  // switch bufstart to other part of buffer

  BufStart = ADC_BUFFER_SIZE - BufStart;

  // reset destination address

  DMA_TCD0_DADDR = (uint32_t)&(MeasuredValues[BufStart]);

  // toggle pin

  GPIO1_ToggleFieldBits(GPIOPtr, TST,1);

  // toggle flag

  Measured = TRUE;

}

 

In the routine above the setting of BufStart switches the start of the buffer to be written by the ADC and toggles the flag "Measured" to true which is tested in the main of ProcessorExpert.c:

 

The pertaining snippet of the code is the following:

 

      if (Measured) {

          cntr++;

          // display only time after time

          if (cntr > 10) {

              // display data

              ShowData();             

              cntr = 0;

          }

          // reset flag

          Measured = FALSE;

      }

 

The call to ShowData() is only made if the flag "Measured" is true, this procedure has the following code:

 

for (i=0; i<37; i++) {   

    val = MeasuredValues[BufStart+i];

    sum += val;

    // substract last average

    val = val - LastAvg;

    if (val < -150) {

       pos = 0;   

    } else if (val < -90) {

       pos = 1;   

    } else if (val < -60) {

       pos = 2;   

    } else if (val < -30) {

       pos = 3;   

    } else if (val < 30) {

       pos = 4;   

    } else if (val < 60) {

       pos = 5;   

    } else if (val < 90) {

       pos = 6;   

    } else {

       pos = 7;   

    }

 

So when this code is reached the for loop has the values addressed by MeasuredValues[BufStart+i] where BufStart already has been advanced to the (double) buffer region shared between the ADC DMA channel and this routine effectively reading the region which the ADC is writing to it.

 

Did I miss something or you agree with my understating?

 

Regards,

--

Cesar Rabak

Outcomes