Forum: PC-Programmierung Probleme mit Linux i2c-Treiber


von Ralf (Gast)


Lesenswert?

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:
1
sudo tail -f /var/log/kern.log
2
Jun 11 19:56:15 localhost kernel: [ 3591.273849] i2c i2c-0: mv64xxx: I2C bus locked, block: 1, time_left: 0
3
Jun 11 19:56:17 localhost kernel: [ 3593.354024] i2c i2c-0: mv64xxx: I2C bus locked, block: 1, time_left: 0
4
Jun 11 19:56:19 localhost kernel: [ 3595.346987] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
5
Jun 11 19:56:46 localhost kernel: [ 3622.906724] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x10, flags: 0x0
6
Jun 11 19:57:23 localhost kernel: [ 3659.840450] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x10, flags: 0x0
7
Jun 11 19:57:31 localhost kernel: [ 3668.019921] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x10, flags: 0x0
8
Jun 11 20:06:26 localhost kernel: [ 4202.894321] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
9
Jun 11 20:07:38 localhost kernel: [ 4274.869937] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
10
Jun 11 20:09:15 localhost kernel: [ 4371.666878] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
11
Jun 11 20:09:39 localhost kernel: [ 4395.481057] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
12
Jun 11 20:25:01 localhost kernel: [ 5317.437496] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
13
Jun 11 21:20:43 localhost kernel: [ 8659.838023] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x10, flags: 0x0
14
Jun 11 21:24:45 localhost kernel: [ 8901.569019] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x41, flags: 0x0
15
Jun 12 08:33:43 localhost kernel: [49041.355650] i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x10, flags: 0x0
16
i2cdetect -y 0
17
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
18
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
19
10: 10 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
21
30: 30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
22
40: -- 41 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
23
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
24
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
25
70: -- -- -- -- -- -- -- --

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

: Verschoben durch User
von i3c (Gast)


Lesenswert?

Pull-Ups nicht vergessen?

Kleinere Bitrate mal versucht?

von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bastler schrieb:
> Der Raspi hat eine Hardwarefehler, der macht das clock streching falsch.

Hier wird ein NanoPi Neo verwendet, der verwendet einen Allwinner H3.

von Ralf (Gast)


Lesenswert?

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.:-)

von Sven B. (scummos)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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.

von Georg A. (georga)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

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

von Jan (Gast)


Lesenswert?

Hallo Ralf

könnte es ein Problem sein, dass die eine Seite mit 5V Pegel und die 
andere Seite mit 3.3V Pegel o.ä. arbeitet?

MfG Jan

von Ralf (Gast)


Lesenswert?

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.

von Heiko L. (zer0)


Lesenswert?

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.

von bingo (Gast)


Lesenswert?

Schau Dir mal die Impulse mit dem Oszi an, evtl. sind die Pullups zu 
gross und damit die Flanken zu flach.

von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

bingo schrieb:
> Schau Dir mal die Impulse mit dem Oszi an

https://www.youtube.com/watch?v=7kWQZdq-Yv8

SCNR :)

: Bearbeitet durch User
von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

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:
1
static irqreturn_t
2
mv64xxx_i2c_intr(int irq, void *dev_id)
3
{
4
...
5
   {
6
    status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS);
7
    mv64xxx_i2c_fsm(drv_data, status);
8
    
9
...    
10
  }
11
...
12
  return rc;
13
}

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

von Sven B. (scummos)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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.

von Sven B. (scummos)


Lesenswert?

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.

von Georg A. (georga)


Lesenswert?

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?

: Bearbeitet durch User
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.