Hallo,
ich versuche gerade die SPI Schnittstelle eines MEGA128 als Master für
die Ansteuerung einer MMC Karte zu verwenden, wobei der MMC Treiber
bereits von Nut/OS bereit gestellt wird.
Nur scheint das SPIF Flag nie gesetzt zu werden und meine Anwendung
hängt endlos.
1
#define SPIDDR DDRB
2
#define SPIPORT PORTB
3
#define SCLK 0x02
4
#define MOSI 0x04
5
#define MISO 0x08
6
7
staticuint8_tSpiMmCardIo(uint8_tval)
8
{
9
SPDR=val;/* put byte to send in SPDR, which initiates xmit */
10
while(!(SPSR&(1<<SPIF))){/* wait for completion */
11
printf("spi wait\n");
12
}
13
returnSPDR;/* return with byte shifted in from slave */
14
}
15
16
17
staticintSpiMmcIfcInit(NUTDEVICE*dev)
18
{
19
SPIDDR=SCLK+MOSI;
20
SPIPORT=0x00;
21
NutSleep(500);
22
SpiMmCardSelect(0);
23
SPCR=(1<<SPE)|(1<<MSTR);/* enable SPI as master, set clk divider and max speed */
24
NutSleep(250);
25
/* start off with 80 bits of high data with card deselected */
26
inti;
27
printf("\nSend dummy bytes\n");
28
for(i=0;i<10;i++){
29
SpiMmCardIo(0xff);
30
printf("byte send\n");
31
}
32
printf("\nInit device\n");
33
returnMmCardDevInit(dev);
34
}
Die Warteschleife sieht aber genau so aus, wie in der ATMEL Doku und
auch wird erst SPDR geschrieben, bevor das Flag zum ersten mal abgefragt
wird.
Auf dem UART erscheint endlos die "spi wait" Meldung und niemals "byte
send". Was geht hier schief?
> Auf dem UART erscheint endlos die "spi wait" Meldung und niemals "byte
send". Was geht hier schief?
Endlos? Es sollte doch eher einmal kommen und dann hängt es. Wenn es
endlos kommt stimmt was anderes nicht.
Gast wrote:
>> Auf dem UART erscheint endlos die "spi wait" Meldung und niemals "byte> send". Was geht hier schief?>> Endlos? Es sollte doch eher einmal kommen und dann hängt es. Wenn es> endlos kommt stimmt was anderes nicht.
Quatsch.
Simon K. (simon) wrote:
> Quatsch.
Selber Quatsch. Jetzt lieste nochmal durch was der OP geschrieben hat.
Einmal hängt die Anwendung endlos und einmal wird endlos spi wait
ausgegeben.
Entweder hängt es oder es gibt dauernd spi wait aus.
> Entweder hängt es oder es gibt dauernd spi wait aus.
Die Anwendung hing in der Warteschleife fest. Und um sicher zu gehen,
dass es auch wirklich die Warteschleife und nichts anderes (wie z.B.
Sprünge ins Nirvana) ist, hatte ich dann da die Meldung eingebaut, die
dann eben dauerhaft ausgegeben wurde.
>>> Ist /SS als Ausgang definiert?!>>Danke, den Teil im Datenblatt hatte ich übersehen. Jetzt funktionierts.
Gern geschehen! Zumal, hatte ich ähnliches Problem (den interessanten
Teil des Datenblattes zuvor geflissentlich ignoriert) auch schon mal.
mfg
SPCR=(1<<SPE)|(1<<MSTR);/* enable SPI as master, set clk divider and max speed */
Entweder solltest du da noch den Kommentar oder den Code ändern.
Maximale Frequenz des SPIs erreichst du erst, wenn auch SPI2X in SPSR
gesetzt ist (F_CPU / 2). Das nur so am Rande.
while(!(SPSR&(1<<SPIF)));// wait until transmission complete
5
}
Wenn ich das richtig verstehe, wird SPIF gesetzt, nachdem das byte durch
das Schieberegister durch ist, es muss also nichtmal ein zweites Gerät
angeschlossen sein, oder? Man empfängt im Gegenzug praktisch 0x00...
Also Kontroller wird bei mir vor Ausführung des Befehls eine LED
ausgeschaltet und nach dem Befehl danach wieder eingeschaltet. Sie geht
aus, aber nicht wieder an, entprechend wird es an der Schleife liegen.
Slave Select wird in der Initialisierung als Output gesetzt, das löst
das Problem leider nicht.
Vielen Dank schonmal!
Hey Holger,
danke für den Tipp, jetzt geht's! Super.
Heißt das, ich kann nur entweder den Interrupt oder die SPIF flag
verwenden? Der Interrupt ist bei mir nämlich ausgelöst worden, habe ich
festgestellt... jetzt ist er natürlich deaktiviert.
Übrigens: habe in dem Code noch einen anderen Fehler entfernt, es muss
natürlich
1
SPCR|=(1<<SPR0|1<<SPR1);
heißen, mit dem "|=" anstelle "=", sonst wird der ISP direkt wieder
deaktivert.
Danke nochmal!