您的位置:首页 > 其它

MINI2440i2c驱动学习一

2011-10-09 23:49 274 查看
int main(int argc, char** argv)

{

struct eeprom e;

fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");

die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0,

"unable to open eeprom device file "

"(check that the file exists and that it's readable)");

fprintf(stderr, " Reading 256 bytes from 0x0\n");

read_from_eeprom(&e, 0, 256);

eeprom_close(&e);

return 0;

}

eeprom_open()函数中设置了打开i2c

int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e)

{

int funcs, fd, r;

e->fd = e->addr = 0;

e->dev = 0;

fd = open(dev_fqn, O_RDWR);

if(fd <= 0)

{

fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));

return -1;

}

// get funcs list

if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0))

{

fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));

return -1;

}

// check for req funcs

CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE );

CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE );

CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA );

CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA );

CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA );

CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA );

// set working device

if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0)

{

fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));

return -1;

}

e->fd = fd;

e->addr = addr;

e->dev = dev_fqn;

e->type = type;

return 0;

}

关键函数是fd = open(dev_fqn, O_RDWR);

函数到这里就打开了设备,现在就是要读写E2prom

fprintf(stderr, " Reading 256 bytes from 0x0\n");

read_from_eeprom(&e, 0, 512);

int eeprom_read_byte(struct eeprom* e, __u16 mem_addr)

{

int r;

ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer

if(e->type == EEPROM_TYPE_8BIT_ADDR)

{

__u8 buf = mem_addr & 0x0ff;

r = i2c_write_1b(e, buf);

} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {

__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };

r = i2c_write_2b(e, buf);

} else {

fprintf(stderr, "ERR: unknown eeprom type\n");

return -1;

}

if (r < 0)

return r;

r = i2c_smbus_read_byte(e->fd);

return r;

}

i2c_write_1b()这个函数是在总线上写要读的地址

static int i2c_write_1b(struct eeprom *e, __u8 buf)

{

int r;

// we must simulate a plain I2C byte write with SMBus functions

r = i2c_smbus_write_byte(e->fd, buf);

if(r < 0)

fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno));

usleep(10);

return r;

}

i2c_smbus_read_byte(e->fd);

这个函数是在读这个地址上的值

static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)

{

union i2c_smbus_data data;

if (i2c_smbus_access(file,I2C_SMBUS_READ,command,

I2C_SMBUS_BYTE_DATA,&data))

return -1;

else

return 0x0FF & data.byte;

}

static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,

int size, union i2c_smbus_data *data)

{

struct i2c_smbus_ioctl_data args;

args.read_write = read_write;

args.command = command;

args.size = size;

args.data = data;

return ioctl(file,I2C_SMBUS,&args);

}

到这个就完成了读eeprom指定地址上的值

接下来就是换写函数(已被)

write_to_eeprom()

static int write_to_eeprom(struct eeprom *e, int addr)

{

int i;

for(i=0, addr=0; i<256;addr++)

{

if( (i % 16) == 0 )

printf("\n %.4x| ", addr);

else if( (i % 8) == 0 )

printf(" ");

printf("%.2x ", i);

fflush(stdout);

die_if(eeprom_write_byte(e, addr, i), "write error");

}

fprintf(stderr, "\n\n");

return 0;

}

这里主要看eeprom_write_byte(e, addr, i),

int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data)

{

if(e->type == EEPROM_TYPE_8BIT_ADDR) {

__u8 buf[2] = { mem_addr & 0x00ff, data };

return i2c_write_2b(e, buf);

} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {

__u8 buf[3] =

{ (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };

return i2c_write_3b(e, buf);

}

fprintf(stderr, "ERR: unknown eeprom type\n");

return -1;

}

static int i2c_write_2b(struct eeprom *e, __u8 buf[2])

{

int r;

// we must simulate a plain I2C byte write with SMBus functions

r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]);

if(r < 0)

fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno));

usleep(10);

return r;

}

static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,

__u8 value)

{

union i2c_smbus_data data;

data.byte = value;

return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,

I2C_SMBUS_BYTE_DATA, &data);

}

到这里就完成了写

先到这里,后来在看底层驱动
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: