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.

Issue with DM369 I2C GPIO mode used for I2C bus recovery

Hi All,

My company has had a product out in the field for a couple of years that uses the DM369 as an I2C bus master (single master bus).  We have a reasonably light load on the bus, typically monitoring various sensors every few seconds.  We find that very infrequently, the I2C bus gets hung at the controller side (it isn't always the same sensor that triggers a 1 second bus timeout).

In order to recover the bus, we have implemented the i2c_recover_bus() code found in the Linux DaVinci git repo.  It uses the DPFUNC GPIO mode used to control the SCK and SDA lines without involving the I2C controller engine.

The issue that we found is that when the lines are set to GPIO outputs, they are always low regardless of the content of the ICPDOUT register.  My assumption is that since the I2C bus is open collector, setting a line high would effectively release the line for the external pullup to drive it high.  That is not so.

The issue is easy to reproduce at the Linux prompt by reading and writing registers using devmem2 and looking at line state using a scope/protocol analyzer:

  1. Set ICIMR to 0 (disable interrrupts)
  2. Set ICMDR to 0 (reset I2C by clearing IRS bit)
  3. Read ICPDIN and check that SDA and SCK are 1
  4. Set ICPDIR to 3 (GPIO outputs)
  5. Set ICPFUNC to 1 (PFUNC GPIO mode)
  6. At this point, both SCK and SDA go low.  I can set ICPDOUT to 3 or 0, it doesn’t matter, the lines stay low.
  7. If I take the I2C out of reset (ICMDR = 0x20), SCK and SDA stay stuck low, no difference regardless of ICPDOUT content.
  8. If I switch ICPDIR to 0 (SCK and SDA input), the lines float high, as expected.  If I set ICPDIR to 3, the lines go low again regardless of ICPDOUT content.

BTW, I've verified that no other device is using the bus.

There is a cryptic comment in the datasheet that might shed some light on this:

Note: If I2C_SDA is connected to an open-drain buffer at the chip level, the I2C cannot drive I2C_SDA to high.


I'm not sure if this means that the DM369 can't release the line with this register (but then this would make the ICPDOUT register useless), or if there's a setting outside the I2C registers that needs to be changed to make the ICPDOUT register functional.

In the meantime, I'm using ICPDIR to drive and release the lines.

Thoughts?

Andre