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
Da der Controller der Master ist macht der Controller den SCK. Wie macht man den SCK weiter ? Indem man zB 0xFF sendet, oder sonst was.
wieso soll ich was senden, wenn ich empfangen will? Im Vollduplex geht das zwar, aber sinnvoll ist das nicht. Oder doch?
Ein slave wird nie den SCK bewegen. Nur der Master. Send ein 0xFF und lies das SPIDR, und gut ist. SPI geht nun mal so.
>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.
SDI (MISO) mal mit ein paar Kiloohm (4k7 - 10k) gegen High legen.
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
Ob halbduplex, oder vollduplex ist keine Sache des SPI masters sondern des devices. Das device weiss wann es senden muss. gemaess Datenblatt.
@ 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 ist denn das für ein Slave und wie sieht der Schaltplan aus?
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.
Dann würde ich fast vermuten, dass der MISO als Output konfiguriert ist!
Alternativ werden die beiden Chips mit unterschiedlichen Spannungen versorgt....?
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.
Mit welchen Spannungen werden die Teile versorgt? 3,3V und 5V?
@Jürgen (Gast) wie hast du den Pin 40 (VMode) beschaltet? Hast du das ganze Datenblatt mal durchgelesen? Cheers Felix
@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.
>der µC mit 5, der LTC von 10-50V (ja wirklich)
deshalb die Pegelanpassung
>> 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?
Ich sollte mehr Ahnung in E-Technik haben *asche über mein haupt streu*: Was ist wenn ich den µC-MISO-Pin als OpenDrain schalte?
>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.
Noch jemand eine Idee dazu, was man gegen den Offset machen kann?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.