Forum: Mikrocontroller und Digitale Elektronik xmega USART SPI Daten von ADC speichern mit DMA


von Christoph G. (chgamauf82)


Lesenswert?

Hallo

Ich müsste Daten die von einem ADC über den SPI Bus gesendet werden im 
RAM vom µC zwischen speichern und diese dann anschließend an einen PC 
schicken.

Es funktioniert soweit alles. Ich kann die Daten(2 byte) vom ADC 
einlesen und diese dann anschließend weiter schicken.
Jetzt würde ich jedoch die DMA des xmegas für das Zwischenspeichern
verwenden. Auch das geht größtenteils.
Ab und zu stimmt der Wert nicht der gespeichert wird. Verwende ich die 
DMA nicht tritt dieses Problem nicht auf.

Ich verwende zwei DMA Kanäle einen um den SCK Takt zu erzeugen und den 
zweiten um die Daten vom USART.DATA auf den RAM zu schieben.

Dummy - Transmit DMA Channel
1
  DMA.CH1.ADDRCTRL  = DMA_CH_SRCRELOAD_NONE_gc | DMA_CH_SRCDIR_FIXED_gc | DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_FIXED_gc;
2
  DMA.CH1.TRIGSRC   = 0x4C;           // ADC SPI DRE
3
  DMA.CH1.TRFCNT    = 2;            // buffer size
4
  DMA.CH1.SRCADDR0 = (((uint32_t) (dummy_spi_buffer))>>0*8) & 0xFF;
5
  DMA.CH1.SRCADDR1 = (((uint32_t) (dummy_spi_buffer))>>1*8) & 0xFF;
6
  DMA.CH1.SRCADDR2 = (((uint32_t) (dummy_spi_buffer))>>2*8) & 0xFF;
7
  DMA.CH1.DESTADDR0  = (((uint32_t)(&USARTC0.DATA))>>0*8) & 0xFF;
8
  DMA.CH1.DESTADDR1  = (((uint32_t)(&USARTC0.DATA))>>1*8) & 0xFF;
9
  DMA.CH1.DESTADDR2  = (((uint32_t)(&USARTC0.DATA))>>2*8) & 0xFF;

Receive DMA Channel
1
  DMA.CH2.ADDRCTRL  = 0b11000101;     // fixed source addr , incr des, reload dest end block
2
  DMA.CH2.TRIGSRC   = 0x4C;           // ADC SPI DRE
3
  DMA.CH2.TRFCNT    = 2;            // buffer size
4
  
5
  DMA.CH2.DESTADDR0 = (((uint32_t) (usb_tx_buffer_fill))>>0*8) & 0xFF;
6
  DMA.CH2.DESTADDR1 = (((uint32_t) (usb_tx_buffer_fill))>>1*8) & 0xFF;
7
  DMA.CH2.DESTADDR2 = (((uint32_t) (usb_tx_buffer_fill))>>2*8) & 0xFF;
8
  DMA.CH2.SRCADDR0  = (((uint32_t)(&USARTC0.DATA))>>0*8) & 0xFF;
9
  DMA.CH2.SRCADDR1  = (((uint32_t)(&USARTC0.DATA))>>1*8) & 0xFF;
10
  DMA.CH2.SRCADDR2  = (((uint32_t)(&USARTC0.DATA))>>2*8) & 0xFF;
11
DMA.CH2.CTRLA     = 0xA5;


Ich starte den DMA - Transfer mit
1
 DMA.CH1.CTRLA     = 0x86;


Kann mir hier vielleicht wer helfen?

LG chgamauf

von Christoph G. (chgamauf82)


Lesenswert?

So nach einer Zigarette und einem Kaffee habe ich den Fehler gefunden.
Es reicht der Receive DMA Channel und zum Starten verwende ich jetzt
1
  DMA.CH2.CTRLA= 0x86;
2
  USARTC0.DATA=0;

LG chgamauf

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.