Forum: Mikrocontroller und Digitale Elektronik XMEGA DMA SPI


von Hans W. (hans_w30)


Lesenswert?

Hy,
ich versuche DMA mit meinem XMEGA über SPI im Master Mode.
Hierfür muss man den USART benutzen.
Das Funktioniert auch alles soweit.
Ich kann das was auf meinem Bus liegt über ein Oszi bzw. auch über einen 
AARDVARK abhören.

Hierbei stelle ich fest das mein drittes oder viertes Byte nicht 
gesendet werden. Dies kann ich mir nicht erklären, da ich ja gar nicht 
eingreife bzw. eingreifen kann wenn ich per DMA Daten sende.

Was auch komisch ist ich schreibe:
1
blockSize= 6;
2
channel->TRFCNT = blockSize;
und es werden nur 5 Byte gesendet.

Hat jemand hiermit schon erfahrungen gemacht?

Danke für die Hilfe

von Hans W. (hans_w30)


Lesenswert?

Es geht nicht nur das 3 Byte verloren sondern in einem Regelmäßigen 
abstand von 4 oder 5 Bytes eines Verloren.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Schreibst Du während der Ausgabe auf den DMA-Puffer?

von Hans W. (hans_w30)


Lesenswert?

Nein ich initialisiere meine Buffer und ändere danach nichts mehr an 
diesem.
Ich benutze die Treiber von Atmel

Verkürzt mache ich das:
1
static char sendData[NUM_BYTES] ;
2
3
void spi_send_init(DMA_CH_t * ch,USART_SPI_Master_t *usart_spi){
4
  DMA_SetupBlock(ch,
5
    sendData,      
6
    DMA_CH_SRCRELOAD_TRANSACTION_gc,
7
    DMA_CH_SRCDIR_INC_gc,
8
    (void*) &usart_spi->module->DATA,      
9
    DMA_CH_DESTRELOAD_NONE_gc ,
10
    DMA_CH_DESTDIR_FIXED_gc,
11
    NUM_BYTES,
12
    DMA_CH_BURSTLEN_1BYTE_gc,
13
    0,
14
    false);
15
  
16
    DMA_SetTriggerSource(ch,DMA_CH_TRIGSRC_USARTC0_DRE_gc);
17
    DMA_EnableSingleShot(ch);
18
    DMA_SetIntLevel( ch, DMA_CH_TRNINTLVL_LO_gc, DMA_CH_ERRINTLVL_LO_gc );
19
20
}
21
22
main(){
23
24
  for(int i=0;i<NUM_BYTES;i++)
25
    sendData[i]=i;
26
............................
27
  DMA_Enable();
28
  spi_send_init(Channel1,&usart_spiMaster);
29
  DMA_EnableChannel( Channel1 );
30
}

von Hans W. (hans_w30)


Lesenswert?

Kann das ein Problem mit der Geschwindigkeit sein?
Das er nicht nachkommt und deswegen Bits verschluckt?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Hans W. schrieb:
> Kann das ein Problem mit der Geschwindigkeit sein?
> Das er nicht nachkommt und deswegen Bits verschluckt?

Nö. Wenn der DMA-Controller nicht nachkommen würde, würden Pausen im 
Datenstrom entstehen, aber es würde nichts verschwinden.

von Hans W. (hans_w30)


Angehängte Dateien:

Lesenswert?

Vielleicht hilft es was wenn ich mal meine Datei anhänge

von Hans W. (hans_w30)


Lesenswert?

Hat jemand zufällig auch was mit dem dma usart spi gemacht und kann mir 
seine Datei als Beispiel mal geben?
Ich versteh nicht wo das Byte hängen bleibt

von Hans W. (hans_w30)


Angehängte Dateien:

Lesenswert?

Hier mal noch ein Log vom SPI.
Es sollte normal
01 02 03 04 05 06 07 08 09 0A
herauskommen.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Kann das sein, dass die Bitrate von Deinem ControlCenter vielleicht 
etwas zu niedrig ist?!

Hans W. schrieb:
> Hat jemand zufällig auch was mit dem dma usart spi gemacht

Jupp, gerade frisch: Audio-Ein-/Ausgabe über eine über die UART im 
MASTER-SPI-Modus laufende I2S-Emulation. Der XMega macht gut 36Mhz, 
Samplerate des I2S ist 48kHz, 24Bit. Die BitClock liegt bei 3.072Mhz. 1 
Eingabe- und 2 Ausgabestreams laufen zur gleichen Zeit über 3 
DMA-Kanäle. Ich verliere keine Bytes, kann stundenlang Musik über den 
XMEGA hören, ohne dass etwas stottert. Leider verstehe ich nichts von C, 
dafür aber von ASM :-). Ich wollte damit nur sagen, dass die UART im SPI 
hervorragend läuft.

von Hans W. (hans_w30)


Lesenswert?

Mercy, das ist aber nicht das problem die eingestellte Bitrate ist nur 
zum Senden da wenn das ControlCenter als Master arbeitet.

Ich hab den Fehler gefunden.

Und zwar hab ich ein
1
void USART_DMA_StartTransfer( volatile DMA_CH_t * channel )
2
{
3
  channel->CTRLA |= DMA_CH_TRFREQ_bm;
4
}
5
6
StartTransfer(Channelx);
gemacht was dazu geführt hat das der DMA Controller bereits am Senden 
war und bei einem Byte nochmal den Befehl bekommen hat und somit dieses 
einfach übersprungen hat.

Trozdem Danke für eure Hilfe.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ah ja. Der DMA-Controller sendet natürlich immer dann, wenn die 
Triggerbedingung erfüllt ist. Im Falle dessen, dass Du das DRE-Flag der 
UART dafür verwendest, ist die Triggerbedingung von Anfang an und 
solange erfüllt, bis Du 2 Bytes in das DATA-Register eingetragen hast.

von Hans W. (hans_w30)


Lesenswert?

Ja das stimmt ich hab mich leider zu sehr an dem Beispiel von AVR 
geklammert. Und die machen in dem Beispiel einen Transfer im Speicher.
Habe glaube ich 3 Tage lang diesen Fehler gesucht.

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.