1.在linux下提供另种I2C读写方式:
a. 一种是带寄存器读写的方式。(因为很多I2C设备的操作都是读写寄存器,所以Linux提供了这样一种接口)
b.一种是纯粹的数据发送。(a实际上调用的是b来实现)
a.方式的实现:
以下这个结构体,定义在#include <linux/i2c-dev.h> 中, 里边有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 这个功能。
}