This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d31609d8dd8e044ecf0bc3f0c2c9aab788a7e696
Author: Felipe Moura <[email protected]>
AuthorDate: Sat Sep 19 17:56:39 2026 -0300

    esp32s3/esp32s3_idle.c: unwedge the PM state machine after the first wakeup
    
    up_idlepm() put the domain back in PM_NORMAL with pm_changestate() but
    left its local oldstate holding whatever it was before sleeping, usually
    PM_STANDBY.  The pm_checkstate() below then returned PM_STANDBY again,
    the "newstate != oldstate" test compared PM_STANDBY against a stale
    PM_STANDBY, and the whole block was skipped -- including the
    esp_pmstandby() call that is the only thing in here that ever sleeps.
    
    So after the very first wakeup the board reported PM_NORMAL essentially
    forever, and light-slept only when something else happened to perturb
    oldstate, such as an application taking and releasing a PM_IDLE wakelock
    around a transmission window.
    
    Measured on the esp32s3-xiao collar before this fix: 4.1 s of actual
    light sleep in 2 h of near-total idleness, a 1780:1 awake-to-asleep
    ratio.  After it: ~13.5% of wall time asleep, thousands of sleeps, no
    storms.
    
    The dead "newstate = PM_NORMAL" assignment that used to sit here was
    presumably meant to be this; it is overwritten by pm_checkstate() a few
    lines below and never had any effect.
    
    Note that fixing this is what exposed two further bugs that had been
    dormant behind a board that never slept: the systimer double-count in
    esp_pmstandby(), and I2C transfers being cut in half by sleep.  Both are
    fixed in their own commits.
    
    Signed-off-by: Felipe Moura <[email protected]>
    Assisted-by: Claude:claude-opus-5
---
 arch/xtensa/src/esp32s3/esp32s3_idle.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_idle.c 
b/arch/xtensa/src/esp32s3/esp32s3_idle.c
index 7b4da12a3e3..e441a7eade5 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_idle.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_idle.c
@@ -104,7 +104,12 @@ static void up_idlepm(void)
       /* Release the stay above: it only forces this one state change. */
 
       pm_relax(PM_IDLE_DOMAIN, PM_NORMAL);
-      newstate = PM_NORMAL;
+
+      /* Without this, oldstate goes stale after the first wakeup and the
+       * state machine wedges in PM_NORMAL forever -- see commit message.
+       */
+
+      oldstate = PM_NORMAL;
     }
 
   /* Decide, which power saving level can be obtained */

Reply via email to