可变大小的 i2c 读取 Raspberry
Variable sized i2c reads Raspberry
我正在尝试通过 i2c 将 A71CH 与 raspberry PI 3 连接,该设备需要重复启动,并且当发出读取请求时,设备发送的第一个字节始终是整个消息的长度。当我尝试读取时,而不是读取固定大小的消息,我想读取第一个字节,然后在接收到第一个字节指示的一定数量的字节后向从机发送 NACK 信号。我曾经遵循以下代码,但无法获得预期的结果,因为它只读取一个字节而不是发送 NACK 信号,如下所示。
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
int r = 0;
int i = 0;
if (bus != I2C_BUS_0) // change if bus 0 is not the correct bus
{
printf("axI2CWriteRead on wrong bus %x (addr %x)\n", bus, addr);
}
messages[0].addr = axSmDevice_addr;
messages[0].flags = 0;
messages[0].len = txLen;
messages[0].buf = pTx;
// NOTE:
// By setting the 'I2C_M_RECV_LEN' bit in 'messages[1].flags' one ensures
// the I2C Block Read feature is used.
messages[1].addr = axSmDevice_addr;
messages[1].flags = I2C_M_RD | I2C_M_RECV_LEN|I2C_M_IGNORE_NAK;
messages[1].len = 256;
messages[1].buf = pRx;
messages[1].buf[0] = 1;
// NOTE:
// By passing the two message structures via the packets structure as
// a parameter to the ioctl call one ensures a Repeated Start is triggered.
packets.msgs = messages;
packets.nmsgs = 2;
// Send the request to the kernel and get the result back
r = ioctl(axSmDevice, I2C_RDWR, &packets);
有什么方法可以让我进行可变大小的 i2c 读取吗?我该怎么做才能让它发挥作用?感谢观看。
Raspbery 不支持 SMBUS 块读取,克服此问题的唯一方法是在 GPIO 引脚上进行位转换。正如@Ian Abbott 上面提到的,我通过检查接收到的消息的第一个字节并随后更新读取长度来设法修改 bbI2CZip 函数以满足我的需要。
我在 rpi3 上遇到了类似的问题。我想 正好 从从属设备上的寄存器读取 32 字节的数据,但是 i2c_smbus_read_block_data()
返回 -71 和 errno 71 EPROTO
.
解决方案是使用 i2c_smbus_read_i2c_block_data()
而不是 i2c_smbus_read_block_data()
。
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
__u8 *values);
我正在尝试通过 i2c 将 A71CH 与 raspberry PI 3 连接,该设备需要重复启动,并且当发出读取请求时,设备发送的第一个字节始终是整个消息的长度。当我尝试读取时,而不是读取固定大小的消息,我想读取第一个字节,然后在接收到第一个字节指示的一定数量的字节后向从机发送 NACK 信号。我曾经遵循以下代码,但无法获得预期的结果,因为它只读取一个字节而不是发送 NACK 信号,如下所示。
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
int r = 0;
int i = 0;
if (bus != I2C_BUS_0) // change if bus 0 is not the correct bus
{
printf("axI2CWriteRead on wrong bus %x (addr %x)\n", bus, addr);
}
messages[0].addr = axSmDevice_addr;
messages[0].flags = 0;
messages[0].len = txLen;
messages[0].buf = pTx;
// NOTE:
// By setting the 'I2C_M_RECV_LEN' bit in 'messages[1].flags' one ensures
// the I2C Block Read feature is used.
messages[1].addr = axSmDevice_addr;
messages[1].flags = I2C_M_RD | I2C_M_RECV_LEN|I2C_M_IGNORE_NAK;
messages[1].len = 256;
messages[1].buf = pRx;
messages[1].buf[0] = 1;
// NOTE:
// By passing the two message structures via the packets structure as
// a parameter to the ioctl call one ensures a Repeated Start is triggered.
packets.msgs = messages;
packets.nmsgs = 2;
// Send the request to the kernel and get the result back
r = ioctl(axSmDevice, I2C_RDWR, &packets);
有什么方法可以让我进行可变大小的 i2c 读取吗?我该怎么做才能让它发挥作用?感谢观看。
Raspbery 不支持 SMBUS 块读取,克服此问题的唯一方法是在 GPIO 引脚上进行位转换。正如@Ian Abbott 上面提到的,我通过检查接收到的消息的第一个字节并随后更新读取长度来设法修改 bbI2CZip 函数以满足我的需要。
我在 rpi3 上遇到了类似的问题。我想 正好 从从属设备上的寄存器读取 32 字节的数据,但是 i2c_smbus_read_block_data()
返回 -71 和 errno 71 EPROTO
.
解决方案是使用 i2c_smbus_read_i2c_block_data()
而不是 i2c_smbus_read_block_data()
。
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
__u8 *values);