linux i2c子系统看不懂啊,I2C子系统2 - ARM_Linuxx的个人空间 - OSCHINA - 中文开源技术交流社区...
I2C子系统I2C协议I2C协议运用已经非常广泛,直接看图,一图胜前言。 I2C设备驱动数据处理Linux内核代码:drivers\i2c\i2c-core.c数据处理函数: i2c_transfer/*** i2c_transfer - execute a single or combined I2C message* @adap: Handle to I2C bus* @msgs: One o
I2C子系统
I2C协议
I2C协议运用已经非常广泛,直接看图,一图胜前言。
I2C设备驱动数据处理
Linux内核代码:drivers\i2c\i2c-core.c
数据处理函数: i2c_transfer
/**
* i2c_transfer - execute a single or combined I2C message
* @adap: Handle to I2C bus
* @msgs: One or more messages to execute before STOP is issued to
*terminate the operation; each message begins with a START.
* @num: Number of messages to be executed.
*
* Returns negative errno, else the number of messages executed.
*
* Note that there is no requirement that each message be sent to
* the same slave address, although that is the most common model.
*/
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
使用i2c_transfer函数发送数据之前要先构建好i2c_msg 。
i2c_msg 结构体定义在文件 include/uapi/linux/i2c.h
struct i2c_msg {
__u16 addr;/* slave address*/
__u16 flags;
#define I2C_M_RD0x0001/* read data, from slave to master */
/* I2C_M_RD is guaranteed to be 0x0001! */
#define I2C_M_TEN0x0010/* this is a ten bit chip address */
#define I2C_M_RECV_LEN0x0400/* length will be first received byte */
#define I2C_M_NO_RD_ACK0x0800/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK0x1000/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR0x2000/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART0x4000/* if I2C_FUNC_NOSTART */
#define I2C_M_STOP0x8000/* if I2C_FUNC_PROTOCOL_MANGLING */
__u16 len;/* msg length*/
__u8 *buf;/* pointer to msg data*/
};
以读取 I2C 设备寄存器数据为例:
(参考正点原子)
int ret;
struct i2c_msg msg[2];
/* msg[0],第一条写消息,发送要读取的寄存器地址 */
msg[0].addr = addr; /* I2C 设备地址 */
msg[0].flags = 0; /* 标记为发送数据 */
msg[0].buf = ® /* 读取的首地址 */
msg[0].len = 1; /* reg 长度 */
/* msg[1],第二条读消息,读取寄存器数据 */
msg[1].addr = addr; /* I2C 设备地址 */
msg[1].flags = I2C_M_RD; /* 标记为读取数据 */
msg[1].buf = val; /* 读取数据缓冲区 */
msg[1].len = len; /* 要读取的数据长度 */
ret = i2c_transfer(adapter, msg, 2);
向 I2C 设备寄存器写入数据:
(参考正点原子)
int ret;
u8 b[256];
struct i2c_msg msg;
struct i2c_client *client = (struct i2c_client *)
dev->private_data;
b[0] = reg; /* 寄存器首地址 */
memcpy(&b[1],buf,len); /* 将要发送的数据拷贝到数组 b 里面 */
msg.addr = addr; /* I2C 设备地址 */
msg.flags = 0; /* 标记为写数据 */
msg.buf = b; /* 要发送的数据缓冲区 */
msg.len = len + 1; /* 实际数据长度 + 寄存器地址长度*/
ret = i2c_transfer(client->adapter, &msg, 1);
Linux内核对i2c_transfer进一步封装,形成两个API函数分别用于I2C数据的接收和发送操作 。代码位于:drivers\i2c\i2c-core.c
i2c_master_recv
/**
* i2c_master_recv - issue a single I2C message in master receive mode
* @client: Handle to slave device
* @buf: Where to store data read from slave
* @count: How many bytes to read, must be less than 64k since msg.len is u16
*
* Returns negative errno, or else the number of bytes read.
*/
int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
i2c_master_send
/**
* i2c_master_send - issue a single I2C message in master transmit mode
* @client: Handle to slave device
* @buf: Data that will be written to the slave
* @count: How many bytes to write, must be less than 64k since msg.len is u16
*
* Returns negative errno, or else the number of bytes written.
*/
int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)