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:
1 | #define SCK 5 // USART XCK
|
2 | #define MISO 6 // USART RxD
|
3 | #define MOSI 7 // USART TxD
|
4 | #define SS 4 // just an output pin
|
5 |
|
6 | // set the TxD pin value high, and optionally the XCK pin low
|
7 | PORTD.OUTSET = (1 << MOSI);
|
8 | PORTD.OUTCLR = (1 << SCK);
|
9 |
|
10 | // set the TxD and optionally the XCK pin as output
|
11 | // and chip select as output
|
12 | PORTD.DIRSET = (1 << MOSI) | (1 << SCK) | (1 << SS);
|
13 |
|
14 | // MISO is input
|
15 | PORTD.DIRCLR = (1 << MISO);
|
16 |
|
17 | // max 400 kHz allowed during initialization
|
18 | // 29.4912 MHz / (2 * (39 + 1)) = 368.64 kHz
|
19 | USARTD1.BAUDCTRLA = 39;
|
20 | USARTD1.BAUDCTRLB = 0;
|
21 |
|
22 | // set spi mode and bitsize
|
23 | USARTD1.CTRLC = USART_CMODE_MSPI_gc | USART_CHSIZE_8BIT_gc;
|
24 |
|
25 | // interrupt
|
26 | USARTD1.CTRLA = USART_RXCINTLVL_LO_gc;
|
27 |
|
28 | // enable RX and TX
|
29 | 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?