Forum: FPGA, VHDL & Co. undefinierter Pegel auf der I2C-Leitung


von Heiko M. (edev)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich arbeite momentan an einem Projekt, bei dem ich ein Lattice-FPGA 
(MachXO2, auf dem entsprechenden Breakout-Board) über eine 
I2C-Schnittstelle konfigurieren möchte. Zu Testzwecken erfolgt die 
I2C-Kommunikation mit dem FPGA fürs erste über einen USB-to-I2C-chip der 
Firma FTDI (FT 2232H Mini Module).

Momentan zeigt sich bei der Kommunikation folgendes Problem: Befehle und 
Daten können zwar über den Bus zum FPGA gesendet werden und werden auch 
von ihm acknowledged ('0'-Pegel auf dem 9. high-Pegel des Taktes), 
allerdings nur, solange das letzte übertragene Datenbit (während des 
8.Taktpegels)eine '0' ist. [Eine erfolgreiche Übertragung seht ihr im 
ersten Bild im Anhang]
Sobald da letzte Datenbit eine '1' ist, kommt es auf dem Bus zu dem 
undefinierten Zustand der Taktleitung, den ihr auf dem 2. Bild im Anhang 
zwischen dem 8. und dem 9. high-Pegel der Clock erkennen könnt.

Zu den Bildern: oben findet ihr jeweils die Clockleitung, darunter die 
Datenleitung.

Informationen zum Bus:
--> beide Leitungen werden über Pull-ups auf 3.3V DC gezogen
--> Pullup-Werte: je 2K-Ohm
--> momentane Übertragungsfrequenz: 100kHz

Informationen zum USB-to-I2c-Chip:
--> Drive-only-zero ('1' wird nicht aktiv getrieben)
--> Three-Phase-Clocking ist aktiviert
--> Die Eingänge für Daten- und Clockleitung sind Open Drain (deshalb 
werden die externen Pullups benötigt)

Information zum FPGA.
--> ebenfalls open-Drain Pins für die Daten und die Clock

von Klaus (Gast)


Lesenswert?

Hallo Heiko,

> und werden auch von ihm acknowledged (...), allerdings nur, solange das letzte 
übertragene Datenbit (...) eine '0' ist.

In beiden Fällen sieht das für mich nach einem Acknowledge aus...

Bist Du sicher, daß alle beteiligten ICs open-drains haben?  Die 
steigenden Flanken sehen mir sehr steil aus.  Da sind ja sogar 
Überschwinger drauf (sowohl Daten als auch Clock).

Auch der seltsame Pegel bei der fehlgeschlagenen Übertragung deutet mir 
darauf hin, daß ein IC eine 1 treibt und ein anderes eine 0.

Gruß,
Klaus

von Lattice User (Gast)


Lesenswert?

Nach der fallenden Clockflanke for dem ACK, darf der Slave die 
Datenleitung auf low ziehen. Offensichtlich wird diese aber vom Sender 
aktiv auf high getrieben.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nebenbei bemerkt:

Für mich sieht es so aus als würdest du keine STOP Conditions senden. 
Das führte bei mir auch mal zu solch schönen Effekten ;)

von Tcf K. (tcfkao)


Lesenswert?

Außerdem muss im Idle-Zustand SDA = SCL = High sein, damit eventuelle 
andere Master einen Bustransfer initiieren können. Da stimmt also 
einiges nicht.

von Heiko M. (edev)


Angehängte Dateien:

Lesenswert?

Erstmal danke für die Antworten :)

@Magnus M.: Die Conditions kannst du da nicht sehen, weil es sich um 
einen Multi-Byte-transfer handelt, aus dem ich einfach ein Stück 
rausgeschnitten habe...start und stop sind also durchaus vorhanden ;)

@Tcf Kao: siehe Magnus M. - links und rechts ist kein Idle-Zustand, da 
sich der Sender gerade in einer bertragung befindet. Nachdem die 
Übertragung beendet ist, liegen beide Leitungen wieder auf einem 
high-Pegel

@Klaus: Du hattest leider recht...Zwar hat der Chip an sich open Drain 
Anschlüsse...auf dem Board, auf dem ich ihn gekauft habe, sind 
allerdings bereits Pullups gegen 3.3V eingebaut [habe meine eigenen 
Pullups jetzt natürlich entfernt]. Außerdem unterstützt der betreffende 
Chip leider hardwareseitig doch kein drive-only-zero, womit der 
undefinierte Pegel wohl tatsächlich durch zwei gegeneinander treibende 
Devices verursacht wird.

Das Problem muss also irgendwo im Timing liegen, speziell scheint es an 
der 3-phasen-Clock zu liegen, weil exakt in der Zeit, in der der Pegel 
undefiniert ist, der Sender wohl noch seine '1' treibt (wegen der 
speziellen clk-Einstellung), der Empfänger allerdings schon die Null 
zieht.
Sobald ich die three-phase-clock deaktiviere, beomme ich nur leider 
keine Acknowledges mehr, egal, welchen Befehl ich ans FPGA sende (einzig 
für die Adresse kommt ich dann noch ein ACK) :/

Im Anhang sind zwei Bilder mit deaktiviertem 3-phase-Clocking:
Das erste ist die Adresse des FPGA, auf die ich auch einen ACK bekomme; 
das zweite zeigt das erste Command-byte das ohne 3-phase-clock nicht 
akzeptiert wird, obwohl das timing an sich passend aussieht.

von Klaus (Gast)


Lesenswert?

Hi Heiko,

> Zwar hat der Chip an sich open Drain Anschlüsse
> ...
> Außerdem unterstützt der betreffende Chip leider hardwareseitig doch kein 
drive-only-zero

??? Was denn nun?  Der FT2232H sollte Open-Drain können.  Laut FTDI 
AN-108 Abschnitt "7.1 Set I/O to only drive on a ‘0’ and tristate on a 
‘1’" jedenfalls.  Zu tun hatte ich damit aber noch nie.

Bei abgeschaltetem 3 Phase Data Clocking sind die Änderungen auf SDA ja 
immer sehr nah an der fallenden Flanke von SCL (jedenfalls soweit die 
zeitliche Auflösung Deiner Bildchen das erkennen läßt).  Laut I2C-Spec 
ist das OK, aber wenn das FPGA ein bißchen Hold-Time braucht, könnte das 
vielleicht schiefgehen.  Dann könnte das FPGA ein falsches Kommando 
erkennen und keinen ACK erzeugen.  Wobei das nicht erklärt, wieso die 
Adresse korrekt erkannt wird.

Ein I2C-Master ohne Open-Drain-Ausgänge ist auf jeden Fall problematisch 
(Ultra Fast Mode mal ausgenommen).  Z.B. darf jeder Slave 
Clock-Stretching machen (=SCL low halten wenn der Master die nächste 
high-Phase beginnen möchte, um den Master zu bremsen), das geht nur wenn 
SCL Open-Drain ist.

Die saubere Lösung ist, dem FT2232H über geeignete Programmierung 
Open-Drain-Verhalten beizubiegen.  Notfalls auch unter Zuhilfenahme 
eines externen Tri-State-Buffers und entsprechend modifizierter 
Software.  Wenn das nicht gehen sollte (was mich wundern würde), müßtest 
Du auf einen anderen I2C-Master ausweichen.

Eine Frickellösung wäre vielleicht ein Serienwiderstand in SDA, groß 
genug, daß die ICs nicht leiden wenn sie gegeneinandertreiben, aber 
klein genug, daß die Pegel noch stimmen - in beiden Richtungen.

Gruß,
Klaus

von Tcf K. (tcfkao)


Lesenswert?

Heiko M. schrieb:
> @Klaus: Du hattest leider recht...Zwar hat der Chip an sich open Drain
> Anschlüsse...auf dem Board, auf dem ich ihn gekauft habe, sind
> allerdings bereits Pullups gegen 3.3V eingebaut [habe meine eigenen
> Pullups jetzt natürlich entfernt]. Außerdem unterstützt der betreffende
> Chip leider hardwareseitig doch kein drive-only-zero, womit der
> undefinierte Pegel wohl tatsächlich durch zwei gegeneinander treibende
> Devices verursacht wird.
>
> Das Problem muss also irgendwo im Timing liegen, speziell scheint es an
> der 3-phasen-Clock zu liegen, weil exakt in der Zeit, in der der Pegel
> undefiniert ist, der Sender wohl noch seine '1' treibt (wegen der
> speziellen clk-Einstellung), der Empfänger allerdings schon die Null
> zieht.
> Sobald ich die three-phase-clock deaktiviere, beomme ich nur leider
> keine Acknowledges mehr, egal, welchen Befehl ich ans FPGA sende (einzig
> für die Adresse kommt ich dann noch ein ACK) :/

Grundsätzlich: Außer beim Stop- und Start-Bit darf SDA nur dann den 
Pegel wechseln wenn SCL = Low ist.

Es sieht mir so aus (Bild fail.tif) als ob Du mit dem 3-phase-clock nach 
dem achten SCL-Clock vom FPGA statt eines ACK (SDA = L) ein NAK (SDA = 
H) bekommst. Das siehst Du überhaupt nur durch den Buskonflikt der durch 
die 3-phase-clock zusammen mit dem totem-pole des FPGA entsteht. Der NAK 
verschwindet meiner Meinung durch den Glitch (selbes Bild) auf SCL, den 
der FPGA als vollen SCL-Zyklus interpretiert. Wer den Glitch verursacht 
weiß ich nicht, möglicherweise der FPGA selber der den SCL treibt.

Bei der deaktivierten 3-phase-clock (Bild CMD.tif) siehst Du den NAK 
deutlich, SDA wird sofort High nach fallender SCL. Es ist also kein 
Timing-Problem, sondern Du schickst dem FPGA irgendetwas was er nicht 
versteht oder mag.

Abgesehen davon ist totem-pole-drive bei I²C ein absolutes No-go, sieht 
man ja hier. Einzig in einem Single-Master-System darf der Master SCL 
(und nur SCL) per totem-pole treiben.
Ich habe I²C vor einigen Jahren auf verschiedenen µC implementiert und 
diesen Murks-Bus jedesmal gehasst.

Weiter Infos zum Bustiming findest Du recht gut erklärt hier:
http://www.timmermann.org/ralph/index.htm?http://www.ralph.timmermann.org/elektronik/i2c.htm

von Klaus (Gast)


Lesenswert?

Tcf Kao schrieb:
> Es sieht mir so aus (Bild fail.tif) als ob Du mit dem 3-phase-clock nach dem 
achten SCL-Clock vom FPGA statt eines ACK (SDA = L) ein NAK (SDA = H) bekommst.

Das glaube ich nicht.  Der FT2232H macht bei der 3-phase-clock für jedes 
Bit drei etwa gleichlange Phasen:

1. SDA = BIT; SCL = L
2. SDA = BIT; SCL = H
3. SDA = BIT; SCL = L

Sieht man schön beim ersten Bit von fail.tif.

Also glaube ich, daß der Master sich auch beim 8. Bit so verhält.  Die 
Stelle mit dem komischen Pegel auf SDA ist damit die dritte Phase des 8. 
Bits, also ist SDA(Master) noch H.  Der komische Pegel kommt also 
zustande, weil das FPGA L (also ACK!) treibt.  Der Glitch auf SCL ist 
genau da, wo die Treiber aufhören, gegeneinanderzuarbeiten, wo also der 
große Strom in SDA aufhört.

Wobei das ein guter Punkt ist: auf den Leitungen scheint ziemliches 
Übersprechen zu sein, man sieht wunderbar das SCL-Signal auf SDA bei 
Address.tif und CMD.tif.  Wenn das real ist, könnte das auch Probleme 
verursachen.

Tcf Kao schrieb:
> Ich habe I²C vor einigen Jahren auf verschiedenen µC implementiert und diesen 
Murks-Bus jedesmal gehasst.

Ich fand den immer super, erstaunlich das auf zwei popeligen Leitungen 
ein Multi-Master-Bus mit Flußkontrolle in allen Richtungen realisierbar 
ist.  Man muß sich natürlich an die Regeln halten, Push-Pull ist Mist.

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.