Skip to content

ESP32-C6 Actual I2C frequency not change, always 100KHz #11241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
bhcuong2008 opened this issue Apr 12, 2025 · 14 comments
Closed
1 task done

ESP32-C6 Actual I2C frequency not change, always 100KHz #11241

bhcuong2008 opened this issue Apr 12, 2025 · 14 comments
Labels
Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue

Comments

@bhcuong2008
Copy link

Board

ESP32-C6-DevKitC-1

Device Description

ESP32-C6-DevKitC-1

Hardware Configuration

GPIO 23 for SDA, 22 for SCL.

Version

latest stable Release (if not listed below)

IDE Name

Arduino IDE

Operating System

Ubuntu 22

Flash frequency

80Mhz

PSRAM enabled

no

Upload speed

512000

Description

Using Wire Scan example. I set frequency 10Khz but actual waveform is still 100Khz. Change to 400Khz, it still keeps 100Khz. Using Wire.getClock() shows the same freq as setting.

Sketch

#include "Wire.h"

void setup() {
  Serial.begin(115200);
  Wire.begin(23, 22, 10000);
}

void loop() {
  byte error, address;
  int nDevices = 0;

  delay(5000);
  Serial.printf("Wire freq: %u\n", Wire.getClock());
  Serial.println("Scanning for I2C devices ...");
  for (address = 0x01; address < 0x7f; address++) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.printf("I2C device found at address 0x%02X\n", address);
      nDevices++;
    } else if (error != 2) {
      Serial.printf("Error %d at address 0x%02X\n", error, address);
    }
  }
  if (nDevices == 0) {
    Serial.println("No I2C devices found");
  }
}

Debug Message

Not show any errors/warnings.

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@bhcuong2008 bhcuong2008 added the Status: Awaiting triage Issue is waiting for triage label Apr 12, 2025
@bhcuong2008
Copy link
Author

I also test the code on ESP32 S3, and it is the same issue. It's always 100KHz.

@bhcuong2008
Copy link
Author

But with Wire Master example, its frequency could be changed. It's strange.

@lbernstone
Copy link
Contributor

Please verify which version of arduino-esp32 you are using, as this driver is currently going through changes.

@bhcuong2008
Copy link
Author

I use esp-arduino 3.2.

@Jason2866 Jason2866 added Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue and removed Status: Awaiting triage Issue is waiting for triage labels Apr 14, 2025
@FrankS71
Copy link

Have you tried Wire.setClock(); ? This is working fine for me.

@TD-er
Copy link
Contributor

TD-er commented Apr 22, 2025

Just looking at the code for ESP32-classic and ESP32-C6.

ESP32-classic:

https://github.com/espressif/esp-idf/blob/186f2a8929d2a2ecbc773fe62fe20dc936241f01/components/hal/esp32/include/hal/i2c_ll.h#L86-L96

ESP32-C6:
https://github.com/espressif/esp-idf/blob/186f2a8929d2a2ecbc773fe62fe20dc936241f01/components/hal/esp32c6/include/hal/i2c_ll.h#L90-L126

The code for ESP32-classic is very basic and easy to understand.
However the code for the -C6 is really odd and I still have no clue what it should do.

Take for example this line:

    uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1;

Since nearly all I2C clock frequencies are >= 100 kHz, this clkm_div will likely always be 1? (unless the source_clk > 102.4 MHz)
In test code, this seems to be the xtal_freq
This is always < 80 MHz.

This same line is present for:

  • ESP32-C2
  • ESP32-C3
  • ESP32-C5
  • ESP32-C61
  • ESP32-H2
  • ESP32-H21
  • ESP32-P4
  • ESP32-S3

Only the ESP32-classic and the ESP32-S2 seem to do it differently.

To draw some conclusions...
Frequencies < 80 kHz should be different and frequencies < (Xtal / 1024) should also be different. (thus < 39 kHz for 40 MHz x-tal and < 23 kHz for 26 MHz x-tal)

Edit:
OK, I may need some coffee...
This does still compute a half_cycle based on the bus frequency.

    uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1;
    uint32_t sclk_freq = source_clk / clkm_div;
    uint32_t half_cycle = sclk_freq / bus_freq / 2;

@TD-er
Copy link
Contributor

TD-er commented Apr 22, 2025

OK, just hooked up an ESP32-C6 to the logic analyzer....

400 kHz

Image

200 kHz

Image

100 kHz

Image

N.B.
This is without any pull-up resistor connected, so the duty-cycle may be off, where the low times will be longer than they should.

@bhcuong2008
Copy link
Author

bhcuong2008 commented Apr 23, 2025

@TD-er , you run my test code above? If I run normal code of I2C, such as writing, reading then I could change I2C freq at any value within its possible range. Only scan code above is fixed at 100KHz.

@bhcuong2008
Copy link
Author

Have you tried Wire.setClock(); ? This is working fine for me.

I've already tried. But it is still fixed at 100KHz for my scan code above. For other readings, writings, it could be changed to any frequency I set.

@TD-er
Copy link
Contributor

TD-er commented Apr 23, 2025

@TD-er , you run my test code above? If I run normal code of I2C, such as writing, reading then I could change I2C freq at any value within its possible range. Only scan code above is fixed at 100KHz.

Nope, I ran my own project code.
Just to make sure there isn't something seriously wrong with the Arduino/IDF code.

I'll have a look at your code to see if I see something obviously different compared to how I initialize Wire

@TD-er
Copy link
Contributor

TD-er commented Apr 23, 2025

Have you tried Wire.setClock(); ? This is working fine for me.

I've already tried. But it is still fixed at 100KHz for my scan code above. For other readings, writings, it could be changed to any frequency I set.

Hmm scan code running at 100 kHz is some really good feature, so you can be sure to also find those older devices not capable of running at > 100 kHz.
So this might also be a specific feature to limit the clock to 100 kHz on scanning.

@TD-er
Copy link
Contributor

TD-er commented Apr 23, 2025

Just checked my code...
This is what I use to init Wire...

    Wire.setPins(sda, scl);
    Wire.begin();
    Wire.setClock(clockFreq);

This differs from what you're doing, so maybe you can try it using this sequence?

@me-no-dev
Copy link
Member

Here is the answer: https://github.com/espressif/esp-idf/blob/master/components/esp_driver_i2c/i2c_master.c#L1295-L1300

The new IDF driver always does scan at 100kHz. Closing the issue :)

@bhcuong2008
Copy link
Author

@me-no-dev thank you for your clarification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue
Projects
None yet
Development

No branches or pull requests

6 participants