fix(esp_hw_support): clear LP core SW interrupt in wake stub before sleep

When ulp_lp_core_wakeup_main_processor() is called, it sets the
PMU_SW_INT_RAW bit on the HP side. The normal sleep path clears this
bit before re-entering sleep, but esp_wake_stub_sleep() did not, leaving
the wakeup cause sticky. This caused the PMU to immediately re-trigger a
wakeup as soon as sleep was requested from the wake stub, producing a
rapid re-wakeup loop that eventually triggered LP_WDT_SYS resets.

Add a test case that verifies the wake stub can return to sleep correctly
across multiple LP core wakeup cycles without the re-wakeup bug.

Closing https://github.com/espressif/esp-idf/issues/18308

Made-with: Cursor
This commit is contained in:
Marius Vikhammer
2026-03-12 16:46:21 +08:00
parent 9df5d023bc
commit 67913c7df8
4 changed files with 122 additions and 1 deletions
@@ -62,6 +62,13 @@ void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub)
pmu_ll_hp_clear_wakeup_intr_status(&PMU);
pmu_ll_hp_clear_reject_intr_status(&PMU);
pmu_ll_hp_clear_reject_cause(&PMU);
#if CONFIG_ULP_COPROC_TYPE_LP_CORE
/* Clear the pending LP core SW interrupt before sleeping. Without this,
* the LP core wakeup cause bit (PMU_SW_INT_RAW) remains asserted after
* ulp_lp_core_wakeup_main_processor(), causing the PMU to immediately
* re-trigger a wakeup as soon as sleep is requested. */
pmu_ll_hp_clear_sw_intr_status(&PMU);
#endif
pmu_ll_hp_set_sleep_enable(&PMU);
#else
rtc_cntl_ll_sleep_enable();