This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x: i2c_read returns wrong values in U-boot

Other Parts Discussed in Thread: PCF8574, TLV320AIC3106, TCA9554

Hi,

I work on Sitara am335x-evmsk with ti-processor-sdk-linux-am335x-evm-02.00.00.00.

During boot phase, I want to read board version value from PCF8574 device at address 0x21 via i2c ,so I use i2c_read ()  with the following params:

i2c_read(0, 0x21, 1,buffer, 2); but the function always return value 0. But when the boot phase end and kernel is up, I operate i2cget() with this params:

i2cget -f -y 0 0x21 and I receive correct value.

What can be the problem? How to receive to correct value in the boot phase?

Thanks Oded.

  • Moving to Sitara forum

    Regards,
    Gigi Joseph.
  • Hi,

    What do you get, when using i2c md command from u-boot prompt?

    Maybe you need to do I2C init & i2c_probe first and then read the value of the device (with i2c_read()) connected to the bus.

    Best Regards,
    Yordan
  • Hi Yordan,
    my code is base on the code from board.c file that locate in:
    ti-processor-sdk-linux-am335x-evm-02.00.00.00/board-support/u-boot-2015.07+gitAUTOINC+d49aa5effa/board/ti/am335x
    So I operate i2c_read() after i2c_probe(), as you can see for example in:
    static int read_eeprom(struct am335x_baseboard_id *header).
    and the value is 0.
    What do you mean by operate i2c md command from u-boot prompt? How to do it?
    Thanks Oded.
  • Please check Note 1 below Table 21-5 in the AM335x TRM Rev. M and see that your I2C pinmux is configured accordingly.
  • Hi,

    You can execute i2c md from u-boot prompt, by following the steps bellow:

    Oded Almog said:
    What do you mean by operate i2c md command from u-boot prompt? How to do it?

    1. Stop your board at u-boot (when the countdown appears, hit any key from your keyboard).

    2. type i2c md 0x21 0 0x10   => you'll read 16 bytes from the slave at address 0x21 starting from register 0.

    Could you also attach the modified board.c file? 

    Best Regards, 
    Yordan

  • Hi Yordan,

    This is the output when I operate i2c md 0x21 0 0x10:

    U-Boot SPL 2015.07 (Jan 06 2016 - 10:46:28)
    reading args
    spl_load_image_fat_os: error reading image args, err - -1
    reading u-boot.img
    reading u-boot.img


    U-Boot 2015.07 (Jan 06 2016 - 10:46:28 +0200)

    Watchdog enabled
    I2C: ready
    DRAM: 256 MiB
    NAND: 0 MiB
    MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
    reading uboot.env
    Net: Phy 0 not found
    cpsw, usb_ether
    Hit any key to stop autoboot: 0
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot# i2c md 0x21 0 0x10
    0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    U-Boot#


    And this is the output when I operate i2cget -f -y 0 0x21 when application is up:

    root@am335x-evm:~# i2cget -f -y 0 0x21
    0xe2
    root@am335x-evm:~#


    What is the problem?

    Thanks Oded.
  • Please check Note 1 below Table 21-5 in the AM335x TRM Rev. M and see that your I2C pinmux is configured accordingly.
  • Hi Biser,
    How and where can I configure CONF_<module>_<pin>_RXACTIVE bit ?
    Thanks Oded.
  • Hi,

    Those registers CONF_<module>_<pin> are located in the Control module: Table 9-10. CONTROL_MODULE REGISTERS

    Have a look at mux.c to see which macros are used to mux module pins in u-boot.

    Best Regards,
    Yordan
  • Hi Yordan,
    We try to read extgpio1: pcf8574@21 device in i2c device . This is how it declare in DTS file:

    &i2c0 {
    pinctrl-names = "default";
    pinctrl-0 = <&i2c0_pins>;

    status = "okay";
    clock-frequency = <100000>;

    tps: tps@2d {
    reg = <0x2d>;
    };

    lis331dlh: lis331dlh@18 {
    compatible = "st,lis331dlh", "st,lis3lv02d";
    reg = <0x18>;
    Vdd-supply = <&lis3_reg>;
    Vdd_IO-supply = <&lis3_reg>;

    st,click-single-x;
    st,click-single-y;
    st,click-single-z;
    st,click-thresh-x = <10>;
    st,click-thresh-y = <10>;
    st,click-thresh-z = <10>;
    st,irq1-click;
    st,irq2-click;
    st,wakeup-x-lo;
    st,wakeup-x-hi;
    st,wakeup-y-lo;
    st,wakeup-y-hi;
    st,wakeup-z-lo;
    st,wakeup-z-hi;
    st,min-limit-x = <120>;
    st,min-limit-y = <120>;
    st,min-limit-z = <140>;
    st,max-limit-x = <550>;
    st,max-limit-y = <550>;
    st,max-limit-z = <750>;
    };

    tlv320aic3106: tlv320aic3106@1b {
    compatible = "ti,tlv320aic3106";
    reg = <0x1b>;
    status = "okay";

    /* Regulators */
    AVDD-supply = <&vaux2_reg>;
    IOVDD-supply = <&vaux2_reg>;
    DRVDD-supply = <&vaux2_reg>;
    DVDD-supply = <&vbat>;
    };

    extgpio0: pcf8574@20 {
    compatible = "nxp,pcf8574";
    reg = <0x20>;
    gpio-controller;
    #gpio-cells = <2>;

    reset_fg_i2c_mux{
    gpio-hog;
    gpios = <0 0>;
    output-high;
    };

    /*battery_1_enable{
    gpio-hog;
    gpios = <6 0>;
    output-high;
    };*/
    };

    extgpio1: pcf8574@21 {
    compatible = "nxp,pcf8574";
    reg = <0x21>;
    gpio-controller;
    #gpio-cells = <2>;
    };

    extgpio2: pcf8574@22 {
    compatible = "nxp,pcf8574";
    reg = <0x22>;
    gpio-controller;
    #gpio-cells = <2>;
    };

    extgpio3: tca9554@70 {
    compatible = "ti,tca9554";
    reg = <0x70>;
    gpio-controller;
    #gpio-cells = <2>;

    };

    s35390a: s35390a@30 {
    compatible = "s35390a";
    reg = <0x30>;
    status = "okay";
    };
    };


    In mux.c file in ti-processor-sdk-linux-am335x-evm-02.00.00.00/board-support/u-boot-2015.07+gitAUTOINC+d49aa5effa/board/ti/am335x,
    i2c0_pin_mux declare like this:

    static struct module_pin_mux i2c0_pin_mux[] = {
    {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
    {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
    {-1},
    };

    static struct module_pin_mux i2c1_pin_mux[] = {
    {OFFSET(spi0_d1), (MODE(2) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
    {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
    {-1},
    };


    Is it OK?

    Thanks Oded.
  • Hi Biser,
    Base on Note 1 below Table 21-5 in the AM335x TRM Rev. M, when I changed :

    static struct module_pin_mux i2c0_pin_mux[] = {
    {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
    {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
    {-1},
    };

    to:

    static struct module_pin_mux i2c0_pin_mux[] = {
    {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
    {OFFSET(i2c0_scl), (MODE(1) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
    {-1},
    };

    the result are the same:

    U-Boot 2015.07 (Jan 06 2016 - 10:46:28 +0200)

    Watchdog enabled
    I2C: ready
    DRAM: 256 MiB
    NAND: 0 MiB
    MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
    reading uboot.env
    Net: Phy 0 not found
    cpsw, usb_ether
    Hit any key to stop autoboot: 0
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot# i2c md 0x21 0 0x10
    0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    U-Boot#

    What the problem?

    Thanks Oded.
  • Hi Yordan,
    Base on Note 1 below Table 21-5 in the AM335x TRM Rev. M, when I changed :

    static struct module_pin_mux i2c0_pin_mux[] = {
    {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
    {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
    {-1},
    };

    to:

    static struct module_pin_mux i2c0_pin_mux[] = {
    {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
    {OFFSET(i2c0_scl), (MODE(1) | RXACTIVE |
    PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
    {-1},
    };

    the result are the same:

    U-Boot 2015.07 (Jan 06 2016 - 10:46:28 +0200)

    Watchdog enabled
    I2C: ready
    DRAM: 256 MiB
    NAND: 0 MiB
    MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
    reading uboot.env
    Net: Phy 0 not found
    cpsw, usb_ether
    Hit any key to stop autoboot: 0
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot# i2c md 0x21 0 0x10
    0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    U-Boot#

    What the problem?

    Thanks Oded.
  • Hi Yordan,
    Does the problem relate to read extgpio1: pcf8574@21 device from i2c?
    Thanks Oded.
  • Hi,

    "I work on Sitara am335x-evmsk with ti-processor-sdk-linux-am335x-evm-02.00.00.00"

    You've modified the board, by connecting an I/O expander to I2C0, right?

    So can you verify that the expander is initialized: can you probe:

    1. I2C0_SDA & I2C0_SCL

    2. then if i2c0_sda/scl toggle, can you verify that you get a something on the Px, x = 0..7,  pins, to which your EEPROM is connected?

    If you check the kernel, you'll see that the dts node for PCF8574 binds the expander with the gpio-pcf857x.c driver. So can you perform the above experiment (on both the i2c0 pins & pcf8574_Px pins)?  My guess is that i2c_read() works, but you need some additional initialization of the expander.  

    Best Regards,

    Yordan

  • Hi Yordan,

    I don't know how to verify that the expander is initialized by I2C0_SDA & I2C0_SCL but we saw via scope that there are toggle
    and when kernel is up, I operate i2cget and receive:

    root@am335x-evm:~# i2cget -f -y 0 0x21
    0xe2
    root@am335x-evm:~#

    My problem is that I need to read pcf8574 expander during boot phase and I expect 0xe2 value, but I receive 0 value:

    U-Boot 2015.07 (Jan 06 2016 - 10:46:28 +0200)

    Watchdog enabled
    I2C: ready
    DRAM: 256 MiB
    NAND: 0 MiB
    MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
    reading uboot.env
    Net: Phy 0 not found
    cpsw, usb_ether
    Hit any key to stop autoboot: 0
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot#
    U-Boot# i2c md 0x21 0 0x10
    0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    U-Boot#


    So what else can I do to solve this problem?

    Thanks Oded.
  • Hi Yordan,

    I still have this problem so can you help me to solve it?

    Thanks Oded

  • Hi Yordan,
    This problem not resolved. Can you help me to solve it?
    Thanks Oded.
  • Hi Oded,

    How did you define the PCF I2C address (0x21), and then have you tried to perform i2c_probe(<PCF_ADDRESS>)?

    Best Regards,
    Yordan