I2C – FT232H: Clock Stretching Using MPSSE

ft232ftdii2csmbus

I use an AN108 to drive my I2C line (actually SMBus).

I'm debugging with an oscilloscope.

Doing a read, right after the 8b address, I found that the slave was pulling down my clock signal SDC for a few cycles, therefore the ACK isn't read correctly.

How can I handle that with MPSSE? I would need to wait until the slave stops pulling down the SDC line.

Best Answer

Adaptive clocking feature of MPSSE allows to implement I2C clock stretching. I have a design with FT4232H that implements this, and same feature is supported on FT232H, so it should work there as well.

Adaptive clocking feature (DS_FT232H, 4.8.1 p. 32) uses a pin (GPIOL3, fixed) to sense a delayed copy of TCK after it went through the target and back. It is supposedly used to allow to clock TCK as fast as possible in JTAG mode on old ARM targets. As MPSSE is implemented, this actually works for non-JTAG protocols as well: It works as long as you use MPSSE clocked commands (bit shifts, free running clocks, etc.).

With the following wiring, FTDI TCK/TDI pins drive SCL/SDA down when needed, TDO senses SDA back, GPIOL3 senses SCL back.

MPSSE I2C wiring with adaptive clocking

Here is an excerpt of effect on bus, while the whole MPSSE command stream was sent as one USB transfer, we can see the target stretches the bus while preparing the next data byte:

Clock stretching before byte reads

This can be compared with writes where no stretching happens: Write, no stretching

The only downside is that MPSSE has no timeout on the adaptive clocking feature, so you never have response on MPSSE stream if I2C bus has SCL stuck low. Most common is when target is not powered. In such cases, you are forced to reset the endpoints and the whole MPSSE engine.