Skip to content

rmt-legacy TxRmtDriver produces wrong pulse timing on ESP32-H2 (WS2812 stays dark, no error) #589

Description

@ManfredFr

rmt-legacy TxRmtDriver produces wrong pulse timing on ESP32-H2 (WS2812 stays dark)

esp-idf-hal version: 0.45.2 (feature rmt-legacy)
ESP-IDF version: v5.3.3
Chip: ESP32-H2 (rev v0.1)
Toolchain: nightly, riscv32imac-esp-espidf, std

Bug

Driving a WS2812 (onboard RGB LED of the ESP32-H2-DevKitM-1, GPIO8) with
TxRmtDriver and pulse durations derived from counter_clock() produces no
visible output — the LED never lights. The identical pulse-train logic works
on other chips, and the same LED on the same board works when driven through
ESP-IDF's new RMT TX driver (rmt_new_tx_channel + rmt_new_bytes_encoder,
10 MHz resolution) via raw FFI.

let mut tx = TxRmtDriver::new(p.rmt.channel0, p.pins.gpio8, &TransmitConfig::default())?;
let ticks_hz = tx.counter_clock()?; // <- value inconsistent with actual tick rate on H2
let t0h = Pulse::new_with_duration(ticks_hz, PinState::High, &Duration::from_nanos(350))?;
// ... build 24-bit WS2812 frame, tx.start_blocking(&signal)
// transmits without error, but the LED shows nothing

No error is returned anywhere — the transmit "succeeds" with wrong timing on
the wire, which makes this hard to diagnose.

Suspected cause

The legacy RMT driver's clock assumptions don't hold on the ESP32-H2 (no APB
clock; RMT runs from XTAL 32 MHz / PLL sources). counter_clock() appears to
compute the tick rate from a wrong base frequency, so all
Pulse::new_with_duration conversions are scaled off and the WS2812 sees
out-of-spec pulses. This is the same class of issue as the UART
SourceClock panic on the H2 (filed separately) — chip-specific clock
sources not reflected in the abstraction.

Note ESP-IDF has deprecated the legacy RMT driver; on H2/C6-era chips its
behaviour seems untested.

Expected

Either correct counter_clock()/divider handling for the H2's actual RMT
clock source, or a documented note that rmt-legacy is unsupported on these
chips (ideally a compile error like the one that exists for the onewire
component conflict).

Workaround

Use the new RMT TX driver via esp-idf-sys FFI:
rmt_new_tx_channel (clk RMT_CLK_SRC_DEFAULT, resolution_hz = 10_000_000)

  • rmt_new_bytes_encoder (bit0 = 3H/9L ticks, bit1 = 9H/3L, msb_first) +
    rmt_transmit. Verified working on the same hardware.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions