树霉pi ioctl i2c读取 24c256,其它pi也行
每两字节写入当前地址,连续写入33K字节,地址回卷测试,也能看出是否虚标
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <stdint.h>
#define MAXREADSZ 8*1024
#define PAGESIZE 64
#define ADDRESS 0x50
#define WRITECYCLE 5 //ms
#define PORT 1
int fd;
int _iicwrite(char* buf, int addr, int start, int len)
{
struct i2c_msg msgs ;
char* buf0= malloc(len+2);
msgs.addr = addr;
msgs.flags = 0;
msgs.len = len+2;
buf0[0] = (start>>8)&0xff;
buf0[1] = start&0xff;
memcpy(buf0+2,buf,len);
msgs.buf = buf0;
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = &msgs;
rdwr.nmsgs = 1;
int res = ioctl(fd, I2C_RDWR, &rdwr);
usleep(WRITECYCLE*1000);
free(buf0);
return res;
}
int iicwrite(char* buf, int addr, int start, int len)
{
int pagesize = PAGESIZE;
while(len > pagesize) {
_iicwrite(buf,addr,start,pagesize);
start += pagesize;
buf += pagesize;
len -= pagesize;
}
_iicwrite(buf,addr,start,len);
}
int _iicread(char* buf,int addr, int start, int len)
{
struct i2c_msg msgs[2] ;
char buf0[2];
msgs[0].addr = addr;
msgs[0].flags = 0;
msgs[0].len = 2;
buf0[0] = (start>>8)&0xff;
buf0[1] = start&0xff;
msgs[0].buf = buf0;
msgs[1].addr = addr;
msgs[1].flags = 1; // read
msgs[1].len = len;
msgs[1].buf = buf;
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = msgs;
rdwr.nmsgs = 2;
int res = ioctl(fd, I2C_RDWR, &rdwr);
return res;
}
int iicread(char* buf,int addr, int start, int len){
int max = MAXREADSZ;
while(len > max) {
_iicread(buf,addr,start,max);
start += max;
buf += max;
len -= max;
}
_iicread(buf,addr,start,len);
}
int setup(int port, int addr) {
char fname[16];
snprintf(fname,sizeof(fname),"/dev/i2c-%d",port);
if((fd=open(fname, O_RDWR))<0)
exit(1);
int res = ioctl(fd,I2C_SLAVE_FORCE,addr);
return res;
}
int main(){
int start = 0x00;
int len = 33*1024; //33K
char* mem= malloc(len);
int i;
memset(mem,0,len);
uint16_t* uptr = (uint16_t*)mem;
for( i = 0; i < len/2; i++)
uptr[i] = i*2;
int addr = ADDRESS;
setup(PORT,addr);
iicwrite( mem, addr, start, len);
memset(mem,0,len);
iicread( mem, addr, start, len);
for(i = 0; i < len/2; i+=64){
printf(" %5d ",uptr[i]);
if(((i>>6)&0xf) == 0xf)
printf("\n");
}
printf("\n");
free(mem);
close(fd);
}
PORT 端口号 /dev/i2c-1 默认1
24c256 write cycle time 5 ms
a0 a1 a2 接地 地址 0x50
四个问题
一 i2c 不通优先查线。
二 at24c256 write cycle time max 5毫秒, 写后延时5ms 再读。
三 24c256单次写入最多64字节 ioctl单次读取最大8K字节
四 地址超范围会回卷,从头继续