2009-02-02 11 views
10

Próbuję odczytać/zapisać do układu FM24CL64-GTR FRAM, który jest podłączony przez magistralę I2C pod adresem 0b 1010 011.Czytanie/pisanie z użyciem I2C na Linuksie

Kiedy próbuję napisać 3 bajtów danych (adres + 2 bajty danych, jeden bajt), otrzymuję komunikat jądra ([12406.360000] i2c-adapter i2c-0: sendbytes: NAK bailout.), a także powraca do zapisu = 3. Patrz kod poniżej:

#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); 

... 

jednak kiedy piszę 2 bajty, następnie napisać inną bajt, mam żadnego błędu jądra, ale podczas próby odczytu z FRAM, zawsze wrócić 0. Oto kod do odczytu z 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); 

Żadna z funkcji nie zwraca wartości błędu, a także wypróbowałem ją:

#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); 

które również się powiedzie, ale zawsze zwraca 0. Czy to wskazywać na problem sprzętowy, czy robię coś źle?

Czy są jakieś sterowniki FRAM dla FM24CL64-GTR przez I2C w systemie Linux, a jakie będzie API? Każdy link byłby pomocny.

+0

Powinieneś używać exit() (bez wiodącego podkreślenia), a nie _exit(). _exit() nie zamyka poprawnie biblioteki libc. –

+0

Dzięki, to jest tylko test testowy, ale wciąż dziękuję za opinię. – TheSeeker

Odpowiedz

6

NAK był wielkim wskazówka: pin WriteProtect było zewnętrznie podciągnięte i musiało zostać przeniesione na ziemię, po czym pojedyncze zapisanie adresu zakończonego bajtami danych zakończyło się powodzeniem (pierwszy segment kodu).

Aby odczytać adres, można go najpierw wypisać (przy pomocy write()), a następnie dane sekwencyjne można odczytać zaczynając od tego adresu.

5

Nie mam doświadczenia z tym konkretnym urządzeniem, ale z naszego doświadczenia wynika, że ​​wiele urządzeń I2C ma "dziwactwa", które wymagają obejścia, zwykle powyżej poziomu kierowcy.

Używamy także Linux-a (CELinux) i sterownika urządzenia I2C z Linuksem. Ale nasz kod aplikacji ma również nietrywialny moduł I2C, który zawiera całą inteligencję do pracy z wszystkimi różnymi urządzeniami, z którymi mamy do czynienia.

Ponadto, gdy ma do czynienia z kwestiami I2C, ja często, że muszę ponownie zapoznać się z spec źródło:

http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf

jak również korzystanie z przyzwoitym oscyloskopu.

Powodzenia

powyższy link jest martwy, oto kilka innych linki:

http://www.nxp.com/documents/user_manual/UM10204.pdf i oczywiście wikipedii: http://en.wikipedia.org/wiki/I%C2%B2C

+0

Zacznę od oscyloskopu dziś rano i opublikuję wyniki po tym, jak dostałem go do pracy, chyba że ktoś inny ma sterownik dla I2C FRAM dla Linuksa, ale nie mogłem go znaleźć. – TheSeeker

2

Należy zauważyć, że metoda wykorzystująca struct i2c_rdwr_ioctl_data i struct i2c_msg (czyli ostatnia część kodu, którą podałeś) jest bardziej wydajna niż pozostałe, ponieważ dzięki tej metodzie można uruchomić funkcję wielokrotnego uruchamiania I2c.

Oznacza to, że unikasz przejścia STA-WRITE-STO -> STA-READ-<data>...-STO, ponieważ twoja komunikacja stanie się STA-WRITE-RS-READ-<data>...STO (RS = powtórzony start). Tak więc, oszczędzasz zbędny przejściowy STO-STA.

Nie dlatego, że różni się ona ze sobą wiele czasu, ale jeśli nie jest to konieczne, dlaczego tracą na nim ...

Tylko moje 2 ct.

Najlepsze rgds,

0

Miałeś kilka błędów!

Adres ic jest Ax w hex, x może być tylko na 4 górnych bitów powinna być A=1010 !!!