Forum: Compiler & IDEs Xmega: USART im SPI Modus empfängt nichts


von Marco V. (marcov)


Lesenswert?

Hallo,

ich schlage mich schon den ganzen Tag mit meinem Xmega256A3 herum. Ich 
möchte per USART im SPI Modus mit einem CAN Controller kommunizieren und 
teste das ganze momentan in einem einfachen Loopback-aufbau, also 
TX/MOSI und RX/MISO gebrückt um das gesendete Byte gleich wieder zu 
empfangen. Der Rückgabewert der Funktion soll dem übergebenen Byte 
entsprechen. Wenn das klappt, wird das ganze dann per Interrupt gelöst 
aber zunächst möchte ich es mit der einfachen Pollingmethode versuchen. 
Ich debugge mit AVR Studio 5.1 und dem AVR Dragon.

Konfiguriere ich den USART als asynchrone Schnittstelle, dann klappt es 
einwandfrei. Aber sobald ich mit
1
USARTD0.CTRLC=USART_CMODE_MSPI_gc[c] in den Master SPI Modus wechsle, empfange ich nichts mehr.
2
3
[c]unsigned char usart_read_byte(unsigned char byte){
4
  if(!(USARTD0.STATUS & USART_DREIF_bm)){      //Falls Modul noch sendet,
5
    while(!(USARTD0.STATUS & USART_TXCIF_bm));  //warten, bis Daten verschickt sind
6
    USARTD0.STATUS=USART_TXCIF_bm;      //Flag löschen
7
  }
8
  USARTD0.DATA=byte;          //Daten in den Sendepuffer schreiben
9
  while(!(USARTD0.STATUS & USART_RXCIF_bm));    //Auf empfangene Daten warten
10
  return USARTD0.DATA;
11
}


Per
1
while(!(USARTD0.STATUS & USART_RXCIF_bm))
 kann ich im async-modus auf das Eintreffen des Bytes im Eingangspuffer 
warten, im MSPI Modus wartet er ewig weil das Flag nie gesetzt wird.

Stattdessen auf USART_TXCIF_bm zu warten, bringt auch nichts. Die Idee 
kam mir, weil die zu empfangenen Bits ja gleichzeitig mit den gesendeten 
Bits reingetaktet werden müssten. Zumindest war das "damals" beim alten 
atmega so.

Leider habe ich momentan kein Oszilloskop zur Hand, kann aber mittels 
LED sehen, dass Daten rausgehen. Wie gesagt, asynchron klappt, SPI 
nicht. Es ist zum Haare raufen.

Habt ihr einen heißen Tipp für mich?

Grüße

von Gerhard G. (g_g)


Lesenswert?

Hallo,

ohne Gewähr:


Du sendest als SPI-Master, empfangen kann der Master nur von einem 
Slave.

Master nach Master wird bei SPI auch nicht funktionieren?


Da solltest du schon einen weiteren SPI-Slave aktivieren und testen, was 
bei einem Xmega ja der Fall ist.


Gruß G.G.

von Marco V. (marcov)


Lesenswert?

So,

das Problem ist gelöst. Der USART kann zwar viel, ist aber auch 
teilweise nicht direkt durchschaubar. Die drei zusätzlichen Puffer 
bilden ein FIFO im Empfangsmodul und wollen natürlich auch gelesen 
werden, damit das gerade empfangene Byte "nachrutscht". Also entweder 
immer lesen, auch wenn man die Daten gar nicht braucht, oder vor einem 
Lesevorgang dreimal lesen und die ersten beiden Bytes verwerfen.
Gelöst habe ich es jetzt nach dem Vorbild der Implementierung aus dem 
ASF, die ich für meine Zwecke noch ein wenig abstrahiert habe. Nach dem 
Schema kann man jetzt nach der Pollingmethode einzelne Bytes senden und 
empfangen, je nachdem ob man den Rückgabewert nutzt und ein Dummybyte 
schreibt oder den Rückgabewert nicht nutzt und Nutzdaten schreibt:
1
uint8_t usart_transfer(USART_t *port, uint8_t byte){  
2
  while(!(port->STATUS & USART_DREIF_bm));  //Warten, bis Sendedatenregister frei ist
3
    port->DATA=byte;              //Sendedatenregister laden
4
    while(!(port->STATUS & USART_TXCIF_bm));  //Warten, bis Daten durchs Schieberegister rausgetaktet sind
5
    port->STATUS=USART_TXCIF_bm;        //Sendeflag löschen (bleibt sonst aktiv)
6
    return port->DATA;              //Empfangenes Byte aus dem Empfangsregister zurückgeben
7
}

Beim Lesen wird nicht RXCIF, sondern TXCIF abgefragt. Naja, gut 
jedenfalls dass es das ASF gibt und dass da manchmal doch etwas 
sinnvolles drin steht ;).

Grüße

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.