-
Notifications
You must be signed in to change notification settings - Fork 92
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
I2C: Considering adding I2C clock stretching support #141
Comments
It is the first time I see an I2C chipset (PN532) using that "I2C clock stretching feature" which seems to be also related to a wake-up of the PN532 (which use I2C clock stretching in that case):
I confirm I2C clock stretching is not supported in the hydrafw firmware. Note: I have updated the https://github.com/hydrabus/hydrafw/wiki/HydraFW-I2C-guide to add details on what is not implemented/supported in actual firmware Do you know an other (simpler) I2C device doing "I2C clock stretching" (that will allow to compare with different devices to be sure the implementation of "I2C clock stretching" is done correctly) ? We can then move that to PR with your code https://github.com/r12f/hydrafw/tree/r12f/i2c-clk-stretch (when you will have validated it) |
Hi Benjamin, I am with you and also not a fan of I2C clock stretching (You can probably tell from the comment of the code in my prototype : D). I am updating the firmware for handling it mainly for 2 reasons:
For adding the option, definitely! Currently, the fork is just a prototype that demo the idea and fix and see if it makes sense or not. And will need some polishing before actually move to PR. : ) For testing against other the bad devices, here are some chips having this problem. I checked the devices I have, but didn't find one. I wonder if you happen to have any? (Sorry, I am only an entry level hobbyist with daily bad luck orz, the chip PN532 happens to be one of them.)
|
I have also updated my branch with configuration. It works like below and the default value is set to disabled too.
|
Very nice feature to configure the "I2C clock stretching" timeout especially as it depends on devices and it is better to be configurable than hard coded (as it will do not match all devices ...)
|
Wow!! You mean you have just ordered all these devices? |
Yes I have ordered them, they shall arrive quickly (some tomorrow ...) |
Omg! This is some serious dedication! I have ordered a bno055 too, and they should arrive soon as well. Will see how it looks like tomorrow! |
Just in case, to make things more clear. I have used oscilloscope to check the signal again. Unlike PN532, which only goes half way down. BNO055 goes to 0 when doing clock stretch. This is with the setting disabled, which we can see there are many clock ticks went missing: And this is with the setting set to 100: |
Thanks for all the work & measurements
Could you create a PR with your modifications like that I could merge them and test on my side ? |
Great! Absolutely! Here is the PR: #142. And really appreciate the review in advance! |
Done to be checked all work fine
To be checked if I have not mistake in my commands ... |
So glad to hear it is working! For PN532_GetFirmwareVersion, I get exactly the same result from my chip too. The IC is 0x2A for me as well. I have run logic analyzer and confirmed it on the wire too.
For the timeout, it looks like sometimes the device will go to faulty state, if we send unexpected commands, for example:
And then the clock line will be hold down forever by the device, like below and the timeout actually works, as we can see the SDA line stays low for 100ms, which is what I set - 10000 ticks. now, no matter what we run, they will just fail:
but for SameConfiguration, I double checked the manual here: https://www.nxp.com/docs/en/user-guide/141520.pdf, it looks fine to me. Also if I run it along multiple times, it runs fine as well, so I guess something else must be triggering this, not the command.
For the third one, yes, that is the thing I was trying to debug, since it doesn't work when I uses MCU... my guess is something related to IRQ, so the reply might get delayed and need some way to handle it, but so far I didn't get a successful read via I2C from MCU, so I am quite confused too. I thought it could be me being bad luck again and got a bad chip or somehow damaged it when doing soldering. But seems like you are also seeing the same thing, then it should be something expected, but we might be calling it in a wrong way. |
I have found my mistakes to interpret the PN532 datasheet ...
|
nice!!! and thank you so much for the 3rd item too, Benjamin! With this, I think I am close to my problem. I probably didn't place my tiny NFC card properly sometimes, so it could timed out the first read and then get stuck there, and I will need to power recycle it to get the chip back. The reason is actually caused by PN532 lib here: https://github.com/Seeed-Studio/PN532/blob/40fa7418636da5e03b0126e38c221b143b24b5a4/PN532_I2C/PN532_I2C.cpp#L136. It has a maximum retry count on getResponseLength. When timed out, this function returns -1, and will be used as length to read the response, which ends up making the device being stuck. Thank you so much again! |
Test also done with success with "DollaTek SHT30-D Temperature Humidity Sensor"
Issue solved by commit 0038d20 |
Hi Team, I recently ordered a hydrabus for my hobby project and trying to communicate with my PN532 module via I2C. Then it turns out hydrabus doesn't support clock stretching in I2C, hence when PN532 performs clock stretching, hydrabus will keep sending the new data until it is done. But all data will be dropped by PN532 and ends up with bad communication.
Here is an example. We can see PN532 is doing clock stretching, which makes the clock ticks hydrabus sends lower than I2C min threshold. However, hydrabus continues to send until all data is done.
To help address this problem, I have did a prototype and added the clock stretching handling with 300 cycle as timeout here: https://github.com/r12f/hydrafw/tree/r12f/i2c-clk-stretch. In this fix, it doesn't only wait before ACK or before the first bit, but on every bit, because from my traces, this could happen in other bits too. And after this fix, we can see everything start working from the result of logical analyzer as below:
Please let me know if this idea makes sense! I really like hydrabus and hope this helps too!
Tl;dr - Here are some more details on what I am doing:
Basically I am using I2C talking to PN532 in pull up mode with 100khz frequency, which I found via logical analyzer when using it with MCUs, and 2 2.2K external resistors as pull up resistors.
After entering I2C mode, I am sending a command to PN532, then wait for 300ms and then reading back the response, which will be 7 bytes. The key command is shown as below.
Before the fix, the command and output looks like below. There are lots of NACKs, which indicates problems.
After fix the command output also suggests it is working now:
This is the trace when it works with MCU, and we can see the clock stretching also happens and being handled:
The text was updated successfully, but these errors were encountered: