平台 | 内核版本 | 安卓版本 |
---|---|---|
RK3399 | Linux4.4 | Android7.1 |
节点权限确认
RK
平台支持的I2C
节点位于/dev
下:
ll /dev/i2c*
应用访问I2C节点
我们以I2c0
为例:
#define I2C_FILE_NAME "/dev/i2c-0"
i2c
应用最本质的操作就是对通过i2c
接口对外设模块进行寄存器的操作:
应用程序通过i2c_rdwr_ioctl_data
结构体来给内核传递消息,结构体定义如下:
struct i2c_rdwr_ioctl_data {
struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
__u32 nmsgs; /* number of i2c_msgs */
};
读
static int get_i2c_register(int file, unsigned short addr,
unsigned char reg,
unsigned char *val,
int len) {
unsigned char outbuf;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
/*
* In order to read a register, we first do a "dummy write" by writing
* * 0 bytes to the register we want to read from. This is similar to
* * the packet in set_i2c_register, except it's 1 byte rather than 2.
* */
outbuf = reg;
messages[0].addr = addr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = &outbuf;
/* The data will get returned in this structure */
messages[1].addr = addr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
messages[1].len = len;
messages[1].buf = val;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
if(ioctl(file, I2C_RDWR, &packets) < 0) {
perror("Unable to send data");
return 1;
}
}
写
static int set_i2c_register(int file, unsigned char addr,
unsigned char reg,
unsigned char *value,
int len) {
unsigned char *outbuf = (unsigned char *)malloc(sizeof(unsigned char)*(len+1));
if(outbuf==NULL) {
perror("MALLOC");
return -1;
}
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
messages[0].addr = addr;
messages[0].flags = 0;
messages[0].len = len+1;
messages[0].buf = outbuf;
/* The first byte indicates which register we'll write */
outbuf[0] = reg;
/*
* The second byte indicates the value to write. Note that for many
* * devices, we can write multiple, sequential registers at once by
* * simply making outbuf bigger.
* */
memcpy(outbuf+1, value, len);
/* Transfer the i2c packets to the kernel and verify it worked */
packets.msgs = messages;
packets.nmsgs = 1;
if(ioctl(file, I2C_RDWR, &packets) < 0) {
perror("Unable to send data");
return 1;
}
return 0;
}