-
Notifications
You must be signed in to change notification settings - Fork 7.4k
i2c-sam0 sleeps waiting for interrupt #21092
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
I have another observation regarding the sam0 i2c driver. It appears that the i2c bus can be left in a non idle state. This is a problem because the SCL and/or SDA lines can be held low by the sam0 during and after sleep resulting in significant current (>500uA) due to the pull up resistors on these lines. I have not isolated what is causing this issue but I have confirmed using an oscilloscope that the SCL and/or SDA lines remain low after an i2c transaction. It is possible this issue is not related to the topic of this issue and should be a recorded as a separate issue. |
Optimizations: When using system power management, the bus transactions can be interrupted by low power modes which causes excessive power consumption and can cause the transactions to terminate before completed. Further, other interrupts can cause bus transaction anomalies. When using the RESTART flag, the MB and SB bits must be cleared. This commit prevents interruption of the bus during low power modes and correctly clears the MB or SB flags when a bus transaction is restarted. Also fixes an initialization problem with the INACTOUT timer and ensures the LOWTOUT is properly configured when using i2c_configure(). The GCLK_SERCOM_SLOW clock is used to time the i2c time-outs and must be configured to use a 32KHz oscillator. See 28.6.3.1 This commit configures GCLK4 to 32768 Hz Fixes zephyrproject-rtos#21711, zephyrproject-rtos#21549, zephyrproject-rtos#21233, zephyrproject-rtos#21232, zephyrproject-rtos#21114, zephyrproject-rtos#21092 A problem can arise when back to back transactions occur before the STOP transaction is complete. This commit also introduces a busy wait for the STOP to complete with an timeout in the event there is a bus failure. Signed-off-by: Steven Slupsky <[email protected]>
The driver issues a READREQ for every access to the COUNT register which causes 180us of delay. This is a large delay that causes several problems with other systems including i2c. This commit uses continuous read requests (RCONT) to optimize accessing the COUNT register. This reduces (but does not eliminate) the time spent synchronizing the COUNT register. This commit also prevent interrupts from corrupting COUNT and COMP register access. The kernel does not like it when the RTC does not tick after waking from sleep. RCONT enables continuously syncing the COUNT register but after sleep, we need to wait for a new read request to complete. However, the SYNCBUSY flag is not set when RCONT is enabled so we cannot use that to do the sync. So, we wait for the RTC COUNT register to begin ticking again by reading the COUNT register. We should wait a minimum of the TICK_THRESHOLD which is the amount of time it takes to sync the register. Fixes zephyrproject-rtos#21549, zephyrproject-rtos#21114, zephyrproject-rtos#21092 Fix comment typo The worst case update time after sleep requires 2 sync busy synchronizations. This commit updates the TICK_THRESHOLD to reflect the additional time required for the additional sync busy. Fix clock initialisation conflict. Fix whitespace mnkp recommended that a separate commit be created for the system power management. This commit separates the power_samd2x.c into a separate commit. Signed-off-by: Steven Slupsky <[email protected]>
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
@sslupsky is this still an issue? Otherwise please close it. |
@carlescufi I submitted a PR quite a while ago that addresses this. The PR hasn't been accepted yet so I left this open. I'll close it. |
Describe the bug
This is likely more a question than a bug report. However, at this point I have not been able to determine what the correct course of action is to address this observation.
When CONFIG_SYS_POWER_MANAGEMENT and CONFIG_SYS_POWER_SLEEP_STATES are enabled, the i2c-sam0 driver can suffer corruption when the device enters a sleep state. This happens because the i2c-sam0 driver waits for a semaphore. During the wait, a sleep state can be entered where the i2c clock is turned off.
Here is where this issue manifests itself in the i2c-sam0 driver:
zephyr/drivers/i2c/i2c_sam0.c
Line 459 in 42c5b0a
I believe this issue is related to issue #10524. In that issue @nashif indicates:
and subsequently closed the issue. From the comment it is not clear what is referred to. I reviewed the CONFIG_MULTITHREADING documentation but there is no mention of how to address the pm issue with i2c.
To Reproduce
I have been testing this with my own SAMD21 board with an i2c peripheral. I believe any SAMD21 board (Adafruit M0 proto board) will reproduce the problem if the config options are set as described above and the following sleep states are defined:
Expected behavior
System power sleep states that affect the i2c peripheral clock (sleep state 2 in my example above) should be avoided when an i2c master is waiting for an i2c bus event or transaction to complete.
Note, if a driver is configured to act as an i2c slave, it is possible to wake the cpu on an i2c address match without an internal clock gated on to the peripheral. So, in this instance, the peripheral clock could be gated off while waiting for the device to be addressed.
Impact
I2C is non functional during sleep.
The text was updated successfully, but these errors were encountered: