Hallo, ich habe ein Problem mit der I2C Kommunikation zwischen einem BananaPi(Lubuntu) und einem Sensor. Der Sensor schickt mir beim Adressieren + Read-Bit, den aktuellen Wert in zwei Bytes verpackt. (Start)[ADD+R](ACK)[DATA_Byte1](ACK)[DATA_Byte2](Stop) Nun habe ich mit dem Linuxtreibern für I2C nur die Möglichkeit ein Byte als einfache Read-Anfrage abzuholen(READ_BYTE). Es gibt dann noch die Funktion "I2C_READ_BLOCKDATA". Mit dieser Funktion kann man bis zu 32 Byte lesen, jedoch wird vorher noch mittels Write-Sequenz ein CMD-Byte(was meist das register ist das man lesen will) geschickt und dann mittel reapeated-start das lesen begonnen. Das dumme daran ist, daß der Sensor das repeated start scheinbar nicht mag und nicht wie ich gehoft habe einfach die schreib-Sequenz ignoriert. Hat jemand eine Idee?? Gibt es eine möglichkeit low-level an den I2C-Bus zukommen unter Linux? Kann man irgendwie den repeated- start unterdrücken (also das ein stop zwischen schreiben und lesen gesetzt wird? bin für alle Ideen und Anregungen dankbar!!!!!!!!!!!! Vielen Dank im voraus. Mfg KMT
Schau dir einmal den ioctl Befehl mit den message queue an http://autotargetingcheerup.googlecode.com/svn-history/r33/trunk/saa7113h/i2c_test.c Hier ist der wichtige Abschnitt
1 | i2c_data.msgs = msg; |
2 | i2c_data.nmsgs = 2; // two i2c_msg |
3 | |
4 | tmp[0] = offset; |
5 | i2c_data.msgs[0].addr = saa7113h_ADDR; |
6 | i2c_data.msgs[0].flags = 0; // write |
7 | i2c_data.msgs[0].len = 1; // only one byte |
8 | i2c_data.msgs[0].buf = (__u8 *)tmp; |
9 | |
10 | /*
|
11 | * Second, read data from the EEPROM
|
12 | */
|
13 | i2c_data.msgs[1].addr = saa7113h_ADDR; |
14 | i2c_data.msgs[1].flags = I2C_M_RD; // read command |
15 | i2c_data.msgs[1].len = size; |
16 | i2c_data.msgs[1].buf = (__u8 *)data; |
17 | |
18 | ret = ioctl(fd, I2C_RDWR, &i2c_data); |
Danke erstmal für die Antwort!!! leider erkenne ich im Quelltext nicht wie ich ansetzen könnte. Mein Problem ist ja gerade, daß ich ioctl nichts übergeben kann was es mir erlaubt mehrere Bytes zu lesen ohne vorher ein write durchzuführen. So sieht es für mich auch in deinem Quelltext aus... I2C_RDWR steht ja für eine kombinerte Schreib-/Lese-Aktion. (repeated start) Oder kann man die länge der write-Übertragung auch Null setzen und sie wird dann einfach nicht ausgeführt. Kann leider nicht so schnell damit experimentieren da ich im Moment mittels Python wrapper draufzugreife. Würde nur gerne wissen ob mein Problem überhaupt mit dem linux i2c-dev zu lösen ist ... dann loht es sich auch den wrapper und die c-source aufzupimpen.
Ein write musst du auf jeden Fall ausführen, um die Daten anzufordern.
In der Zeile
> i2c_data.msgs[1].len = size;
legst du dann fest, wieviele Bytes gelesen werden sollen. In deinem Fall
müsste size vermutlich 2 sein.
Oh...entschuldigung....mir ist aufgefallen, daß ich nicht deutlich gemacht habe was ich meine, als ich geschrieben hab, daß der Sensor kein repeated start mag. Das bedeutet in meinem speziellen Fall der Sensor auf mein "repeated start read" mit einem NACK antwortet....ich kann ihn also so nicht auslösen. Kommunikation sieht etwas so aus: (Start)[Add+W](ACK)[Data](ACK)(Start)[Add+R](NACK)(Stop) habe auch schon alle 256 möglichkeiten für das data-byte durchlaufen lassen...ber nach keinem kann ich lesen...kommt immer ein NACK!
Moin, so auf die Schnelle:
1 | i2c_data.msgs = msg; |
2 | i2c_data.nmsgs = 1; // one i2c_msg |
3 | |
4 | i2c_data.msgs[0].addr = sensor_addr; |
5 | i2c_data.msgs[0].flags = I2C_M_RD; // read command |
6 | i2c_data.msgs[0].len = 2; |
7 | i2c_data.msgs[0].buf = (__u8 *)data; |
8 | |
9 | ret = ioctl(fd, I2C_RDWR, &i2c_data); |
Gruss WK
Hallo, habe es leider nicht zustande bekommen mit ioctl das I2C device anzusprechen...da ich die sach in python umsetze ist die übergabe der arg-struct nicht so trivial. aber ich nutze jetzt die python-lib quick2wire und damit habe ich mein problem gelösten. Vielen Dank!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.