Linux i2c-dev驱动 用户空间操作示例


Linux i2c-dev驱动 用户空间操作示例

测试芯片为at24c16

打开i2c总线节点

file = open("/dev/i2c-0", O_RDWR);
if(file < 0){
	fprintf(stderr, "failed to open i2c bus\n");
	return -1;
}

设置器件地址

# I2C_SLAVE_FORCE表示即使该地址的i2c设备已经有驱动程序,也强制其可用
ret = ioctl(file, force?I2C_SLAVE_FORCE:I2C_SLAVE, 0x50);
if(ret < 0){
	fprintf(stderr, "failed to set slave addr\n");
	return -1;
}

at24cxx Byte Write(字节写)流程如下
S Daddr Waddr data T
起始-器件地址-目标地址-数据-结束
符合SMBus如下写序列

使用I2C_SMBUS_WRITE写2字节,详见于linux/i2c.h

__s32 smbus_access(int file, char read_write, __u8 Waddr, int size, union i2c_smbus_data *data)
{
    struct i2c_smbus_ioctl_data msgs;

    msgs.read_write = read_write;
    msgs.command = Waddr;
    msgs.size = size;
    msgs.data = data;

    if(ioctl(file, I2C_SMBUS, &msgs) < 0){
        perror("error, failed to access smbus");
        return -errno;
    }
}

__s32 write_byte_data(int file, __u32 Waddr, __u32 value)
{
    union i2c_smbus_data data;
    data.byte = value;
    return smbus_access(file,I2C_SMBUS_WRITE, Waddr, I2C_SMBUS_BYTE_DATA, &data);
}

at24cxx每次写后需要max 10ms时间处理内部写循环

int waiting_write_cycle()
{
	int ret;
	struct timespec ts;
	/* waiting for at24cxx internal write cycle. 10ms max */
	ts.tv_sec =0;
	ts.tv_nsec = 10 * 1000 * 1000;
	ret = nanosleep(&ts, NULL);
	if(ret < 0){
		fprintf(stderr, "cannot sleep.\n");
		perror("ERRNO: ");
		return -errno;
	}
}

包含如下头文件

#include 
#include 
#include 

#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include