c - Reading and writing EEPROM via I2C with Linux -
i trying read , write atmel 24c256 eeprom raspberry pi b+ on i2c, i'm having trouble getting work right.
here code have far:
#include <stdio.h> #include <stdlib.h> #include <linux/i2c-dev.h> #include <fcntl.h> #include <string.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <linux/i2c.h> #define device_path "/dev/i2c-1" #define page_size 64 #define device_addr 0x50 // 0b1010xxxx int file_desc; char buffer[page_size + 2]; // 64 bytes + 2 address void teardowni2c() { int result = close(file_desc); } void setupi2c() { file_desc = open(device_path, o_rdwr); if(file_desc < 0) { printf("%s\n", strerror(errno)); exit(1); } if(ioctl(file_desc, i2c_slave, device_addr) < 0) { printf("%s\n", strerror(errno)); teardowni2c(); exit(1); } } int write_to_device(char addr_hi, char addr_lo, char * buf, int len) { struct i2c_rdwr_ioctl_data msg_rdwr; struct i2c_msg i2cmsg; char my_buf[page_size + 2]; if(len > page_size + 2) { printf("can't write more %d bytes @ time.\n", page_size); return -1; } int i; my_buf[0] = addr_hi; my_buf[1] = addr_lo; for(i= 0; < len; i++) { my_buf[2+i] = buf[i]; } msg_rdwr.msgs = &i2cmsg; msg_rdwr.nmsgs = 1; i2cmsg.addr = device_addr; i2cmsg.flags = 0; i2cmsg.len = 2+len; i2cmsg.buf = my_buf; if(ioctl(file_desc,i2c_rdwr,&msg_rdwr)<0) { printf("write_to_device(): %s\n", strerror(errno)); return -1; } return 0; } int read_from_device(char addr_hi, char addr_lo, char * buf, int len) { struct i2c_rdwr_ioctl_data msg_rdwr; struct i2c_msg i2cmsg; if(write_to_device(addr_hi, addr_lo ,null,0)<0) { printf("read_from_device(): address reset did not work\n"); return -1; } msg_rdwr.msgs = &i2cmsg; msg_rdwr.nmsgs = 1; i2cmsg.addr = device_addr; i2cmsg.flags = i2c_m_rd; i2cmsg.len = len; i2cmsg.buf = buf; if(ioctl(file_desc,i2c_rdwr,&msg_rdwr)<0) { printf("read_from_device(): %s\n", strerror(errno)); return -1; } return 0; } void fill_buffer(char *buf) { int = 0; while(i < page_size && *buf) { buffer[i+2] = *buf++; } while(i++ < page_size-1) { buffer[i+2] = '*'; // fill buffer } } int main() { setupi2c(); //setup fill_buffer("here words."); write_to_device(0x01, 0x00, buffer, page_size); char newbuf[page_size]; if(read_from_device(0x01, 0x00, newbuf, page_size)>0) { printf("%s\n", newbuf); } teardowni2c(); //cleanup return exit_success; } writing device in line write_to_device(0x01, 0x00, buffer, page_size); doesn't generate errors when try read device, have write "dummy" byte according spec sheet , try read device reason writing dummy byte results in error "input/output error". can't figure out how works. using 2 resources guide me, linux i2c-dev documentation , example similar eeprom device. i'm sort of stuck here , don't know try. suggestions or pointers appreciated!
alternatively, access via kernel at24.c driver, if you're able compile , install different kernel device tree raspberry pi.
the kernel device tree needs specify eeprom's type , address, , i²c bus it's connected to. i'm not sure raspberry pi, beaglebone black eeprom goes this:
&i2c0 { eeprom: eeprom@50 { compatible = "at,24c32"; reg = <0x50>; }; }; for device you'd specify compatible = "at,24c256";
ensure kernel config specifies config_eeprom_at24=y (or =m).
then should able access eeprom memory userspace @ /sys/bus/i2c/devices/0-0050/eeprom or /sys/bus/i2c/drivers/at24/0-0050/eeprom.
Comments
Post a Comment