Lesen / schreiben von mit I2C unter Linux
Ich bin versucht zu Lesen/schreiben auf einem FM24CL64-GTR FRAM
- chip, der verbunden ist über ein I2C-bus-Adresse 0b 1010 011
.
Wenn ich versuche zu schreiben, 3 bytes (Daten, Adresse (2 bytes + Daten ein byte), bekomme ich eine kernel-Meldung ([12406.360000] i2c-adapter i2c-0: sendbytes: NAK bailout.
), sowie das schreiben zurück != 3. Siehe code unten:
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
int file;
char filename[20];
int addr = 0x53; //0b1010011; /* The I2C address */
uint16_t dataAddr = 0x1234;
uint8_t val = 0x5c;
uint8_t buf[3];
sprintf(filename,"/dev/i2c-%d",0);
if ((file = open(filename,O_RDWR)) < 0)
exit(1);
if (ioctl(file,I2C_SLAVE,addr) < 0)
exit(2);
buf[0] = dataAddr >> 8;
buf[1] = dataAddr & 0xff;
buf[2] = val;
if (write(file, buf, 3) != 3)
exit(3);
...
Aber wenn ich Schreibe 2 bytes, dann schreiben ein weiteres byte, bekomme ich kein kernel-Fehler, aber wenn man versucht zu Lesen, von der " FRAM, ich bekomme immer 0 zurück. Hier ist der code zum Lesen aus dem FRAM:
uint8_t val;
if ((file = open(filename,O_RDWR)) < 0)
exit(1);
if (ioctl(file,I2C_SLAVE,addr) < 0)
exit(2);
if (write(file, &dataAddr, 2) != 2) {
exit(3);
if (read(file, &val, 1) != 1) {
exit(3);
Keine der Funktionen einen Fehler zurück Wert, und ich habe es auch ausprobiert mit:
#include <linux/i2c.h>
struct i2c_rdwr_ioctl_data work_queue;
struct i2c_msg msg[2];
uint8_t ret;
work_queue.nmsgs = 2;
work_queue.msgs = msg;
work_queue.msgs[0].addr = addr;
work_queue.msgs[0].len = 2;
work_queue.msgs[0].flags = 0;
work_queue.msgs[0].buf = &dataAddr;
work_queue.msgs[1].addr = addr;
work_queue.msgs[1].len = 1;
work_queue.msgs[1].flags = I2C_M_RD;
work_queue.msgs[1].buf = &ret;
if (ioctl(file,I2C_RDWR,&work_queue) < 0)
exit(3);
Was auch gelingt, aber es wird immer 0 zurückgegeben. Weist das auf ein hardware-Problem, oder mache ich etwas falsch?
Gibt es FRAM Treiber für FM24CL64-GTR über die I2C unter Linux, und was wäre die API werden? Jeder link wäre hilfreich.
InformationsquelleAutor der Frage TheSeeker | 2009-02-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die NAK war ein großer Tipp: die WriteProtect-pin wurde extern nach oben gezogen, und musste Gefahren werden, um Boden, nach, dass ein einziges schreiben der Adresse, gefolgt von Daten-bytes, die erfolgreich ist (im ersten code-segment).
Für das Lesen der Adresse geschrieben werden können, zuerst (mit write()), und dann sequentiell Daten Lesen sich ab, dass-Adresse.
InformationsquelleAutor der Antwort TheSeeker
Ich habe keine Erfahrung mit diesem speziellen Gerät, aber in unserer Erfahrung, die viele I2C-Geräte haben "Macken", die erfordern, dass ein work-around, der in der Regel über die Treiber-Ebene.
Verwenden wir linux (CELinux) und einem I2C-device-Treiber mit Linux. Aber unsere code der Anwendung hat auch eine nicht-triviale I2C-Modul, enthält alle arbeiten, um Intelligenz für den Umgang mit all den verschiedenen Geräten haben wir Erfahrung mit.
Auch im Umgang mit I2C Probleme, oft finde ich, dass ich brauchen, um neu zu lernen, mich mit der Quelle spec:
http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf
sowie die Nutzung von ein anständiges Oszilloskop.
Glück,
Oben genannten link ist tot, hier sind einige links:
http://www.nxp.com/documents/user_manual/UM10204.pdf
und natürlich wikipedia:
http://en.wikipedia.org/wiki/I%C2%B2C
InformationsquelleAutor der Antwort Matthew Eshleman
Beachten Sie, dass die Methode mit der
struct i2c_rdwr_ioctl_data
und diestruct i2c_msg
(,, der Letzte code-Teil, die Sie gegeben haben) ist effizienter als die anderen, da mit dieser Methode führen Sie die wiederholte start-Funktion des I2c.Bedeutet dies, dass Sie vermeiden, eine
STA-WRITE-STO -> STA-READ-<data>...-STO
übergang, denn Ihre Kommunikation wirdSTA-WRITE-RS-READ-<data>...STO
(RS
= wiederholte starten). So erspart Ihnen eine redundanteSTO-STA
transient.Nicht, dass es unterscheidet sich in der Zeit viel, aber wenn es nicht benötigt wird, warum verlieren...
Just my 2 ct.
Beste rgds,
InformationsquelleAutor der Antwort GeertVc
Sie hatte einige Fehler!
Die Adresse von
ic
istAx
in hexx
kann alles sein, aber die 4 oberen bits werden sollteA=1010
!!!InformationsquelleAutor der Antwort ebi