Skip to content

LP_I2C_NUM_0 not supported: hardcoded clk_source causes ESP_ERR_NOT_SUPPORTED #12

@lptr

Description

@lptr

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions