Forum: Mikrocontroller und Digitale Elektronik Xplain (XMEGA) + DMA


von Joe F. (joe1234)


Lesenswert?

Hallo Leute,

ich schaue mir gerade das Beispiel AVR1502 zum Thema DMA an. In diesem 
Beispiel werden die Tasten nach 10 sec abgespeichert und wieder 
abgespielt. Soweit so gut!!!
Nun habe ich mir gedacht, dass ich ja dasselbe für meinen ADC entwerfen 
kann. Also mein ADC soll Werte erstellen und mithilfe von DMA in den 
SRAM schreiben.
Jetzt habe ich meinen ADC eingestellt. Leider habe ich beim Einstellen 
vom DMAC große Problem.
Hier mal meine Einstellungen:
DMA:
1
//Direct Memory Access initialisieren
2
#define ADC_WERTE 10             //Wie viele Werte gespeichert werden sollen
3
int16_t samples[ADC_WERTE];         //ADC-Werte hier abspeichern
4
//ADC-Werte einlesen
5
void SetupReadChannel( DMA_CH_t * dmaChannel )
6
{
7
  DMA_SetupBlock( dmaChannel,          //Channelangabe
8
              (void const *) (0x224),    //Quelladresse: ADC.CH0.RES = 0x224 ; ADC_Result = 0x200F
9
                    DMA_CH_SRCRELOAD_BURST_gc,   //Quellereload nach einem Burst
10
                    DMA_CH_SRCDIR_INC_gc,    //Quellenrichtung increment
11
                    samples,           //Zieladresse
12
                    DMA_CH_DESTRELOAD_BLOCK_gc, //Zielreload nach einem Block
13
                    DMA_CH_DESTDIR_INC_gc,    //Zielrichtung increment
14
                    ADC_WERTE,         //Blockgröße
15
                    DMA_CH_BURSTLEN_2BYTE_gc,   //Burstlänge liegt bei 2 Byte
16
                    0,              //Anzahl der Blocks <- wird nicht verwendet
17
                    false            //Verwendung von Repeat <- wird nicht verwendet, deswegen false
18
                );
19
  
20
    DMA_EnableSingleShot( dmaChannel );
21
  DMA_SetTriggerSource( dmaChannel, DMA_CH_TRIGSRC_ADCA_CH0_gc ); //ADCA als Triggerquelle
22
}

main:
1
//Hauptfunktion
2
int main(void){
3
  // The DMA channel to use for reading switch state.
4
    DMA_CH_t * ReadChannel = &DMA.CH0;
5
  
6
  // Prepare DMA
7
    DMA_Enable();
8
    SetupReadChannel(ReadChannel);
9
    //SetupWriteChannel(WriteChannel);
10
      
11
  while(1){
12
    DMA_EnableChannel(ReadChannel);
13
    DMA_ReturnStatus_blocking( ReadChannel );
14
  }
15
}

Die Abspeicherung in den SRAM klappt auch soweit, es werden jedoch genau 
die HÄLFTE der angegebenen ADC_WERTE hineingeschrieben, obwohl die 
Variable sample die richitge Länge hat.
Also sample sieht so aus, dass 5 Werte vom ADC sind und die anderen 5 
genau 0 sind.
Nun habe ich mal folgendes ausprobiert. Ich habe einfach mal in der 
Funktion DMA_Setupblock die Blockgröße (siehe Komentare) auf 2*ADC_WERTE 
gestellt und siehe da, es wird der komplette Vektor "sample" mit den 
Werten vom ADC gefüllt.
Die Frage ist nun, warum muss die Blockgröße doppelt so groß sein??? 
Oder verstehe ich da was flasch??
Im Beispiel muss ja diese Größe auch nicht doppelt so groß sein!!!

Gruß Joe

von Michael K. (Gast)


Lesenswert?

Hallo Joe,

in der Funktion DMA_SetupBlock wird ja folgendes gesetzt:

channel->TRFCNT = blockSize;

und das Datenblatt sagt:

TRFCNT defines the number of bytes in a block transfer.

Also Blocksize ist die Anzahl der Bytes die übertragen werden, 
unabhängig der Burstlänge und den Datentyp in den geschrieben wird.

Grüße,
Michael

von Joe F. (joe1234)


Lesenswert?

Danke für die Antwort!!! :)

Du wirst es nicht glauben, aber ich habe das gerade selber entdeckt.
Da ja die Blockgröße die Anzahl der zu übertragenen Bytes festlegt und 
ich ja für 2 Byte einen Wert habe, muss ich ja 2 * Anzahl der Werte (in 
meinem Fall "ADC_WERTE") nehmen!!!

Trotzdem Danke für die schnelle Antwort!!!

Gruß Joe

