#19036·esp-idf

ESP32-C6 v0.2: SYSTIMER UNIT0 spontaneously clears counter bits — esp_timer jumps backward minutes to hours (Wi-Fi + I2C) (IDFGH-18220)

Author: danjurgensCreated Sep 1, 2026Updated Sep 17, 2026
LabelsType: BugStatus: In Progress

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

V5.5.5

Espressif SoC revision.

ESP32-C6 rev v0.2

Operating System used.

macOS

How did you build your project?

Command line with CMake

If you are using Windows, please specify command line type.

None

Development Kit.

Seeed Studio XIAO ESP32-C6 (×2)

Power Supply used.

USB

What is the expected behavior?

esp_timer_get_time() is documented monotonic. The SYSTIMER UNIT0 counter should count upward continuously and never lose accumulated count.

What is the actual behavior?

On ESP32-C6 rev v0.2, the SYSTIMER UNIT0 counter spontaneously clears 1–6 of its bits while running, so esp_timer_get_time() jumps BACKWARD by 15 minutes to 12 hours. Verified at the register level on two boards: after each event, UNIT0 equals UNIT1 (the OS-tick counter, which is never affected) with specific bits zeroed — bitwise-exact on all 7 instrumented events — and the sticky UNIT0_LOAD registers read zero, so no write path was used. Both counters stay enabled (CONF WORK_EN bits set) and count at the correct rate before and after; each event is a single discrete loss.

Requires Wi-Fi association AND an in-use I2C master (55.7 h with Wi-Fi off: zero events; non-I2C nodes: zero events over weeks; both active: ~1 event per 7 h). Events always occur while the I2C bus is idle.

Consequence: everything scheduled on esp_timer freezes for the jump duration. With WIFI_PS_MIN_MODEM, the corrupted clock reaches pp_timer_sleep_delay and the PHY shutdown path hangs in temp_sensor_get_raw_value → Interrupt WDT panic (backtrace in the full report).

Full evidence, raw captures, and analysis: https://github.com/danjurgens/esp32c6-systimer-backstep/blob/main/REPORT.md

Steps to reproduce.

  1. Clone https://github.com/danjurgens/esp32c6-systimer-backstep (reproducer/)
  2. Attach any I2C device that ACKs 2-byte reads (we used a VL53L1X at 0x29 on GPIO22/23); create main/repro_secrets.h from the .example with your AP
  3. idf.py set-target esp32c6
  4. idf.py -DREPRO_WIFI=1 -DREPRO_I2C=1 -DREPRO_I2C_HZ=100000
    -DREPRO_INTERNAL_PULLUP=1 -DREPRO_BURST=3
    -DREPRO_IDLE_MS=1000 -DREPRO_IDLE_CHUNK_MS=50 build flash monitor
  5. Wait: first event took 2.8–12.5 h across runs (mean ~7 h). Events are printed with raw counters and persisted to NVS, so a panic-reboot cannot lose them; the last event replays on the next boot banner.

Debug Logs.

plain
E (4519758) repro: *** BACKSTEP DURING IDLE (idx 8) ***
E (4519758) repro:     esp_timer 4518998282 -> 224080988 us  (moved -4294917294 us = -71.58 min)
E (4519760) repro:     I2C SEQ: ok=13530 err=0 burst=4510
E (4519767) repro:     tick=4519017 ms  UNIT0=3585451554 UNIT1=72304272029  CONF=0xf7400002
Guru Meditation Error: Core  0 panic'ed (Interrupt wdt timeout on CPU0).

UNIT1 - UNIT0 = 68,718,820,475 ticks = 2^36 − (41 ms read skew): bit 36 was
set in UNIT1 and clear in UNIT0. All 7 events decompose this way (table in
the linked report).

Diagnostic report archive.

No response

More Information.

  • Not board-specific software: reproduced under ESPHome and bare IDF; also seen with a different sensor on a different I2C driver. Two boards affected (both XIAO ESP32-C6 — same design, so a board-level co-factor is not yet excluded).
  • Working mitigation for others (measure tick−esp_timer, repair via esp_timer_private_advance): components in the same repo; 6 production events absorbed with zero downtime.
  • Questions: is this a known erratum for v0.2? Is v0.3+ affected? Should pp_timer_sleep_delay be defensive against non-monotonic input, since the hang (vs. just a stall) is a software consequence?