Summary
Any i2cdev device configured with dev->port = LP_I2C_NUM_0 on ESP32-C6 fails with ESP_ERR_NOT_SUPPORTED because i2c_setup_port always sets .clk_source = I2C_CLK_SRC_DEFAULT. For LP_I2C, the correct value is LP_I2C_SCLK_DEFAULT. i2c_new_master_bus returns ESP_ERR_NOT_SUPPORTED when it receives the HP default clock source on an LP port.
Affected hardware
ESP32-C6 (and any future ESP32 variant with SOC_LP_I2C_SUPPORTED). HP-only builds are unaffected.
Root cause
In i2c_setup_port (i2cdev.c), the bus config is built as:
i2c_master_bus_config_t bus_config = {
.i2c_port = dev->port,
.sda_io_num = sda_pin,
.scl_io_num = scl_pin,
.clk_source = I2C_CLK_SRC_DEFAULT, // wrong value for LP_I2C_NUM_0
...
};
i2c_new_master_bus(&bus_config, &port_state->bus_handle);
i2c_master_bus_config_t uses a union for the clock-source field so both HP and LP values share the same memory slot. The official ESP-IDF documentation for LP_I2C shows the correct usage:
// from https://docs.espressif.com/projects/esp-idf/en/v6.0.1/esp32c6/api-reference/peripherals/i2c.html
i2c_master_bus_config_t i2c_mst_config = {
.clk_source = LP_I2C_SCLK_DEFAULT, // LP clock source, different from HP default
.i2c_port = LP_I2C_NUM_0,
...
};
i2cdev always passes I2C_CLK_SRC_DEFAULT regardless of port, so LP_I2C receives the HP clock-source value and i2c_new_master_bus rejects it.
Proposed fix
Select the correct clock-source value in i2c_setup_port based on the port:
i2c_master_bus_config_t bus_config = {
.i2c_port = dev->port,
.sda_io_num = sda_pin,
.scl_io_num = scl_pin,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = (sda_pullup || scl_pullup),
};
#if SOC_LP_I2C_SUPPORTED
if (dev->port == (i2c_port_num_t)LP_I2C_NUM_0) {
bus_config.clk_source = LP_I2C_SCLK_DEFAULT;
} else {
bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
}
#else
bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
#endif
This is a ~10-line change, guarded by SOC_LP_I2C_SUPPORTED so it compiles cleanly on chips without LP_I2C. All HP-bus behaviour is unchanged.
Verified on
ESP32-C6, ESP-IDF v6.0.1, i2cdev 2.2.1 from the Espressif component registry (the 2025 i2c_master API rewrite).
I'm happy to open a PR with this fix.
Summary
Any i2cdev device configured with
dev->port = LP_I2C_NUM_0on ESP32-C6 fails withESP_ERR_NOT_SUPPORTEDbecausei2c_setup_portalways sets.clk_source = I2C_CLK_SRC_DEFAULT. For LP_I2C, the correct value isLP_I2C_SCLK_DEFAULT.i2c_new_master_busreturnsESP_ERR_NOT_SUPPORTEDwhen it receives the HP default clock source on an LP port.Affected hardware
ESP32-C6 (and any future ESP32 variant with
SOC_LP_I2C_SUPPORTED). HP-only builds are unaffected.Root cause
In
i2c_setup_port(i2cdev.c), the bus config is built as:i2c_master_bus_config_tuses a union for the clock-source field so both HP and LP values share the same memory slot. The official ESP-IDF documentation for LP_I2C shows the correct usage:i2cdev always passes
I2C_CLK_SRC_DEFAULTregardless of port, so LP_I2C receives the HP clock-source value andi2c_new_master_busrejects it.Proposed fix
Select the correct clock-source value in
i2c_setup_portbased on the port:This is a ~10-line change, guarded by
SOC_LP_I2C_SUPPORTEDso it compiles cleanly on chips without LP_I2C. All HP-bus behaviour is unchanged.Verified on
ESP32-C6, ESP-IDF v6.0.1, i2cdev 2.2.1 from the Espressif component registry (the 2025
i2c_masterAPI rewrite).I'm happy to open a PR with this fix.