Forum: Mikrocontroller und Digitale Elektronik xmega DMA Interupts


von xmega dma (Gast)


Lesenswert?

Wenn ich das Manual zum xmega32a4 bzw. die application note zu DMA 
richtig interpretiere, dann sollte der DMA-Controller erst ein Interrupt 
auslösen wenn eine Transaction abgeschlossen ist, im Repeat-Mode also 
alle Wiederholungen durchgeführt wurden:

"When a transaction on the DMA channel has been completed, the TRNIF 
flag will be set and the optional interrupt is
generated." (AVR Manual)

Trotzdem wird bei mir offenbar bei jedem Triggersignal vom ADC (oder 
nach jedem Block) ein Interrupt ausgelöst, ich komm aber nicht dahinter 
weshalb. Kann mir da jemand weiterhelfen?
1
#define NSAMPLE = 12
2
3
void adc_dma_init()
4
{
5
    // Resset DMA and Enable
6
    DMA_CTRL = DMA_RESET_bm;
7
    while( (DMA_CTRL & DMA_RESET_bm) != 0);
8
    DMA_CTRL = DMA_ENABLE_bm | DMA_DBUFMODE_CH01_gc;
9
10
    adc_dma1_init();
11
    adc_dma0_init();
12
13
    ADC_DMA0.CTRLA |= (1 << 7);
14
15
}
16
17
18
void adc_dma0_init()
19
{
20
    ADC_DMA0.CTRLA  = (DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_REPEAT_bm);
21
    ADC_DMA0.CTRLB  = DMA_CH_TRNINTLVL_LO_gc | DMA_CH_ERRINTLVL_LO_gc;
22
    ADC_DMA0.ADDRCTRL = ( DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_DESTDIR_INC_gc );
23
24
    ADC_DMA0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH2_gc;
25
    ADC_DMA0.TRFCNTL = 0x06;
26
    ADC_DMA0.TRFCNTH = 0x00;
27
    ADC_DMA0.REPCNT = NSAMPLE;
28
29
    ADC_DMA0.SRCADDR0 = 0x10; // CH0RESLOW
30
    ADC_DMA0.SRCADDR1 = 0x02; // ADCA
31
    ADC_DMA0.SRCADDR2 = 0x00;
32
33
    ADC_DMA0.DESTADDR0 = ((uint16_t)&dma0_buff) >> 0;
34
    ADC_DMA0.DESTADDR1 = ((uint16_t)&dma0_buff) >> 8;
35
    ADC_DMA0.DESTADDR2 = 0x00;
36
37
    //ADC_DMA0.CTRLA |= DMA_CH_ENABLE_bm;
38
}
39
40
void adc_dma1_init()
41
{
42
    ADC_DMA1.CTRLA  = (DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_REPEAT_bm);
43
    ADC_DMA1.CTRLB = DMA_CH_TRNINTLVL_LO_gc | DMA_CH_ERRINTLVL_LO_gc;
44
    ADC_DMA1.ADDRCTRL = ( DMA_CH_SRCRELOAD_BLOCK_gc |DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_DESTDIR_INC_gc );
45
46
    ADC_DMA1.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH2_gc;
47
    ADC_DMA1.TRFCNTL = 0x06;
48
    ADC_DMA1.TRFCNTH = 0x00;
49
    ADC_DMA1.REPCNT = NSAMPLE;
50
51
    ADC_DMA1.SRCADDR0 = 0x10; // CH0RESLOW
52
    ADC_DMA1.SRCADDR1 = 0x02; // ADCA
53
    ADC_DMA1.SRCADDR2 = 0x00;
54
55
    ADC_DMA1.DESTADDR0 = ((uint16_t)&dma1_buff) >> 0;
56
    ADC_DMA1.DESTADDR1 = ((uint16_t)&dma1_buff) >> 8;
57
    ADC_DMA1.DESTADDR2 = 0x00;
58
59
    //ADC_DMA1.CTRLA |= DMA_CH_ENABLE_bm;
60
}
61
62
ISR(DMA_CH0_vect)
63
{
64
    
65
    if (DMA_INTFLAGS & DMA_CH0TRNIF_bm) 
66
    {
67
        DMA.INTFLAGS = DMA_CH0TRNIF_bm;
68
        ADC_DMA0.REPCNT = NSAMPLE;
69
        ADC_DMA0.CTRLA |= DMA_CH_REPEAT_bm;
70
        adc_process(dma0_buff);
71
    }
72
    else // DMA Error
73
    {
74
        DMA.INTFLAGS = DMA_CH0ERRIF_bm;
75
        // TODO: Error handling
76
    }
77
78
}
79
80
ISR(DMA_CH1_vect)
81
{
82
    
83
    if (DMA_INTFLAGS & DMA_CH1TRNIF_bm) 
84
    {
85
        DMA.INTFLAGS = DMA_CH1TRNIF_bm;
86
        ADC_DMA1.REPCNT = NSAMPLE;
87
        ADC_DMA1.CTRLA |= DMA_CH_REPEAT_bm;
88
        adc_process(dma1_buff);
89
    }
90
    else // DMA Error
91
    {
92
        DMA.INTFLAGS = DMA_CH1ERRIF_bm;
93
        // TODO: Error handling
94
    }
95
96
}

Hier sollte dma0 dma0_buff mit NSAMPLES von ADCA CH0-2 füllen, dann 
einen interrupt generieren während dma1 übernimmt und dma1_buff füllt 
usw.

Was passiert ist (soweit ich das bisher beobachten konnte), dass dma0 
einen Block (nach einem Trigger des ADCs) kopiert, einen interrupt 
auslöst, dann dma1 einen block kopiert und einen Interrupt auslöst usw.
Im Grund Verhält es sich so, als wäre der Repeat Mode nicht aktiv.

von xmega dma (Gast)


Lesenswert?

Hab meinen Denkfehler gefunden, im Repeat Modus wird nicht ein Block 
transfer getriggert sondern die komplette Transaction.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.