Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
19 years ago

I2C WRITE/READ problem

Hi all,

Some weeks ago, hippo help me sort out the OC i2c drivers, and it now works. I am now able to send commands via i2c. I was having a bit of problem when trying to do a sequence of write read. Herei s what I want:

[Start]

[Slave addr, W]

[Device Param addr, 2 bytes]

[Repeat Start]

[Slave addr, R]

[Receive 3 bytes]

[No ack]

[Stop]

What I got is

[Start]

[Slave addr, W]

[Device Param addr, 2 bytes]

[Repeat Start]

[Slave addr, R] <-- WRONG slave address (0x00)

<------------ No data received due to wrong sequence.

[No ack]

[Stop]

My code is based on the following:

st linux (http://www.stlinux.com/docs/manual/distribution/distribution_guide6.php)

ozlabs (http://ozlabs.org/pipermail/linuxppc-embedded/2002-august/008013.html)

Can anyone help ???

The following is my code

#include <stdio.h># include <linux/types.h># include <fcntl.h># include <unistd.h># include <stdlib.h># include <sys/types.h># include <sys/ioctl.h># include <errno.h># include <assert.h># include <string.h># include "i2c-dev.h"
# define MAX_I2C_MSG         2# define SIGMA_ADDR      0x34
int main(int argc, char **argv)
{
    struct i2c_rdwr_ioctl_data work_queue;
      unsigned int fd;
      //unsigned short start_address;
      int ret;
 /*
      if ( argc < 2 ) 
      {
    printf("Usage:\n%s /dev/i2c-x \n",argv);
    return 0;
      }
 //*/
  
      //if ((fd = open(argv, O_RDWR)) < 0) 
      if ((fd = open("/dev/i2c-0", O_RDWR)) < 0)
      {
    printf("Error on opening the device file\n");
    return 0;
      }
  
      //sscanf(argv,"%x",&start_address);
      work_queue.nmsgs = 2;
 
      work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs*sizeof(struct i2c_msg));
      if (!work_queue.msgs) 
      {
        printf("Memory alloc error\n");
        close(fd);
        return 0;
      }
 
    
  char param_addr0 = {0x00,0x02};
  char param_value = {0x00,0x00,0x00};
  
  
  work_queue.msgs.len = 2;
  work_queue.msgs.addr = SIGMA_ADDR;
  work_queue.msgs.flags = 0;
  work_queue.msgs.buf = param_addr0;
  
  
  work_queue.msgs.len = 10;
  work_queue.msgs.addr = SIGMA_ADDR;
  work_queue.msgs.flags = I2C_M_RD;
  work_queue.msgs.buf = param_value;
  
  
      ioctl(fd,I2C_TIMEOUT,2);  // set the timeout    
      ioctl(fd,I2C_RETRIES,4);  // set the retries    
 
      //ret = ioctl(fd,I2C_RDWR,(unsigned long)&work_queue);
      ret = ioctl(fd,I2C_RDWR,&work_queue);
 
      if ( ret < 0 ) 
      {
    printf("Error during I2C_RDWR ioctl with error code: %d\n",ret);
      }
 
      close(fd);
      return 0; 
}

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I found out the problem.

    The inlcude of i2c-dev.h was pointing to the wrong file.

    It should be pointing to

    #include "i2c-dev.h" // This file has to be in /home/uclinux/uClinux-dist/user/lm_sensors/kernel/include/i2c-dev.h

    It now works.