Forum: Mikrocontroller und Digitale Elektronik Xmega Master SPI RX Problem


von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Community,


ich verzweifle gerade an einem Fehler eines Boards mit angeschlossenem 
SRAM und LCD Modul auf einem USART Master SPI.

Schreiben der Daten ist Einwandfrei. (LCD Modul ist in Betrieb)
Beim Rücklesen der Daten habe ich aber einen "um eins daneben" Fehler. 
Ein "0xFF" auf der MISO Leitung interpretiert der Xmega als "0x7F".

Ich Versuche, Wörter aus dem LCD RAM herauszulesen. Diese müssten 
0xFF00, 0xFF00 ... heißen, der Controller liest aber 0x7F80, 0x7F80 ... 
usw.


Die Bitreihenfolge ist um eins nach Rechts verschoben, obwohl die Daten 
richtig im Bus anliegen. (Siehe Foto im Anhang)

Codeschnipsel zur Initialisierung:
1
  PORTC.PIN5CTRL = (PORT_INVEN_bm | PORT_OPC_PULLUP_gc);
2
  PORTC.OUTSET = (DISP_MOSI | DISP_CLK | LCD_CS);
3
  PORTE.OUTSET = LCD_CS;
4
  
5
  DISP_USART.BAUDCTRLA = 32;
6
  DISP_USART.BAUDCTRLB = 0;
7
  
8
  DISP_USART.CTRLC = (USART_CMODE_MSPI_gc);
9
  DISP_USART.CTRLC |= (USART_CHSIZE1_bm);
10
  DISP_USART.CTRLB = USART_TXEN_bm | USART_RXEN_bm;

PIN5 ist hier die CLK Leitung


Lese / Empfangsroutine:
1
uint8_t LCD_TX_RX(uint8_t DataByte)
2
{
3
  uint8_t temp;
4
5
    while (DISP_USART.STATUS & USART_RXCIF_bm)
6
      temp = DISP_USART.DATA;
7
  
8
    DISP_USART.DATA = DataByte;              
9
    while (!(DISP_USART.STATUS & USART_RXCIF_bm)) {;}    
10
    return DISP_USART.DATA;
11
}
die while Schleife soll Müll aus dem Empfangsregister holen.
Danach Dummy Byte schreiben, das empfangene Zurückgeben. Mehr sitzt da 
nicht zwischen.


Hat jemand eine Idee woher das kommen kann?


Danke

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


Lesenswert?

Geh einfach immer so vor, dass Du für jedes gesendete Byte auch immer 
eins ausliest. Ansonsten kann es zu einem RX-Buffer-Overflow kommen.

Kurze Frage: Warum invertierst Du Port C5?

von Markus (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Kurze Frage: Warum invertierst Du Port C5?

Um den korrekten Modus im Master SPI zu fahren (Atmel Dokumentation)
Bei USART Master SPI sollte das mit dem INVEN Bit des Clockpins und dem 
UCPHA Bit im CTRLC Register passieren.



Es wird mit der Funktion auch immer das Data Register geleert wenn ein 
Byte gesendet wird. Die "While" Schleife ist entstanden weil ich mal 
vermutet habe dass der Controller sich irgend ein Müll-Bit in das Shift 
Register holt, denn bevor ich im Programm Daten zurücklese, wird jede 
Menge gesendet (LCD Init, ClearDisplay, Hauptmenüaufruf)




Noch eins.

Schalte ich kurz vor dem SPI Transmit per Hand (Im Debugging Fenster) 
das UCPHA bit aus und wieder ein kommen alle Daten sauber rein.

Mit einer entsprechenden Codezeile fuktioniert das nicht.

von Markus (Gast)


Lesenswert?

Problem gelöst:

1
uint8_t LCD_TX_RX(uint8_t DataByte)
2
{
3
  uint8_t temp;
4
5
    DISP_USART.CTRLB |= USART_RXEN_bm;
6
    DISP_USART.DATA = DataByte;            
7
    while (!(DISP_USART.STATUS & USART_RXCIF_bm)) {;}    
8
      temp = DISP_USART.DATA;
9
    DISP_USART.CTRLB &= ~(USART_RXEN_bm);
10
    
11
    return temp;
12
}


So funktionierts, auch bei 16 MHz SPI Clock.

Das Shift Register des RX Puffers holt sich tatsächlich irgendwo ein 
Müll-Bit rein, was dann Probleme macht.

von abc (Gast)


Lesenswert?

>   DISP_USART.BAUDCTRLA = 32;
>   DISP_USART.BAUDCTRLB = 0;
>
>   DISP_USART.CTRLC = (USART_CMODE_MSPI_gc);

>   DISP_USART.CTRLC |= (USART_CHSIZE1_bm);

probier es doch mal mit

 DISP_USART.CTRLC |= USART_CHSIZE_8BIT_gc;

>   DISP_USART.CTRLB = USART_TXENEN_bm | USART_RXEN_bm;

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.