System calls to I2C Peripheral, unable to reset FD index

Hi everyone,
I'm trying to get my C++ main app software(running on an ARM w/embedded linux) to do reads() from my I2C peripheral on /dev/i2c-1. I'm able to open the bus just fine and the read works properly, however as expected it increments the file descriptor index. When I run lseek() to reset the file descriptor, I get an ESPIPE errno. I'm wondering if lseek is the proper function to use in this case. I'm using the unbuffered read & write so there's no need for flushing, and I'd thought that for low-level commands such as this lseek was the way to go.

Code snippet is here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Constructor
Myclass::Myclass(string name)
{
    //"file" is a private int variable defined in class header
    if ((file = open("/dev/i2c-1", O_RDWR)) < 0) {
        /* ERROR HANDLING: can check errno to see what went wrong */
        printf("Failed to open the i2c bus\n\r");
    }

    if (ioctl(file, I2C_SLAVE_FORCE, 0x50) < 0) {
        printf("Failed to acquire bus access and/or talk to slave.\n\r");
        /* ERROR HANDLING; can check errno to see what went wrong */
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//function
bool Myclass::my_read_function(void){
    char buf[1] = {0};
    int lseek_ret_val = lseek(file,0,SEEK_SET);
    int err = errno;
    printf("lseek value is: %d\n", lseek_ret_val);
    if( err == EBADF)
        printf("lseek EBADF\n");
    if( err == EINVAL)
        printf("lseek EINVAL\n");
    if( err == ESPIPE)
        printf("lseek ESPIPE\n");


    if (read(file,buf,1) != 1) {
        printf("Failed to read from the i2c bus.\n");

        return false; 
   }

    //buffer prints, removed
}


So the bus is able to open and reads happen fine, but lseek fails with ESPIPE. Of note is that the kernel accesses this peripheral on bootup, and ties up the device, forcing me to use system calls & the i2c_slave_force ioctl to grab the periph. Any help would be appreciated!

EDIT: I just tried substituting read with pread, but the index continues to increment. I'm wondering what exactly is causing the incrementing index.

Thanks,
--Varun
Last edited on
You can only seek on devices that support random access. Are you connected to something that only supports serial access? Probably.
Thanks for the reply. I'm trying to read from a Microchip EEPROM over I2C. You're probably right about
not supporting random access. In this case, how do I go about resetting the file descriptor's index?

Edit: I guess I should have read the datasheet better. Turns out it is the EEPROM itself that is internally incrementing the address, and that there is a special sequence of commands(write addr, then read) that allows you to disable this.

Thanks,
--Varun
Last edited on
Topic archived. No new replies allowed.