i2c Can Say the Darndest Things

Having trouble manipulating my i2c bus. I have come so far as having a
active i2c port, that can detect and read/write to chips using the lm-
sensors i2ctools.

I'm successfully opening /dev/i2c-0 but I can't do a ioctl to the
specific chip address. I've already verified the chip address and r/w
using i2cdetect. At the level of ioctl(file, I2C_SLAVE_FORCE ,address)
I get the following error: "Error opening file: Invalid argument".

//CODE

    //TEST BEGIN
    int file;

    //Open i2c dev
    if(file = open( "/dev/i2c-0", O_RDWR )<0)
    {
        enabled = -1;
        printf("Unable to open file /dev/i2c-0.\n");
    }
    else
    {
        printf("Opened file /dev/i2c-0.\n");
        enabled = 1;
    }

    printf("File is %d\n",file);

    if( ioctl( file, I2C_SLAVE_FORCE, 0x4b ) < 0 )
    {
        printf("Error opening file: %s\n", strerror( errno ) );
        printf("Open chip %d FAILED file %d\n", 0x4b, file);
    }
    else
    {
        printf("Open chip %d Succeeded file %d\n",0x4b, file);
    }

//CODE END

What am I missing?

I just put it in my src directory and I #include "i2c-dev.h" as my
final include in my .cpp file. All the defines and functions are
configuring correctly, so I imagine the functions will operate
normally? But I wonder if I need to compile the i2c-dev.h file
separately or in a different way than my other code? I've tried to
replicate the way lm-sensors include it in their project, but I can't
really figure that part out.

BTW I'm not mistaken about the 7-bit address, I am inputting it based
on the i2cdetect output, so I can't imagine that's the mistake.

Thanks,

-Nathan

Dear Nathan,

I also have a trivial C program that does something similar; perhaps you can
study its differences from your code to see what is causing the fault?

Hello Nathan,
you might look at my work here
http://elinux.org/BeagleBoard_Trainer_Nunchuk
to see if there is anything that will help.
   Perhaps you are using the wrong i2c BUS
I use BUS 2 in userland which is same as BUS 1 in u-boot.

djlewis
Don

The reason I'm using force is in case something else might be
accessing the bus. It will force it regardless. I'm quite certain the
bus is correct. It is registering the open as correct, just not the
ioctl. The only possibilities I've heard is that there is either
something wrong with the address or something wrong with the write
permissions. I'm running as root and even tried chmod'ing to 777.

Can someone tell me what persmissions their "dev/i2c-0" is set to?

Why does your app do this?

    bus_addr = strtol(argv[2], 0, 0);
    if(bus_addr < 0x66 || bus_addr > 0x6F) {
        fputs("Invalid bus address\n", stderr);
        return 1;
    }

Why is an address below 0x66 incorrect? I believe that i2c chip
addresses run wider than that? Is this more specific to the chip
you're using?

-Nathan

Yes; this address range is specific to the chip the test program was written
for.

Bye for now,

AARCGH.

I decided to make a stub application to test out the application. And
it worked properly when I opened it up inside my main() function. But
when I do the same code elsewhere inside a cpp object it does not
work. So I'm kind of happy that I know how it's not happening, but not
why.

My main() func declares an object that allocates and controls another
object that I want do the ioctl. How is it that this is no possible ?
All the relevant headers are declared in the object's .cpp file. The
functions trigger fine but they fail. I'm also noticing that instead
of file being assigned "0" each time, instead it's being assigned
numbers higher.

So anyway. How can I do this properly within an object?

I decided to make a stub application to test out the application. And
it worked properly when I opened it up inside my main() function. But
when I do the same code elsewhere inside a cpp object it does not
work. So I'm kind of happy that I know how it's not happening, but not
why.

My main() func declares an object that allocates and controls another
object that I want do the ioctl. How is it that this is no possible ?
All the relevant headers are declared in the object's .cpp file. The
functions trigger fine but they fail. I'm also noticing that instead
of file being assigned "0" each time, instead it's being assigned
numbers higher.

Do you mean the file descriptor from open() is incrementing? It sounds like
you are failing to call close() on a previous descriptor. Just to check: if
ioctl() returns an error, you are still calling close() on the file
descriptor, right?

So anyway. How can I do this properly within an object?

Perhaps you'd like to show some of the code for us to comment on it? Wrapping
the I2C code in an object is a perfectly sensible approach and the mere fact
you are using an object would not affect the correctness of the program, so
it must be a plain and simple bug somewhere.

Have you tried putting printf() or other logging statements in?

I also find the output of strace can be very illuminating for small test
cases such as this program; it allows you to see what the program actually
does with the hardware, and from there you can work backwards through your
program logic to see why. This process can often enlighten you with respect
to bugs.

Bye for now,