Looking for I2c expertise to check and improve my modifications to the I2c master

So - back to a variation of my original question - can anyone say with confidence given a software I2c master, the exact point or points in which the master should be looking to see if the slave is trying to clock-stretch?

The PWM code is also in the universal I/O bridge… If you want something really smart, see here: http://www.esp8266.com/viewtopic.php?f=4&t=10600&p=51084#p51084 but beware that the author seems to have abandonded the code. For me, I found it to be too complex, not quite transparent code so I wrote my own. But both implementations share that they make all period values usable, 0%-100%. My code uses the maskable interrupt, which may not yield perfect wave forms, but doesn’t interfere with other stuff.

@Erik_Slagter That’s news to me Erik - I might be lucky but I’ve always ran them at 16Mhz at 3v3. Call it ignorance but I’ve not suffered accordingly - most of the boards come with a 16Mhz xtal so it never occurred to me to use anything else and no the 328 IS no match for the ESP - except for useful pins :slight_smile: and hence we come back around to ports. I’ve just realised if you sacrifice serial on the 328 - not needed in my little “peripheral” - you can use the direct port setting, writing and reading registers to do port 0-7 in one fell swoop - I have that working and am about to see how this drives my Hitachi display as against the port expander… mind you - I’d probably be just as well off shoving the whole driver software for the Hitachi (4 line) onto the Arduino - but it will be interesting just to compare high speed byte-wide port writing on the Arduino - to the dedicated port expander - given that the slowest part of the whole thing is the I2c.

@Erik_Slagter Oh… you might just’ve made my day… reading now.

So Erik - bear with me as I’m usually slow at first - what’s the plan here - remove libPWM.a from the and the makefile and add your C file to the list of files included in the makefile - put that include in my own code and the #define you mention - is that it??? Complete compatibility? I’m really hoping you’re going to say yes?

And now the answer to the question you’ve been waiting for all this time :wink:

Clock stretching may happen at moments where the master requires a reply from the slave. The slave pulls down the SCL line on it’s own until it is ready to reply and then releases it, which, on itself, gives the next clock phase (because the master should have already released it at that point).

IMHO the best practise to handle clock stretching is like this: every time you release SCL, you should monitor the SCL line and see it really go up. The ESP8266 can read an (open drain) output just like it’s an input, so just read the input bit. Wait for some time until the SCL really goes high and then either continue (if within the timeout) or give an error to the end user and give up (outside the timeout).

I’ve found very few I2C slaves actually implement clock stretching. One notable exception is the SHT21, which can stretch the clock for more then 10000 ESP8266 asm “nop” instructions, so you were warned :wink: If it takes even longer for the SCL to recover, you may assume a bus lock and most of the time, that means all connected slaves must be power cycled, because one of them in a weird state.

Having said this, it’s also smart to just always monitor toggles to both SDA and SCL. Really, it will make your life so much simpler. Sometimes a slave hogs SCL and sometimes SDA and sometimes both. It’s good to know what actually happens then and not just have the report “doesn’t work”.

There is a procedure to get all connected slaves out of “weird” states, which includes toggling the SCL nine times and then send a stop condition. I have found it’s a great idea in concept, but doesn’t always work.

The max speed of the ATmega’s is always discussed. It seems that ATmel is a bit on the cautious side here. If you look at the graphs in the datasheet you will see what I mean. And indeed many people just run it at 16 Mhz@3.3V, but it isn’t guaranteed by ATmel. Maybe it just works. Maybe it crashes if you use that one instruction, maybe in a tight loop, who knows…

If you want easy compatibility, go with the code from the link, it has a “legacy” compatibility interface. Although I found it only works as expected if you convert the period to 200ns ticks yourself and not use the #defines (see the explanation).

My code is tightly integrated with the already existing data structures in my app. I don’t think it will be quite easy to port it. This by the way contrary to the i2c code, which is quite standalone.

The best option would be of course if Espressif would listen to their users, open up the code and accept improvements from the community. That remains a weak point.

So just to confirm - you are referring to THIS link?

Yes. Be sure the also read the blog text for good understanding of the whole.