linux下I2C的读写

2019-07-13 04:06发布

1.在linux下提供另种I2C读写方式:  a.  一种是带寄存器读写的方式。(因为很多I2C设备的操作都是读写寄存器,所以Linux提供了这样一种接口)  b.一种是纯粹的数据发送。(a实际上调用的是b来实现)
a.方式的实现: 以下这个结构体,定义在#include  中, 里边有command参数,也就是寄存器地址。
//定义结构体 struct i2c_smbus_ioctl_data args;

//填充数据 args.read_write = read_write;
args.command = command;
args.size = size;
args.data = data;
//写数据 ioctl(file,I2C_SMBUS,&args)

b.方式的实现 // 定义结构体 struct i2c_rdwr_ioctl_data  bh1200_data; 
// 填充数据 bh1200_data.nmsgs = 1;
bh1200_data.msgs = (struct i2c_msg *)malloc(bh1200_data.nmsgs * sizeof(struct i2c_msg));
bh1200_data.msgs[0].len = len;
bh1200_data.msgs[0].addr = BH1200_DEV_ADDR;
bh1200_data.msgs[0].flags = 0;
bh1200_data.msgs[0].buf = (unsigned char*)malloc(len);
memcpy((void *)bh1200_data.msgs[0].buf, value, len);
//写数据 ioctl (g_bh1200fd, I2C_RDWR, (unsigned long)&bh1200_data);
以下内容转自别的地方: drivers/i2c/i2c-dev.c中的ioctl驱动接口,其实两个接口本质差不多,特别是写,关键是你把command当成寄存器还是数据,只是I2C_SMBUS这个你需要发送的一组的数据的第1个字节当成寄存器,即command,其余的作为数据;而I2C_RDWR则更通用,没有寄存器这个说法,都看成数据,所以I2c_transfer是最通用的接口。 所谓的smbus,只是对发送的数据格式增加的限定而已,基于内容的特定协议,它最终还是要调用i2c_transfer的。
以下内容来自实际测试: 1.如果向一个从机发送一串数据,而从机没有响应,则后续数据好像不会发送,如下图,后边数据不再发送

2. 我想忽略应答,设置以下命令   struct i2c_msg {     __u16 addr;    /* slave address          */
    __u16 flags;
#define I2C_M_TEN      0x0010  /* this is a ten bit chip address */
#define I2C_M_RD       0x0001  /* read data, from slave to master */
#define I2C_M_STOP     0x8000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART      0x4000  /* if I2C_FUNC_NOSTART */
#define I2C_M_REV_DIR_ADDR 0x2000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK   0x1000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK        0x0800  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN     0x0400  /* length will be first received byte */
    __u16 len;     /* msg length             */
    __u8 *buf;     /* pointer to msg data          */
};     但是需要I2C_FUNC_PROTOCOL_MANGLING这个功能支持。   我去xilinx的I2C 驱动看了下,发现它不支持这个功能。   static u32 xiic_func(struct i2c_adapter *adap)
 {
    return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;    // 没有I2C_FUNC_PROTOCOL_MANGLING 这个功能。
 }