esp-hal icon indicating copy to clipboard operation
esp-hal copied to clipboard

ESP32-C6 I2C pins not usable with the I2C module

Open decafboba opened this issue 3 months ago • 4 comments

Bug description

The datasheet Page 77 Table 7-1. QFN40 Pin Overview shows:

Pin No. Pin Name Pin Type Power Pin At Reset After Reset Analog Function LP Function 0 LP Function 1 IO MUX Func 0 Type 0 IO MUX Func 1 Type 1 IO MUX Func 2 Type 2 Module Pin
12 MTCK IO VDDPST1 IE, WPU ADC1_CH6 LP_GPIO6 LP_I2C_SDA MTCK I1 GPIO6 I/O/T FSPICLK I1/O/T 15
13 MTDO IO VDDPST1 IE LP_GPIO7 LP_I2C_SCL MTDO O/T GPIO7 I/O/T FSPID I1/O/T 16

Now, my goal with configuring my hardware to use GPIO6 (LP_I2C_SDA) and GPIO7 (LP_I2C_SCL) was that if I needed low-power / sleep capabilities, then I could do so without hardware changes, but if I didn't need these capabilities, I could always just go back to using them in HP mode.

But is that assumption correct? Can these pins still be read on the high-power (HP) core like normal gpio pins?

I certainly assumed so, but after struggling with multiple attempts in firmware, it feels like not. This is what I tried:

Initial Integration with esp-hal I2C Master

1. Direct integration using esp-hal's blocking I2C API:

let i2c = I2c::new(peripherals.I2C0, Config::default()).expect("I2C init failed");

This failed, and I couldn't find I2C devices / it thinks the pins are unused.

And then I tried:

2. Force ESP32 I2C peripheral to specifically use these pins:

let i2c_blocking = I2c::new(
    peripherals.I2C0,
    Config::default().with_frequency(Rate::from_hz(50_000)),
).unwrap()
.with_sda(peripherals.GPIO6)  // Explicit pin assignment
.with_scl(peripherals.GPIO7); // Explicit pin assignment

let i2c = i2c_blocking.into_async();

This also didn't work. Both attempts show no I2C devices detected.

But if I just connect to them directly and check if they are high:

let gpio6 = Input::new(peripherals.GPIO6, InputConfig::default().with_pull(Pull::None));
if gpio6.is_high() {
    println!("✅ GPIO6 = HIGH - Good for I2C SDA");
}

let gpio7 = Input::new(peripherals.GPIO7, InputConfig::default().with_pull(Pull::None));
if gpio7.is_high() {
    println!("✅ GPIO7 = HIGH - Good for I2C SCL");
}

I see that the gpio6/7 pins are detected. So for some reason I2C is just not functioning.

Expected behavior

I would expect I2C to work out of the box with gpio6/7 pins.

Environment

  • Target device:
Chip type:         esp32c6 (revision v0.2)
Crystal frequency: 40 MHz
Flash size:        4MB
Features:          WiFi 6, BT 5
MAC address:       <NA>

Security Information:
=====================
Flags: 0x00000000 (0)
Key Purposes: [0, 0, 0, 0, 0, 0, 12]
Chip ID: 13
API Version: 0
Secure Boot: Disabled
Flash Encryption: Disabled
SPI Boot Crypt Count (SPI_BOOT_CRYPT_CNT): 0x0
  • Crate name and version: esp-hal: 1.0.0-rc.0

decafboba avatar Sep 14 '25 19:09 decafboba

We have regular tests on real hardware that use GPIO6 and GPIO7 without any issues. esp-hal connects internal pullups automatically, but that shouldn't be an issue for most I2C devices. I'm afraid we'll need more information than "just isn't functioning". In general, all pins can be used with almost any peripherals (except for SDIO and USB).

bugadani avatar Sep 14 '25 19:09 bugadani

@bugadani Thanks, I will double-check my code. Do you happen to know of an up-to-date example of using I2C with esp-hal?

decafboba avatar Sep 14 '25 22:09 decafboba

And also, of the two code snippets I showed, which one would be preferred?

decafboba avatar Sep 14 '25 23:09 decafboba

Do you happen to know of an up-to-date example of using I2C with esp-hal?

I have one. Just finished work on this: https://github.com/finalyards/ZOO-esp32/blob/main/tof/vl_api/examples/many-emb.rs#L104

Disclaimer: I don't want to draw people to the repo, it's a work-in-progress. But the tof side (with ST.com distance sensors) does use I2C, and it's up to date.

finalyards avatar Sep 19 '25 14:09 finalyards