Forum: Mikrocontroller und Digitale Elektronik SilLabs C8051F320, SPI-Master- WCOL-Problem


von Uwe (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich prgrammiere gerade ein Testprogramm für eine 
Single-Master-SPI-Verbindung
und bekomme dabei Schwierigkeiten mit dem WCOL-Interrupt. Er blockiert 
ab einer bestimmten Stelle permanent den Ablauf meines Programmes.

Daher meine Frage:

Wie kann ich den SPI-Datenpuffer (SPI0DAT) löschen? Muß ich dies? --> 
Denn ich denke hier führt mein Problem hin.

-----------------
Habe mein Programm an folgende Programmbeispiele angelehnt:
- F32x_SPI0_Master.c von SilLabs
- Testbsp. vom Hersteller (ACAM) für den verwendeten TDC, der 
angesprochen werden soll, auch in C. (Allgm. gehalten für einen 
8Bit-8051-uC --> siehe PPT-Doku zum Projekt)

Unterschiede der Programmbeispiele bzgl. meiner Frage:

- Das ACAM-Testprogramm liest nach jedem Senden den Inhalt des SPIDAT um 
ihn zu "Löschen". Beim SilLab-Bsptext ist mir dies nicht aufgefallen.

 L> Ich habe bei meinem Testprogramm schon beides ausprobiert.

-----------------
Was soll mein Programm machen:
- Es soll ein Register eines TDCs zur Konfiguration füllen (also 
Schreibbefehl an TDC + 3 weitere Datenbyte)
- Danach geht ein spezieller Test-Lesebefehl an den TDC, welcher dann 
mit dem Inhalt des höchsten Datenbytes (aus der voran erwähnten 
TDC-Register) antworten soll.

Realisierung der SPI-Verbindung:
- Schreiben per Polling, alle Interrupts ausgeschaltet
- Lesen auch per Polling bei eingeschalteten Interrupts
- Mein Programm ist in Assembler gehalten. In C bin ich nicht so sicher, 
doch die Beispiele konnte ich verstehen.

Hintergrund:
- Habe meinen momentanen Projektstand angehängt, soweit es hier geht.



Ich hoffe mein Fragetext erschlägt Euch nicht.
Vielen Dank im Vorraus!

von Ralf (Gast)


Lesenswert?

> ...Schwierigkeiten mit dem WCOL-Interrupt. Er blockiert ab einer
> bestimmten Stelle permanent den Ablauf meines Programmes.
> Daher meine Frage:
> Wie kann ich den SPI-Datenpuffer (SPI0DAT) löschen? Muß ich dies? -->
> Denn ich denke hier führt mein Problem hin.
Ne, musst du nicht, denn wenn es wirklich der WCOL-Interrupt ist, dann 
hast du m.E. ein Verständnisproblem :)
Auszug aus Datenblatt:

WCOL: Write Collision Flag. This bit is set to logic 1 by hardware (and 
generates a SPI0 interrupt) to indicate that a write to the SPI0 data 
register was attempted while the transmit buffer already contained 
data. It must be cleared by software.

Hier stecken zwei Aussagen drin:
1. Schreibe nicht SPI0DAT, solange noch gesendet wird -> SPIF muss den 
Interrupt auslösen -> aktuelles Byte gesendet -> SPIF via Software 
löschen
2. WCOL muss ebenfalls durch Software gelöscht werden.

Ohne in deinen Code geschaut zu haben bleibt also grad die Frage, ob du 
irgendwo aus Versehen Daten ins Senderegister butterst, bevor der 
Transfer fertig ist, und ob du evtl. dann vergessen hast, die 
entsprechenden Flags zu löschen, da ja dann angeblich blockiert wird.

Ralf

von Uwe (Gast)


Lesenswert?

Hallo Ralf,

Du meinst also, daß ich nur die Flags zurücksetzen muss, nicht aber 
das SPI0DAT lesen, um den Grund für WCOL=1 zu beseitigen, richtig?

Oder kann es auch sein, daß ich mich um den SPI-Takt kümmern muß und 
dies das eigentliche Problem ist? Denn im SPI0DAT sehe ich nie mehr als 
00 oder FF, obwohl alle Übergabeadressen einwandfrei funktionieren.

Bisher bin ich davon ausgegangen, daß der Takt egal ist. Wann ist für 
mich der  SPI-Takt interessant?

Vielen Dank für die Antwort!
Boris

von Uwe (Gast)


Lesenswert?

Vielleicht dazu noch eine Frage zu WCOL, TXBMT und SPIF:

Betrachte ich nur den Schreibevorgang, so verbergen sich hinter dem 
SPI0DAT 2 Register (siehe Doku C8051F320: Figure 18.1. SPI Block 
Diagram). Ein Shift-Register, der eigentliche Ein- und Ausgang und ein 
Sende-Übergansregister (in Figure 18.1 "Transmit Data Buffer" genannt).


Sind meine Vermutungen so richtig?:

TXBMT = 0 wenn in Sende-Übergangsregister etwas reingeschrieben wird
      = 1 wenn an Shiftregister weitergegeben, (8Bit) innerhalb eines 
Taktes

SPIF = bezieht sich immer auf das Shiftregister, also 1 wenn letztes Bit 
gesendet (1 beim 9.Bit)

WCOL = 1 wenn im Shiftregister noch etwas steht und wieder etwas 
hineingeschrieben wird.


- Für mich ist das WCOL der in der Doku am ungeschicktesten beschriebene 
Punkt.

von Ralf (Gast)


Lesenswert?

> Du meinst also, daß ich nur die Flags zurücksetzen muss, nicht aber
> das SPI0DAT lesen, um den Grund für WCOL=1 zu beseitigen, richtig?
Nicht ganz. Den Grund beseitigst du damit nicht, aber WCOL gehört zu 
den Flags, die den Controller veranlassen, die SPI-ISR anzuspringen. 
Löschst du generell die Interrupt-Flags nicht, welche IRQs auslösen 
können, wird nach Verlassen der Interrupt-Routine ein Befehl des 
Hauptprogramms (oder einer unterbrochenen, niedriger priorisierten 
Interrupt-Routine) ausgeführt, und sofort wieder in die 
Interrupt-Routine gesprungen.
Den Grund muss man rausfinden, denn eigentlich sollte WCOL bei 
korrekter Implementierung der SPI-Routinen gar nicht gesetzt werden.

> Oder kann es auch sein, daß ich mich um den SPI-Takt kümmern muß und
> dies das eigentliche Problem ist?
Natürlich musst du dich "kümmern". Die Antwort ist genauso wachsweich 
wie die Frage :)
Du kannst beispielsweise nicht mit 20MHz rauspusten, wenn dein Slave nur 
maximal 5MHz kann.

> Denn im SPI0DAT sehe ich nie mehr als 00 oder FF, obwohl alle
> Übergabeadressen einwandfrei funktionieren.
SPI0DAT zu lesen gibt dir das Empfangsregister, Schreiben in SPI0DAT 
verwendet ein anderes Register!

> Bisher bin ich davon ausgegangen, daß der Takt egal ist. Wann ist für
> mich der  SPI-Takt interessant?
Siehe oben, ist u.a. davon abhängig, wie schnell der F320 getaktet ist, 
ob er Master/Slave und wie schnell dein Slave ist.
Hinzu kommt noch, ob du 3- oder 4-Wire implementierst etc.
Die o.g. empfangenen 0x00/0xFF können auf verschiedene Sachen hindeuten. 
Entweder sendet dein Slave nichts bzw. er bekommt die Takte nicht 
richtig mit, oder SPI0 ist noch nicht richtig konfiguriert -> Hast du 
das Interface in der CrossBar richtig eingestellt bzw. kannst du prüfen, 
ob MOSI/MISO/SCK/SS an den richtigen Pins rauskommen? Wenn die CrossBar 
falsch konfiguriert bzw. generell nicht aktiviert(!) ist, kommt auch 
nirgends was an. Was das SPI0DAT macht, wenn SPI0 in der CrossBar nicht 
konfiguriert ist, weiss ich nicht.

> Vielleicht dazu noch eine Frage zu WCOL, TXBMT und SPIF:
Nur zu... :)

> Betrachte ich nur den Schreibevorgang, so verbergen sich hinter dem
> SPI0DAT 2 Register (siehe Doku C8051F320: Figure 18.1. SPI Block
> Diagram). Ein Shift-Register, der eigentliche Ein- und Ausgang und ein
> Sende-Übergansregister (in Figure 18.1 "Transmit Data Buffer" genannt).
> Sind meine Vermutungen so richtig?:

> TXBMT = 0 wenn in Sende-Übergangsregister etwas reingeschrieben wird
>       = 1 wenn an Shiftregister weitergegeben, (8Bit) innerhalb eines
Taktes
Wenn TXBMT gesetzt ist, kannst du neue Daten in SPI0DAT schreiben

> SPIF = bezieht sich immer auf das Shiftregister, also 1 wenn letztes Bit
> gesendet (1 beim 9.Bit)
Wieso 9.Bit?
SPIF wird gesetzt, wenn ein Byte rausgepustet bzw. empfangen wurde. Muss 
bei zugelassenem Interrupt in der ISR gelöscht werden.

> WCOL = 1 wenn im Shiftregister noch etwas steht und wieder etwas
> hineingeschrieben wird.
Nein, es ist gesetzt, wenn im Sendebuffer Daten stehen, die noch nicht 
ans Shiftregister gegeben wurden.

> - Für mich ist das WCOL der in der Doku am ungeschicktesten beschriebene
> Punkt.
Nja, wie man's nimmt. Ich hab auch schon schlimmere Datenblätter gesehen 
(Atmel, Philips) grins
Aber generell gehören die SiLabs Datenblätter m.E. zu den 
detailiertesten.

Fazit: Poste doch bitte mal deinen Code für die CrossBar/Port- sowie 
SPI-Initialisierung, für den System- und SPI-Takt sowie die SPI-ISR und 
evtl. die Routinen, die die SPI-Daten verarbeiten. Sofern sich da nichts 
zum o.g. ZIP-File geändert hat, kann ich nachher mal dort reingucken, 
wenn das ZIP-File komplett ist. Aber jetzt geh ich erstmal kurz was 
essen :)

Ralf

P.S: Heisst du jetzt eigentlich Uwe oder Boris?

von Ralf (Gast)


Lesenswert?

Ach ja, vor der Vorspeise noch folgende Bitte: Lies doch bitte mal 
SPI0CFG und SPI0CN im Fehlerfall aus und sag mir was drinsteht.

Ralf

von Uwe (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Ralf,

im Internet wechseln meine Namen ständig.

Die Konfiguration steckt bereits im beigelegten Kode des Zip-Files drin.
Doch ich habe die neueste Version Programmversion plus Wizard-File 
angehängt.
Phase und Polarisierung sollten so wie sie im Wizard-File beschrieben 
sind stimmen. Denke im Programmtext sind sie noch anders, weil ich heute 
daran herum probiert hatte.

Ich halte es für sehr unwahrscheinlich, daß die Pins im Layout 
verwechselt wurden. Aber ich werde es morgen nochmal prüfen. Ich bin 
vielmehr auf eine weitere wahrscheinlichere Fehlerquelle gestoßen:

Ich habe den TDC (Slave) mit 6MHz per uC getaktet. Laut TDC wurden 
2...8MHz gewünscht. Heute jedoch habe ich gelesen, daß der geforderte 
SPI-Takt weit darüber liegt (25MHz), kann das stimmen?? Denn so wie ich 
den uC verstehe kann er für den SPI nur einen Takt verwenden der 
langsamer ist, als der Sysclock und in jedem Fall unterhalb 25MHz.

Im Allgemeinen kann ich nur vom SPI0DAT lesen, was vom Slave geschickt 
wurde, also nicht das was der Master dort selbst rein getan hat. Ist das 
richtig?


SPI0DAT  SPI0CFG  SPI0CN PC  Text
00       6B       0B     151 mov A,R2 ; R2 = Schreibinhalt
00       6B       0B     152 mov SPI0DAT,A
00       6B       09     154
00       6B       0B     154 jnb TXBMT,$
00       EB       0B     157 mov A,SPI0DAT
00       EB       0B     159 mov R7,A ; R7 = Dummyregister
00       EB       0B     15A clr WCOL ; heute zu Testzwecken eingefügt
...
FF       6B       8B     142 call SPI_SENDEN
FF       6B       8B     151 mov A,R2
...ISR

Hoffe es haben sich beim Schreiben (hier) keine Fehler eingeschlichen, 
aber so müßte der momentane Verlauf sein.


Vielen Dank, nochmal, für Deine Mitarbeit, Ralf!

von Ralf (Gast)


Lesenswert?

> Ich halte es für sehr unwahrscheinlich, daß die Pins im Layout verwechselt
> wurden.
Aber ich halte es für mindestens möglich, dass die Konfiguration der 
CrossBar evtl. falsch ist. Wer sich zum ersten Mal mit SiLabs-MCU 
beschäftigt, braucht ne Weile, bis er versteht, dass er die Pinbelegung 
mit leichten Einschränkungen frei wählen kann. Daher ist das eine 
beliebte Fehlerquelle :)

> Ich habe den TDC (Slave) mit 6MHz per uC getaktet.
Hast du nicht. Nach meiner Rechnung pustest du 3MHz raus.
1
mov  OSCICN, #081h
IFCN1 = 0 und IFCN1 = 1 ergibt für SYSCLK interner Oszillator 12MHz mit 
Vorteiler durch 4 => Ergibt nach meiner Rechnung 3MHz SYSCLK

