Xmega: USART im SPI Modus empfängt nichts

OP #2710065
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
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.
OP
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.