Is there any good reason that I[sup:]2[/sup:]C clock stretching is not implemented? Simple omission or oversight or lack of development resources is one thing, but is there any reason this hasn't been done? Like we tried, but the system puked, so we backed it out?
I was thinking of hacking it in there this week (time permitting). The issue has come up several times, and it really can be a significant limiting factor to using Bus Pirate I[sup:]2[/sup:]C for things like sensors or other real-world interfacing devices... basically anything other than an EEPROM, which is the only thing I would always 100% depend on to work at full bus speed.
Since we use a software library (on v3) for I[sup:]2[/sup:]C, it should be very easy to add. I had a look at the code, and I am sure it can be done with less than 10 lines of code added. For hardware I[sup:]2[/sup:]C on v4, well, I'd implement that too if I had a v4. The I[sup:]2[/sup:]C peripheral supports it, but does require extra code.
I never though it was do-able in software. We never used the hardware I2C as there was an issue with a certain revision PIC which had broken I2C hardware. IIRC it was only 1 or 2 batches in 2010 but Ian decided to leave it out to avoid confusing.
If you can do it in software it would be great! Don't you fear the performance drop?
The basic idea is to check and wait for the clock line to go high after releasing it (setting it high). The idea behind clock stretching is that the slave device can hold the clock low in order to delay this low to high transition. So you just do a simple loop checking the I/O Pin state until it goes high (or you time out). If it goes high immediately, the additional overhead is just a few instruction cycles, as few as 2 or 3. At 16 MIPS, that's not long (do we run at 16 MIPS/64 MHz? I didn't see the clock config). I see plenty of opportunity to gain back plenty of performance with some optimizations in the bit-bang code, such as making critical functions "inline". The only tricky thing then is determining the new clock delays to achieve the various clock speeds (I am equipped to do that).
I think the issue is that we didn't want to get stuck waiting forever for the clock to finish stretching. A timeout is fine though, but since I2C shares the binIO library it got complicated fast to include it.