Resolved: I2C Clock stretching issue.

30 Nov 2009 . Edited: 01 Dec 2009

Hello everybody.

I came across a problem with the I2C library Read function "i2c.read(addr, cmd, 2);" when it face a slave the stretches the clock.

I found, for example, that if the Mbed tries to read two, or more, byte from the slave that holds the clock low "ie clock stretching" that it would wait for the first byte but not for the second and return the array filled in with the first byte.

Anybody else faced this problem?

 

Code Example: (Master Reading 16 byte from slave)

 

#include "mbed.h"

Serial pc(USBTX, USBRX);
I2C i2c(p28, p27);
DigitalOut myled(LED1);

int main() {
    
    char buffer[20];
    
    pc.printf("Test message\n\r");
    
    int retval = i2c.read( (0x41 << 1) | 1, buffer, 16); 
    
    if (retval == 1)
    {
        error("FAILED!\n\r");
    }
    else
    {
        printf("SUCCESS!\n\r");
        buffer[16] = 0;
        
        printf("%s\n\r", buffer);
        while(1);
        }
}
01 Dec 2009 . Edited: 01 Dec 2009

Hi Ronald,

Ronald Sousa wrote:
I came across a problem with the I2C library Read function "i2c.read(addr, cmd, 2);" when it face a slave the stretches the clock. I found, for example, that if the Mbed tries to read two, or more, byte from the slave that holds the clock low "ie clock stretching" that it would wait for the first byte but not for the second and return the array filled in with the first byte.

We've not tested on a slave that inserts clock stretching as far as I know. Can you confirm a few things:

  • If you run your test program, does it print "SUCCESS!" or "FAILED!"
  • Can you confirm it does write to all 16 buffer entries (i.e. if you set all of buffer chars to a known value, do they all change?)
  • What is the device? It might be good for us to get one to add to a test rig!

We'll see if we can track it down; the LPC1768/2368 manual says little about it so will need some investigation.

Simon

01 Dec 2009

Hi Simon, Nice one on the quick reply.

Simon Ford wrote:
# If you run your test program, does it print "SUCCESS!" or "FAILED!" # Can you confirm it does write to all 16 buffer entries (i.e. if you set all of buffer chars to a known value, do they all change?) # What is the device? It might be good for us to get one to add to a test rig!
When I tested codes I had a success Print. I've also set the buffer to a know state and same problem occur.

I'm using a microchip pic24fj64GA002 programmed by me ( would be quite happy to supply the Hex).

Now I almost forgot to mention, That the above code worked fine when the PIC (slave) didn't stretch the clock for too long. However, when the PIC did stretch the clock in the region of seconds that's when the Mbed exhibit the problem mention above.

01 Dec 2009 . Edited: 01 Dec 2009

Hi Ronald,

Ronald Sousa wrote:
Now I almost forgot to mention, That the above code worked fine when the PIC (slave) didn't stretch the clock for too long. However, when the PIC did stretch the clock in the region of seconds that's when the Mbed exhibit the problem mention above.

Ok, that could be it! Clock stretching is designed for a slave to hold off the clock to e.g. enable it to create the response if it isn't quite fast enough to respond. But it is meant to be short, not the order of seconds.

If you look at the I2C-bus specification and user manual, it says there isn't actually a timeout for basic I2C, but for SMBus (which is a bit tighter specified version of I2C) it is 35ms. I'd therefore suggest the bus is "correctly" timing out, hence it working for short times, but not for long times.

If you really need more than ms to do work, it might be worth looking at using a ACK/NACK approach to specify when ready and have the master poll, as would be done for most I2C eeproms.

Does this sound like the problem/solution?

Simon

01 Dec 2009 . Edited: 01 Dec 2009

Heya Simon sorry for the delay just got back to the office.

The reason for the long CLK stretch was that I was using a Pic debugger to step through that portion of the codes I didn’t realize that Mbed used the SMBus type. However that not the case anymore, what I'll do instead check the read and write buffers of the slave at the end of the I2C routine so that it doesn’t lock up the Mbed.

Thank you, I now understand that CLK stretch is there for slower devices that need just enough time to response to the master, and the NACK is there to tell the master that it needs more time to process that task. (Sorry just double checking that I understand)

How about the "i2c.read(addr, cmd, 2);" is there any way for this function, as well as the write, let you know if the device has timeout rather than return a buffer filled with that first byte? For example could it return a -1 for an error instead?