linux下I2C的讀寫
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 這個功能。
}