Forum: Compiler & IDEs Kein Zugriff auf I2C


von Reto H. (huberret)


Lesenswert?

Hallo,

ich versuche mich mit dem I2C Bus, doch leider klappt es nicht wie es 
soll.

Vorneweg, der Bus scheint in Ordnung zu sein, ich kann über den 
entsprechenden Treiber die Temperatur eines LM75 über I2C auslesen. Ich 
arbeite auf einem PPC405GPr.

Doch wenn ich ohne Treiber direkt darauf zugreifen will, oder auch auf 
andere Bausteine, dann klappt das nicht.

Ich habe zwei Dinge versucht. Erst mit dem Programm i2cdetect: 
http://www.lm-sensors.org/wiki/man/i2cdetect
1
i2cdetect -l
 sagt mir
1
 i2c-0   i2c             IBM IIC                                 I2C adapter
Mein Bus ist der i2c-0, soweit alles ok. Doch wenn ich
1
i2cdetect i2c-0
 ausführe erhalte ich
1
Error: I2C bus name doesn't match any bus present!

:-( Dann habe ich versucht selbst ein paar Zeilen zu coden:
1
int file;
2
char *filename = "/dev/i2c-0";
3
//const gchar *buffer;
4
  
5
if ((file = open(filename, O_RDWR)) < 0) {
6
    /* ERROR HANDLING: you can check errno to see what went wrong */
7
    perror("Failed to open the i2c bus");
8
    exit(1);
9
}
10
    
11
int addr = 0x93;    // Adresse des LM75 0b10010011
12
  
13
if (ioctl(file, I2C_SLAVE, addr) < 0) {
14
    perror("Failed to acquire bus access and/or talk to slave");
15
    /* ERROR HANDLING; you can check errno to see what went wrong */
16
    exit(1);
17
}

Dies bricht ab mit
1
Failed to acquire bus access and/or talk to slave: Invalid argument

Hat wer eine Idee was da falsch läuft? Warum "invalid argument"? Und 
warum funktioniert nicht mal i2cdetect?


Vielen Dank,

Reto

von Oliver S. (oliverso)


Lesenswert?

Abgesehen davon, das der Fehler vermutlich in Zeile 42 liegt, was genau 
hat das mit gcc zu tun?

Oliver

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Reto H. schrieb:
> Mein Bus ist der i2c-0, soweit alles ok. Doch wenn ich
> i2cdetect i2c-0
> ausführe erhalte ich
> Error: I2C bus name doesn't match any bus present!
>
in deinem Fall muss es heissen:
1
i2cdetect 0

Reto H. schrieb:
> Dies bricht ab mit
> Failed to acquire bus access and/or talk to slave: Invalid argument

Ich tippe mal, dass deine Slave-Adresse nicht stimmt. Du musst die 
eintragen, die du mit i2cdetect ermittelst...

Grundsätzliches zu I2C (unter Linux) mal hier auf dieser Seite:

http://bralug.de/wiki/BLIT2008-Board_mit_i2c-tiny-usb-Firmware


Grüße Uwe

von Reto H. (huberret)


Lesenswert?

Uwe,

danke für den Tipp! Auf das mit dem Bus wäre ich nicht gekommen, macht 
aber irgendwie Sinn. Und siehe da, i2cdetect funktioniert!
1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
2
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
3
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
5
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
6
40: -- -- -- -- -- -- -- -- 48 UU UU UU 4c 4d -- --
7
50: -- UU 52 -- -- -- -- -- -- -- -- -- -- -- -- --
8
60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- --
9
70: -- -- -- -- -- 75 -- --

Nur stimmen die Adressen nicht mit dem überein was ich erwartet hätte. 
Ich weiss von devices an den Adressen 49, 4a, 4b und 51... Hm... und was 
bedeutet UU?

Na gut, ein weiterer Leseversuch von Adresse 0x91 und 0xA5 aber immer 
noch der selbe Fehler: "invalid argument". Doch welches? Am "int addr" 
wird es wohl nicht liegen, oder? Ist mit meinem "file" etwas nicht in 
Ordnung? Oder ein falches include, sodass "I2C_SLAVE" nicht stimmt? Habe 
"i2c-dev.h" includiert.

Hat wer ne weitere Idee? Danke!

von Reto H. (huberret)


Lesenswert?

Hm, mir fällt gerade auf die mit UU sind genau die Adressen, die über 
einen Treiber laufen: 49, 4a, 4b und 51...
Und im Code steht UU bedeutet EBUSY. Sind die wohl mit dem Treiber 
beschäftigt und so kann ich nicht gleichzeitig darauf zugreifen?

Aber auf die anderen, z.B. 0x91 oder 0xA5 sollte ich doch problemlos 
zugreifen können?

von Jim M. (turboj)


Lesenswert?

1
int addr = 0x93;    // Adresse des LM75 0b10010011

Als ich das letzte Mal mit I²C Adressen gearbeitet habe, waren die 7 
Bits lang. Dazu kommt ein R/W Bit. Der Wert 0x93 sieht eher nicht wie 
eine gültige Adresse aus - zu viele Bits.

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Jim Meba schrieb:
> Und im Code steht UU bedeutet EBUSY. Sind die wohl mit dem Treiber
> beschäftigt und so kann ich nicht gleichzeitig darauf zugreifen?
>
wie du richtig erkannt hast, mit UU werden die Devices gekennzeichnet, 
die zwar erkannt werden, aber bereits durch etwas anderes benutzt 
werden. Ich vermute mal, dass das Kernelmodul lm75 am laufen ist. Dieses 
müsstest du entladen (rmmod lm75).

Jim Meba schrieb:
> Als ich das letzte Mal mit I²C Adressen gearbeitet habe, waren die 7
> Bits lang. Dazu kommt ein R/W Bit. Der Wert 0x93 sieht eher nicht wie
> eine gültige Adresse aus - zu viele Bits.
>
korrekt, es muss die 7-Bit-Adresse, ohne dem R/W-Bit angegeben werden. 
Also, wie ich eingangs schon geschrieben hatte, so wie es i2cdetect 
anzeigt. In deinem Fall also 0x49, 0x4a usw.. Ob das R/W-Bit gesetzt 
wird, wird intern entschieden, je nach dem ob mit read() oder write() 
(oder z.B. auch i2cget, i2cset aus den i2c-Tools) zugegriffen wird. 
Darum musst du dich nicht kümmern. Mit der richtigen Adresse sollte dein 
Codeschnipsel funktionieren...

Grüße Uwe

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.