-
Notifications
You must be signed in to change notification settings - Fork 7.6k
I2C/Wire/TwoWire can lock up or cease working in some conditions #349
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
Excellent bug report! |
Yes I know about that first pulse. It comes from the hardware. I have tried many things to make it not happen, but all unsuccessful. I think I put a bit of delay there to help the device differentiate it from actual data, but that is as much as I can do about it. As for the slave pulling SDA low... that usually means that the slave has stuff to do and will release the data line once done. Used in many devices. |
Teo (Espressif's boss) just gave me an idea :) I'll give it a go and report. If you do not hear from me in the next 3 days, please bug me to do it. I am not in my country currently and will return tomorrow, so there is a chance that I will forget. |
I've had similar problems with i2c. In my case the device locks up when SDA keeps pulled low. This also happened with ESP8266, maybe the recovery code could be reused: esp8266/Arduino#1025 |
Looking at my code, I have already come up with the same idea... that is that strange transmission at init. A transmission that aims to reset the bus. |
I have been fighting with this problem myself for a almost a week now. What I have observed is the following:
|
what if we give it timeout and then manually set |
Either or both of those are valid options for testing. I am willing to test anything you want to try. I am getting familiar with the esp32-hal-* files but haven't ventured into the idf code very deep just yet. Let me know how you wish to proceed. |
@lonerzzz I went through the code and I do not see me checking after write if bus_busy is 0. It is done only in case of error. I have the feeling that I did this on purpose but my memory of the case is not that good. Maybe we need to make sure that the bus is not busy at the end of write, wait a bit and set it to 0 if it fails (then return some error I guess). |
@me-no-dev I have been trying a number of things, but I am not able to reset the state such that the flag i2c->dev->status_reg.bus_busy gets set back to 0. I have also observed that in a number of situations, this flag is already set before i2cInitFix is even called just after starting to boot. I added code in i2cInitFix to check bus_busy because the i2cInitFix code was sitting in the tight loop at the end of the method after a reasonable percentage of reboots and preventing system startup. I am using the ESP32 as an I2C master and nothing is using the bus in my application prior to the Wire.begin() call. |
I am not being able to generate the I2C clock on the pin. Don't know why the simple clock is also not present. I have the following code. Hardware:Board: ESP32 Dev Module Description:I am not able to generate the I2C clock. I have an ST microelectronics accelerator that I am using which has an I2C interface. So just wanted to see if I2C is working. I have seen many people running into the same problem but could not find a solution for this issue. No errors generated when compiling the code. Please find my code below. Sketch://Change the code below by your sketch #include "Wire.h" void setup() { void loop() { // 0x20 is the address of a pcf8574 GPIO expander delay(1000); |
Something similar happens when I run the following code on my ESP-WROOM-32, however the problem seems to disappear when I comment out the WiFi stuff in setup()... I had an oscilloscope hooked up to the clock line and got the same readings as OP describes in Observed Behavior step 3 second case: steady oscillation on clock line and nothing on the data line (except that I did not pull down the data line, at least not manually) I noticed that for each reset/run it takes a different amount of time before the fault appears. Can anyone replicate this using different I2C perferals?
|
@Curclamas |
I dunno if this is closed or .. but i have a problem where my bus freezes with sda high and scl clocking constantly with duty of 50%. All devices fail to read and whole bus is frozen. Shorting sda to ground and then releasing it fixed the problem but after some random time it happens again. I have 7 devices on bus and 4 of them have pull ups(modules). My problem is explained here . I tried to short SDA with GND really fast and it is temp. fix. Here is it explained if youre lazy to open that link:
So i was wondering if this is maybe part of this issue? Edit: |
@DjordjeMandic You might want to try my fork. stickbreaker/arduino-esp32 You can just grab the Release V0.2.0 Zip file, it only contains the modified i2c files, just overwrite the existing files of the same name. The Release files are here: Release V0.2.0 Stickbreaker/Arduino-ESP32 Chuck. |
@stickbreaker Thank you, you made it so simple to indentify problem and recover bus. I tried shorting any of i2c pins and it shows error busy which is logical and also right after i let it go it recovered itself!!! Thank you a lot! Shorting SDA to ground gives
Shorting SCL to ground gives
I wrote it to print hex received data, not chars but it works like a charm!! |
@DjordjeMandic It is kind of nice when the hardware and software work. Thanks for the compliment. I should be releasing new version later this week. I'm testing multiple Master transaction arbitration. The current V0.2.0 assumes a Bus_Busy ( Chuck. |
@stickbreaker What does |
@DjordjeMandic That message is an internal status value that was passed back from the ISR handler to the application HAL layer. 0x112 breaks out as: (these error values are defined in esp32-hal-i2c.h) The reason it emitted that message is because my code may not have handled the event correctly, my code is still in development I am not yet comfortable with how I have coded the response. So, I have the code emit this type of message so that users will give me feed back and describe the circumstances when this message happened. Interpreting that error:
Does your I2C bus have multiple Master devices? If does, then, V0.2.0 code will cause havoc. Every time a bus collision occurs and the ESP32 looses, it will attempt to regain control of the bus by resetting it's hardware and YELLING at the top of its lungs. (MINE, MINE, MINE). If the other Master is polite, this obstreperous ESP32 will grab the bus, use it, and then backoff allowing the polite Master to 'share' it. If your hardware does not include Multiple Master I2C devices, then Yes you should be concerned, Because the error should not exist. Something is interfering with SDA (holding it low). Chuck. |
@Curclamas Have you tried the current main branch code? |
@stickbreaker thanks alot for your I2C driver! This seams to work much better and yet recovered from all spurious/provoked faults. I will close this ticket therefore. |
Is this modification already part of the main ESP32 Arduino project? |
@Vankurt Yes it should be since at least 1.0.2 and has been pretty stable from a core I2C perspective. Libraries which use it though may not be 100% stable due to various reasons. |
Bug description
Steps to reproduce
Given the following minimum code example:
We've run this on a Nano32, WROOM32 and on a custom board. Run it:
also try to change the condition of the test during the runtime of the code (e.g. remove a pullup or a cable on a breadboard).
Observed behavior
Initially we see error code⚠️ we have not even sent data here ⚠️ )). When we then put in the missing component again the outputted error code will stay
0
(no error, i.e. device ACKed) or2
(NACK on address). After removing a wire or pull up we see error code3
(NACK on data (3
until we reset the ESP32.If we pull down SDA the code execution will stop / there will be no more stuff printed to the console.
Observing what happens on an oscilloscope we see in the first case (removed pullup) that after the faulty code (
3
) has occured the first time the I2C bus stays dark (high) on SCL and SDA.In the second case (SDA pulled down) we observed a steady oscillation at 100kHz on SCL until we reset the device and remove the pulldown on SDA. Removing the pulldown alone does not work.
We have observed an error condition as in (1.) on a known good board after several days of polling a value from a PCF8754 every 20ms. It looks like if the request fails once it will fail over and over again until we reboot.
Expected behavior
0
(if we have an i2c device) or2
(if no device is present) error code. I.e. it MUST be resilient against faulty conditions without a reboot.The text was updated successfully, but these errors were encountered: