Through the/dev/i2c-n node, the user can directly access the I2C peripheral registers on the userspace board, mainly through i2c_rdwr this IO control command to pass i2c_msg array to kernel to execute. The following code can complete this function:
#include <stdio.h> #include <linux/types.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ioctl.h> #include <errn o.h> #include <assert.h> #include <string.h> #include <linux/i2c.h>/* This is the structure as used in the I2C_RDWR IOCTL call */struct I2c_rdwr_ioctl_data {struct i2c_msg __user *msgs; /* Pointers to I2C_MSGS * * __u32 nmsgs;
/* Number of I2C_MSGS */}; int I2c_read_reg (char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len) {str
UCT I2c_rdwr_ioctl_data Work_queue;
unsigned char w_val = reg_address;
int ret;
int fd = open (dev, o_rdwr);
if (!FD) {printf ("Error on opening the device file\n");
return 0; }
WORK_QUEUE.NMSGS = 2;
Work_queue.msgs = (struct i2c_msg*) malloc (work_queue.nmsgs *sizeof (struct i2c_msg));
if (!work_queue.msgs) {printf ("Memory alloc error\n");
Close (FD);
return 0;
} IOCTL (FD, I2c_timeout, 2);
IOCTL (FD, i2c_retries, 1);
(Work_queue.msgs[0]). len = 1;
(Work_queue.msgs[0]). addr = slave_address;
(Work_queue.msgs[0]). BUF = &w_val;
(Work_queue.msgs[1]). len = len;
(Work_queue.msgs[1]). Flags = I2C_M_RD;
(Work_queue.msgs[1]). addr = slave_address;
(Work_queue.msgs[1]). buf = BUF;
RET = IOCTL (FD, I2C_RDWR, (unsigned long) &work_queue);
if (Ret < 0) {printf ("error during I2C_RDWR IOCTL with error code:%d\n", ret);
Close (FD);
Free (WORK_QUEUE.MSGS);
return 0; } else {
printf ("Read salve:%02x reg:%02x\n", slave_address, reg_address);
Close (FD);
Free (WORK_QUEUE.MSGS);
return Len; } int I2c_write_reg (char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int
Len) {struct I2c_rdwr_ioctl_data work_queue;
unsigned char w_val = reg_address;
unsigned char w_buf[len+1];
int ret;
W_buf[0] = reg_address;
int fd = open (dev, o_rdwr);
if (!FD) {printf ("Error on opening the device file\n");
return 0;
} work_queue.nmsgs = 1;
Work_queue.msgs = (struct i2c_msg*) malloc (work_queue.nmsgs *sizeof (struct i2c_msg));
if (!work_queue.msgs) {printf ("Memory alloc error\n");
Close (FD);
return 0;
} IOCTL (FD, I2c_timeout, 2); IOctl (FD, i2c_retries, 1);
(Work_queue.msgs[0]). Len = 1 + len;
(Work_queue.msgs[0]). addr = slave_address;
(Work_queue.msgs[0]). buf = W_buf;
memcpy (w_buf + 1, buf, Len);
RET = IOCTL (FD, I2C_RDWR, (unsigned long) &work_queue);
if (Ret < 0) {printf ("error during I2C_RDWR IOCTL with error code:%d\n", ret);
Close (FD);
Free (WORK_QUEUE.MSGS);
return 0;
else {printf ("Write salve:%02x reg:%02x\n", slave_address, reg_address);
Close (FD);
Free (WORK_QUEUE.MSGS);
return Len;
int main (int argc, char **argv) {unsigned int fd;
unsigned int slave_address, reg_address;
unsigned r_w;
unsigned w_val;
unsigned char rw_val; if (ARGC < 5) {printf ("Usage:\n%s/dev/i2c-x start_addr reg_addr RW[0|1]
[write_val]\n ", argv[0]);
return 0;
FD = open (argv[1], O_RDWR);
if (!FD) {printf ("Error on opening" device file%s\n ", argv[1]);
return 0;
} sscanf (Argv[2], "%x", &slave_address);
SSCANF (Argv[3], "%x", ®_address);
SSCANF (Argv[4], "%d", &r_w);
if (R_w = = 0) {I2c_read_reg (argv[1], &rw_val, slave_address, reg_address, 1);
printf ("Read%s-%x reg%x, read value:%x\n", Argv[1], slave_address, reg_address, Rw_val); else {if (ARGC < 6) {printf ("Usage:\n%s/dev/i2c-x start_addr reg_addr r|w[0|1] [writ
E_val]\n ", argv[0]);
return 0;
} sscanf (Argv[5], "%d", &w_val);
if ((W_val & ~0xff)!= 0) printf ("Error on written value%s\n", argv[5]); Rw_val = (unsigned char) W_val;
I2c_write_reg (Argv[1], &rw_val, slave_address, reg_address, 1);
return 0; }
In android/external/new I2c-util directory, the above source code into ANDROID/EXTERNAL/I2C-UTIL/I2C-UTIL.C, write the corresponding android.mk:
Local_path: = $ (call My-dir)
include $ (clear_vars)
local_module_tags: = Optional local_module
: = i2c-util< C4/>local_src_files + +
i2c-util.c \
include $ (build_executable)
Once Android is compiled, the above tools are located in the/system/bin directory. Use it on a circuit board:
/# I2c-rw/dev/i2c-2 0x38 0x1 0
read salve:38 reg:01 value:12
/#
/# i2c-rw/dev/i2c-2 0x38 0x2 0
Read salve:38 reg:02 value:81
This article is from the "Song Baohua blog" blog, please be sure to keep this source http://21cnbao.blog.51cto.com/109393/976137