Skip to content
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 hangs when power removed from bus on nrf52840 #8093

Closed
furbrain opened this issue Jun 19, 2023 · 5 comments · Fixed by #8827
Closed

I2C hangs when power removed from bus on nrf52840 #8093

furbrain opened this issue Jun 19, 2023 · 5 comments · Fixed by #8827

Comments

@furbrain
Copy link

CircuitPython version

8.1.0-beta.1-44
(Running on a Seeed XIAO nrf52840 Sense)

Code/REPL

import board
import busio
import time
from adafruit_lsm6ds.lsm6ds3 import LSM6DS3
import digitalio

# board.IMU_PWR provides the power to both the LSM6DS3 chip and also the pullups to the I2C bus
pwr = digitalio.DigitalInOut(board.IMU_PWR)
pwr.switch_to_output(True)
print("Starting")
time.sleep(5)
print("Connecting to IMU")
with busio.I2C(scl=board.IMU_SCL, sda=board.IMU_SDA) as i2c_bus:
    imu = LSM6DS3(i2c_bus, address=0x6A)
    print("This works")
    print(imu.acceleration)
    time.sleep(1)
    pwr.switch_to_output(False)
    print("This crashes")
    print(imu.acceleration)
    print("We don't get here")

Behavior

The code above gets as far as the second print(imu.acceleration) and then the device hangs and can only be recovered by a manual reset.

Description

No response

Additional information

Debugging with STLINK-V2 identifies that the call to nrfx_twim_xfer in common_hal_busio_i2c_write is where the device hangs

@furbrain furbrain added the bug label Jun 19, 2023
furbrain added a commit to furbrain/circuitpython that referenced this issue Jun 19, 2023
This adds a check to make sure that SDA and SCL are in a sane condition
before starting any I2C operation. If they are not it tries to rectify it,
and then returns an error code if unable to do so.
@DJDevon3
Copy link

Could this be related to the warning about not using one of the SPI periphs while on battery power detailed here? I know that's SPI and your issue is I2C but seems similar enough to bring up.

@furbrain
Copy link
Author

furbrain commented Jun 20, 2023

@DJDevon3 I don't think so. This issue only occurs when the I2C bus pull-ups are unpowered - this leaves both SDA and SCL low (which is an invalid state for I2C). It also affects both TWIM peripherals, whereas the one you reference only affects SPIM3. Also this bug occurs both when battery and USB powered.

@tannewt tannewt added the nordic label Jun 20, 2023
@tannewt tannewt added this to the Long term milestone Jun 20, 2023
dhalbert added a commit that referenced this issue Jun 23, 2023
@dhalbert
Copy link
Collaborator

@furbrain Sorry for the on-again off-again approval/revert of your #8094 PR. I realized this is another manifestation of an old issue, #2253. Rather than look for good initial conditions (which might change out from under us), I think adding a timeout, as suggested in #2253, would be a better solution, since a bad I2C device can hang the bus while a transaction is in progress.

@furbrain
Copy link
Author

Yes, I think that could work, but would need to change to a callback related method. I disagree with the comment about the timeout not getting called in #2253 - could have the callback set a flag and then poll for this flag while checking the time and abort if the time increases by a certain amount before the flag is set.

I'd be happy to look at this, though I have found a different route around this problem in my use case in any event.

@furbrain
Copy link
Author

My main issue in doing this would be working out a good way to test that I haven't broken any I2C functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants