Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

I2C WRITE/READ problem

Altera_Forum
Honored Contributor II
3,682 Views

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; }
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
2,841 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
2,841 Views

you are right

0 Kudos
Reply