Hallo zusammen,
ich bräuchte mal dringend Hilfe. Ich möchte mittels eines ALIX-Boards
6B2 (PC-Engines) und einem dort installierten voyage-Linux 0.5.2 (kernel
2.6.30) mittels des implementierten I2C-Busses mit einem PCF8574
(Horter&Kalb - I2C-Ausgabe) kommunizieren.
Jetzt die Frage aller Fragen: Wie stelle ich das an?
Ich habe bereits einige Sachen ausprobiert - leider recht erfolglos.
Zuerst hatte ich mir die i2c-tools installiert (
1 | apt-get install i2c-tools
|
). Ebenso die Kernel-Module i2c_dev und i2c_core.
Somit habe ich anscheinend mittlerweile ein Device namens /dev/i2c-0.
Wenn ich jetzt mit
mir die erkannten Bus-geräte anzeigen lasse, erhalte ich folgende
Ausgabe:
i2c-0 smbus CS5536 ACB0 SMBus adapter
Dann kann man ja mit
sich die Geräte auf dem Bus anzeigen lassen. Das sieht dann bei mir so
aus:
1 | WARNING! This program can confuse your I2C bus, cause data loss and worse!
|
2 | I will probe file /dev/i2c-0.
|
3 | I will probe address range 0x03-0x77.
|
4 | Continue? [Y/n] y
|
5 | 0 1 2 3 4 5 6 7 8 9 a b c d e f
|
6 | 00: -- -- -- -- -- -- -- -- -- -- -- -- --
|
7 | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
8 | 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
9 | 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
10 | 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
11 | 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
12 | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
13 | 70: -- -- -- -- -- -- -- --
|
Tja...und ich denke genau hier liegt der Hase im Pfeffer. Normalerweise
sollte hier ja bei 0x42 (Hex für die ID 66) irgendetwas stehen ( siehe:
http://ubuntuforums.org/showthread.php?t=1181192 - ca. Mitte).
Auch wenn ich manuell versuche mittels i2cget i2cset i2cdump
irgendwelche Informationen auszulesen, schlägt dies fehl (Error: Read
failed). Des Weiteren bekomme ich auf der Konsole(RS232), die
anscheinend als stdErr fungiert, folgende Fehlermeldungen:
i2c-adapter i2c-0: bus error in state write , bzw.
i2c-adapter i2c-0: bus error in state read
Dieser Fehler wird für jeden Doppelstrich in der Tabelle ausgegeben.
Daraufhin hatte ich bereits die Vermutung, dass die Pullup-Widerstände
fehlen würden. Somit hatte ich dann zwei Potis in meinen Aufbau
integriert (+3,3V zu SCL; +3,3V zu SDA) und diese auf ca. 1,1k
eingestellt. Die Fehlermeldungen konnten somit zwar unterbunden werden,
aber meine Tabelle sah immer noch unverändert aus. Nachdem ich mir dann
nochmal das Board des 6B2 genauer angesehen habe, konnte ich am Port des
I2C zwei kleine SMD-Widerstände entdecken, die laut PC-Engines die
Pull-Up-Widerstände darstellen. Somit habe ich die Potis wieder entfernt
(allerdings sind somit die Fehlermeldungen auch wiedergekommen). Noch
ein Wort zu den Leitungslängen - ich arbeite hier mit einer Buslänge von
ca. 30cm. Allerdings habe ich die Kabel der einzelnen Busteilnehmer
zusammen auf eine Experimentierplatine gesteckt - soll heißen: es ist
keine "klassische" Busverdrahtung (von Peer zu Peer zu Peer zu Peer...).
Aber ich denke, dass ich mir bezüglich irgendwelcher etwaigen
Signal-Reflektionen keine Gedanken machen muss (wie gesagt...30cm max.).
Nachdem ich hier nicht so recht weiterkam, versuchte ich den Ansatz per
C-Programmierung. Dabei orientierte ich mich an dieser Dokumentation (
http://www.mjmwired.net/kernel/Documentation/i2c/dev-interface )
Das sah dann bei mir so aus:
1 | #include <stdio.h>
|
2 | #include <linux/i2c-dev.h>
|
3 | #include <linux/types.h>
|
4 | #include <sys/ioctl.h>
|
5 | #include <fcntl.h>
|
6 | #include <sys/stat.h>
|
7 |
|
8 | int main (int argc, char *argv[])
|
9 | {
|
10 | int file;
|
11 | int adapter_nr = 0;
|
12 | char filename[20];
|
13 |
|
14 | snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
|
15 | file = open(filename, O_RDWR);
|
16 | if (file < 0){
|
17 | /* Errorhandling */
|
18 | printf("Kann /dev/i2c-%d nicht oeffnen.\n", adapter_nr);
|
19 | return(1);
|
20 | }
|
21 |
|
22 | int addr = 0x42;
|
23 | if (ioctl(file, I2C_SLAVE, addr) < 0){
|
24 | /* Errorhandling */
|
25 | printf("Kein Kontakt zu ID %d.\n", addr);
|
26 | return(1);
|
27 | }
|
28 |
|
29 | __u8 reg = 0x10; /*Device register to access*/
|
30 | __s32 res;
|
31 | char buf[10];
|
32 |
|
33 | /* i2c-read*/
|
34 | if (read(file, buf, 1) != 1){
|
35 | /* Error i2c-transaction*/
|
36 | printf("i2c-read fehlgeschlagen\n");
|
37 | }else{
|
38 | /* buf[0] contains read-Byte */
|
39 | printf("Ausgabe: %s\n", buf[0]);
|
40 | }
|
41 | cd /roo
|
42 | return(0);
|
Hier verlässt er mich dann mit "i2c-read fehlgeschlagen"
Weiter Recherchen haben dann ergeben, dass es wohl für den PCF8574
I2C-Controller ein eigenes Kernel-Modul gibt ( pfc857x ). Einige Infos
habe ich hier dazu gefunden (
http://www.mjmwired.net/kernel/Documentation/i2c/chips/pcf8574 ).
Dort heißt es dann ja, dass der Chip "fies und gemein" ist, da er
anscheinend nicht gefunden werden kann und dass man beim Laden des
Kernels durch den Parameter force=<irgendwas> den Bus und die ID
übergeben soll. Wie dieser Parameter aber dann wirklich heißt, bleibt
ein großes Geheimnis. Ich hatte mal einen Versuch mit
1 | modprobe pcf857x force=0,0x42
|
gemacht, allerdings gab es dann im stdErr nur den Hinweis, dass dieser
Parameter (force) ungültig sei.
Ich muss gestehen, dass ich auch noch nicht so wirklich geblickt habe,
ob ich das Kernel-Modul für den PCF857x überhaupt brauche. Ziel ist es
ja eigentlich, später per Programmierung (ob Shell oder C ist mir
ziemlich egal) mit den E/As interagieren zu können. Für mein Verständnis
wir diese Kommunikation ja über den I2C-Controller des CS5536 gehen. Dem
gebe ich dann doch die ID des Gerätes , mit dem ich kommunizieren will,
und dieser gibt diese Inforamtion dann auf die Busleitung, oder?
Weswegen muss der kernel dann wissen, wie er mit einem PCF8574 zu
kommunizieren hat?
Nun...ich muss gestehen, dass ich an einer Stelle angelangt bin, wo ich
ein wenig ins Straucheln gerate, da mir die Ideen ausgehen.
Ich möchte noch anmerken, dass ich außer dem PCF8574 auch noch zwei
weitere I2C-Chips an dem Bus habe, die ebenfalls nicht erkannt werden (
PCF8591 (analog E/A); LM75 (Thermosensor)). Ich hatte auch schon
versucht die Module einzeln an das Board anzuschließen - ohne Erfolg.
Eingangs hatte ich mit einem RS232-zu-I2C-Konverters (Horter&Kalb)
bereits mit den Komponenten problemlos kommunizieren können (da gab es
ja diese Excel-Demo-Applikation).
Nun, ich will das Vorangegangene nochmal in einem Wort zusammenfassen:
HILFE!
Schöne Grüße