I am curious why SINGLE_THREADED_SECTION() is used throughout TwoWire, the class for I2C Wire. This seems to be one of the few places where SINGLE_THREADED_SECTION() is used in the system firmware.

Could someone explain why TwoWire needs SINGLE_THREADED_SECTION()?

I have written an I2C library, I2cMaster, that allows large I2C transfers and I also disabled scheduling in this class for I2C transfers.

I am would prefer to not disable scheduling since a 250 byte transfer at 100kHz could take about 25 ms.

I have written I2cMaster so delays should be OK for devices that allow SCL clock stretching.

It was added in response to this issue: https://github.com/spark/firmware/issues/698

I too would prefer not to have to disable task switching, but we didn’t see any other solution.

We’re open to suggestions if there is a way to keep I2C reliable as well as with task switching!

I happen to have several of the MCP23017 I/O Expander chips mentioned this issue.

I will experiment to see what I can find.


After a lot of experiments, I now think the problem is not task switching but a bug in not waiting for the stop condition to complete correctly in endTransmission().

SINGLE_THREADED_SECTION() insures a bit of delay between back-to-back endTransmission()/requestFrom() calls.

See this issue I added: https://github.com/spark/firmware/issues/854