I am trying to interface A71CH with raspberry PI 3 over i2c, the device requires repeated starts and when a read request is made the first byte the device sends, is always the length of the whole message. When I am trying to make a read, instead of reading a fixed sized message , I want to read the first byte then send NACK signal to the slave after certain amount of bytes have been received that is indicated with the first byte. I used to following code but could not get the results I expected because it only read one byte than sends a NACK signal as you can see below.
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);
Is there any way that allows me to make variable sized i2c reads ? What can I do to make it work ? Thanks for looking.
i2c_smbus_read_block_data
from libi2c (part of i2c-tools)? – Ian Abbottcommand
is the command byte value you need to send in the transmit part of the transaction.values
is a pointer to a 32 byte region to receive the part of the response after the first "count" byte. The function returns the value of the "count" byte (the length of data returned in thevalues
buffer) on success, or a negative error value on error. – Ian Abbottioctl
, I'm assuming you are doing this from user-level. Your comment above containing the prototype ofi2c_smbus_read_block_data
is for the kernel API. The user-space API from libi2c has__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 * values);
.file
is the file descriptor from opening the /dev/i2c-n device. Your original code passes the I2C slave address in the transaction, but for SMBus messages you need to set the I2C slave address first using theI2C_SLAVE
ioctl command. – Ian Abbott