www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik XMega SPI über USART


Autor: Tobias K. (tobi123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nutze erfolgreich den SPI Bus, um Daten auf eine SD-Karte zu loggen. 
Nun möchte ich die DMA Funktionalität des XMega128A1 nutzen, um den 
Prozessor beim Schreiben der FAT Sektoren zu entlasten. DMA funktioniert 
aber nur, wenn man SPI über USART nutzt.

Nun habe ich zum SPI Mastermode des USART Fragen, da es bei mir noch 
nicht funktionieren will. Hier erstmal die Initialisierung:
#define SCK 5   // USART XCK 
#define MISO 6  // USART RxD
#define MOSI 7  // USART TxD
#define SS 4    // just an output pin

// set the TxD pin value high, and optionally the XCK pin low
PORTD.OUTSET = (1 << MOSI);
PORTD.OUTCLR = (1 << SCK);            

// set the TxD and optionally the XCK pin as output
// and chip select as output
PORTD.DIRSET = (1 << MOSI) | (1 << SCK) | (1 << SS);

// MISO is input
PORTD.DIRCLR = (1 << MISO); 

// max 400 kHz allowed during initialization
// 29.4912 MHz / (2 * (39 + 1)) = 368.64 kHz
USARTD1.BAUDCTRLA = 39;
USARTD1.BAUDCTRLB = 0; 
    
// set spi mode and bitsize
USARTD1.CTRLC = USART_CMODE_MSPI_gc | USART_CHSIZE_8BIT_gc;

// interrupt
USARTD1.CTRLA = USART_RXCINTLVL_LO_gc;

// enable RX and TX
USARTD1.CTRLB = USART_RXEN_bm | USART_TXEN_bm;

Danach schalte ich die Interrupts ein, setze Chipselect und sende über 
USARTD1.DATA.
Ist es nun richtig, den Receive Complete Interrupt (USARTD1_RXC_vect) zu 
nutzen? Er wird bei mir aufgerufen, aber das Empfangene Byte ist immer 
0. Beim "normalen" SPI kommt hier 0xFF von der SD-Karte. Vorher habe ich 
den Data Register Empty Interrupt genutzt, aber durch die Bufferung im 
USART macht das glaube ich beim USART keinen Sinn.

Also wie nutze ich SPI über USART richtig? Hat das schonmal jemand von 
euch hinbekommen?

Autor: Tobias K. (tobi123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe den Fehler entdeckt:
// set spi mode and bitsize
USARTD1.CTRLC = USART_CMODE_MSPI_gc | USART_CHSIZE_8BIT_gc;

Bitsize gibt es im SPI Modus nicht und die enstprechenden Bits im CTRL 
Register haben daher eine andere Funktion (UDORD und UCPHA). Durch meine 
Zuweisung werden daher UDORD und UCPHA falsch gesetzt, sie mussten auf 0 
stehen. Richtig ist daher
// set spi mode 
USARTD1.CTRLC = USART_CMODE_MSPI_gc;

Offensichtlich gibt es den USART SPI Modus nicht erst beim XMega. Hier 
habe ich eine Application Note zum Thema gefunden:
http://www.atmel.com/dyn/resources/prod_documents/...

Zum Thema Interrupts:
- Will man nur senden, dann kann man den Data Register Empty Interrupt 
nutzen um ein neues Byte zu schreiben. Durch die Pufferung des 
Senderegisters kriegt man dadurch die Bytes schneller raus als beim 
normalen SPI.

- Zum Empfangen sendet man wie immer erst ein Byte und wartet dann auf 
den Receive Complete Interrupt.

Ich werde jetzt DMA ausprobieren, aber dieser Thread ist wohl hiermit 
erledigt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.