www.mikrocontroller.net

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


Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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:
//Direct Memory Access initialisieren
#define ADC_WERTE 10             //Wie viele Werte gespeichert werden sollen
int16_t samples[ADC_WERTE];         //ADC-Werte hier abspeichern
//ADC-Werte einlesen
void SetupReadChannel( DMA_CH_t * dmaChannel )
{
  DMA_SetupBlock( dmaChannel,          //Channelangabe
              (void const *) (0x224),    //Quelladresse: ADC.CH0.RES = 0x224 ; ADC_Result = 0x200F
                    DMA_CH_SRCRELOAD_BURST_gc,   //Quellereload nach einem Burst
                    DMA_CH_SRCDIR_INC_gc,    //Quellenrichtung increment
                    samples,           //Zieladresse
                    DMA_CH_DESTRELOAD_BLOCK_gc, //Zielreload nach einem Block
                    DMA_CH_DESTDIR_INC_gc,    //Zielrichtung increment
                    ADC_WERTE,         //Blockgröße
                    DMA_CH_BURSTLEN_2BYTE_gc,   //Burstlänge liegt bei 2 Byte
                    0,              //Anzahl der Blocks <- wird nicht verwendet
                    false            //Verwendung von Repeat <- wird nicht verwendet, deswegen false
                );
  
    DMA_EnableSingleShot( dmaChannel );
  DMA_SetTriggerSource( dmaChannel, DMA_CH_TRIGSRC_ADCA_CH0_gc ); //ADCA als Triggerquelle
}

main:
//Hauptfunktion
int main(void){
  // The DMA channel to use for reading switch state.
    DMA_CH_t * ReadChannel = &DMA.CH0;
  
  // Prepare DMA
    DMA_Enable();
    SetupReadChannel(ReadChannel);
    //SetupWriteChannel(WriteChannel);
      
  while(1){
    DMA_EnableChannel(ReadChannel);
    DMA_ReturnStatus_blocking( ReadChannel );
  }
}

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

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gern!

Autor: Harald M. (mare_crisium)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joe,

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

mare_crisium

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, nun habe ich aber wirklich ein Problem. :(
Laut diesem Beispiel wird ja die Zieladresse (destination memory adress) 
als
void * destAddr
 angegeben. In meinem Beispiel ist das
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

Autor: Joe F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir keiner die Frage mit DMA beantworten?

Gruß Joe

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Joe,

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

Grüße,
Michael

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Joe,

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

Grüße,

Michael

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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...

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


Gruß Joe

Autor: Florian G. (stromflo)
Datum:

Bewertung
0 lesenswert
nicht 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/...

Gruß Flo

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und das unglaubliche ist, das Beispiel AVR1312 mit 128 kb SRAM 
funktioniert einwandfrei!!!

Gruß Joe

Autor: Joe F. (joe1234)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.