Skip to content

i2cdev should adopt an already-installed bus handle rather than failing with ESP_ERR_INVALID_STATE #14

@lptr

Description

@lptr

Problem

If another component (e.g. espressif/esp_lcd, espressif/i2c_bus, or
application code) has already called i2c_new_master_bus for a given port
before i2cdev touches it, i2c_setup_port will attempt a second
i2c_new_master_bus on the same port and return ESP_ERR_INVALID_STATE.

This makes i2cdev fragile in any project where the bus lifetime is managed
outside of i2cdev — which is a common pattern when multiple components share
a single I2C bus.

Suggested fix

Call i2c_master_get_bus_handle(port, &handle) before i2c_new_master_bus.
If a handle already exists, adopt it and skip installation. This is exactly
the pattern espressif/i2c_bus already implements:

// From espressif/i2c_bus
esp_err_t ret = i2c_master_get_bus_handle(i2c_num, &p_i2c_bus->i2c_master_handle);
if (ret == ESP_ERR_INVALID_ARG) {
    // No existing handle — install a new bus
    ret = i2c_master_bus_init(i2c_num, conf, &p_i2c_bus->i2c_master_handle);
    p_i2c_bus->bus_mode = I2C_BUS_MODE_OWNER;
} else {
    // Reuse the existing handle
    p_i2c_bus->bus_mode = I2C_BUS_MODE_REFERENCE;
}

A similar externally_owned flag could be tracked in i2cdev's port_state
so that i2cdev_done / the port teardown path knows not to call
i2c_del_master_bus on a handle it didn't create.

Context

This came up while working on LP_I2C support (see #12 / PR #13). Before the
clock-source fix landed we pre-installed the LP bus from application code to
work around the wrong clock source, which then caused i2cdev to fail with
ESP_ERR_INVALID_STATE on first use. The clock-source fix removes our need
for pre-installation, but the underlying fragility remains for any project
that shares bus ownership between i2cdev and another component.

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