分类: LINUX
2010-07-14 19:58:44
Key to symbols
==============
S (1 bit) : Start bit 开始位
P (1 bit) : Stop bit 结束位
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A, NA (1 bit) : Accept and reverse accept bit.应答位和不应答位
Addr (7 bits): I
get a 10 bit I
Comm (8 bits): Command byte, a data byte which often selects a register on
the device.
Data (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
for 16 bit data.
Count (8 bits): A data byte containing the length of a block operation.
[..]: Data sent by I
Simple send transaction 简单发送传输
======================
This corresponds to i
Simple receive transaction简单接收传输
===========================
This corresponds to i
Combined transactions 复合传输
====================
This corresponds to i
They are just like the above transactions, but instead of a stop bit P,a start bit S is sent and the transaction continues. An example of a byte read, followed by a byte write:
Modified transactions
=====================
We have found some I
Flag I
In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some point. For example, setting I
If you set the I
Flags I
This toggles the Rd/Wr flag. That is, if you want to do a write, but Normally message is interrupted immediately if there is [NA] from the client. Setting this flag treats any [NA] as [A], and all of message is sent.
These messages may still fail to SCL lo->hi timeout.
Flags I
In a read message, master A/NA bit is skipped.
Terminology 术语
===========
When we talk about I
Bus -> Algorithm
Adapter
Device -> Driver
Client
An Algorithm driver contains general code that can be used for a whole class of I
A Driver driver (yes, this sounds ridiculous, sorry) contains the general code to access some type of device. Each detected device gets its own data in the Client structure. Usually, Driver and Client are more closely integrated than Algorithm and Adapter.
For a given configuration, you will need a driver for your I
At this time, Linux only operates I
I
I
static const struct file_operations i2cdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = i2cdev_read,
.write = i2cdev_write,
.unlocked_ioctl = i2cdev_ioctl,
.open = i2cdev_open,
.release = i2cdev_release,
};
实际使用时, i2cdev_read和i2cdev_write使用比较少,不建议使用,因为他们不具有太强的通用性。使用的时候一般就使用i2cdev_ioctl,当然i2cdev_open与i2cdev_release也是需要使用的。
要使用i
下面是一个例子,参考的华清远见的刘老师的,如下
/*i2c_test.c
* hongtao_liu <>
*/
#include
#include
#include
#include
#include
#include
#include
#include
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_SLAVE 0x0703
#define I2C_RDWR 0x0707
/*********定义struct i2c_rdwr_ioctl_data和struct i2c_msg,要和内核一致*******/
struct i2c_msg
{
unsigned short addr;
unsigned short flags;
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
unsigned short len;
unsigned char *buf;
};
struct i2c_rdwr_ioctl_data
{
struct i2c_msg *msgs;
int nmsgs;
/* nmsgs这个数量决定了有多少开始信号,对于“单开始时序”,取1*/
};
#define SLAVE_ADD 0x50
/***********主程序***********/
int main()
{
int fd,ret;
struct i2c_rdwr_ioctl_data e2prom_data;
fd=open("/dev/i2c0",O_RDWR);
/*
dev/i2c-0是在注册i2c-dev.c后产生的,代表一个可操作的适配器。如果不使用i2c-dev.c
的方式,就没有,也不需要这个节点。
*/
if(fd<0)
{
perror("open error");
}
e2prom_data.nmsgs=2;
/*因为操作时序中,最多是用到2个开始信号(字节读操作中),所以此将e2prom_data.nmsgs配置为2 */
e2prom_data.msgs=(struct i2c_msg*)malloc(e2prom_data.nmsgs*sizeof(struct i2c_msg));
if(!e2prom_data.msgs)
{
perror("malloc error");
exit(1);
}
ioctl(fd,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd,I2C_RETRIES,2);/*重复次数*/
/***write data to e2prom**/
e2prom_data.nmsgs=1;
(e2prom_data.msgs[0]).len=3; //1个 e2prom 写入目标的地址和1个数据
(e2prom_data.msgs[0]).addr=SLAVE_ADD;//e2prom 设备地址
(e2prom_data.msgs[0]).flags=0; //write
(e2prom_data.msgs[0]).buf=(unsigned char*)malloc(3);
(e2prom_data.msgs[0]).buf[0]=0x10;// e2prom 写入目标的地址
(e2prom_data.msgs[0]).buf[1]=0x55;//the data to write
(e2prom_data.msgs[0]).buf[2]=0xaa;//the data to write
ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
if(ret<0)
{
perror("ioctl error1");
}
sleep(1);
/******read data from e2prom*******/
e2prom_data.nmsgs=2;
(e2prom_data.msgs[0]).len=1; //e2prom 目标数据的地址
(e2prom_data.msgs[0]).addr=SLAVE_ADD; // e2prom 设备地址
(e2prom_data.msgs[0]).flags=0;//write
(e2prom_data.msgs[0]).buf[0]=0x10;//e2prom数据地址
(e2prom_data.msgs[1]).len=2;//读出的数据
(e2prom_data.msgs[1]).addr=SLAVE_ADD;// e2prom 设备地址
(e2prom_data.msgs[1]).flags=I2C_M_RD;//read
(e2prom_data.msgs[1]).buf=(unsigned char*)malloc(2);//存放返回值的地址。
(e2prom_data.msgs[1]).buf[0]=0;//初始化读缓冲
(e2prom_data.msgs[1]).buf[1]=0;//初始化读缓冲
ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);
if(ret<0)
{
perror("ioctl error2");
}
printf("buff[0]=0x%x,buff[1]=0x%x\n",(e2prom_data.msgs[1]).buf[0],(e2prom_data.msgs[1]).buf[1]);
close(fd);
return 0;
}