xmega DMA Interupts

Gast #4481858
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.