0
\$\begingroup\$

How can I reduce the delay happening between writes to the DAC (as shown below)?

The yellow represents how long the DAC writes last for which is 232.9us The green represents the output from the DAC, if zoomed in you will see a 16.30kHz sine wave.

After the first DAC write (0 - 1024) there's a 15.4ms delay until the second write occurs which is also shown below.

It takes ~232.9us to write 1024 values into the DAC. How do I close this 15.4ms gap and make it transition to the second write much cleaner? I was thinking using perhaps timers?

The way I have the DMA set up is as follows:

  • When the ADC detects an incoming signal DMA starts sampling
  • The DMA will first sample 1024 values this takes 15.7ms
  • Once done it will request a half complete interrupt where then I start my first DAC writes
  • the DMA will sample the other 1024 values as this takes 15.7ms as well
  • Once done will request a complete interrupt then I start my second DAC writes

Code:

void DMA2_Channel3_IRQHandler(void){

    if (((DMA2->ISR) & (1<<10)) != 0){ // Check to see if the Half Complete Flag is set
        halfTransferComplete = 1;
        DMA2->IFCR |= (1<<10);
    } else if (((DMA2->ISR) & (1<<9)) != 0){ // Check to see if the Complete Flag is set
        transferComplete = 1;
        DMA2->IFCR |= (1<<9);
    }
}

int main(void) {

    while (1) {

        if (halfTransferComplete == 1){ //Stays in this block of code for 15.7mS
            GPIOA->BSRR = 1<<0;
            for (int i = 0; i < 1024; i++){
                DAC1->DHR12R1 = adcValue[i];
            }

            GPIOA->BSRR = 1<<16;
            halfTransferComplete = 0;
        }

        if (transferComplete == 1){ //Stays in this block of code for 15.7mS
            GPIOA->BSRR = 1<<0;
            for (int i = 1024; i < 2048; i++){
                DAC1->DHR12R1 = adcValue[i];
            }

            GPIOA->BSRR = 1<<16;
            transferComplete = 0;
        }
      }
}

Figure 1:

\$\endgroup\$
1
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$ – Voltage Spike Jun 13 '20 at 4:18
0
\$\begingroup\$

You're writing values out to the DAC in a loop as fast as the CPU/bus will let you, with no connection to the rate they're coming in. You need to use a timer to clock them out at a controlled rate, or maybe a DMA. If the source and destination are in the same clock domain, and you manage your code properly (making sure things run in close to constant time) you should be able to run the input and output in lockstep without any glitches.

\$\endgroup\$
7
  • \$\begingroup\$ So a timer I see \$\endgroup\$ – Leoc May 15 '20 at 0:56
  • \$\begingroup\$ I dont think I fully understand this. I know I am writing the DAC values as fast as possible and I know thats causing the problem. Are you suggesting I control how each value gets outputted? Would that affect the frequency of the output then? if I delay each value? \$\endgroup\$ – Leoc May 15 '20 at 1:19
  • 1
    \$\begingroup\$ @Pllsz yes, naturally. You can't write out more samples/sec than you read, at least not continuously. \$\endgroup\$ – hobbs May 15 '20 at 1:46
  • \$\begingroup\$ Yeah thats fair, I thought about doing that then. I was just worried about keeping the fidelity of the frequency, by adding delays between increments would that cause the frequency to change? \$\endgroup\$ – Leoc May 15 '20 at 1:55
  • 1
    \$\begingroup\$ Adding fixed delays accumulate on top of the variances in execution time. What you want is things in scheduled lockstep which is why he said timers, not delays. \$\endgroup\$ – DKNguyen May 15 '20 at 1:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.