Skip to content

Conversation

@quinkq
Copy link
Contributor

@quinkq quinkq commented Jun 9, 2025

Summary

Migrate i2cdev to new ESP-IDF I2C master driver API (v5.3+)

Changes Made

  • Replace legacy command-based I2C with handle-based master API for ESP-IDF v5.3 and newer.
  • Add device handle tracking and automatic resource cleanup
  • Enhance addressing support (7-bit/10-bit) and error handling
  • Implement smart retry logic with exponential backoff
  • Add buffer overflow protection and memory optimization
  • Full Backward Compatibility

Compatibility

  • Drop-in replacement for existing sensor drivers
  • Legacy compatibility maintained in i2cdev_legacy.c
  • Automated Build-Time Driver Selection - build system automatically detects the ESP-IDF version and selects the appropriate driver (modern or legacy).
  • Manual Override: A Kconfig option (I2CDEV_USE_LEGACY_DRIVER) to force the use of the legacy driver on any platform.
  • Same public API signatures preserved

Testing

  • Tested in two configurations where devices shared a single I2C bus: 1. ESP32-C3 with SHT40/BME280 & 2. ESP32-S3 with SHT40, BME280, 2x ADS1115, INA219, and AS5600 (own esp-idf-lib compatible driver).
  • Verified backward compatibility by successfully toggling I2CDEV_USE_LEGACY_DRIVER in Kconfig and by compiling for ESP8266.

Modern I2cdev Workflow

Initialization Phase

  • i2cdev_init() → Creates port mutexes for all I2C ports
  • sensor_init_desc()i2c_dev_create_mutex() → Creates device mutex + registers device + sets defaults (7-bit addressing)

First I2C Operation (Lazy Setup)

Call Stack Order:

i2c_dev_read_reg()
└── i2c_do_operation_with_retry() ─── Entry point with retry logic
    └── i2c_setup_device() ────────── Called on each retry attempt  
        └── i2c_setup_port() ──────── Called if device setup needed
            └── Create bus/validate pins
            

When i2c_dev_read_reg() or i2c_dev_write_reg() is called for the first time:

Logical Flow:

  1. i2c_setup_port() - Bus management (called by setup_device)

    • Port not setup? → Create I2C master bus with pins/pullups
    • Port exists? → Validate pin consistency (first device wins)
  2. i2c_setup_device() - Device registration (called by retry function)

    • Calls i2c_setup_port() to ensure port is ready
    • Add device to bus → Get device handle
    • Configure per-device speed and addressing mode
    • Increment port reference count
  3. i2c_do_operation_with_retry() - Entry point

    • Handles retry logic with exponential backoff: 20ms → 40ms → 80ms
    • Calls i2c_setup_device() before each attempt
  4. Direct ESP-IDF calls - Actual I2C operation

    • i2c_master_transmit(), i2c_master_receive(), or i2c_master_transmit_receive()
    • No command building overhead

Subsequent Operations

  • Fast path: Bus and device handles already exist
  • Direct operation execution with existing optimized configuration

Cleanup Phase

  • i2c_dev_delete_mutex() → Remove device from bus, decrement ref count
    • Last device on port? → Delete entire I2C master bus
  • i2cdev_done() → Final cleanup of all remaining resources

FIXES #667

@quinkq quinkq force-pushed the feature-i2cdev-i2c-master-support branch 6 times, most recently from 7235547 to c5c8580 Compare June 11, 2025 17:06
- Replace legacy command-based I2C with handle-based master API
- Add device handle tracking and automatic resource cleanup
- Enhance addressing support (7-bit/10-bit) and error handling
- Implement smart retry logic with exponential backoff
- Add buffer overflow protection and memory optimization
- Maintain backward compatibility via i2cdev_legacy.c bridge
- Preserve existing sensor driver API compatibility
potentialy fixes UncleRus#667 UncleRus#713 #741
@quinkq quinkq force-pushed the feature-i2cdev-i2c-master-support branch from c5c8580 to 8faefbe Compare June 12, 2025 15:50
@AxelLin
Copy link
Contributor

AxelLin commented Jun 15, 2025

Hi @quinkq

I just tested it with both idf-5.2 and idf-5.4 branchs.
CONFIG_I2CDEV_USE_LEGACY_DRIVER=n, so the IDF version decides to use new or legacy driver.
On idf-5.2, it works.
On idf-5.4, it does not work:
W (1672) i2cdev: [0x44 at 0] Cannot probe - bus not ready on port 0
W (1679) i2cdev: [0x45 at 0] Cannot probe - bus not ready on port 0
Do you have any idea what could be wrong? Or any application code change is required for new driver?

Thanks,
Axel

…nfig

- Fix "bus not ready" probe failures on ESP-IDF 5.3+
- Add CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS option
- Improve probe function consistency across ESP-IDF versions
@quinkq
Copy link
Contributor Author

quinkq commented Jun 15, 2025

Hi @AxelLin
Thanks for testing, issue was that when it switched to run modern version of the driver (i2c_master) in idf-5.4, i2c_dev_check_present (modern version of i2c_dev_probe) wasn't calling i2c_setup_port before probing, unlike other I2C functions. Should be fixed now.

@AxelLin
Copy link
Contributor

AxelLin commented Jun 16, 2025

Hi @quinkq

Thank you for the fix.
Confirm it's working now with idf-5.4.

Regards,
Axel

@trombik
Copy link
Collaborator

trombik commented Jun 16, 2025

@quinkq Thanks for the proposal. I will certainly have a close look.

@trombik trombik self-assigned this Jun 16, 2025
@trombik trombik added the enhancement New feature or request label Jun 16, 2025
@trombik
Copy link
Collaborator

trombik commented Jun 16, 2025

Also, please have a look at my proposal and have your voice heard.

@AxelLin
Copy link
Contributor

AxelLin commented Jun 30, 2025

Hi @trombik
Do you have target timeline to merge this PR?

@trombik
Copy link
Collaborator

trombik commented Jul 6, 2025

@AxelLin Sorry for my inactivity. I'll take a look and merge it ASAP.

@trombik
Copy link
Collaborator

trombik commented Jul 6, 2025

Just a brief comment about the PR: I can see how you devoted your time and you I appreciate it.

@trombik trombik merged commit 75ec40f into UncleRus:master Jul 10, 2025
65 checks passed
@trombik
Copy link
Collaborator

trombik commented Jul 10, 2025

@AxelLin Merged, thanks!

@trombik
Copy link
Collaborator

trombik commented Jul 10, 2025

Forgot to mention @quinkq. Thank you, too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for new I2C driver used in IDF 5.4

3 participants