Skip to content

I2C Bus error leaves board unrecoverable without power down #2635

Open
@Panometric

Description

@Panometric

In my example, in a loop reading the device as fast as possible, and doing other unrelated things..

while 1:
     acceleration = cpx.acceleration
    .....

You can get an error:


Traceback (most recent call last):
  File "code.py", line 63, in <module>
  File "adafruit_circuitplayground/circuit_playground_base.py", line 261, in acceleration
  File "adafruit_lis3dh.py", line 159, in acceleration
  File "adafruit_lis3dh.py", line 328, in _read_register
  File "adafruit_lis3dh.py", line 327, in _read_register
  File "adafruit_bus_device/i2c_device.py", line 82, in readinto
OSError: [Errno 5] Input/output error

Press any key to enter the REPL. Use CTRL-D to reload.soft reboot

Once this occurs, the I2C device bus is stuck because the device is holding the bus. The board never recovers unless you power it down. Every restart just issues a RuntimeError. This could happen on any I2C device.


Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
  File "code.py", line 3, in <module>
  File "adafruit_circuitplayground/__init__.py", line 29, in <module>
  File "adafruit_circuitplayground/express.py", line 75, in <module>
  File "adafruit_circuitplayground/express.py", line 72, in __init__
  File "adafruit_circuitplayground/circuit_playground_base.py", line 110, in __init__
RuntimeError: SDA or SCL needs a pull up

The industry standard response to this is to bit-bang single clocks onto SCLK until the bus is released by the slave. This should be done at start, or even on error to recover the bus silently. It usually requires disconnecting the peripheral temporarily, using the SCLK os GPIO and then reconnecting.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions