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 | }
|