- 论坛徽章:
- 0
|
原帖由 yidou 于 2009-3-5 12:48 发表 ![]()
1.如果才一个msgs 那么offset command放在哪个变量呢?
都往msg[0].buff里放。
目前你的代码只放了address, 而且buff是个指针,指向了slave_address.
你需要申请一个buffer, 用来暂存slave_address ...
1.如果才一个msgs 那么offset command放在哪个变量呢?
都往msg[0].buff里放。
目前你的代码只放了address, 而且buff是个指针,指向了slave_address.
你需要申请一个buffer, 用来暂存slave_address & offset, 然后把这个buffer的地址赋给msg[0].buff
>>你的意思是说:
(work_queue.msgs[0]).len = 1;
(work_queue.msgs[0]).addr = slave>>1;
(work_queue.msgs[0]).flags=0;
(work_queue.msgs[0]).buf = slave_address & offset 还是 只是offset?
2.单独write是没有问题的。 操作了read(re-start模式)后在写就有问题了。 why? investigating..
如果单独write没问题, 你试试write + read呢,是否正常?
或者说,你的单独的read正常吗?
>> write->read 是成功的。 读不了数据的。 因为read是mode 1. 时序不对。
参考代码 http://blog.chinaunix.net/u3/91468/showart_1798987.html
linux下24c08的i2c读写程序
#include <stdio.h>
#include <linux/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#define MAX_I2C_MSG 2
#define I2C_RETRIES 0x701
#define I2C_TIMEOUT 0x702
#define I2C_RDWR 0x707
#define I2C_M_RD 0x1
struct i2c_msg
{
__u16 addr;
__u16 flags;
__u16 len;
__u8 *buf;
};
struct i2c_rdwr_ioctl_data
{
struct i2c_msg *msgs;
int nmsgs;
};
void clear_whole_eeprom();
void set_whole_eeprom();
void read_whole_eeprom();
void print_usage(__u8 *argv)
{
printf("\nUsage: %s [-c\\-s\\-r]\n",argv);
}
int main(int argc, char **argv)
{
int cmd;
if (argc!=2)
{
print_usage(argv[0]);
return 0;
}
if(strcmp(argv[1],"-c") == 0)
cmd=1;
else if(strcmp(argv[1],"-s")==0)
cmd=2;
else if(strcmp(argv[1],"-r")==0)
cmd=3;
else
{
print_usage(argv[0]);
return 0;
}
int fd;
fd = open("/dev/i2c/0",O_RDWR);
if(fd<=0)
{
printf("ERROR on opening the device file,fd=%d\n",fd);
return 0;
}
switch(cmd)
{
case 1:
clear_whole_eeprom();
break;
case 2:
set_whole_eeprom();
break;
case 3:
read_whole_eeprom();
break;
default:
break;
}
close(fd);
return 0;
}
__s32 write_eeprom(__s32 fd,__u32 offset,__u32 len,__u8 *buf)
{
__s32 ret;
struct i2c_rdwr_ioctl_data work_queue;
__u8 tmp[24];
__u32 i,bytes;
bytes=len;
if((offset+len)>1024)
{
printf("write too long than 1024\n");
return -1;
}
work_queue.nmsgs = 1;
work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));
do{
work_queue.msgs->len=len>(16-offset%16)?(16-offset%16+1):len+1;
work_queue.msgs->addr=0x50+offset/256;
work_queue.msgs->flags=0;//write
tmp[0]=offset%256;
memcpy(tmp+1,buf,16);
work_queue.msgs->buf = tmp;
#if 0
printf("buf=%x,offset=%u,len=%u,addr=%x\n",buf,tmp[0],work_queue.msgs->len,work_queue.msgs->addr);
printf("tmp=");
for(i=0;i<(work_queue.msgs->len-1);i++)
{
printf("%u ",tmp[i+1]);
}
printf("\n");
#endif
ret = ioctl(fd, I2C_RDWR, (unsigned long)&work_queue);
if(ret<0)
{
printf("Error dring I2C_RDWR ioctl with error code: %d\n",ret);
return ret;
}
len = len - (work_queue.msgs->len-1);
buf=buf+16-offset%16;
offset=offset+(16-offset%16);
// usleep(1);
}while(len>0);
return bytes;
}
__s32 read_eeprom(__s32 fd,__u32 offset,__u32 len,__u8 *buf)
{
struct i2c_rdwr_ioctl_data work_queue;
__u8 tmp[24];
__s32 ret=0,bytes;
if((offset+len)>1024)
{
printf("read too long than 1024\n");
return -1;
}
bytes=len;
work_queue.nmsgs = 2;
work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));
(work_queue.msgs[0]).len = 1;
(work_queue.msgs[0]).addr = 0x50 + offset/256;
(work_queue.msgs[0]).flags=0;
tmp[0]=offset%256;
(work_queue.msgs[0]).buf = tmp;
(work_queue.msgs[1]).len = len;
(work_queue.msgs[1]).addr = 0x50 + offset/256;
(work_queue.msgs[1]).flags=1;
(work_queue.msgs[1]).buf = buf;
ret = ioctl(fd, I2C_RDWR, (unsigned long)&work_queue);
if(ret<0)
{
printf("Error dring I2C_RDWR ioctl with error code: %d\n",ret);
return ret;
}
return len;
}
void clear_whole_eeprom(int fd)
{
__s32 ret;
__u8 buf[1024];
bzero(buf,1024);
ret=write_eeprom(fd,0,1024,buf);
if(ret<0)
printf("write eeprom error\n");
else
printf("clear %u bytes\n",ret);
} |
|