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.

I2C3 in X-Loader on OMAP3630

Greetings, I'm porting X-Loader (from https://gitorious.org/x-loader/x-loader) to an OMAP3630 phone. While X-Loader boots fine, I cannot seem to manage to use I2C3.

The code shipped in that X-Loader version comes from an old U-Boot version and handles I2C1 at 100Mhz speed correctly. For instance, I can access the TWL5030 registers that way. However, when changing the I2C base address from 0x48070000 (I2C1) to 0x48060000 (I2C3), it doesn't work anymore and I cannot probe the chip I'm interested in, not to mention perform read/write. During these, it times out waiting for I2C_STAT, which stays at 0x00.

Here is some complementary information:

  • CM_FCLKEN1_CORE and CM_ICLKEN1_CORE have the I2C3 bits set
  • CM_IDLEST1_CORE confirms that I2C3 can be accessed
  • I2C3 pins (SCL and SDA) are muxed properly (IEN  | PTU | EN  | M0)
  • The slave I2C device's datasheet reports a max speed of 400Mhz so I'm assuming it should work fine at 100Mhz
  • The slave I2C device is powered on and should have its I2C connection ready
  • There are external pullup resistors on the I2C3 SCL and SDA lines with 4.7K resistors (connected to 1.8V_VIO)
  • CONTROL_PROG_IO2 confirms that internal pullup on I2C3 is disabled
  • It all works with the Linux kernel, so this is not a hardware issue


It addition, I have tried code from newer mainline U-Boot versions, where the prescalar, scll and sclh are calculated differently and it works on I2C1 at 400Mhz (not at 100Mhz though) but still doesn't work with the I2C3 base address (same time out with 0x00 on I2C_STAT).


I would really appreciate some help sorting out what I could possibly have missed here. Thanks in advance!

  • Hi Paul,

    I suggest you and example for initialization of the clock of I2C 1, 2, 3 according Beagle board board file:

           /* Turn on all 3 I2C clocks */
           sr32(CM_FCLKEN1_CORE, 15, 3, 0x7);
           sr32(CM_ICLKEN1_CORE, 15, 3, 0x7);      /* I2C1,2,3 = on */

    See the whole file in attachment:

    4201.omap3beagle.c

    The max frequency on which I expect to operates the I2C is 96 MHz. For more details about I2C configuration look at the TRM section 17.5 HS I2C Basic Programming Model at the link:

    http://www.ti.com/lit/ug/swpu177aa/swpu177aa.pdf

    BR

    Tsvetolin Shulev

  • Well, I already mentioned this is done correctly already (CM_FCLKEN1_CORE and CM_ICLKEN1_CORE have the I2C3 bits set). I will read the TRM more closely in case I missed anything relevant.

    The devices has external pullup on the I2C3 lines and I disabled any internal pullup, but what would happen if I was to enable the internal pullups as well?

    In the meantime, please let me know if there is any specific PRCM configuration that I must check to make sure the I2C3 FCLK is correctly enabled. Unfortunately, I don't have access to a probe that would let me verify whether the clocks are good.

    Thanks for your support!

  • I did check the following;

    • external pullup is applied (SDA/SCL are at 1.8V when there is no activity)
    • PIN muxing is correctly in place, internal pullup is disabled
    • OMAP3630_PRG_I2C3_PULLUPRESX is set so that further internal pullup is disabled (enabling internal pullup by removing OMAP3630_PRG_I2C3_PULLUPRESX doesn't solve the issue)
    • the I2C3 clock is enabled, prescaler is set to have a 9600kHz internal sampling clock
    • SCLL and SCLH are set to have 400kHz on I2C3_SCL
    • I thoroughly followed the TRM examples and recommendations for I2C implementation

    My guess is that for some reason, the transaction never actually takes place. For instance, when I'm trying to write to a slave that is non-existent on the bus, I don't get a NACK after writing to I2C3_DATA.

    The code I'm using works perfectly when I change the I2C base address to I2C1, so this is not a software issue.

    Any clues would be greatly appreciated, thanks!

  • I had access to an oscilloscope and confirm that both SCL and SDA are going properly. The levels are correct and there is no timing issue.

    After some further investigation, the problem seems to be that the controller cannot read on the lines: when I attempt to probe an i2c slave, the STP bit in the I2C_CON register is not cleared, while the controller should clear it automatically after detecting its own-emitted stop condition. Same goes for NACK: while the ACK bit is high (indicating NACK), the controller does not report the NACK bit in the I2C_STAT register.

    Moreover, disabling input on the mux configuration for I2C1 or I2C2 provides the exact same results as what I have with I2C3. Note that the mux configuration explicitly allows input for I2C3.

    Is there an additional bit to set somewhere to actually enable input on the I2C3 SDA and SCL lines? Or maybe some other parameter makes input unreliable/flawed?

  • It appears that muxing the pins to GPIO shows that both I2C2 SDA and SCL report logical-high levels (1), because of the pullup to 1.8V, I2C3 SDA reports 1 as well but I2C3 SCL reports 0, despite the pullup that is applied on it. Looking at it with a scope shows that I2C3 SCL is at 1.8V: when muxed to GPIO, it should report 1, but doesn't.

    Everything looks as if I2C3 SCL input was disabled, but the PADCONF registers for I2C3 have the input enable bit set.

    What am I possibly missing here? I would appreciate some help from TI.

    Thank-you