[ Prev ] [ Index ] [ Next ]

6. i2cWriteRead

Getting Started LINUX I2C control and interaction. March 2017

Since the majority of interraction with an I2C device involves writing a register index followed by writing data to that indexed register, let's create a function to make this process easier, while still allowing many bytes to be read in sequence in the case of I2C EEPROMs. The following assumes a single I2C bus, "/dev/i2c-1". The bus number can be added as a parameter for devices with multiple I2C bus interfaces.

#define I2C_DEVICE_NAME "/dev/i2c-1"
// Return number of i2c_msg's transferred, else negative value for error
int i2cWriteRead(int i2cAddress, char * pWriteData, int writeBytes, char * pReadData, int readBytes)

struct i2c_msg msg[2]; // declare a two i2c_msg array
struct i2c_rdwr_ioctl_data i2c_data; // declare our i2c_rdwr_ioctl_data structure
int msgsUsed=0; // how many i2c_msg structures are used
int result; // return value from ioctl() call
// Assume the first i2c_msg is used for writing
if(pWriteData && writeBytes) {
ds3231msg[0].addr = i2cAddress;
ds3231msg[0].flags = 0;
ds3231msg[0].buf = pWriteData;
ds3231msg[0].len = writeBytes;

// Load the second i2c_msg for receiving if the first one is used
if(pReadData && readBytes) {
// Load up receive msg
ds3231msg[1].addr = i2cAddress;
ds3231msg[1].flags = I2C_M_RD;
ds3231msg[1].buf = pReadData;
ds3231msg[1].len = readBytes;
else if(pReadData && readBytes) {
// Load the first i2c_msg for receiving (no transmit data)
ds3231msg[0].addr = i2cAddress;
ds3231msg[0].flags = I2C_M_RD;
ds3231msg[0].buf = pReadData;
ds3231msg[0].len = readBytes;
// Continue if we have data to transfer
if(msgsUsed) {
// i2c_msg array is loaded up. Now load i2c_rdwr_ioctl_data structure.
i2c_data.msgs = msg;
i2c_data.nmsgs = msgsUsed;

// Open file descriptor to I2C bus
int fd = open(I2C_DEVICE_NAME,O_RDWR);
if(fd<0) {
printf("Failed to open i2c-1.");
return -1;
// With our open file descriptor, perform I2C message transfers
// This function call returns the number of i2c_msg structures processed,
// or a negative error value
result = ioctl(fd,I2C_RDWR,&i2c_data);
if(result < 0)
printf("ioctl error: %s\n", strerror(errno));
return -2;
else {
printf("i2cWriteRead: No i2c_msg's processed\n");

return result; // return number of i2c_msg structures processed

Home Page