Open sslupsky opened 5 years ago
I determined the source of this problem. When the Wire tells the I2C to stop the bus cycle, the command is issued and synced to the peripheral. The command to stop is non-blocking so program execution continues. If you subsequently go to sleep right away before the stop sequence has not been completed by the peripheral, the master still owns the bus and keeps SCL and SDA low. To fix this, you need to insert a short delay (about 20 us) after issuing the STOP command.
I'll submit a PR for this issue.
This issue was also posted on the Arduino forum:
https://forum.arduino.cc/index.php?topic=618735.0
@sslupsky did you open a pull request for this?
Not yet ... I was trying to think of a way to ensure the STOP is complete without using an arbitrary delay. At the moment, it seems to me there would need to be a check in the deepSleep() method. Any thoughts?
@sandeepmistry I think I have determined the underlying cause of the issue in the Wire library. When a command written (CTRLB CMD) to send a stop bit, the library sends the command but does not wait for the bus to return to the idle state. This occurs in four places:
I believe the proper way to address this issue is to add the following line after each of the above statements:
while (!sercom->isBusIdleWIRE()) {}
I'll submit a PR for this. Is there any feedback I should consider before I do so?
One concern I have is if there is any reason that the the bus would not return to idle after issuing the stop bit, the while loop would block indefinitely.
Another approach would be to add a check in the Arduino Low Power library before going to sleep that checks that the I2C bus is idle. To do the check however would require creating an API in the Wire library to do so.
Thanks for the efforts here. Did this get resolved in user code?
There is an issue with the I2C bus state when using low power deep sleep. The problem occurs when the sleeping. When the I2C master goes to sleep, the SCL and SDA lines are pulled low while the MCU is sleeping. This causes excessive power consumption during sleep because of the I2C pull up resistors. The next time the master wakes up, the SCL and SDA lines are pulled high and stay that way until the next I2C transaction. This cycle repeats. Here is the sketch. In this example, the rtc alarm event fires every 10 seconds.