XMEGA DAC & DMA control for waveform generation

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am using ATMEGA32a4u. I have been trying to generate waveform by using DMA to load data to DAC.

Needless to say I have studied AVR Freak previous forums and also many AVR manuals.

 

I am trying to send 16 bit values stored in an uint16 array to DAC 2 bytes at a time.But it seems the Transfer Count register is not getting incremented correctly.

static const uint16_t sine[NR_OF_SAMPLES] = {
    32768, 35325, 37784, 40050, 42036, 43666, 44877, 45623,
    45875, 45623, 44877, 43666, 42036, 40050, 37784, 35325,
    32768, 30211, 27752, 25486, 23500, 21870, 20659, 19913,
    19661, 19913, 20659, 21870, 23500, 25486, 27752, 30211,
};
    
    
    EVSYS.CH0MUX = EVSYS_CHMUX_TCC0_OVF_gc;
    TCC0.CTRLA = TC_CLKSEL_DIV2_gc;
    
     DMA.CTRL = 0x80;            // Enable DMA, single buffer, round robin
     
     DMA.CH0.CTRLB=0x00;
     DMA.CH0.ADDRCTRL =  0xd9; 
     DMA.CH0.TRIGSRC= 0x40;      // TCC0 Trigger Source
     DMA.CH0.TRFCNT = 32;       // AWG Buffer is 256 bytes
     DMA.CH0.SRCADDR0 = ((uint16_t)(&sine[0]) >> 0) & 0xFF;
     DMA.CH0.SRCADDR1 = ((uint16_t)(&sine[0]) >>  8) & 0xFF;
     DMA.CH0.SRCADDR2 =0;
     DMA.CH0.DESTADDR0 = ((uint16_t)(&DACB.CH1DATA) >> 0) & 0xFF;
     DMA.CH0.DESTADDR1 = ((uint16_t)(&DACB.CH1DATA) >> 8) & 0xFF;
     DMA.CH0.DESTADDR2 = 0;
     DMA.CH0.CTRLA = DMA_CH_REPEAT_bm | DMA_CH_BURSTLEN_2BYTE_gc | DAC_CHSEL_SINGLE1_gc;
     DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm;
            

The image of the waveform obtained using the above code is attached .

Can anybody suggest what should be the settings to load this waveform to DAC.

 

 

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Thanks for the code, it work without problems and it helps understanding the DAC/DMA set up. One question, though:

- Is it possible to make the sin/wave run infinitely on "background" - without any interrupts; this would be perfect for me, I plan just to change frequency of the timer and possibly the amplitude (my wave has only 9 steps, so it is not such a problem).

Last Edited: Fri. Feb 26, 2016 - 09:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, you can.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for keeping the hope alive, I guess :)

 

I managed to do it, though there might be less lame solution.

I use two DMA channels, triggered by the same timer OVF - the first DMA generates sin signal (from array to DAC), the second one clears the OVF_IF of the timer :)

 

I've connected Potentiometer as an input signal and I change the frequency, according to the input voltage of an ADC - I can hear pretty clear sound.