Forum: Mikrocontroller und Digitale Elektronik [SAM7] SPI + VS1011 = Problem


von Thomas P. (pototschnig)


Lesenswert?

Hallo,

ich hab da ein sehr seltsames Problem. Und zwar hab ich an meinem
SAM7S256 per SPI-Bus folgende Peripherie dran: LCD-Display, MP3-Decoder
(VS1011B), SD-Card. Sowohl LCD-Display als auch SD-Card funktionieren
einwandfrei. Beim MP3-Decoder hab ich aber Probleme. Nach ewigem
rumtüfteln und rummessen bin ich zu dem Schluss gekommen, dass man zwar
korrekt Daten in den Decoder schreiben kann, sie beim Lesen auch korrekt
rauskommen (sagt mir mein Oszi), aber der SAM7 die Daten falsch
einliest. Polarität und Phase des Busses passen. Der Decoder
funktioniert ansonsten so wie er soll. Man kann ihn konfigurieren und
er dekodiert auch brav den MP3-Stream. Aber man kann um's verrecken
(und egal welchen der 4 SPI-Modis ich ausprobiere) keine Sinnvollen
Daten zurücklesen.
Schreibe ich z.B. in das VOLUME-Register 0xaa55 kommt 0xffaa zurück.
Schreibe ich 0x2020 rein, kommt 0x0020 raus. Etwas sehr verwirrend. Ich
hab auch schon alle möglichen BUS-Geschwindigkeiten mit alle möglichen
Delays versucht, aber da ändert sich nichts.

Hat jemand ähnliche Erfahrungen gemacht oder hat noch einen Tipp, was
man probieren könnte?

von Dirk B. (dirk-)


Lesenswert?

Hi,

uebertraegst du vielleicht mit einer falschen befehlsbreite?

von Thomas P. (pototschnig)


Lesenswert?

Der SAM7 kann leider keine 32Bit SPI Transfers. Das hab ich dann in 4*
8Bit aufgeteilt (2*16Bit verhält sich genauso). Damit aber das CS nicht
nach jedem Byte wieder auf high geht, hab ich das so konfiguriert:

Im CSR (Chip-Select-Register) hab ich CSAAT (=Chip Select Activ After
Transfer) gesetzt, das mir die CS-Leitung nach einem Transfer aktiv
lässt. So werden erstmal 3 Byte übertragen und beim 4ten Byte wird dann
im Dataregister zusätzlich das LASTXFER-Bit gesetzt. Das ist dazu da,
dass dann nach dem Transfer das CS wieder inaktiv geschalten wird. Das
sieht dann im gesamten so aus, als wäre es ein 32Bit Transfer gewesen.

Gelesen wird so:
Es werden erstmal READ und Adresse rausgeschrieben. Dann gehts in die
Empfangsroutine. Die löscht erstmal das Overflow-Bit im
SPI-Statusregister (Datenblatt:"If the SPI_RDR (Receive Data Register)
has not been read before new data is received, the Overrun Error bit
(OVRES) in SPI_SR is set. As long as this flag is set, no data is
loaded in SPI_RDR. The user has to read the status register to clear
the OVRES bit."), schreibt dann ein 0xff raus und liest danach vom
Receive Data Register das empfangene Datum ein. Das passiert 2 mal
hintereinander. Im letzten Transfer wird dann LASTXFER wieder gesetzt.

Irgendwie hab ich so das Gefühl, dass ich irgendwie ein alter Byte oder
so auslese. Bei dem Beispiel aus meinem ersten Posting lässt sich
erkennen, dass das zweite Byte das ausgelesen wird, gleich ist mit dem
ersten, das man kriegen sollte.

Mach ich das mit dem Empfangen überhaupt richtig? Also mit der SD-Card
geht das so wunderbar, aber vielleicht ist das nur Glück.

von Thomas P. (pototschnig)


Lesenswert?

Ich glaub ich weiß jetzt wo mein Problem ist:
Datenblatt:"When all the bits are processed, the received data is
transferred in the Receive Data Register and the RDRF bit rises. If
RDRF is already high when the data is transferred, the Overrun bit
rises and the data transfer to SPI_RDR is aborted."

Bei mir ist das so, dass ich beim Empfangen das Overflow-Bit lesen und
damit lösche. Es ist aber von vorherigen Transfers eventuell noch ein
Datum im Receive-Data-Register, das ich nicht rausgelesen habe. Das
Overflow-Bit wird deshalb erst dann gesetzt, wenn ich einen neuen
Transfer anschmeisse, der dann das gewünschte Datum in das
Data-Register speichern soll. Da ist aber noch der Schrott von vorher
drin und das Overflow wird gesetzt. Beim 2ten Byte wird erkannt, dass
Overflow gesetzt ist und es wird gelöscht. Dann funktioniert es so wie
es soll :-) Muss ich dann gleich mal ausprobieren g

Meistens hilft es mir schon etwas zu erklären, weil man dann relativ
komplexe Vorgänge doch in etwas verständliches übersetzen muss. Da
fallen mir die Fehler dann gleich schon immer selber auf :-)

von Thomas P. (pototschnig)


Lesenswert?

Nein - das wars auch nicht. Man kann doch da kaum was falsch machen ?!

von MartinS (Gast)


Lesenswert?

Du macht bestimmt einen Fehler beim einlesen der Bytes. Das erste Byte
sieht nach einem Dummy Byte aus und das 2. das Byte was du brauchst und
das 3. liest du nicht ein.

von MartinS (Gast)


Lesenswert?

Bzw. hast du die Reihenfolge beachtet. Ich kenne zwar den ARM nicht aber
du braucht trotzdem bestimmt diese Reihenfolge:


1. Dummy Byte senden damit der SPI-CLK erzeugt wird
2. Lesen, was der VS1011 gesendet hat
3. Dummy Byte senden damit der SPI-CLK erzeugt wird
4. Lesen, was der VS1011 gesendet hat

von Thomas P. (pototschnig)


Lesenswert?

<<<
Das erste Byte
sieht nach einem Dummy Byte aus und das 2. das Byte was du brauchst
und
das 3. liest du nicht ein.
>>>

Das ist auch meine Theorie, ich hab aber noch nicht rausfinden können
wo ich das dummy-byte herkrieg.

<<<
1. Dummy Byte senden damit der SPI-CLK erzeugt wird
2. Lesen, was der VS1011 gesendet hat
3. Dummy Byte senden damit der SPI-CLK erzeugt wird
4. Lesen, was der VS1011 gesendet hat
>>>
Genauso hab ich es immer gemacht. Ich hatte als letztes Müll im
Empfangsbuffer vermutet aber das auslesen, bis nichts mehr drin ist und
danach erst das Dummy-Byte senden hat nicht funktioniert.

von MartinS (Gast)


Lesenswert?

Dann fällt mir im augenblick nichts dazu ein.

von gerhard (Gast)


Lesenswert?

hallo thomas,
beim lesen list du beim ersten byte immer das zuletzte gesendete byte
=> ein dummy-byte mehr senden.

gruss
gerhard

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.