Discovered in https://forums.adafruit.com/viewtopic.php?t=224841
When CIRCUITPY_I2CIOEXPANDER was added in the late development of 10.1.0, reset_board_buses() was changed so that any existing board.I2C() that was already created before a VM was started was not reset, because it might be used for an IO expander.
This caused the following scenario:
- On Feather RP2350, the HSTX I2C pins are probed in
picodvi_autoconstruct_enabled() to detect I2C device 0x50, the EDID peripheral, and if it exists, some EDID data is fetched. This is done with the board.I2C() device, which is instantiated before the heap exists.
- The user in the forum topic above has an MCP9601 on the I2C bus. MCP9600 and MCP9601 do not like an I2C probe using a zero length write. The driver specifically avoids doing a probe. But due to 1. above, the bus was being probed.
- Before
CIRCUITPY_I2CIOEXPANDER, the board.I2C() bus was deinited and marked as non-existent in reset_board_buses. Then in user code, board.I2C() will re-instantiate the bus object, and the MCP960x seem OK with that, because the bus is reset. However, after CIRCUITPY_I2CIOEXPANDER, the bus is not torn down, and the MCP9601 hangs and causes ETIMEDOUT when you attempt to use it.
A possible fix is for the EDID probe to tear down the bus itself. But if there are other probes in board startup (e.g. probing for an I2C expander), the same problem might happen. The current IOExpander.c code does not do probe(), fortunately.
Discovered in https://forums.adafruit.com/viewtopic.php?t=224841
When
CIRCUITPY_I2CIOEXPANDERwas added in the late development of 10.1.0,reset_board_buses()was changed so that any existingboard.I2C()that was already created before a VM was started was not reset, because it might be used for an IO expander.This caused the following scenario:
picodvi_autoconstruct_enabled()to detect I2C device0x50, the EDID peripheral, and if it exists, some EDID data is fetched. This is done with theboard.I2C()device, which is instantiated before the heap exists.CIRCUITPY_I2CIOEXPANDER, theboard.I2C()bus was deinited and marked as non-existent inreset_board_buses. Then in user code,board.I2C()will re-instantiate the bus object, and the MCP960x seem OK with that, because the bus is reset. However, afterCIRCUITPY_I2CIOEXPANDER, the bus is not torn down, and the MCP9601 hangs and causesETIMEDOUTwhen you attempt to use it.A possible fix is for the EDID probe to tear down the bus itself. But if there are other probes in board startup (e.g. probing for an I2C expander), the same problem might happen. The current
IOExpander.ccode does not doprobe(), fortunately.