Hallo,
ich habe es mit einem Infineon XC888CM zu tun.
Die Konfiguration (SPI usw.) habe ich größtenteils mit dem Assistenten
DAvE vorgenommen, der SPI und alles andere schön einstellt. Des weiteren
habe ich das UserManual schon ausgiebig studiert, habe aber keine Lösung
(irgendein Bit eines SPI-Registers o.ä.) gefunden.
UserMan:
http://www.infineon.com/dgdl/XC88xCLM_UM_v1_1.pdf?folderId=db3a304412b407950112b408e8c90004&fileId=db3a304412b407950112b40c53da0b0b
^^Kapitel 12.3 (ab Seite 12-31)
Folgende Situation: der µC als SPI-Master. Die Kommunikation mit dem
Slave funktioniert prinzipiell, zumindest einseitig, d.h.:
Senden funktioniert einwandfrei, der Slave tut auch nach Senden von
Befehlen das, was er soll. Problem: Wenn ich dem Slave sage, dass er mir
was schicken soll, verweigert der µC den SCK weiter zu treiben, damit
der Slave dann auch seine Daten auf die Leitung legen kann.
Beim Transmit schreibe ich meine Daten ja einfach ins Transferregister
und schon beginnt der SPI die Daten ordentlich zu senden.
Wenn ich im Gegenzug Daten aus dem Receiveregister lese, sollte ja das
gleiche passieren: Master generiert den Clock und Slave haut seine Daten
auf SDO.
Fakt ist aber: Die Leitung bleibt nach dem Senden des Lesekommandos an
den Slave (Transmit) tot, wo eigentlich etwas zu empfangen sein sollte.
Zur Veranschaulichung noch das Oszi-Bildchen dazu: Oben SCK, unten
SDI/SDO.
Die Leseabfolge: Ich sende ein Read-Kommando, warte bis der Bus frei ist
und lese dann das Receiveregister aus.
Eine Abfrage des Receive-Interrupt-Bits
if (IRCON1 & 0x04) // if Receive Interrupt Request
bringt auch keinen Erfolg, denn dahin kommt er gar nicht.
Was kann man da machen?
Vielen Dank für eure Hilfe.
Zum Abschluss: Meine SPI-Konfigs:
/// - Port Selection
SSC_PISEL = 0x00; // load SSC Port Input Select Register to
// Port A
///
-----------------------------------------------------------------------
/// Configuration of the used SSC Port Pins:
///
-----------------------------------------------------------------------
/// Pin SCLK (P1.2) is selected for SCLK ouput
/// Pin MTSR_0 (P1.3) is selected for Master Transmit Output
/// Pin MRST_0 (P1.4) is selected for Master Receive Input
/// Pin CSBO (P1.5) is selceted for Master Chip Select Output
SFR_PAGE(_pp1, noSST); // switch to page 1 without saving
P1_PUDSEL |= 0x14; //P1.4 SDI Pull-up (wird von Slave benötigt)
P1_PUDEN |= 0x14; //Test: P1.2 Clock pull-up
//funzt auch ohne CLK-Pull-up nicht.
SFR_PAGE(_pp2, noSST); // switch to page 2 without saving
P1_ALTSEL0 |= 0x1C; // set AltSel0
P1_ALTSEL1 &= ~(ubyte)0x1C; // set AltSel1
SFR_PAGE(_pp0, noSST); // switch to page 0 without saving
P1_DIR |= 0x2D; // set OutPut Direction
SSC_CONH_P &= ~(ubyte)0x80; // enable access to control bits
///
-----------------------------------------------------------------------
/// Configuration of the SSC Baud Rate Generator:
///
-----------------------------------------------------------------------
/// - required baud rate = 500,000 kbaud
/// - real baud rate = 500,000 kbaud
/// - deviation = 0,000 %
SSC_BRH = 0x00; // load SSC baud rate time reload register
// high
SSC_BRL = 0x17; // load SSC baud rate time reload register
// low
///
-----------------------------------------------------------------------
/// Configuration of the SSC Operation Mode:
///
-----------------------------------------------------------------------
/// - this device is configured as SSC master
/// - transfer data width is 8 bit
/// - transfer/receive MSB first
/// - shift transmit data on the leading clock edge,
/// latch on trailing edge
/// - idle clock line is low,
/// leading clock edge is low-to-high transition
/// - check receive error is enabled
/// - check phase error is enabled
SSC_CONH_P = 0x46; // load SSC control register
SSC_CONL_P = 0xB7; // load SSC control register
SSC_CONH_P |= 0x80; // disable access to control bits
/// - SSC interrupt is enabled
IEN1 |= 0x02; // Enable SSC interrupt
>wieso soll ich was senden, wenn ich empfangen will?
Weil der Slave nichts von alleine sendet.
Der Master muss dazu einen Clock generieren.
Deshalb sendet man 0xFF.
Aha, und wieso generiert der Master keine Clock wenn ich einfach nur das
Receive-Register lese? Dann weiß der doch, dass ich Daten haben will.
...
Ok, mehr als Probieren kann ich das mit dem 0xFF senden ja nicht ...
schaun wir mal.
SPI sind zwei Schieberegister, eins das rausgeht, eins das reinkommt.
Und das Schieberegister lesen generiert keinen Clock, sondern laedt nur
dessen wert
Ok, dann hätte ich wohl einfach nur bisschen Grundverständnis von SPI
mitbringen müssen. Dass beim Lesen da intern wirklich nur das Register
ausgelesen wird war mit unbekannt.
Ich habs ausprobiert und es funzt in soweit, dass erstmal was aufm Bus
zu sehen ist. Ob das nun was ordentliches ist muss ich noch prüfen.
Danke für die erste Hilfe.
Hm.. 0xFF gut und schön, aber der µC sendet komischer Weise immer auf
beiden Kanälen: SDO und SDI. Nun sehe ich zwar Signale auf dem µC-SDI,
die vom Slave generiert werden, aber der Low-Pegel ist zu hoch, weil ich
ja 0xFF sende. (siehe Oszi-Screenshot). 1,8V sind bisschen im verbotenen
Bereich. Was macht man da? Pull-down-R oder sowas?
Danke für eure Hilfe.
Vielleicht mal das SPI diagramm anschauen ? MISO bedeutet
Master-In-Slave-Out, MOSI bedeutet Master-out-Slave-in. Das Device auf
der anderen Seite hat auch einen Eingang, ueblicherweise einen SDI, und
einen ausgang, der SDO. Jetz muss man die Richtigen zusammenschalten.
Was offensichtlich geschah, sonst waere eh nichts. Wenn nun dieser Pegel
zu hoch ist, so arbeiten zwei Ausgaenge aufeinander. Koennte es sein,
dass das Device kein SPI, sondern ein I2C ist, welches die Richtung
umschaltet ?
Die dinger sind schon richtig zusammengeschaltet. ;)
Der Slave hat definitiv eine SPI-Schnittstelle (kein I²C). Der
µC-Receive Input (MISO) Pin 1.4 ist wie oben in der Konfig angegeben
(P1_DIR |= 0x2D //BIT:0=Input,1=Output) als Input gesetzt. Trotzdem will
der µC dort auch immer gleichzeitig auch Senden (was mir unsinnig
erscheint, ich aber nicht ergründen konnte warum das so ist, trotz, dass
ich den Halbduplex, der in der Konfig oben noch fälschlicher Weise
angegeben ist (SSC_CONL_P = 0xB7 //oberstes Bit:
0=LoopBack(Halbduplex),1=normal(vollduplex)), wieder rausgenommen habe)
Die Bytes die Übertragen werden scheinen auf den ersten Blick auch i.O.
zu sein (abzüglich des Low-Offsets von 1,8V). Es liegt also wirklich nur
am 0xFF welches fälschlicher Weise auch auf dem MISO-Pin (1.4) gesendet
wird (warum auch immer). Ich habe außerdem schon versucht vor dem Senden
von 0xFF das MOSI-Pin zu blockieren, indem ich die Richtung auf Input
änderte (MISO ist ja sowieso Input - klar) - ohne Erfolg. Was mir grad
noch einfällt wäre, das Pin aus dem SPI-Modus für diese Zeit
rauszunehmen, sofern das überhaupt geht, denn dann muss ich den
SPI-Modus generell erstmal ausschalten, dann das Pin in den Normalen
I/O-Modus setzen, SPI wieder anschalten, Daten senden (wobei ich das
Receive-Register Lese), SPI ausmachen, MOSI-Pin wieder in SPI-Modus, SPI
wieder anmachen. Uiui ... Das probiere ich heute nicht mehr - Morgen ist
auch noch ein Tag. =)
Danke für eure Hilfe.
Aber danke für den Versuch.
Noch jemand einen Rat?
Ideen:
1.) du könntest einfach versuchen, eine 0 zu senden (falls nicht schon
probiert)
2.) prüfen, ober es zwischen MISO und MOSI auf der Platine ein
niederohmige Verbindung gibt
Grüße
@ Marco:
zu 1.) 0-Byte senden natürlich schon probiert, da zieht der µC die
Leitung gleich voll auf Low, sodass keine Daten vom Slave durchkommen
(der zieht ja seinerseits auch nur über den Pull-up vom µC die Leitung
auf Masse, wenn er ne 0 senden will - von daher kann das ja auch nicht
funzen).
zu 2.) Ja, eine "niederohmige" Verbindung besteht ab dem Moment, wo ich
bestimme welche Pins Ausgänge sein sollen (P1_DIR = 0x2D) --> zw. Pin
1.4 (MISO) und Pin 1.3 (MOSI) sind dann 240 Ohm (vorher 14K) - Kann mir
das einer erklären? Hängt das u.U. daran, dass MISO am Pull-up (wie vom
Slave erfordert) und MOSI ein Ausgang ist? warum die aber dann fast
kurzgeschlossen sind weiß ich nicht zu beantworten. Fakt ist: Beide Pins
hängen vor und nach P1_DIR an 5V - Es wird also wirklich intern eine
Verbindung gesetzt. Warum auch immer (LoopBack ist ja wie gesagt aus).
Danke für eure Gedankenimpulse
Also meine Idee von gestern hinkt noch einbisschen: Trotz dass ich den
SPI-Modus vorher ausschalte (SSC_EN=0), dann jetzt sogar zusätzich schon
einen anderen Port als MOSI wähle, SPI-Modus wieder einschalte, sendet
der trotzdem auf dem alten Pin 1.3 Daten. Ich glaub der will mich
foppen.
Das gibts ja nicht! Ich habe jetzt mal aus lauter Verzweiflung mit den
MISO und MOSI Leitungen rumgespielt. Egal welche Kombination ich
ausprobiere (1. Nur MOSI, 2. nur MISO, 3. µC-MISO an Slave-MOSI und
umgekehrt) - Der Slave reagiert immer darauf. (Selbst wenn ich nur die
MISO-Leitung an die richtigen Pins anlege - Der Slave empfängt also auch
auf dem Sendepin - so ein Schmarn!)
Was für ein IC hängt da als Slave dran?
(Evtl. Datenblatt in den Anhang).
Es gibt ICs denen kann man zum Lesen von Daten nicht irgendwas als
"Dummybyte/-Wort" senden, sondern es gibt dafür spezielle Bytes (glaub
ein
CC1100 Chipcon hat dafür ein speielles NOP Kommandobyte).
Slave ist ein LTC6802. Datenblatt im Anhang. Mit den Kommandos (in
diesem Fall Read-Kommando) stimmt ja aber alles soweit. Er führt ja das
aus was er soll, es geht nur um den erhöhten Low-Pegel beim Empfang von
Daten wie oben geschildert, den ich so nicht akzeptieren möchte.
Setz mal einen Widerstand (ca. 4k7) zwischen SDO und MISO. Dann miss die
Spannungen an beiden Seiten. Wenn an der SDO Seite die Spannung sauber
auf
0 runtergeht, dann muss wohl der MISO einen aktiven Ausgangstreiber
haben.
Alternativ dazu könnte es sein, dass Du dir den LTC irgendwie schon
abgeschossen hast. Dann hast Du hoffentlich noch ein paar Ersatz ICs
rumliegen.
Prüf mal sie Platine, nach den Beschreibungen vermute ich fast das du
Kurzschlüsse zwischen den einzelnen Pins hast.
Oder das eins/beide der IC's defekt sind.
@ Matthias: Also auf der LTC-SDO Seite wird mit zusätlichem R zwischen
µC MISO und LTC-SDO schön auf Masse gezogen. der LTC scheint also OK.
Beim LTC gibts auch zwischen SDI und SDO nen Megaöhmchen.
Der MISO ist eben genau nicht als Output definiert sondern hat lediglich
einen µC-internen Pull-up (siehe Konfig: P1_PUDSEL=0x10 & P1_DIR=0x2D
-->Pin 1.4=MISO). Warum aber trotzdem auf der Leitung gesendet wird ist
mir ja ebenfalls unklar.
Ja die beiden Komponenten haben verschiedene Spannungsquellen, die
Massen beider habe ich aber verbunden.
Danke für alles Denken.
@Ralph: inwiefern Pegelanpassung, außer, dass ich Masse schon verbunden
habe und der SDO-Pegel auch 5V hat?
@Felix: VMODE ist mit VREG verbunden, also TTL-Pegel. Ja das Datenblatt
hab ich schon paar mal durch (zumindest den relevanten Teil) ;)
Danke fürs Helfen.
>> deshalb die Pegelanpassung
Ist nicht notwendig, der LTC6802 hat eine internen Regler. Das SPI wird
ab diesem Regler betrieben.
@Jürgen (Gast)
poste doch mal dein Schema. Das wurde schon von anderen vorgeschlagen.
Cheers
>Warum aber trotzdem auf der Leitung gesendet wird ist>mir ja ebenfalls unklar.
Weil dort immer etwas gesendet wird wenn ein Clock anliegt.
Dazu muss an SDI nichts angeschlossen sein.
Sonst könnte man die Dinger nicht in Reihe schalten.
Der SDO kann nur 1,2mA sinken. Da der Lowlevel zu
hoch ist liegt die Vermutung nahe daß der Pullup
zu klein ist (oder doch ein Ausgang aktiv, wie auch immer).
@Felix: Hier ein unprofessionelles Aufbauschema. Der µC sitzt ja auf so
nem StarterKit, daher dort nix weiter dran. Hoffe das reicht euch so.
Wie gesagt, die Massen noch verbunden.
@Holger: Dass der Pull-up zu klein sein könnte hatte ich auch schon in
Betracht gezogen, allerdings habe ich daraufhin dann mal einen externen
5k Pullup versucht - ohne Erfolg - selbes Ding.
Problem ist eben, dass der µC auch auf MISO sendet.
holger (Gast):
>Weil dort immer etwas gesendet wird wenn ein Clock anliegt.>Dazu muss an SDI nichts angeschlossen sein.>Sonst könnte man die Dinger nicht in Reihe schalten.
^^könntest du das bitte genauer erläutern?
>5k Pullup versucht - ohne Erfolg - selbes Ding.
Viel zu klein. Laut Datenblatt ist die Spannung an
SDO bei 500uA bereits bei max. 0.3V. Und mit 5k
ziehst du doppelt so viel.
>Problem ist eben, dass der µC auch auf MISO sendet.
Dann könnte er einfach nur defekt sein.
Normal ist das nicht.
>holger (Gast):>>Weil dort immer etwas gesendet wird wenn ein Clock anliegt.>>Dazu muss an SDI nichts angeschlossen sein.>>Sonst könnte man die Dinger nicht in Reihe schalten.>^^könntest du das bitte genauer erläutern?
Ich meinte damit den SDO. Dort kann z.B. das zuletzt
gesendete Kommando wieder rauskommen wenn der Slave nichts
zum senden eingefügt hat. SPI besteht nur aus Schieberegistern.
>Viel zu klein. Laut Datenblatt ist die Spannung an>SDO bei 500uA bereits bei max. 0.3V. Und mit 5k>ziehst du doppelt so viel.
Stimmt, aber selbst bei doppelt so viel kommts noch nicht an das davon
Dreifache ran, was sich auf meiner Leitung befindet. Schon blöd.
>Dann könnte er einfach nur defekt sein.>Normal ist das nicht.
defekt wär noch blöder. Komisch eben nur, dass er nach der
Richtungszuweisung (P1.3 Output, P1.4 Input) da eine Verbindung zwischen
den Pins schaltet. Das ist wirklich nicht normal aber kann natürlich
auch noch an irgend einem Register liegen, was ich noch nicht entdeckt
habe, obwohl das ja mit der Konfiguration über den Assistenten
einwandfrei laufen sollte. Hach!
>Ich meinte damit den SDO. Dort kann z.B. das zuletzt>gesendete Kommando wieder rauskommen wenn der Slave nichts>zum senden eingefügt hat. SPI besteht nur aus Schieberegistern.
^^Achso, ja das ist richtig.
Hallo Jürgen,
hast du schon weitere Erfolge verzeichnen können?
Bei mir tritt der gleiche Effekt auf.
Habe auch das EasyKit XC888-LQFP von Infineon.
Ich habe als Slave einen RFM21b, da ist aber im Prinzip egal, außer das
dort keine Pull-Up/Down-Rs an den Ltg gebraucht werden.
Mit dem Slave hat das anscheinend nichts zu tun, weil wenn dieser nicht
angeschlossen, dann passiert das trotzdem.
Das Signal auf SDI und SDO ist immer komplett gleich.
Noch jemand eine Idee?
Viele Grüße
Florian
Hm.. ist jetzt schon ein Weilchen her, dass ich mit dem Starterkit
rumgefummelt habe. Ich glaube, dass ich das dann einfach irgendwann
aktzeptiert habe, weils trotzdem ging und ich noch andere Sachen zu tun
hatte. Wie es jetzt auf dem selbst hergestellten Board aussieht könnte
ich ja mal testen - aber ich glaub da war der Pegel voll ok. Könnte als
an zu langen SPI-Leitungen zwischen Slave und Master hängen.