Hallo,
Ich habe schon seit längerem eine Steuerung in Betrieb. Dabei nutze ich
den i2C-Bus der VGA Schnittstelle eines alten Laptops um damit einige
ATmegas anzusteuern. Der Code auf den ATmegas ist simple. Sie fungieren
eigentlich als reiner Port-Expander.
Nun habe ich den Laptop durch einen NanoPi NEO mit der aktuellen armbian
Version ersetzt.
Grundsätzlich funktioniert ist, es scheint aber Probleme beim Schreiben
auf den Bus zu geben. in einer Schleife mit Delay, schreibe ich jetzt
schon extra jeden Schaltbefehl 7 mal auf den Bus, damit wenigstens ein
Befehl durchkommt.
Vom Kernel bekomme ich auch Fehlermeldungen, die ich nicht deuten kann:
ich habe zwar das passende c-File gefunden, welches die Meldung
generiert:
https://github.com/spotify/linux/blob/master/drivers/i2c/busses/i2c-mv64xxx.c
aber scheinbar wird hier state 0x2 nicht interpretiert. Leider habe ich
auch kein Oszi, um mich dem Problem von der Hardwareseite zu nähern.
Vielleicht habt ihr ja einen guten Überblick über die Funktionsweise des
Kernels an der Stelle? Über Tips würde ich mich jedenfalls sehr freuen.
Vielen Dank
Ralf
Ralf schrieb:> Leider habe ich> auch kein Oszi, um mich dem Problem von der Hardwareseite zu nähern
Falls du große Ausgaben scheust, ist vielleicht so ein
5-Euro-Logic-Analyzer von ebay drin. Ich hab mir auch sowas zugelegt
(das etwas teuerer DSLogic), weil ich mit I2C und SPI Probleme hatte.
Hat mir sehr viel Nerv erspart.
i3c schrieb:> Pull-Ups nicht vergessen?>> Kleinere Bitrate mal versucht?
Pull-Ups habe ich...wenn die fehlen, dann hängt auch i2cdetect, dass
kenne ich schon.
Bitrate kann ich bei armbian offenbar nur durch Kernel-Kompilieren
ändern. Davor scheue ich mich noch.
Der Raspi hat eine Hardwarefehler, der macht das clock streching falsch.
(Das fällt bei i2c-ICs nicht auf, die sind schnell genug)
Benutzt der ATmega clock streching?
Um das zu umgehen gibt es reine Softwareimplementation von i2c.
Und ja, mit einem Logic-Analyzer kann man das debuggen.
Bastler schrieb:> Der Raspi hat eine Hardwarefehler, der macht das clock streching falsch.
Hier wird ein NanoPi Neo verwendet, der verwendet einen Allwinner H3.
Bastler schrieb:> Der Raspi hat eine Hardwarefehler, der macht das clock streching falsch.> (Das fällt bei i2c-ICs nicht auf, die sind schnell genug)> Benutzt der ATmega clock streching?
Von dem Raspi-Problem habe ich gelesen, aber ich verwende ja einen
Nanopi Neo (Allwinner H3 Chip). Ob es dort auch dieses Clock-Stretching
Problem gibt weiß ich nicht. ABER, so wie ich es verstehe verzögert der
ATmega nur, bis man das TWI-Register leer macht. Ich übertrage aber nur
gelegentlich mal ein Byte um ein Relais zu schalten...und auf den Atmels
ist nur der TWI-Interrupt aktiv. Entsprechend springt er dort auch
direkt rein....ich kann es mir kaum vorstellen.
Der Kernel-Treiber will mir ja sogar etwas mitteilen, ich kann es nur
noch nicht deuten.:-)
Im Zweifel würde ich einfach mal in den Code vom Treiber kucken, evtl.
auch extra Debug-Meldungen einfügen. Wenn wirklich unklar ist was
passiert, ist das das einzige systematische Vorgehen.
Sven B. schrieb:> Im Zweifel würde ich einfach mal in den Code vom Treiber kucken, evtl.> auch extra Debug-Meldungen einfügen. Wenn wirklich unklar ist was> passiert, ist das das einzige systematische Vorgehen.
Ich glaube, wenigstens zwischen den Zeilen habe ich durchblicken lassen,
dass ich an dieser Stelle (so tief drin im Kernel) an meine Grenzen
stoße und daher hier um Unterstützung bitte.
Wenn man sich den Treibercode anschaut, kommt die Meldung dann, wenn
keiner der "normalen" Zustände des I2C-Controllers auftaucht, in dem
Fall 0. Und das ist laut Doku MV64XXX_I2C_STATUS_BUS_ERR. Fälle wie
Ack/No Ack sind da schon raus, also ist das was eher selteneres. Laut
state (2) passiert das bei WAITING_FOR_START_COND. Das Ding verreckt
also schon vor/beim Abschicken der Start-Condition. Könnte auf einen
pegelmässig kaputten Bus hindeuten, evtl. durch die Geschwindigkeit.
Schau doch mal, ob du die im Device-Tree kleiner drehen kannst:
https://www.kernel.org/doc/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
Georg A. schrieb:> Laut> state (2) passiert das bei WAITING_FOR_START_COND.Ralf schrieb:> mv64xxx: I2C bus locked,
Der regelgerechte Ablauf beim Erzeugen einer Start-Condition ist: Warte
auf Bus idle, dann erzeuge Start. Und "idle" heißt, SDA und SCL high.
Das könnten sowohl Pegelprobleme als auch ein verklemmter Slave sein.
Ralf schrieb:> Dabei nutze ich> den i2C-Bus der VGA Schnittstelle eines alten Laptops um damit einige> ATmegas anzusteuern.
Es ist auch gut denkbar, daß ein (softwaremäßig) kaputter Slave an einem
Master funktioniert hat, mit einem anderen aber nicht klar kommt. Die
PC-internen I2C Busse sind IMHO auch SMB, haben also TTL-Pegel
(0,4V/2,0V) und einen Timeout.
MfG Klaus
Jan schrieb:> könnte es ein Problem sein, dass die eine Seite mit 5V Pegel und die> andere Seite mit 3.3V Pegel o.ä. arbeitet?
In der Tat sind die Atmels mit 5V versorgt, aber ich habe extra einen
dieser kleinen Pegelwandler verbaut.
Die Pegel im Ruhezustand stimmen auch, das habe ich mit dem Multimeter
überprüft.
Ich hatte mal so ähnliche Probleme...
Da mit einem Scope am Bus alles funktionierte, habe ich mich am Kopf
gekratzt und ein bisschen Kapazität an beide Leitungen geklemmt, was
dann auch tatsächlich das Problem behoben hat.
Einer der Chips am Bus hatte wohl eine etwas abweichende
i2c-Implementierung.
Hallo,
die Antwort von Gregor & Klaus haben mir weitergeholfen, den Treiber
etwas besser zu verstehen....vielen Dank dafür. Jetzt tauchen allerdings
noch mehr Fragen auf. :-)
Kurze Rekapitulation:
Es beginnt wohl damit, dass in der Interrupt-Routine des Treibers das
Statusregister des Chips ausgelesen wird und die Statemachine in
mv64xxx_i2c_fsm() aufgerufen:
Der Wert von Status ist 0x00, deswegen läuft die Switch-Anweisung in den
Default und meldet einen Fehler. Status 0x00 ist laut Allwinner
Datenblatt "Bus-Error"
Nun stimmen die Register des Treibers aber nicht 100% mit dem Datenblatt
überein. Der Treiber erwartet das Status Register auf Adresse 0x0c,
während das Datenblatt des Chips die Adresse 0x10 benennt (siehe
Anhang). Ist das evtl. ein Problem?
Den Hinweis mit dem Device Tree bekomme ich noch nicht umgesetzt. Dafür
fehlt mir noch der Ansatz. Ich verstehe es aber richtig, dass der Kernel
dafür nicht kompiliert werden muss?
Vielen Dank
Um den Device Tree zu ändern musst du den Kernel nicht neu übersetzen,
nein. Mir wäre aber gar nicht bekannt, dass Linux auf x86 standardmäßig
überhaupt einen Device Tree benutzt?!
Die Register sehen völlig unterschiedlich aus. Bist du sicher, dass das
der richtige Chip ist? Dann gibt es vermutlich verschiedene Varianten
davon oder so, dieser Treiber mit den Register-Offsets wird deinen Chip
jedenfalls keinesfalls korrekt ansteuern.
Sven B. schrieb:> Um den Device Tree zu ändern musst du den Kernel nicht neu übersetzen,> nein. Mir wäre aber gar nicht bekannt, dass Linux auf x86 standardmäßig> überhaupt einen Device Tree benutzt?!
Ist armbian ein x86 Build?
Sven B. schrieb:> Die Register sehen völlig unterschiedlich aus. Bist du sicher, dass das> der richtige Chip ist? Dann gibt es vermutlich verschiedene Varianten> davon oder so, dieser Treiber mit den Register-Offsets wird deinen Chip> jedenfalls keinesfalls korrekt ansteuern.
Evtl. wird der Treiber für armbian auch abgeändert? Ich tue mir mit der
Linux-Struktur echt schwer.
Das Repository von armbian ist hier zu finden:
https://github.com/armbian/build
allerdings finde ich darin den besagten Linux Treiber
(drivers/i2c/busses/i2c-mv64xxx.c) nicht.
Ah, ne, sorry ist es nicht, ist arm. Ich bin nochmal hochgescrollt und
las was von altem Notebook, bis zu dem Punkt dass es jetzt was anderes
ist bin ich nicht mehr gekommen.
Das verlinkte Repo ist ein Build-System. Da ist der Linux-Tree nicht
drin. Der wird wahrscheinlich von irgendeinem Skript in diesem
Repository heruntergeladen.
Nachdem Treiber bei so PCI-losen Chips ja "per Definition" geladen
werden, kann es evtl. sein, dass der mv* der falsche Treiber ist. Ich
finde beim H3 oft einen sunxi-ng-Treiber erwähnt. Bist du sicher, dass
du die richtige Distribution oder so hast?