• Hi

    I wanted to do a i2c read - write operation on imx6 . So i have added the following code.

    #include <stdio.h>

    #include <unistd.h>

    #include <stdlib.h>

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <sys/ioctl.h>

    #include <fcntl.h>

    #include <linux/fs.h>

    #include <errno.h>

    #include <string.h>

    #include <linux/i2c-dev.h>

    #include <linux/i2c.h>

    int main(void)

    {

    unsigned char rbuf[16];

    int i2c_addr = 0x21;

    int status;

    unsigned short int i;

    // OPENING I2C DEVICE

    int fd = open("/dev/i2c-2", O_RDWR);

    if (fd < 0)

    {

    printf("ERROR: open(%d) failed\n", fd);

    return -1;

    }

    printf("\nSUCCESS: open(%d) passed\n", fd);

    status = ioctl(fd, I2C_SLAVE, i2c_addr>>1);

    if (status < 0)

    {

    printf("ERROR: ioctl(fd, I2C_SLAVE, 0x%02X) failed\n", i2c_addr);

    close(fd);

    return -1;

    }

    printf("\nSUCCESS: ioctl(fd, I2C_SLAVE, 0x%02X>>1) passed\n", i2c_addr);

    printf ("\nPerforming MONZA Read operation\n");

    if (read(fd,rbuf,16) != 16)

    {

    printf("ERROR: read() failed\n");

    close(fd);

    return -1;

    }

    for(i = 0; i< 16; i++)

    printf("ReadBuffer[%d] %d \r\n", i, rbuf[i]);

    printf("\nSUCCESS: Data READ from the MONZA\n");

    printf("\n MONZA test successfull \n");

    close(fd);

    }

    When i run this code i get read error

    SUCCESS: open(3) passed

    SUCCESS: ioctl(fd, I2C_SLAVE, 0x21) passed

    Performing MONZA Read operation

    ERROR: read() failed

    read: Input/output error

    errno = 5

    My Device is connected i2c-dev 2. I observed it using i2cdetect-2. My slave address came to be 0x21.

    Can somebody please help me out?

    Hello, Agnes!

    I use struct i2c_rdwr_ioctl_data for this, follow example:

    int I2C::read8(unsigned char reg) const
    {
    i2c_rdwr_ioctl_data data;
    i2c_msg msgs[2];
    __u8 buf[sizeof(__u8) * 1] = {static_cast<__u8>(reg)};
    int r;

    msgs[0].addr = static_cast<__u16>(_address);
    msgs[0].buf = buf;
    msgs[0].flags = 0;
    msgs[0].len = static_cast<__u16>(sizeof(unsigned char));
    msgs[1].addr = static_cast<__u16>(_address);
    msgs[1].flags = I2C_M_RD;
    msgs[1].len = static_cast<__u8>(sizeof(unsigned char));
    msgs[1].buf = buf;
    data.msgs = msgs;
    data.nmsgs = 2;

    r =  ioctl(_fd, I2C_RDWR, &data);

    return (-1 == r) ? r : buf[0];
    }

    bool I2C::write(unsigned char reg, unsigned char val, bool check) const

    {

    i2c_rdwr_ioctl_data data;

    i2c_msg msgs;

    __u8 buf[sizeof(__u8) * 2] = {0};

    int r;

    buf[0] = static_cast<__u8>(reg);

    buf[1] = static_cast<__u8>(val);

    memset(&data, 0, sizeof(data));

    msgs.addr = static_cast<__u16>(_address);

    msgs.buf = buf;

    msgs.flags = 0;

    msgs.len =

    static_cast<__u16>(sizeof(unsigned char) + sizeof(unsigned char));

    data.msgs = &msgs;

    data.nmsgs = 1;

    r = ioctl(_fd, I2C_RDWR, &data);

    if (r < 0)

    return false;

    if (check) {

    usleep(1000);

    return read8(reg) == static_cast<int>(val);

    }

    return true;

    }

    Hope this help you.

    Hi AGNES,

    also hardware better first to test with SDK

    "MX6_PLATFORM_SDK "

    http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX6Q&nodeId=018rH3ZrDRB24A&fpsp=1&t...

    Best regards

    chip

    -----------------------------------------------------------------------------------------------------------------------

    Note: If this post answers your question, please click the Correct Answer button. Thank you!

    -----------------------------------------------------------------------------------------------------------------------

    Hello, Agnes!

    I use struct i2c_rdwr_ioctl_data for this, follow example:

    int I2C::read8(unsigned char reg) const
    {
    i2c_rdwr_ioctl_data data;
    i2c_msg msgs[2];
    __u8 buf[sizeof(__u8) * 1] = {static_cast<__u8>(reg)};
    int r;

    msgs[0].addr = static_cast<__u16>(_address);
    msgs[0].buf = buf;
    msgs[0].flags = 0;
    msgs[0].len = static_cast<__u16>(sizeof(unsigned char));
    msgs[1].addr = static_cast<__u16>(_address);
    msgs[1].flags = I2C_M_RD;
    msgs[1].len = static_cast<__u8>(sizeof(unsigned char));
    msgs[1].buf = buf;
    data.msgs = msgs;
    data.nmsgs = 2;

    r =  ioctl(_fd, I2C_RDWR, &data);

    return (-1 == r) ? r : buf[0];
    }

    bool I2C::write(unsigned char reg, unsigned char val, bool check) const

    {

    i2c_rdwr_ioctl_data data;

    i2c_msg msgs;

    __u8 buf[sizeof(__u8) * 2] = {0};

    int r;

    buf[0] = static_cast<__u8>(reg);

    buf[1] = static_cast<__u8>(val);

    memset(&data, 0, sizeof(data));

    msgs.addr = static_cast<__u16>(_address);

    msgs.buf = buf;

    msgs.flags = 0;

    msgs.len =

    static_cast<__u16>(sizeof(unsigned char) + sizeof(unsigned char));

    data.msgs = &msgs;

    data.nmsgs = 1;

    r = ioctl(_fd, I2C_RDWR, &data);

    if (r < 0)

    return false;

    if (check) {

    usleep(1000);

    return read8(reg) == static_cast<int>(val);

    }

    return true;

    }

    Hope this help you.