Page 1 of 1

I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 4:30 am
by vishnu92narayanan
When I run the following I2C code, it do not start reading the register from 0x0000 (from EEPROM M24128), but it starts from some arbitary location (but the same location everytime (0x0016)). I want the program to read from 0x0000. What should I do?


Code: Select all

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>				
#include <fcntl.h>				
#include <sys/ioctl.h>			
#include <linux/i2c-dev.h>	

void main()
{	
int file_i2c;
	int length;
int i;
	unsigned char buffer[35] = {0};

	
	
	char *filename = (char*)"/dev/i2c-1";
	if ((file_i2c = open(filename, O_RDONLY)) < 0)
	{
		
		printf("Failed to open the i2c bus");
		return;
	}
	
	int addr = 0x54;          
	if (ioctl(file_i2c, I2C_SLAVE, addr) < 0)
	{
		printf("Failed to acquire bus access and/or talk to slave.\n");
		//ERROR HANDLING; you can check errno to see what went wrong
		return;
	}
	
	
	
	length = sizeof(buffer);			
	if (read(file_i2c, buffer, length) != length)		
	{
		
		printf("Failed to read from the i2c bus.\n");
	}
	else

	{     while(1)
             {
              for(i=0;i<=length;i++)
              
		{printf("Data read: %c\n", buffer[i]);
                   delay(1000);
               }
	}
}

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 7:39 am
by joan
As always read the datasheet. It will tell you what you need to do.

I have not read the datasheet for your device. However typically to read from register x you precede the read by a write of x to the device.

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 7:47 am
by vishnu92narayanan
I have written a separate code for writing, could able to read the written values using linux eeprog command. It works fine. But through program, read is showing error as I mentioned

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 8:09 am
by joan
vishnu92narayanan wrote:I have written a separate code for writing, could able to read the written values using linux eeprog command. It works fine. But through program, read is showing error as I mentioned
It looks like you will have to read the datasheet.

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 9:06 am
by vishnu92narayanan
Thank you for the response. Could you brief me on how that would help? because I have completely checked on the write protect thing, I2C Wirings etc, I could able to read only from 0016 even using i2cdump command.

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 10:10 am
by Hove
vishnu92narayanan wrote:I have written a separate code for writing, could able to read the written values using linux eeprog command. It works fine. But through program, read is showing error as I mentioned
Can you post your separate code for writing the value. My guess is what Joan says: immediately before doing the read, you need to write the register address you want to read from, something a bit like this:

Code: Select all

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>            
#include <fcntl.h>            
#include <sys/ioctl.h>         
#include <linux/i2c-dev.h>   

void main()
{   
int file_i2c;
   int length;
int i;
   unsigned char buffer[35] = {0};

   
   
   char *filename = (char*)"/dev/i2c-1";
   if ((file_i2c = open(filename, O_RDONLY)) < 0)
   {
      
      printf("Failed to open the i2c bus");
      return;
   }
   
   int addr = 0x54;          
   if (ioctl(file_i2c, I2C_SLAVE, addr) < 0)
   {
      printf("Failed to acquire bus access and/or talk to slave.\n");
      //ERROR HANDLING; you can check errno to see what went wrong
      return;
   }
   
   // Hove: Write the  register address you want to read from first.
  // Note this has not been compiled, nor do I have any experience in
  // using I2C in C: I'm just basing this on a possible misunderstand between
  // you and Joan about defining the register before writing to it.
  write(file_i2c, i2c_register, 1)
   
   length = sizeof(buffer);         
   if (read(file_i2c, buffer, length) != length)      
   {
      
      printf("Failed to read from the i2c bus.\n");
   }
   else

   {     while(1)
             {
              for(i=0;i<=length;i++)
              
      {printf("Data read: %c\n", buffer[i]);
                   delay(1000);
               }
   }
}

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 10:40 am
by vishnu92narayanan
Hove wrote:
vishnu92narayanan wrote:I have written a separate code for writing, could able to read the written values using linux eeprog command. It works fine. But through program, read is showing error as I mentioned
Can you post your separate code for writing the value. My guess is what Joan says: immediately before doing the read, you need to write the register address you want to read from, something a bit like this:

Code: Select all

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>            
#include <fcntl.h>            
#include <sys/ioctl.h>         
#include <linux/i2c-dev.h>   

void main()
{   
int file_i2c;
   int length;
int i;
   unsigned char buffer[35] = {0};

   
   
   char *filename = (char*)"/dev/i2c-1";
   if ((file_i2c = open(filename, O_RDONLY)) < 0)
   {
      
      printf("Failed to open the i2c bus");
      return;
   }
   
   int addr = 0x54;          
   if (ioctl(file_i2c, I2C_SLAVE, addr) < 0)
   {
      printf("Failed to acquire bus access and/or talk to slave.\n");
      //ERROR HANDLING; you can check errno to see what went wrong
      return;
   }
   
   // Hove: Write the  register address you want to read from first.
  // Note this has not been compiled, nor do I have any experience in
  // using I2C in C: I'm just basing this on a possible misunderstand between
  // you and Joan about defining the register before writing to it.
  write(file_i2c, i2c_register, 1)
   
   length = sizeof(buffer);         
   if (read(file_i2c, buffer, length) != length)      
   {
      
      printf("Failed to read from the i2c bus.\n");
   }
   else

   {     while(1)
             {
              for(i=0;i<=length;i++)
              
      {printf("Data read: %c\n", buffer[i]);
                   delay(1000);
               }
   }
}
Thank you for the response. Yes, I got your point, but setting the i2c_reg value is not possible. write(file_i2c, i2c_register, 1) suggests to write into the register and not set the register value for reading.

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 11:03 am
by Hove
Yeah, I was expecting my code not to be right, but I think the principle holds true: your read code does not define the register to be read from. Hopefully Joan is still watching this post as the expert who can explain the right way to do it.

Re: I2C read starts from arbitary register

Posted: Wed Apr 27, 2016 2:20 pm
by FTrevorGowen
@vishnu92narayanan, AFAICT (unless I've missed something in your posts) you haven't stated what (type of) device you're trying to read from. Can you post more details please? Hopefully, someone who is more familiar with that sort of device (or has a better understanding of any associated datasheet) can advise you better.
Trev.

Re: I2C read starts from arbitary register

Posted: Thu Apr 28, 2016 3:57 am
by vishnu92narayanan
FTrevorGowen wrote:@vishnu92narayanan, AFAICT (unless I've missed something in your posts) you haven't stated what (type of) device you're trying to read from. Can you post more details please? Hopefully, someone who is more familiar with that sort of device (or has a better understanding of any associated datasheet) can advise you better.
Trev.
Thank you for notifying . Ya I havent mentioned it. It is M24128 EEPROM. Read is working perfectly from 0x0000 with other device (m24c16 EEPROM). I just couldnt read any particular register though, Even that is not happening in M24128, it starts reading from 0X0016 as I mentioned.

Re: I2C read starts from arbitary register

Posted: Thu Apr 28, 2016 4:36 am
by ghellquist
Reading the data sheet, it says the following.

1) Tell the device which adress you want to read from. This requires you to send three bytes of data: device select, address byte, address byte. Here the R/W bit should be 0 in the select.
2) Read the data: You send device select, the devices responds with data. Here the RW bit should be 1.

/Gunnar