Passt aber immer noch in den erlaubten Bereich.

> Heute jedoch habe ich gelesen, daß der geforderte SPI-Takt weit darüber
> liegt (25MHz), ...
Erstens: Lass mich beim nächsten Mal bitte nicht nach dem Datenblatt 
suchen ;)

> ...kann das stimmen??
Zweitens: Nö, wenn du die Tabelle nochmal anguckst und genau liest, 
wirst du feststellen, dass sie dir sagt, dass du bei 2.0V 
Versorgungsspannung mit maximal 10MHz SPI-Takt fahren darfst, bei 2.5V 
mit maximal 20MHz und bei 3.3V mit maximal 25MHz. Wenn der 
geforderte Takt mindestens 25MHz sein müsste, würde nicht MAX in der 
Tabelle stehen, sondern... ? Richtig, MIN.
Datenblätterlesen/verstehen ist etwas, was man lernen muss :)
Ist je nach Hersteller gar nicht so einfach.

> Im Allgemeinen kann ich nur vom SPI0DAT lesen, was vom Slave geschickt
> wurde, also nicht das was der Master dort selbst rein getan hat. Ist das
> richtig?
Zumindest würde ich so das Blockbild der SPI-Schnittstelle 
interpretieren. Ist ja auch nicht nötig, zu lesen, was der Master (= du 
selbst) geschrieben hat, er weiss das ja :)

Was deinen Sourcecode an sich angeht, wen muss ich da eigentlich nun 
klopfen? oO
Deinen Professor oder dich?
Erstens: ISRs müssen mit RETI beendet werden, nicht mit RET!

Zweitens: Warum bedienst du die SPI-Schnittstelle gleichzeitig im 
Polling- UND im Interrupt-Betrieb? Da kannst du ja nur sche*sse 
rausbekommen.
Orientiert sich dein Code am SiLabs Beispielcode für SPI? Jedenfalls 
solltest du im normalen Code keine Flags beeinflussen, die den IRQ 
steuern oder beeinflussen können.
Entscheide dich für Interrupt oder Polling, aber nicht beides 
gleichzeitig :)
Interrupt ist etwas komplexer, aber dafür musst du nicht wie bei Polling 
auf irgendwas warten.

Drittens: Was um Gottes willen macht dein SPI-IRQ?
1
  jnb SPIF,ISR_SPI_SPIF
Sollte wohl eher JB anstatt JNB heissen, oder? Das gleiche für die Zeile 
drunter. Abgesehen davon, mit dem ganzen Konstrukt musst du die ISR 
zweimal durchlaufen, wenn beide Flags gesetzt sind.

> Vielen Dank, nochmal, für Deine Mitarbeit
Bitte, wir haben ja beide was davon.

Ralf

von Uwe (Gast)


Lesenswert?

Hallo Ralf,

habe 6MHz wieder eingestellt,
jb statt jnb in der ISR korrigiert,
keine Interrupts außerhalb der ISR mehr rückgesetzt,
ISR wurden bei mir bereits richtig mit reti beendet - s.oben bei den 
ORG-Befehlen,
Datenblatt wollte ich nicht angängen, weil schon auf JPG... hingewiesen 
wurde...

...gleiches Problem.  :S

Doch ich habe den Grund gefunden. Und ich wollte es nicht glauben!!!
Die Pinbelegung wurde im Layout vertauscht.
SCK (uC) liegt auf SO (TDC) und
MISO (uC) liegt auf SCK (TDC).

Ich lerne daraus wieder einmal, daß man alles selbst kontrollieren muss.

Vielen Dank Ralf.



PS: Sollte die Geschichte weitergehen hänge ich das Datenblatt zum 
TDC-GP2 mit an.

von Ralf (Gast)


Lesenswert?

Hi,

> Doch ich habe den Grund gefunden. Und ich wollte es nicht glauben!!!
> Die Pinbelegung wurde im Layout vertauscht.
grins
Siehst du, genau deswegen habe ich auch diesen möglichen Fehlerfall 
erwähnt :) Bei fix vergebenen Pinfunktionen ist es schwierig, etwas 
falsch zu machen, aber ein Layouter, der nicht weiss, dass sich die 
Pinfunktionen verschieben können, fällt dann schon mal auf die Nase.

Das ggw. Software-Design mag zwar funktionieren, ist aber m.E. 
fehleranfällig bzw. -behaftet. Wenn du die Zeit übrig hast, solltest du 
das Schritt für Schritt überarbeiten.

Ralf

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.