This library implements an I2C slave protocol for the RP2040 using PIO, with support for responding to multiple I2C addresses.
It is compatible with both the Pico SDK and Arduino-Pico.
- I2C slave implemented in PIO
- Supports multiple I2C addresses
- Compatible with Pico SDK and Arduino
- Optional receive, request, and stop handlers
- Supports fixed-length transfers for compatibility with buggy I2C masters
- Supports standard I2C speeds up to 1 MHz
- Uses one full PIO instance
The library has been tested beyond standard I2C speeds.
Operation at 2 MHz has been verified, but timing margins become very small, especially with back-to-back transactions and the stop callback enabled. Speeds above 1 MHz should therefore be considered experimental.
Add the following files to your project:
i2c_multi.pioi2c_multi.hi2c_multi.c
Then update your CMakeLists.txt to:
- call
pico_generate_pio_header - link the required libraries:
pico_stdlibhardware_irqhardware_piohardware_i2c
See sdk/CMakeLists.txt for an example.
Add the following files to your project:
i2c_multi.pio.hi2c_multi.hi2c_multi.c
- Define the receive, request, and stop handlers if needed
- Set the write buffer pointer
- Enable the I2C addresses you want to use for communication
Use pull-up resistors from 1 kΩ to 3.3 kΩ.
Use lower resistor values for higher bus speeds.
See sdk/main.c for a usage example.

RP2040 configured as an I2C slave (left), receiving and sending data through multiple I2C addresses from an I2C master (right)
Must be called first.
Parameters
pio- PIO instance where the program will be loaded (pio0orpio1)pin- SDA pin number; SCL is assigned topin + 1
Sets the receive handler.
Parameters
i2c_receive_handler- function called when data or an address is received
Sets the request handler.
Parameters
i2c_request_handler- function called when the master requests data
Sets the stop handler.
Parameters
i2c_stop_handler- function called when a STOP condition is detected
Sets the write buffer.
Parameters
buffer- write buffer
Puts I2C on hold by disabling the PIO state machines.
Restarts the PIO state machines and resets the byte counter.
Removes the PIO state machines and clears handlers, write buffer, and byte counter.
Enables one I2C address.
Parameters
address- I2C address to enable
Disables one I2C address.
Parameters
address- I2C address to disable
Enables all I2C addresses.
Disables all I2C addresses.
Checks whether an I2C address is enabled.
Parameters
address- I2C address to check
Returns
trueif the address is enabledfalseotherwise
Releases the bus after the specified number of bytes has been sent.
Useful for compatibility with buggy I2C masters.
Called when a byte or address is received.
Parameters
data- received byte or addressis_address-trueifdatais an address,falseif it is a data byte
Called when the master requests data.
Parameters
address- I2C address used in the request
Called when a STOP condition is detected.
Parameters
length- number of bytes received or sent
Remark
I2C callbacks run in interrupt context and should be kept short and non-blocking. This is especially critical for the stop callback, since a STOP condition releases the bus and the next transaction may start immediately.
Avoid printf, Serial, delays, or other slow operations inside the stop callback, particularly with back-to-back transactions. If debug output is required, store the data in the callback and print it later from the main loop.
- Fixed repeated START support and documented timing considerations for stop callbacks and high-speed/back-to-back transactions.
- PIO program size increased to 30 instructions
- Reduced from 32 to 28 PIO instructions
- Improved high-speed operation
- Added
i2c_multi_fixed_length()to release the bus after a fixed number of bytes
- Initial release