From: Francois Gervais Date: Sun, 15 Aug 2021 02:49:37 +0000 (-0400) Subject: mcp2221: allow empty i2c payload X-Git-Tag: 6.14.0~1^2~1 X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/commitdiff_plain/d3636d7313d5a05b6f321ad09d53f92d3d47fee0 mcp2221: allow empty i2c payload This fix allow sending I2C transactions with an empty payload. Before this change, sending an empty payload is bogus as it won't transfer anything but will still try to get the status of the transaction. It will basically get the current status of the bus. One way to manifest this problem is when connecting to a device. On I2CDevice() init, it will probe the device by sending en empty payload message. This actually works fine if the bus is in a good state like on first use. It won't actually send the probe out but we will read the good initial state and things will go smoothly from here. However if we start by initializing a device with an address at which there is no device, it won't send the empty payload probe but will fail later on as there is no device at that address. At this point the bus is basically in DoS as trying to init a device will again not send the empty payload but now since the bus is in the error state it will fail even if the device is in fact present. --- diff --git a/src/adafruit_blinka/microcontroller/mcp2221/mcp2221.py b/src/adafruit_blinka/microcontroller/mcp2221/mcp2221.py index 30f45f6..e5b24bb 100644 --- a/src/adafruit_blinka/microcontroller/mcp2221/mcp2221.py +++ b/src/adafruit_blinka/microcontroller/mcp2221/mcp2221.py @@ -198,7 +198,7 @@ class MCP2221: length = end - start retries = 0 - while (end - start) > 0: + while (end - start) > 0 or not buffer: chunk = min(end - start, MCP2221_MAX_I2C_DATA_LEN) # write out current chunk resp = self._hid_xfer( @@ -223,6 +223,8 @@ class MCP2221: # yay chunk sent! while self._i2c_state() == RESP_I2C_PARTIALDATA: time.sleep(0.001) + if not buffer: + break start += chunk retries = 0