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.

DM365: i2c setup

Hello,

this code is used in spectrum digital's i2c initialization sequence. Has anyone idea what's for?

static void setup_i2c(void)
{

unsigned int val;
int i;

/* GPIO20 */
davinci_cfg_reg(DM365_GPIO20, PINMUX_RESV);

/* Configure GPIO20 as an output */
gpio_direction_output(20, 0);

for (i = 0; i < 20; i++) {
gpio_set_value(20, 0);
mdelay(100);
gpio_set_value(20, 1);
}

/* Free GPIO20, for I2C */
davinci_cfg_reg(DM365_GPIO20, PINMUX_FREE);

/* I2C */
davinci_cfg_reg(DM365_I2C_SCL, PINMUX_RESV);

}

  • Marco Braga said:
    this code is used in spectrum digital's i2c initialization sequence. Has anyone idea what's for?

    While I am not sure exactly why this is necessary, I can at least say that it looks like the code is effectively generating 20 clock cycles in I2C_SCL by switching the pin into GPIO mode and flipping the output back and forth. My suspicion is that some I2C device on the EVM requires, or is more stable, with initial clocking of the I2C SCL line, as the I2C user's guide makes no mention of such a requirement in the initialization sequence. 

    Assuming no one else on the forum has more specific reasoning as to why this is needed, if the code is coming from the Spectrum Digital test cases, you may want to ask them about it.

  • Bernie,

    thanks for your comment. I am investigating a problem with davinci's i2c driver that does not seem to handle well if I try to read from an i2c device with the wrong address, i.e. when no ack is received. So I've noticed that strange code. I'll ask to spectrum digital what's used for.

     

  • That sort of code is used for recovering a hung I2C bus.  If for example the processor was reset while in the middle of an I2C transaction and the slave happened to be holding SDA low then the bus would be stuck forever.  Toggling SCL a bunch of times at startup guarantees nothing will keep the bus tied up.

    Please see the "Detecting and Handling NACK" section of this wiki page I wrote:

    http://wiki.davincidsp.com/index.php/I2C_Tips

  • PS.  I've seen some similar looking patches recently on the Davinci mailing list related to being able to probe the I2C bus to detect what addresses are present.  You may need to pull in some of those patches.

  • Brad,

    thanks for your explanation. I suspected something similar but I was puzzled by the fact that the code does not create a perfect square wave on the clock, since it is missing a mdelay when gpio is set to 1. Also the frequency seems very low for an i2c device (if the delay is 100ms as I suspect).

    My problem is that even with the 20 clock cycle workaround, sometimes the i2c bus seems to be stuck with some device (or the master) keeping the clock low. This condition seems to be undetected by the i2c driver.

    Can you please direct me to the DaVinci mailing list. Is this url correct?

    http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

    Thanks again!

     

  • That's the right list. Can you get a screenshot of the activity on the bus just before it hangs?  Does a NACK occur?  If so, it's likely the dm365 holding scl low. My wiki page tells how this should be handled.

    I'm also attaching a thread to a different list, which may have been the one I was thinking of...

    Fix smbus Oops.pdf