ATXmega DMA mit DAC funktioniert nicht richtig

#5803657
Lesenswert?

Hallo zusammen

Ich möchte eine Sinustabelle mittels DMA am DAC des Atxmega128A3U 
ausgeben.
Leider wechselt die Ausgangsspannung aktuell von ca. 0.8V zu 1V hin und 
her.

Vielleicht sieht jemand was das Problem sein könnte?

Danke!
1
#define SYMBOL_BUFFER_SIZE  32
2

3
const uint16_t sineLUT[SYMBOL_BUFFER_SIZE * 2] =
4
{
5
  // 100%
6
  0x800,0x98f,0xb0f,0xc71,0xda7,0xea6,0xf63,0xfd8,
7
  0xfff,0xfd8,0xf63,0xea6,0xda7,0xc71,0xb0f,0x98f,
8
  0x800,0x670,0x4f0,0x38e,0x258,0x159,0x9c,0x27,
9
  0x0,0x27,0x9c,0x159,0x258,0x38e,0x4f0,0x670,
10
  0x800,0x98f,0xb0f,0xc71,0xda7,0xea6,0xf63,0xfd8,
11
  0xfff,0xfd8,0xf63,0xea6,0xda7,0xc71,0xb0f,0x98f,
12
  0x800,0x670,0x4f0,0x38e,0x258,0x159,0x9c,0x27,
13
  0x0,0x27,0x9c,0x159,0x258,0x38e,0x4f0,0x670,  
14
};
15

16
void vInitDAC()
17
{
18
  DACB.CTRLA = DAC_CH0EN_bm;  // Enable CH0
19
  DACB.CTRLB = DAC_CH0TRIG_bm;  // AutoTrigger CH0
20
  DACB.CTRLC = 0x0;  // Refernece Voltage
21
  DACB.EVCTRL = DAC_EVSEL_0_gc;  // Event Channel 1
22
  DACB.CTRLA |= DAC_ENABLE_bm;
23
  PORTB.DIRSET = 0x04;
24
}
25

26
void vInitDMA()
27
{
28
  vInitDAC();
29

30
  // set TCC1 to 11024Hz overflow, actually 11019.2838Hz (-0.052% error)
31
  TCC1.CTRLA = 0; // stop if running
32
  TCC1.CNT = 0;
33
  TCC1.PER = 0xFFFF;
34

35
  EVSYS.CH0MUX = EVSYS_CHMUX_TCC1_OVF_gc; // trigger on timer overflow  
36

37
  // reset DMA controller
38
  DMA.CTRL = 0;
39
  DMA.CTRL = DMA_RESET_bm;
40
  while ((DMA.CTRL & DMA_RESET_bm) != 0);
41
  
42
  DMA.CTRL = DMA_CH_ENABLE_bm | DMA_DBUFMODE_CH01_gc; // double buffered with channels 0 and 1
43
  
44
  //Bei Double Buffering wird automatisch aus Channel 0 und 1 ein "Pair" gebildet. 
45
  //Siehe dazu AVR1304.P8
46
  
47
  // channel 0
48
  // **** TODO: reset dma channels
49
  DMA.CH0.REPCNT    = 0;
50
  DMA.CH0.CTRLA    = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; // ADC result is 2 byte 12 bit word
51
  DMA.CH0.CTRLB    = 0x1;
52
  DMA.CH0.ADDRCTRL  = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | // reload source after every burst
53
  DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc; // reload dest after every transaction
54
  DMA.CH0.TRIGSRC    = DMA_CH_TRIGSRC_TCC1_OVF_gc;
55
  DMA.CH0.TRFCNT    = SYMBOL_BUFFER_SIZE * 2; // always the number of bytes, even if burst length > 1
56
  DMA.CH0.DESTADDR0  = ((uint16_t)(&DACB.CH0DATA)>>0) & 0xFF;
57
  DMA.CH0.DESTADDR1  = ((uint16_t)(&DACB.CH0DATA)>>8) & 0xFF;
58
  DMA.CH0.DESTADDR2  = 0;
59
  DMA.CH0.SRCADDR0  = ( (uint16_t) (&sineLUT[0]) >> 0) & 0xFF;
60
  DMA.CH0.SRCADDR1  = ( (uint16_t) (&sineLUT[0]) >> 8) & 0xFF;
61
  DMA.CH0.SRCADDR2  = 0;
62

63
  // channel 1
64
  DMA.CH1.REPCNT    = 0;
65
  DMA.CH1.CTRLA    = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; // ADC result is 2 byte 12 bit word
66
  DMA.CH1.CTRLB    = 0x1;
67
  DMA.CH1.ADDRCTRL  = DMA_CH_SRCRELOAD_TRANSACTION_gc  | DMA_CH_SRCDIR_INC_gc | // reload source after every burst
68
  DMA_CH_DESTRELOAD_BURST_gc  | DMA_CH_DESTDIR_INC_gc; // reload dest after every transaction
69
  DMA.CH1.TRIGSRC    = DMA_CH_TRIGSRC_TCC1_OVF_gc;
70
  DMA.CH1.TRFCNT    = SYMBOL_BUFFER_SIZE * 2;
71
  DMA.CH1.DESTADDR0  = ((uint16_t)(&DACB.CH0DATA)>>0) & 0xFF;
72
  DMA.CH1.DESTADDR1  = ((uint16_t)(&DACB.CH0DATA)>>8) & 0xFF;
73
  DMA.CH1.DESTADDR2  = 0;
74
  DMA.CH1.SRCADDR0  = ( (uint16_t) (&sineLUT[0]) >> 0) & 0xFF;
75
  DMA.CH1.SRCADDR1  = ( (uint16_t) (&sineLUT[0]) >> 8) & 0xFF;
76
  DMA.CH1.SRCADDR2  = 0;
77

78
  DMA.CH0.CTRLA    |= DMA_CH_ENABLE_bm;
79
  
80
  TCC1.CTRLA      = TC_CLKSEL_DIV1024_gc; // start timer, and in turn ADC
81

82

83
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren