01 #include <stdio.h>
02 #include <string.h>
03 #include <sys/ioctl.h>
04 #include <unistd.h>
05 #include <fcntl.h>
06 #include <linux/i2c-dev.h>
07 #include <linux/i2c.h>
08 
09 /* eeprom所对应的I2C控制器的设备节点 */ 
10 #define EEPROM_DEVICE    	"/dev/i2c-0"	
11 
12 /* eeprom的I2C设备地址 */
13 #define EEPROM_ADDR    0x50				
14 
15 /*函数名：eeprom_write
16 **功能：向eeprom写数据
17 **参数：fd：eeprom对应I2C控制器设备节点的文件名
18 **		dev_addr：eeprom的I2C从设备地址
19 **		reg_addr：eeprom的寄存器地址
20 **		data_buf：要向eeprom写数据的数据buf
21 **		len：要写多少个字节。本例中当前最大支持为8个字节
22 **返回值：负数表示操作失败，其他为成功
23 */
24 int eeprom_write(int fd, unsigned char dev_addr, unsigned char reg_addr, unsigned char * data_buf,int len)
25 {
26 	int ret;
27 
28 	unsigned char msg_buf[9];
29 	struct i2c_rdwr_ioctl_data data;
30 
31 	struct i2c_msg messages;
32 
33 
34 	/* 1. 构建msg_buf*/
35 	/* 1.1. 将要操作的寄存器首地址赋给要进行I2C数据通信的首字节数据 */
36 	msg_buf[0] = reg_addr;
37 	
38 	/* 1.2. 将要向eeprom写数据的数据buf赋在I2C数据通信中eeprom寄存器的后面 */
39 	if (len < 9) {			/* 本demo最大支持一次向eeprom写一页大小的8个字节数据 */
40         memcpy((void *) &msg_buf[1], data_buf, len);  //第1位之后是数据
41     } else {
42         printf("This function supports up to 8 bytes at a time !!!\n");
43         return -1;
44     }
45 
46 	/* 2. 构建 struct i2c_msg messages */
47 	/* 2.1. 赋值eeprom的I2C从设备地址 */
48 	messages.addr = dev_addr;  
49 
50 	/* 2.2. 赋值flags为本次I2C通信完成写功能 */
51 	messages.flags = 0;    
52 
53 	/* 2.3. 赋值len为数据buf的长度 + eeprom寄存器地址的数据长度 */
54 	messages.len = len+1;
55 
56 	/* 2.4. 构建消息包的数据buf*/
57 	messages.buf = msg_buf;  
58 
59 	/* 3. 构建struct i2c_rdwr_ioctl_data data */
60 	/* 3.1. 将准备好的消息包赋值给i2c_rdwr_ioctl_data中的msgs消息*/
61 	data.msgs = &messages;
62 
63 	/* 3.2. 由于本次I2C通信只有写动作，所以消息数为1次 */
64 	data.nmsgs = 1;
65 
66 	/* 4. 调用驱动层的读写组合的I2C数据传输 */
67 	if(ioctl(fd, I2C_RDWR, &data) < 0)
68 	{
69 		printf("I2C_RDWR err \n");
70 		return -1;
71 	}
72 
73 	/* 5. 等待I2C总线写入完成 */
74 	sleep(1);
75 
76 	return 0;
77 }
78 
79 /*函数名：eeprom_read
80 **功能：从eeprom读数据
81 **参数：fd：eeprom对应I2C控制器设备节点的文件名
82 **		dev_addr：eeprom的I2C从设备地址
83 **		reg_addr：eeprom的寄存器地址
84 **		data_buf：存放从eeprom读数据的buf
85 **		len：要读多少个字节。
86 **返回值：负数表示操作失败，其他为成功
87 */
88 int eeprom_read(int fd, unsigned char dev_addr, unsigned char reg_addr, unsigned char * data_buf,int len)
89 {
90 	int ret;
91 
92 	unsigned char msg_buf[9];
93 	struct i2c_rdwr_ioctl_data data;
94 
95 	struct i2c_msg messages[2];
96 
97 	/* 1. 构建 struct i2c_msg messages */
98 	/* 1.1. 构建第一条消息 messages[0] */
99 	/* 1.1.1. 赋值eeprom的I2C从设备地址 */
100 	messages[0].addr = dev_addr;  
101 
102 	/* 1.1.2. 赋值flags为本次I2C通信完成写动作 */
103 	messages[0].flags = 0;    
104 
105 	/* 1.1.3. 赋值len为eeprom寄存器地址的数据长度是1 */
106 	messages[0].len = 1;
107 
108 	/* 1.1.4. 本次写动作的数据是要读取eeprom的寄存器首地址*/
109 	messages[0].buf = &reg_addr;  
110 	
111 	/* 1.2. 构建第二条消息 messages[1] */
112 	/* 1.2.1. 赋值eeprom的I2C从设备地址 */
113 	messages[1].addr = dev_addr;  
114 
115 	/* 1.1.2. 赋值flags为本次I2C通信完成读动作 */
116 	messages[1].flags = I2C_M_RD;    
117 
118 	/* 1.1.3. 赋值len为要读取eeprom寄存器数据长度len */
119 	messages[1].len = len;
120 
121 	/* 1.1.4. 本次读动作的数据要存放的buf位置*/
122 	messages[1].buf = data_buf; 
123 
124 	/* 2. 构建struct i2c_rdwr_ioctl_data data */
125 	/* 2.1. 将准备好的消息包赋值给i2c_rdwr_ioctl_data中的msgs消息*/
126 	data.msgs = messages;
127 
128 	/* 2.2. 由于本次I2C通信既有写动作也有读动作，所以消息数为2次 */
129 	data.nmsgs = 2;
130 
131 	/* 3. 调用驱动层的读写组合的I2C数据传输 */
132 	if(ioctl(fd, I2C_RDWR, &data) < 0)
133 	{
134 		printf("I2C_RDWR err \n");
135 		return -1;
136 	}
137 
138 	/* 4. 等待I2C总线读取完成 */
139 	sleep(1);
140 
141 	return 0;
142 }
143  
144 int main()
145 {
146 	int fd,i,ret=0;
147 	unsigned char w_add=0x10;
148 	
149 	/* 将要读取的数据buf*/
150 	unsigned char rd_buf[8] = {0};  
151 	
152 	/* 要写的数据buf*/
153 	unsigned char wr_buf[8] = {0};  
154 
155 	printf("hello,this is I2C_RDWR i2c test \n");
156 	
157 	/* 打开eeprom对应的I2C控制器文件 */
158 	fd =open(EEPROM_DEVICE, O_RDWR);
159 	if (fd< 0) 
160 	{
161 		printf("open"EEPROM_DEVICE"failed \n");
162 	}	
163 
164 	/* 把要写入的数据写入到后面的buf中 */
165 	for(i=0;i<8;i++)
166 		wr_buf[i]=i;
167 
168 	/* 通过I2C_RDWR完成向eeprom读数据的功能 */
169 	eeprom_write(fd,EEPROM_ADDR,w_add,wr_buf,8);
170 
171 	
172 	/* 通过I2C_RDWR完成向eeprom写数据的功能 */
173 	eeprom_read(fd,EEPROM_ADDR,w_add,rd_buf,8);
174 
175 	for(i=0;i<8;i++)
176 	{
177 		printf("rd_buf is :%d\n",rd_buf[i]);
178 	}
179 	
180 	/* 完成操作后，关闭eeprom对应的I2C控制器的设备文件 */
181 	close(fd);
182 
183 	return 0;
184 }
185 
186  
