-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Double I2C read in one transaction skips a clock pulse #5528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@maarten-pennings Thank you for the analysis and for offering a fix! |
I'm not yet familiar enough with the code, so I'm not sure if the fix works in all cases. |
By the way, I added a comment to #5340, but that was already closed. Is my comment lost, should I reopen the issue, create a new issue? Sorry - new to this process. |
I have written an i2c clock stretch injector https://github.com/maarten-pennings/I2C-tool |
@maarten-pennings ok, let's try to resolve here. |
@devyte your comment "Is there any chance you can implement something that doesn't depend on specialized hardware? Example: two ESPs where one is master and the other is slave," did make sense to me. However I could not commit to developing that back then. And on hindsight, it was way more work than expected :-) Please have a look (when you find your afternoon of peace). My I2C-tool suffers from long interrupt latency and from something I don't understand; the first couple of interrupts are missed, but once it is running it is fine (see the for loop in Let me know if you have question. And let me know if I can be of any assistance. |
|
The primary issue here has a proposed solution, but testing it depends on having a testbench, i.e.: a robust master-slave example, and that's not yet done. Pushing back. |
Hi, I'm confused. I wrote a test framework (https://github.com/maarten-pennings/I2C-tool), you seemed positive about this ("what you did is precisely what I envisioned: a master-slave set up, where the slave sketch can do a configurable clock stretch"), but now you "push back". What do you want me to do? |
@maarten-pennings I was waiting for a PR with the changes proposed in "how to fix". The two sketches should be added as examples in the Wire lib. |
I submitted 5718. Is this what you wanted? |
Ok, as I said above, let's resolve in this issue. |
@maarten-pennings Are you going to make a PR for the changes you posted at https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix and the examples as requested by @devyte ? |
See esp8266#5528 and the more elaborate [description](https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix) where @maarten-pennings did all the hard work, but as far as I could see, no PR was made.
Since all the hard work of @maarten-pennings has not resulted in a pull request, I made one. See #6579 |
Thanks @TD-er for picking this up. I already forgot about it... |
See esp8266#5528 and the more elaborate [description](https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix) where @maarten-pennings did all the hard work, but as far as I could see, no PR was made.
See esp8266#5528 and the more elaborate [description](https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix) where @maarten-pennings did all the hard work, but as far as I could see, no PR was made.
See esp8266#5528 and the more elaborate [description](https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix) where @maarten-pennings did all the hard work, but as far as I could see, no PR was made. I also noticed some code duplication, which I moved to separate functions. According to [this documentation on I2C clock stretching](https://www.i2c-bus.org/clock-stretching/) it is not allowed to have some slave keep the clock low during transmission of a byte, only after an ack. So that's why it is not done in the while loop. But I wondered if there should be an extra delay between the sequence of pulses and the extra added clock "valley". See my comment in the code. Fixes esp8266#5528
* Double I2C read in one transaction skips a clock pulse (#5528) See #5528 and the more elaborate [description](https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix) where @maarten-pennings did all the hard work, but as far as I could see, no PR was made. I also noticed some code duplication, which I moved to separate functions. According to [this documentation on I2C clock stretching](https://www.i2c-bus.org/clock-stretching/) it is not allowed to have some slave keep the clock low during transmission of a byte, only after an ack. So that's why it is not done in the while loop. But I wondered if there should be an extra delay between the sequence of pulses and the extra added clock "valley". See my comment in the code. Fixes #5528 * [I2C] Restore clock stretch functionality during transfer As requested here: https://github.com/esp8266/Arduino/pull/6654/files/8357a8c644244096cce1df30acd660c35d24a0e4#r339310509 * [I2C] Move duplicated clock stretch call to twi_scl_valley function
I was writing a clock stretch injector for #5340 and then I stumbled on another error in the driver file core_esp8266_si2c.c "Software I2C library for esp8266" function
twi_readFrom
.The problem occurs when issuing two reads in one I2C transaction (i.e. with a repeated START in between). In this scenario, one clock pulse is not generated by the master: the clock pulse for the 9th bit (the ack bit) just before the repeated start. I tested this with the latest release 2_5_0_BETA2 (but it also
fails on 2.4.2).
Unfortunately, I don't know how to write a single ESP8266 program that detects this. Instead, I took an arbitrary I2C slave, and hooked a logic analyzer to the I2C bus
This is the test code running on the ESP8266 (see full sketch attached at the end):
and this logic analyzer capture shows the problem:
I tried to fix the code, the following seems to work (but I have not thoroughly tested it):
This leads to the following capture of the logic analyser:
Here is the test sketch:
ESP8266-i2c2xread.zip
The text was updated successfully, but these errors were encountered: