I2C READ and WRITE

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C READ and WRITE

Jump to solution
18,178 Views
amonica
Contributor II

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?

Labels (2)
Tags (1)
1 Solution
4,585 Views
BrilliantovKiri
Senior Contributor I

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.

View solution in original post

0 Kudos
2 Replies
4,585 Views
igorpadykov
NXP Employee
NXP Employee

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!

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

0 Kudos
4,586 Views
BrilliantovKiri
Senior Contributor I

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.

0 Kudos