PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer triggert DMA, aber Overflow Flag wird nicht zurück gesetzt



erik_wolfram
22.08.2014, 09:35
Hallo,

ich denke die Überschrift sagt schon alles.
Ich habe einen Timer TCC0 der in regelmäßigen Abständen überläuft.
Parallel hierzu wurde ein DMA Kanal eingerichtet um vom Überlauf des TCC0 getriggert zu werden um Daten in den DAC zu schreiben.
Das bewirkt aber ein permanentes Triggern des DMA's, da der DMA nach dem Trigger den Overflow-Flag das Timers nicht löscht.

Da das ganze ausschließlich in der Hardware realisiert werden soll, ist ein" software" Interrupt nicht möglich, welches natürlich den Flag löschen würde...

Alternativ habe ich schon gesehen, dass das Eventsystem den Flag automatisch löscht. Wenn ich dieses "dazwischen schalte" funktioniert das ganze.
Aber ich dachte mir, dass das ganze unötig sei, dass Eventsystem nur dafür zu missbrauchen...

void SetupSinusChannel( DMA_CH_t * dmaChannel )
{
DMA_SetupBlock( dmaChannel,
SinusSignal,
DMA_CH_SRCRELOAD_BLOCK_gc,
DMA_CH_SRCDIR_INC_gc,
(void *) &DACA.CH0DATA,
DMA_CH_DESTRELOAD_BURST_gc,
DMA_CH_DESTDIR_INC_gc,
SinusSignalResolution * 2,
DMA_CH_BURSTLEN_2BYTE_gc,
0,
true );

DMA_EnableSingleShot( dmaChannel );
DMA_SetTriggerSource( dmaChannel, DMA_CH_TRIGSRC_EVSYS_CH0_gc );
}

TCC0.PER = PER_TCC0;
EVSYS.CH0MUX = EVSYS_CHMUX_TCC0_OVF_gc;

Es muss doch möglich sein, dass der DMA den Flag löscht oder? Leider wird in den Application Notes nichts dazu geschrieben (AVR1304, AVR1514).
In der XMEGA A Manual wird im DMA auf die Einstellungen des Timers verwiesen, dort finde ich aber leider keine Hinweise.

Auf der Suche im WWW bin ich aber auch schon darauf gestoßen, dass andere das Eventsystem ebenfalls hierzu genutzt haben.

Da das ganze für meine Bachelor Arbeit ist, würde ich den Code gerne so einfach und sauber wie möglich schreiben.

Es würde mich freuen, wenn mir jemand einen nützlichen Hinweis hierzu geben könnte.

Gruß Erik

Che Guevara
22.08.2014, 10:54
Hi,

ich glaube, ich hatte vor kurzer Zeit das gleiche Problem!
Ich hab mich dafür entschieden, einen EventSystem Kanal dafür zu nutzen, dort kann man ja auch einen Prescaler einstellen.
Was mir gerade einfällt, wäre, den Interrupt des Timers zu deaktivieren, müsste man mal probieren.
Falls nötig kannst du ja nach der Transaktion auch durch den DMA einen Int auslösen lassen.

Gruß
Chris

EDIT:
Hab gerade mal im DB gekuckt:


Bit 0 – OVFIF: Overflow/Underflow Interrupt Flag
This flag is set either on a TOP (overflow) or BOTTOM (underflow) condition, depending on the WGMODE setting.
OVFIF is automatically cleared when the corresponding interrupt vector is executed. The flag can also be cleared
by writing a one to its bit location.
OVFIF can also be used for requesting a DMA transfer. A DMA write access of CNT, PER, or PERBUF will then
clear the OVFIF bit.

Da bleibt wohl nur der Umweg übers Eventsystem oder eben die in-Kaufnahme des zusätzlichen ISR.

erik_wolfram
22.08.2014, 13:29
Dankeschön,
ja dann habe ich wenigtens noch einen NAchweis dafür. Ich finde es schade, dass es dafür keine Funktion in der Hardware gibt.
Da ich durch den extrem hohen Rechenaufwand keine Ressourcen für ein ISR habe muss ich wohl das Eventsystem verwenden...

Che Guevara
22.08.2014, 13:33
Hi,

ja, ich finds auch sehr Schade! Aber es gibt ja gott-sei-dank genügend EventSystem Kanäle, zumindest ich hab noch nie mehr als 4 gleichzeitig gebraucht und so bleibt auch der Timer für eventuelle andere Aufgaben frei (PWM, Freq, etc..).

Gruß
Chris