User space i2c app compile fails.

Hi All,

I wanted to test an i2c peripheral using the user space i2c dev method.  See Documentation/i2c/dev-interface.

This is supposed to provide a simple user space API for reading and writing data to an i2c client on an i2c bus.  I've used this before on other ARM based boards, but the MV kernel seems to be NQR in this regard.  When I try to build my (very simple) app, I get;

$ arm_v5t_le-gcc -O2 -o touchpad main.c
In file included from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/timex.h:58,
                 from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/sched.h:11,
                 from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/module.h:10,
                 from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/i2c.h:31,
                 from main.c:5:
/opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/time.h:12: error: redefinition of `struct timespec'
/opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/time.h:18: error: redefinition of `struct timeval'
In file included from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/timex.h:61,
                 from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/sched.h:11,
                 from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/module.h:10,
                 from /opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/linux/i2c.h:31,
                 from main.c:5:
/opt/mv_pro_4.0.1/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/include/asm/timex.h:16:28: asm/arch/timex.h: No such file or directory

<snip - this goes on for ages>

So it looks like my MV tools are NQR, as this compiles ok using my desktop kernel.

From the source:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

int main(int argc, char **argv)
{
        int ret;
        int addr = 5;
        int reg = 0;
        char buf[4];

        int fd = open("/dev/i2c/0", O_RDWR);
        if (fd < 0) {
                perror("open");
                return 1;
        }

        ret = ioctl(fd, I2C_SLAVE, addr);
        if (ret < 0) {
                perror("ioctl");
                return 1;
        }

        buf[0] = 0;

        ret = write(fd, buf, 1);
        if (ret < 0) {
                perror("write");
                return 1;
        }

        ret = read(fd, buf, 2);
        if (ret < 0) {
                perror("read");
                return 1;
        }

        fprintf(stderr, "read: %04x\n", *(unsigned short *)buf);

        close(fd);
        return 0;
}

Has anyone else seen this type of thing?

 

James.

5 Replies

  • I have written similar user level programs on our DaVinci platform; you are very likely missing a include path. 

    Below are the include header files I used for my user application

    #include <stdio.h>

    #include <stdlib.h>

    #include <unistd.h>

    #include <sys/ioctl.h>

    #include <fcntl.h>

    #include <getopt.h>

    #include <errno.h>

    #include "i2c-dev.h"

     

     

    Below is part of a Makefile I used in the past to write such user application

     

     

    # Define the location the TI-DaVinci kerenel

    DAVINCI_ROOT = /opt/mv_pro_4.0/montavista/pro/devkit/lsp/ti-davinci

    # Define the prefix used for the cross compiler

    CROSS_COMPILE = arm_v5t_le-

    # Define the location of the target

    ARM_ROOT = /opt/mv_pro_4.0.orig/montavista/pro/devkit/arm/v5t_le/target

    # List locations that have include files we need

    INC = $(DAVINCI_ROOT)/include $(ARM_ROOT)/usr/include

  • In reply to Juan Gonzales:

    I didn't see my last message get through.  Thanks, this helped, including the lsp/ti-davinci/include path to gcc.

     

    I also note that in drivers/i2c/busses/i2c-davinci.c;

    static struct i2c_algorithm i2c_davinci_algo = {
            .name = "DAVINCI I2C algorithm",
            .id = I2C_ALGO_EXP,
            .master_xfer = i2c_davinci_xfer,
            .smbus_xfer = NULL,                            <----  Oops - no SMBus transfers implemented!!
            .slave_send = NULL,
            .slave_recv = NULL,
            .algo_control = NULL,
            .functionality = i2c_davinci_func,
    };

     

    That kinda sucks, but at least the write/read functions *seem* to work.  I get a lot of errors at 20kHz and 100kHz.  I wonder if the DM355 handles clock stretching.

     

    James.

  • In reply to JamesS:

    Please note that on our DM355 EVM, MSP430 limits i2c bus to 20 KHz; spec allows for more, but a hardware re-design would be required.

  • In reply to Juan Gonzales:

    I'm using an Appro IPNC dev kit.  I'm not sure that it as this limitation.  I'll see if it does.  It's whether this is true...

            if (machine_is_davinci_evm())
                    i2c_davinci_busFreq = 20;


    but in arch/arm/mach-davinci/board-dm355-ipnc.c

    int cpu_type(void)
    {
            return MACH_TYPE_DAVINCI_DM355_IPNC;
    }

     

    and in include/asm-arm/mach-types.h

    # define machine_is_davinci_dm355_evm()    (machine_arch_type == MACH_TYPE_DAVINCI_DM355_IPNC)

    So, I'm guessing the restriction doesn't hold.

     

    James.

  • In reply to JamesS:

    One way to know for sure is to check the schematics.  Did Appro provide the schematics for this dev kit?