von Michael K. (Gast)


Lesenswert?

Gern!

von Harald M. (mare_crisium)


Lesenswert?

Joe,

kurze OT-Frage: Auf welchem Weg überträgst Du Dein Program an den XMega 
auf dem XPlain-Board?

mare_crisium

von Joe F. (joe1234)


Lesenswert?

So, nun habe ich aber wirklich ein Problem. :(
Laut diesem Beispiel wird ja die Zieladresse (destination memory adress) 
als
1
void * destAddr
 angegeben. In meinem Beispiel ist das
1
samples[ADC_WERTE]
Nun möchte ich aber 20 Messungen machen und diese alle hintereindaner 
auf den SRAM schieben. So wie ich das verstehe, aber ich bin halt noch 
Anfänger, müsste ich ja mehrere Vektoren anlegen (z.B. samples2, 
samples3...) und dann mithilfe einer Interation immer den nächsten 
Vektor nehmen. Dies ist aber nicht sehr elegant und benötigt 
zusätzlichen Speicher. Ist es vllt möglich, dass immer den selben Vektor 
verwende?
Ich bin mir sogar relativ sicher, dass es gehen muss, aber ich komme 
nicht darauf.

Gruß Joe

von Joe F. (Gast)


Lesenswert?

Hi Harald,

früher habe ich dieses LUFA Project verwendet, dadurch konnte ich aber 
nicht debuggen. Nun habe ich mir einen Jtagice MK2 gekauft, nun kann ich 
debuggen und die Register einzeln auslesen. Das ist wirklich 
vorteilhaft, kostet aber auch einiges.

Gruß Joe

von Joe F. (joe1234)


Lesenswert?

Kann mir keiner die Frage mit DMA beantworten?

Gruß Joe

von Michael K. (mmike)


Lesenswert?

Hi Joe,

Du machst doch eh einen Single - Shot ... dann kannst Du ja die 
Destination Adresse verbiegen ... ggf. mach doch einfach nen 2 
dimensionales Array ...

Grüße,
Michael

von Joe F. (joe1234)


Lesenswert?

Das ist ein gute Idee. Jedoch ist mir aufgefallen, dass wenn ich einen 
großen Vektor anlege (z.B mit 1000 Werten) mein Speicher zu 25% voll 
ist. Wenn ich also z.B. noch 20 Messungen mache, dann ist das anlegen 
einer solchen Matrix (Vektor) nicht machbar.
Deswegen war meine Idee, dass ich einen Vektor anlege und diesen ständig 
überschreibe.

Mir ist aufgefallen, als ich mich heute so im Forum mal durchgekämpft 
habe, dass es einen gewaltigen Unterschied gibt, zumindest beim 
Xplain-Board, zwischen SRAM und SDRAM. Viele schreiben zwar, dass sie 
SDRAM ansteuern wollen, aus dem Code heraus liest man jedoch, dass sie 
SRAM ansteuern, da sie kein EBI verwenden. Da ich noch ein Anfänger bin, 
bin ich auch so ein Beispiel reingefallen und habe statt SDRAM SRAM 
angesteuert (sieht man ja an meinem Code). Was auch den 25% vollen 
Speicher erklärt. Bei großen Datenmengen werde ich wohl nicht drum 
herumkommen, den SDRAM ansteuren zu müssen. Dazu muss ich aber noch 
einiges lesen.

Gruß Joe

von Klaus (Gast)


Lesenswert?

> Was auch den 25% vollen
>Speicher erklärt. Bei großen Datenmengen werde ich wohl nicht drum
>herumkommen, den SDRAM ansteuren zu müssen. Dazu muss ich aber noch
>einiges lesen.

In dem Thread findet sich ein Beispiel:
Beitrag "XMEGA/ AVR-EXPLAIN code examples und Diskussion"

von Michael K. (mmike)


Lesenswert?

Hi Joe,

was genau willst Du denn mit den Werten machen?? Brauchst Du die 
Wertehistorie, oder möchtest Du filtern??

Grüße,
Michael

von Joe F. (joe1234)


Lesenswert?

Hallo,

Danke erstmal für die Antworten und Tipps.

also ich möchte erstmal ein Signal AD wandeln, dazu habe ich meinen 
AD-Wandler schon richtig eingestellt (12 Bit Auflösung, differential, 
usw.). Nun möchte ich bei einer 500kHz Abtastung die Werte, ca 1000 
Stück pro Messung, in den SDRam schreiben. Dabei will ich ca. 20 
Messungen machen. Dies entspricht 20000 Werten, die alle 12 Bit lang 
sind. Diese Werte möchte ich später wieder aus dem SDRam lesen und 
weiterverarbeiten. Da mein SRam auf dem Xplain nicht ausreicht, wollte 
ich SDRam nutzen. Dieser hat ja beim Xplain Board 8MB. Dies sollte auf 
jeden Fall reichen.
Um den 8MB SDRam "anzusteuern", muss ich ja EBI verwenden. Das ist für 
mich völlig neu, deswegen muss ich mich da einlesen.

@ Klaus
Danke für den Tipp.
Ich habe mir diesen Thread mal durchgelesen und habe 3 Fragen.
1. Werden hier die vollen 8MB angesteuert? Ich meine mich erinnern zu 
können, dass ich irgendwo gelesen habe, dass man mit Winavr-gcc und AVR- 
Studio nicht den gesamten Speicher ansprechen kann! Warum eigentlich 
nicht?

2. EBI.REFRESH und EBI.INITDLY, wie werde diese Werte berechnet und was 
bedeuten diese genau bzw. für was werden diese benötigt? Ich habe sie im 
Datenblatt zwar gefunden, aber die Erklärung ist nicht gut.

3. Im Moment habe ich meinen µC auf 32 MHz eingestellt. Wenn ich die 
Einstellungen vom Taktsystem von Hagen Re verwende, ändert sich meine 
aktuelle Taktfrequenz? So wie ich es verstanden habe, ist seine 
Taktfrequenz auch auf 32 MHz eingestellt (Quarz extern oder intern??), 
nur für das Schreiben in den SDRam verwendet er eine höhere Frequenz, 
oder?


Gruß Joe

von Michael K. (mmike)


Lesenswert?

Hi Joe,

da wirst Du um den SDRAM nicht rumkommen ... hab da leider auch noch 
keine Erfahrung ... aber viel Erfolg!

Grüße,

Michael

von Klaus (Gast)


Lesenswert?

>1. Werden hier die vollen 8MB angesteuert? Ich meine mich erinnern zu
>können, dass ich irgendwo gelesen habe, dass man mit Winavr-gcc und AVR-
>Studio nicht den gesamten Speicher ansprechen kann! Warum eigentlich
>nicht?

Wenn Du die separaten Funktionen nimmst, wird der ganze Speicher 
angesprochen. Die Begrenzung für kleiner 8MB tritt nur auf, wenn man das 
SD-RAM direkt in den GCC einbindet, wenn man also z.B. via 
x=data[uint32_t d] zugreifen will.

von Joe F. (joe1234)


Lesenswert?

Danke Klaus.
Eine Frage noch dazu:
Wenn ich Winavr-gcc und AVR-Studio verwende und in den SDRam schreibe, 
kann ich trotzdem per Debug diesen Wert irgendwie anschauen? Wenn ich 
die geschriebene Variable, die ich anschauen will, in das 
"Watch-Fenster" schiebe, steht bei mir "out of location". Ist das 
korrekt?


Mal eine andere Frage:
Ich habe nun viel über den XMEGA gelesen und was ich nicht verstehe, 
wieviel SRAM steht denn dem XMEGA nun zur Verfügung? Im Datenblatt steht 
8kb, soweit so gut. Aber laut dem AVR1312 stehen dem XMEGA 128kb SRAM 
zu. Was entspricht nun was?

Damit ihr nicht lange suchen müsst, hier die Links:
SRAM 8kb:
http://www.atmel.com/dyn/products/product_card.asp?part_id=4298

SRAM 128kb (AVR1312):
http://www.atmel.com/dyn/products/app_notes.asp?family_id=607


Gruß Joe

von Florian G. (stromflo)


Lesenswert?

Hi,

eine schöne Auflistung über den jeweiligen SRAM bekommst du im 
Datenblatt Xmega A1 auf Seite 2.

http://www.atmel.com/dyn/resources/prod_documents/doc8067.pdf

Gruß Flo

von Joe F. (joe1234)


Lesenswert?

Klar, die Tabelle habe ich auch schon gesehen. Das ist ja was mir unklar 
ist. Überall steht, dass XMEGA 128A1 8kb SRam hat.
TROTZDEM werden im AVR1312 128kb SRam angesprochen????

Gruß Joe

von Joe F. (joe1234)


Lesenswert?

Und das unglaubliche ist, das Beispiel AVR1312 mit 128 kb SRAM 
funktioniert einwandfrei!!!

Gruß Joe

von Joe F. (joe1234)


Lesenswert?

Ok, falls sich das ein Admin durchliest, bitte den Beitrag obendrüber 
löschen.
Dieses sram_example.c mit 128kb SRam funktioniert nicht auf dem 
XMEGA128A1. Es geht nur, wenn man die SRAM_SIZE auf 8kb reduziert, was 
ja auch Sinn macht, denn dieser XMEGA hat nur 8 kb SRam.

Gruß Joe

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.