Closed
Conversation
Added function declaration for getting shared I2C bus handle.
Contributor
|
@quinkq Would you comment on this? |
quinkq
suggested changes
Dec 26, 2025
Contributor
There was a problem hiding this comment.
Hi @trombik. Thanks for the initiative @jnischler. I couldn't get myself to finish this for a quite a while, but here's my idea with a few improvements:
- Added mutex protection to prevent race conditions
- Included defensive checks for uninitialized state and detailed error messages for better guidance
- Added some documentation with usage examples and debugging logs
Comment on lines
+898
to
+909
|
|
||
| esp_err_t i2cdev_get_shared_handle(i2c_port_t port, void **bus_handle) | ||
| { | ||
| if (port >= I2C_NUM_MAX || bus_handle == NULL) | ||
| return ESP_ERR_INVALID_ARG; | ||
|
|
||
| if (!i2c_ports[port].installed || i2c_ports[port].bus_handle == NULL) | ||
| return ESP_ERR_INVALID_STATE; | ||
|
|
||
| *bus_handle = (void *)i2c_ports[port].bus_handle; | ||
| return ESP_OK; | ||
| } |
Contributor
There was a problem hiding this comment.
Suggested change
| esp_err_t i2cdev_get_shared_handle(i2c_port_t port, void **bus_handle) | |
| { | |
| if (port >= I2C_NUM_MAX || bus_handle == NULL) | |
| return ESP_ERR_INVALID_ARG; | |
| if (!i2c_ports[port].installed || i2c_ports[port].bus_handle == NULL) | |
| return ESP_ERR_INVALID_STATE; | |
| *bus_handle = (void *)i2c_ports[port].bus_handle; | |
| return ESP_OK; | |
| } | |
| esp_err_t i2cdev_get_shared_handle(i2c_port_t port, void **bus_handle) | |
| { | |
| if (port >= I2C_NUM_MAX || bus_handle == NULL) | |
| { | |
| ESP_LOGE(TAG, "Invalid arguments: port=%d, bus_handle=%p", port, bus_handle); | |
| return ESP_ERR_INVALID_ARG; | |
| } | |
| i2c_port_state_t *port_state = &i2c_ports[port]; | |
| // Check if i2cdev subsystem is initialized | |
| if (port_state->lock == NULL) | |
| { | |
| ESP_LOGE(TAG, "[Port %d] I2C subsystem not initialized - call i2cdev_init() first", port); | |
| return ESP_ERR_INVALID_STATE; | |
| } | |
| // Take port mutex for thread-safe access | |
| if (xSemaphoreTake(port_state->lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE) | |
| { | |
| ESP_LOGE(TAG, "[Port %d] Could not take port mutex for get_shared_handle", port); | |
| return ESP_ERR_TIMEOUT; | |
| } | |
| // Check if bus is initialized | |
| if (!port_state->installed || port_state->bus_handle == NULL) | |
| { | |
| xSemaphoreGive(port_state->lock); | |
| ESP_LOGE(TAG, "[Port %d] Bus not initialized - create an i2c_dev_t device first to initialize the bus", port); | |
| return ESP_ERR_INVALID_STATE; | |
| } | |
| // Return the bus handle | |
| *bus_handle = (void *)port_state->bus_handle; | |
| ESP_LOGI(TAG, "[Port %d] Shared bus handle retrieved: %p (SDA=%d, SCL=%d, ref_count=%" PRIu32 ")", | |
| port, port_state->bus_handle, port_state->sda_pin_current, | |
| port_state->scl_pin_current, port_state->ref_count); | |
| xSemaphoreGive(port_state->lock); | |
| return ESP_OK; | |
| } |
Comment on lines
+318
to
+324
|
|
||
| /** | ||
| * @brief Get shared I2C bus handle (requires sensor initialized first) | ||
| */ | ||
| esp_err_t i2cdev_get_shared_handle(i2c_port_t port, void **bus_handle); | ||
|
|
||
|
|
Contributor
There was a problem hiding this comment.
Suggested change
| /** | |
| * @brief Get shared I2C bus handle (requires sensor initialized first) | |
| */ | |
| esp_err_t i2cdev_get_shared_handle(i2c_port_t port, void **bus_handle); | |
| /** | |
| * @brief Get shared I2C bus handle for external ESP-IDF components | |
| * | |
| * This function allows external ESP-IDF components (like esp_lcd) to access | |
| * the i2cdev-managed I2C bus handle for shared bus operations. This enables | |
| * thread-safe sharing of the I2C bus between i2cdev-based sensors and native | |
| * ESP-IDF components. | |
| * | |
| * @note USAGE PATTERN: | |
| * 1. Initialize i2cdev subsystem with i2cdev_init() | |
| * 2. Create at least one i2c_dev_t device on the desired port (this initializes the bus) | |
| * 3. Call this function to retrieve the bus handle | |
| * 4. Pass the handle to ESP-IDF components (e.g., esp_lcd_new_panel_io_i2c) | |
| * | |
| * @note USAGE EXAMPLE: | |
| * // 1. Initialize i2cdev | |
| * i2cdev_init(); | |
| * | |
| * // 2. Create a sensor device (initializes the bus) | |
| * i2c_dev_t sensor = { | |
| * .port = I2C_NUM_0, | |
| * .addr = 0x29, // TSL2591 light sensor | |
| * .cfg = { | |
| * .sda_io_num = GPIO_NUM_21, | |
| * .scl_io_num = GPIO_NUM_22, | |
| * .master.clk_speed = 400000 | |
| * } | |
| * }; | |
| * i2c_dev_create_mutex(&sensor); | |
| * | |
| * // 3. Get the shared bus handle | |
| * i2c_master_bus_handle_t bus_handle; | |
| * ESP_ERROR_CHECK(i2cdev_get_shared_handle(I2C_NUM_0, (void **)&bus_handle)); | |
| * | |
| * // 4. Use it with esp_lcd or other ESP-IDF components | |
| * esp_lcd_panel_io_handle_t io_handle; | |
| * esp_lcd_panel_io_i2c_config_t io_config = { | |
| * .dev_addr = 0x3C, // SSD1306 display | |
| * .control_phase_bytes = 1, | |
| * .dc_bit_offset = 6, | |
| * .lcd_cmd_bits = 8, | |
| * .lcd_param_bits = 8, | |
| * }; | |
| * ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(bus_handle, &io_config, &io_handle)); | |
| * | |
| * // Both the sensor and display now share the same I2C bus with proper synchronization! | |
| * | |
| * @param port I2C port number (e.g., I2C_NUM_0) | |
| * @param[out] bus_handle Pointer to store the bus handle | |
| * @return ESP_OK on success | |
| * @return ESP_ERR_INVALID_ARG if port is invalid or bus_handle is NULL | |
| * @return ESP_ERR_INVALID_STATE if i2cdev_init() was not called or bus for this port is not initialized yet | |
| * @return ESP_ERR_TIMEOUT if port mutex could not be acquired | |
| * | |
| * @warning The returned handle is managed by i2cdev. Do NOT call i2c_del_master_bus() | |
| * on it directly - i2cdev will handle cleanup when the last device is removed. | |
| */ | |
| esp_err_t i2cdev_get_shared_handle(i2c_port_t port, void **bus_handle); | |
Merged
Contributor
|
Done in #8 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
see:
esp-idf-lib/core#53