Hallo Zusammen,
heute wollte ich mal einen alternativen Baustein testen, den Intersil
X9118 mit 1024 Schritten via I2C.
Nun habe ich folgendes Problem. Das Einstellen des Wipers funktioniert
einwandfrei. ID&&R/W-Bit + 0xa0 + 2Byte meines Wertes
Das funktioniert auch, laut Messgerät am Wiper-Pin.
Nun möchte ich diesen Wert auslesen. Laut Datenblatt entspricht das
Config-Byte 0x80.
ID&&R/W-Bit + 0x80 und müsste als Antwort 2 Bytes erhalten. Jedoch
erhalte ich nichts. Als würde das Gerät eine Art "Lock" haben. Habe ich
da was übersehen? Bei der Verschaltung gibt es nichts Spektakuläres.
Danke vorab für Tipps.
R/W bit falsch gesetzt?
Stop condition innerhalb der 4 Bytes beim Read?
Mach mal einen Screenshot mit einem Speicheroszi oder Logic-Analyzer von
deinem Read-Zugriff.
Read und write sowie stop condition laufen automatisch. Ich arbeite mit
einer Software, deren Treiber automatisch die Bits setzt. Daran liegt es
definitiv nicht
Mike schrieb:> ID&&R/W-Bit + 0x80 und müsste als Antwort 2 Bytes erhalten. Jedoch> erhalte ich nichts. Als würde das Gerät eine Art "Lock" haben.
Und was passiert dabei auf dem Bus?
Mike schrieb:> Nichts.
Deine Software liefert dir nichts.
Aber auf dem Bus wird etwas passieren.
Deswegen fragen wir hier auch nach weiteren Informationen, ansonsten ist
kein Erkenntnisgewinn zu erwarten.
Guck, was auf dem Bus (elektrisch) passiert, und lasse uns daran
teilhaben.
Ein häufiger Fehler sind auch falsche Pullups.
Jeweils 2.2K für SDA und SCL sind eine gute Wahl.
Mike schrieb:> Die pullups sind km BeagleBone Black integriert.
Und welchen Wert haben die?
> Der write Befehl geht, nur das lesen nicht
das wurde glaube ich inzwischen klar.
Setze mal die I2C Clock deutlich runter, so auf 10 KHz. Wenn es dann
geht, schließt du mal parallel zu den im BeagleBone Black vorhandenen
Pullups weitere 2.2K an.
Ich habe jetzt keine Lust für dich zu recherchieren, ob beim Beaglebone
Black viel zu schwache interne Prozessor-Pullups verwendet werden, oder
andere Pullups (4.7K? 10K) verbaut sind.
Wenn es dann mit den 2.2K auch bei 400KHz geht, lag es daran.
Ausserdem sollte dir deine Software auch mitteilen, ob bei der
Übertragung Fehler passiert sind (fehlendes ACK z.B.).
Ich werde es morgen mal versuchen. Die Software teilt mir lediglich eine
i/o Fehler mit. Der Befehl wird garnicht erst Gesendet bzw. geschrieben.
Demnach erhalte ich auch keine Antwort. Das Lesen des Daten Registers
funktioniert jedoch, wobei hier wiederum immer 65535 resultiert. Wie
dieser Wert zustande kommt, ist mir unklar.
Mike schrieb:> Das Lesen des Daten Registers funktioniert jedoch, wobei hier wiederum> immer 65535 resultiert.
Das würde ich mal als stabiles 0xFFFF, also lauter Einsen
interpretieren. Bist du sicher, dass der Wert so aus dem Datenregister
über den Bus kommt oder liefert dir da deine Software einen ungültigen
Wert?
Hast du die 0xFFFF mit vernünftigem I2C-Protokoll als elektrisches
Signal auf dem Bus gesehen? Sonst häng auch mal ein Oszi an und guck dir
die Signalqualität an. Wie lang ist dein Bus und wie schnell taktest du
ihn?
Guten Morgen,
zu den Pullups habe ich auf Seite 85 des Datenblattes einen Eintrag
gefunden: https://cdn-shop.adafruit.com/datasheets/BBB_SRM.pdf
Aus dem Text wird jedoch nicht ersichtlich, wie grpß die internen
Pullups sind.
i2cdump liefert mir folgendes:
i2cdump -y 1 0x29
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
Sebi schrieb:> Aus dem Text wird jedoch nicht ersichtlich, wie grpß die internen> Pullups sind.
Seit der Erfindung des Spannungsteilers kann man soetwas nachmessen.
Ein Widerstand von z.B. 2.2kΩ als Last an dem Bus und Nachmessen des
Buspegels mit und ohne Widerstand gibt dir den Wert des Pull-Up
Widerstandes. Um zu gucken, ob da noch irgendwer am Bus zieht, empfiehlt
es sich, die Versorgungsspannung ebenfalls zu messen.
Mike schrieb:> Nun möchte ich diesen Wert auslesen.
Ich hab mal ins Datenblatt gesehen, das Ding ist nicht I2C-kompatibel,
sondern fährt beim Lesen ein abweichendes Protokoll.
Lt. I2C-Standard muß der Master direkt nach dem Slave-ACK auf das
RW_Bit=1 auf Lesen umschalten.
Der IC will dann aber noch das Kommando gesendet haben und erst danach
gelesen werden und das kann kein Standard-I2C.
Ein Lesen geht daher nur, wenn man dieses non-I2C zu Fuß (Bit-Banging)
mit 2 IO-Pins programmiert.
Also beddeutet das, dass es zwar über I2C ansteuerbar ist, jedoch nicht
mit dem Standard-Protokoll? Falls ich es doch verwenden möchte, bleibt
mir lediglich der Schreibbefehl, der ja funktioniert. Das Auslesen
müsste ich dann über einen ADC regeln. Oder gibt es doch eine
Möglichkeit es über I2C zu betreiben? Mit den Standard I2C-Treibern?
Wir kennen leider deinen Code nicht.
Vergleiche mal zu einem EEPROM.
Da wird beim Read auch erst per Write Befehl die Adresse gesendet, auf
der gelesen werden soll. Danach kommt ein Repeated Start mit dem Read
Kommando.
Vielleicht funktioniert das.
Du könntest uns auch deinen Code posten. Vielleicht hast du auch nur
irgendwas übersehen.
Grüße, Jens
Sebi schrieb:> Das Auslesen> müsste ich dann über einen ADC regeln.
Was !? 8-/
Nein. Zwei Leitungen, wie bei I²C. Nur dass Du die I²C-Hardware des
Controllers nicht verwenden kannst, sondern das Protokoll zu Fuß
erzeugen musst.
Normalerweise ist die Datenrichtung bei I²C nach dem R/W-Bit festgelegt.
Zum lesen muss also zunächst geschrieben werden, was man vom Chip will
und dann kann man nach einer erneuten Verbindung mit R/W = 1 die Daten
vom Chip lesen. Ich hatte das weiter oben schon angedeutet.
Dein Chip wechselt während der Kommunikation die Datenrichtung. Das
macht eine ordnungsgemäße I²C-Schnittstelle nicht mit.
Daher musst Du das Protokoll händisch abwickeln. Also Portpins auf H / L
legen oder als Eingang schalten und auslesen. Bitbanging nennt man diese
Herangehensweise.
Gruß
Jobst
Mit der verwendeten Kontrollsoftware wird das aber nicht funktionieren,
da die I2C-Treiber hier bereits geschrieben sind. Ich kann lediglich die
Bits für die Geräte-ID und die Konfigurationsbits setzen. Das R/W-Bit
ist beispielsweise fest. Jenachdem ob ich eine Input oder Output
funktion wählen, wird das Bit automatisch gesetzt. Ich muss im Protokoll
lediglich die ID angeben, gefolgt von den Config-Bits, in meinem Fall
zum Lesen 0x80 und der Anzahl der Bytes, die ich als Antwort erhalte.
Aber laut Protokolldatei ist bei Lesevorgang bereits das Schreiben der
Konfigurationsbits nicht erfolgreich.
Hallo nochmal,
entweder (siehe weiter oben habe ich das schon erwähnt) vergleiche mit
einem EEPROM,
oder (am Besten) postest du den Code.
Wenn ein Ansprechen eines EEPROMs funktioniert (vielleicht gibt es hier
schon eine Implementierung für dein Board) kannst du das für deinen
Baustein übernehmen (natürlich mit Anpassung der Adressen).
Ansonsten musst du deine Treiber anpassen und kannst halt nicht auf
etwas fertiges zurück greifen.
Gruß, Jens
Das Ansprechen eines MCP4725 funktioniert einwandfrei. Ich sehe auch
keine Unterschied zum X 9118, was den Lesevorgang betrifft. Es gibt
keine Code. ich gebe einfach als Parameter die oben genannten Werte ein.
Es hat bisher mit zahlreichen anderen Bausteinen einwandfrei
funktioniert.
Bzw. ich sehe nur, dass eigentlich das ACK nach dem zweiten Byte vom
Master umgeschaltet werden müsste, was hier nicht passiert. Ich werde
mich mal mit dem Thema näher befassen, wobei die Treiber umschreiben
nicht das Problem ist, sondern die tatsache, dass ich diese dann für
Standard-ICs nicht verwenden kann.
Sebi schrieb:> Mit der verwendeten Kontrollsoftware wird das aber nicht funktionieren,> da die I2C-Treiber hier bereits geschrieben sind.Sebi schrieb:> wobei die Treiber umschreiben> nicht das Problem ist, sondern die tatsache, dass ich diese dann für> Standard-ICs nicht verwenden kann.
Heisst du eigentlich nur heute "Sebi", und morgen wieder "Mike"?
Gib uns doch bitte mal ein wenig mehr Hintergrundinformationen.
Ein Oszilloskop oder Logic-Analyzer scheint dir offenbar nicht zur
Verfügung zu stehen, richtig?
Um welche Platform / welchen I2C Treiber handelt es sich denn? Evtl.
kann man sich den Request ja irgendwie aus vorhandenen Funktionen
zusammenbasteln. Viele APIs erlauben die Kontrolle über die
start/stop/repeated-start Konditionen.
Könnte ich den Wert über i2c-tools unter Linux abrufen? Wenn ich für den
Leser Zugriff zuerst 0x80 schreibe, erhalte ich ein write error, da 0x80
laut i2cdump "xx" ist, also nicht belegt. Erst ab 0xa0 bis 0xf0 scheint
es zu funktioniert.
Sebi schrieb:> Mit einem 2,2k auf VDD erhalte ich 3,395V. Ohne den Wiederstand 3.209V
Wieso auf VDD. Wenn du den Widerstand parallel zum Pull-Up schaltest,
kannst du doch mit der Methode den Wert vom Pull-Up nicht bestimmen.
High bleib high, wenn keine Last dran hängt :-)
Aber immerhin scheint dein VDD also bei gut 3.3V zu liegen.
Sebi schrieb:> Wenn ich für den> Leser Zugriff zuerst 0x80 schreibe
Natürlich geht das nicht!
Du sagst der Schnittstelle, dass Du lesen möchtest und schreibst dann?
Möchtest Du die Elektronik belügen?
Gruß
Jobst
Sebi schrieb:> I'm vorherigen Beitrag hiess es, man muss das Kommando senden und dann> erhält man die Antwort
Ja, aber keine I²C konforme Hard- / Software wird das mitmachen.
Dir wurde ja schon gesagt, dass Dich selber um das Protokoll kümmern
musst.
Gruß
Jobst
Ich habe mir den X9118 nochmal angeschaut. Ich verstehe es irgendwie
nicht. Ich sende die Geräte-ID. Der Slave quittiert. Dann sende ich
0x80. Der Slave quittiert. Dann folgen die zwei Bytes. Im Prinzip
arbeiten andere Bausteine wie der MCP4725 genau so. Ich sende die ID,
dann wird vom Slave quittiert.
Sebi schrieb:> Ich sende die Geräte-ID. Der Slave quittiert. Dann sende ich> 0x80. Der Slave quittiert. Dann folgen die zwei Bytes.
Wenn Du auch diese beiden Bytes sendest, dann ist es I²C konform.
Aber Du sendest sie nicht, Du möchtest sie empfangen. Das geht so nach
I²C nur mit erneutem Start.
Sebi schrieb:> Im Prinzip> arbeiten andere Bausteine wie der MCP4725 genau so.
Nein. Dort kannst Du immer nur in einer Richtung arbeiten. Wie bei I²C
vorgesehen.
Gruß
Jobst
Also wenn ich mir den read-Vorgang anschaue, erhalte ich zwar 5 Bytes
als Antwort, muss aber dennoch den slave ansprechen und die ID senden.
Bei anderen Bausteinen die dem AD527x ist das auch nicht anders. Ich
spreche das Device an gefolgt von der entsprechenenden Register Adresse
und erhalte dann die Antwort. Verstehe den Unterschied nicht.
Sebi schrieb:> Also wenn ich mir den read-Vorgang anschaue, erhalte ich zwar 5 Bytes> als Antwort,> muss aber dennoch den slave ansprechen und die ID senden.
Das musst Du immer!
Nach START kommt IMMER die SlaveID + R/W, gefolgt von einer Bestätigung
vom Slave.
Und dann werden entweder Daten vom Master geschrieben (R/W = 0) oder vom
Slave gesendet (RW = 1).
UND DAS WECHSELT INNERHALB EINER ÜBERTRAGUNG AUCH NICHT!!!
> Bei anderen Bausteinen die dem AD527x ist das auch nicht anders.
DOCH!
> Ich> spreche das Device an gefolgt von der entsprechenenden Register Adresse> und erhalte dann die Antwort.
Du schreibst aber in der selben Verbindung dann nicht.
> Verstehe den Unterschied nicht.
Nochmal der Unterschied:
Dein X9118:
Ok, ich glaube, dass ich das jetzt verstehe. Bei dem AD527x empfängt der
Slave die Konfigurationsbytes. Nach dem STOp beginnt eine neue
Übertragung mit R/~W=1. Bei dem X 9118 passiert dies während einer
Übertragung.
Könnte man per Hand unter Debian (Raspberry, Beaglebone) das ganze in
C/C++ testweise umsetzen? Oder ist das doch mehr Aufwand? Muss ich dafür
andere GPIOs wählen oder funktioniert das auch über die
I2C-Schnittstelle von Raspberry Pi/Beaglebone? Mit den i2ctools wird es
wohl nicht funktionieren.
Sebi schrieb:> Oder ist das doch mehr Aufwand? Muss ich dafür> andere GPIOs wählen oder funktioniert das auch über die> I2C-Schnittstelle von Raspberry Pi/Beaglebone?
Du benötigst 2 Portpins, welche Du separat bedienen kannst. Sie müssen
OpenCollector mit Pullup sein.
Dann solltest Du durch setzen und abfragen der Pins unter Beachtung der
Zeiten eigentlich recht schnell zum Ziel kommen.
Gruß
Jobst