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

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

commit d4c76b1f60902d2186f82490625c8cb845df9c86
Author: Eren Terzioglu <[email protected]>
AuthorDate: Mon Nov 3 10:17:34 2025 +0100

    arch/risc-v/esp32[-c3|-c6|-h2]: Add deep sleep support
    
    Add deep sleep support for risc-v based Espressif devices
    
    Signed-off-by: Eren Terzioglu <[email protected]>
---
 arch/risc-v/src/common/espressif/Kconfig           | 16 ++++++-
 arch/risc-v/src/common/espressif/Make.defs         |  2 +-
 arch/risc-v/src/common/espressif/esp_idle.c        | 13 +++++-
 arch/risc-v/src/common/espressif/esp_pm.c          | 53 ++++++++++++++++++++++
 arch/risc-v/src/common/espressif/esp_pm.h          | 34 +++++++++++++-
 arch/risc-v/src/esp32h2/hal_esp32h2.mk             |  1 +
 .../esp32c6/common/scripts/esp32c6_sections.ld     | 39 ++++++++++++++++
 .../esp32h2/common/scripts/esp32h2_sections.ld     | 35 ++++++++++++++
 8 files changed, 187 insertions(+), 6 deletions(-)

diff --git a/arch/risc-v/src/common/espressif/Kconfig 
b/arch/risc-v/src/common/espressif/Kconfig
index dd5f835a3d7..c3e2abb29dc 100644
--- a/arch/risc-v/src/common/espressif/Kconfig
+++ b/arch/risc-v/src/common/espressif/Kconfig
@@ -274,7 +274,7 @@ config PM_EXT1_WAKEUP
        default n
        ---help---
                Enable EXT1 wakeup functionality.
-               This allows the system to wake up from PM_STANDBY
+               This allows the system to wake up from PM_STANDBY or PM_SLEEP
                when a GPIO pin configured as an EXT1 wakeup source is 
triggered.
 
 menu "PM EXT1 Wakeup Sources"
@@ -405,7 +405,7 @@ config PM_ULP_WAKEUP
        default n
        ---help---
                Enable ULP coprocessor wakeup functionality.
-               This allows the system to wake up from PM_STANDBY
+               This allows the system to wake up from PM_STANDBY or PM_SLEEP
                when ULP app triggers HP core to wakeup with 
"ulp_lp_core_wakeup_main_processor"
                call on ULP app.
 
@@ -707,6 +707,18 @@ config PM_ALARM_NSEC
        ---help---
                Number of additional nanoseconds to wait in PM_STANDBY mode.
 
+config PM_SLEEP_WAKEUP_SEC
+       int "PM_SLEEP delay (seconds)"
+       default 20
+       ---help---
+               Number of seconds to wait in PM_SLEEP.
+
+config PM_SLEEP_WAKEUP_NSEC
+       int "PM_SLEEP delay (nanoseconds)"
+       default 0
+       ---help---
+               Number of additional nanoseconds to wait in PM_SLEEP.
+
 endif # PM
 
 endmenu # PM Configuration
diff --git a/arch/risc-v/src/common/espressif/Make.defs 
b/arch/risc-v/src/common/espressif/Make.defs
index ad184059eeb..51e9efa9655 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -207,7 +207,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO   = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = a4ffd506e8f77632b90b053b21a788b29191bd93
+       ESP_HAL_3RDPARTY_VERSION = 4f1113915eb5e9048cc885e38290a57dddb283c0
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
diff --git a/arch/risc-v/src/common/espressif/esp_idle.c 
b/arch/risc-v/src/common/espressif/esp_idle.c
index f84c4ed0e24..de891629c64 100644
--- a/arch/risc-v/src/common/espressif/esp_idle.c
+++ b/arch/risc-v/src/common/espressif/esp_idle.c
@@ -55,6 +55,12 @@
 #  ifndef CONFIG_PM_ALARM_NSEC
 #    define CONFIG_PM_ALARM_NSEC 0
 #  endif
+#  ifndef CONFIG_PM_SLEEP_WAKEUP_SEC
+#    define CONFIG_PM_SLEEP_WAKEUP_SEC 20
+#  endif
+#  ifndef CONFIG_PM_SLEEP_WAKEUP_NSEC
+#    define CONFIG_PM_SLEEP_WAKEUP_NSEC 0
+#  endif
 #endif
 
 /****************************************************************************
@@ -149,10 +155,13 @@ static void up_idlepm(void)
           break;
 
         case PM_SLEEP:
-
+          {
             /* Enter Deep-sleep mode */
 
-            break;
+            esp_pmsleep(CONFIG_PM_SLEEP_WAKEUP_SEC * 1000000 +
+                        CONFIG_PM_SLEEP_WAKEUP_NSEC / 1000);
+          }
+          break;
 
         default:
           break;
diff --git a/arch/risc-v/src/common/espressif/esp_pm.c 
b/arch/risc-v/src/common/espressif/esp_pm.c
index bd28e66127b..7d3dfcbf69e 100644
--- a/arch/risc-v/src/common/espressif/esp_pm.c
+++ b/arch/risc-v/src/common/espressif/esp_pm.c
@@ -198,6 +198,8 @@ static void IRAM_ATTR esp_pm_ext1_wakeup_prepare(void)
           esp_sleep_enable_ext1_wakeup_io(pin_mask, level_mode);
         }
     }
+
+  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
 }
 #endif /* CONFIG_PM_EXT1_WAKEUP */
 
@@ -462,6 +464,31 @@ int esp_pm_light_sleep_start(uint64_t *sleep_time)
   return ret;
 }
 
+/****************************************************************************
+ * Name:  esp_pm_deep_sleep_start
+ *
+ * Description:
+ *   Enter deep sleep mode
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_pm_deep_sleep_start(void)
+{
+  esp_deep_sleep_start();
+
+  /* Because RTC is in a slower clock domain than the CPU, it
+   * can take several CPU cycles for the sleep mode to start.
+   */
+
+  while (1);
+}
+
 /****************************************************************************
  * Name: esp_pmstandby
  *
@@ -526,3 +553,29 @@ void esp_pmstandby(uint64_t time_in_us)
     }
 #endif
 }
+
+/****************************************************************************
+ * Name: esp_pmsleep
+ *
+ * Description:
+ *   Enter pm sleep (deep sleep) mode.
+ *
+ * Input Parameters:
+ *   time_in_us - The maximum time to sleep in microseconds.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_pmsleep(uint64_t time_in_us)
+{
+#ifdef CONFIG_PM_EXT1_WAKEUP
+  esp_pm_ext1_wakeup_prepare();
+#endif
+#ifdef CONFIG_PM_ULP_WAKEUP
+  esp_sleep_enable_ulp_wakeup();
+#endif
+  esp_pm_sleep_enable_timer_wakeup(time_in_us);
+  esp_pm_deep_sleep_start();
+}
diff --git a/arch/risc-v/src/common/espressif/esp_pm.h 
b/arch/risc-v/src/common/espressif/esp_pm.h
index cb50a4fcab8..892278ad4f7 100644
--- a/arch/risc-v/src/common/espressif/esp_pm.h
+++ b/arch/risc-v/src/common/espressif/esp_pm.h
@@ -67,7 +67,23 @@ extern "C"
 int esp_pm_light_sleep_start(uint64_t *sleep_time);
 
 /****************************************************************************
- * Name: esp_pmstandby
+ * Name:  esp_pm_deep_sleep_start
+ *
+ * Description:
+ *   Enter deep sleep mode
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_pm_deep_sleep_start(void);
+
+/****************************************************************************
+ * Name: esp_pm_pmstandby
  *
  * Description:
  *   Enter pm standby (light sleep) mode.
@@ -82,6 +98,22 @@ int esp_pm_light_sleep_start(uint64_t *sleep_time);
 
 void esp_pmstandby(uint64_t time_in_us);
 
+/****************************************************************************
+ * Name: esp_pmsleep
+ *
+ * Description:
+ *   Enter pm sleep (deep sleep) mode.
+ *
+ * Input Parameters:
+ *   time_in_us - The maximum time to sleep in microseconds.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_pmsleep(uint64_t time_in_us);
+
 #endif /* CONFIG_PM */
 
 #ifdef __cplusplus
diff --git a/arch/risc-v/src/esp32h2/hal_esp32h2.mk 
b/arch/risc-v/src/esp32h2/hal_esp32h2.mk
index c039224082a..9baa02ec277 100644
--- a/arch/risc-v/src/esp32h2/hal_esp32h2.mk
+++ b/arch/risc-v/src/esp32h2/hal_esp32h2.mk
@@ -157,6 +157,7 @@ CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sar_periph_ctrl.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)systimer.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)power_supply$(DELIM)brownout.c
+CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)power_supply$(DELIM)vbat.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_mm$(DELIM)esp_mmu_map.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_mm$(DELIM)esp_cache.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_mm$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)ext_mem_layout.c
diff --git a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld 
b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld
index 577d157a93e..ea1e08d7c0f 100644
--- a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld
+++ b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld
@@ -556,21 +556,60 @@ SECTIONS
   .rtc.text :
   {
     . = ALIGN(4);
+    _rtc_fast_start = ABSOLUTE(.);
+    _rtc_text_start = ABSOLUTE(.);
     *(.rtc.literal .rtc.text)
     *(.rtc.entry.text)
     /* 16B padding for possible CPU prefetch and 4B alignment for PMS split 
lines */
     . += 16;
     . = ALIGN(4);
+    _rtc_text_end = ABSOLUTE(.);
+  } > lp_ram_seg AT > ROM
+
+  /* RTC fast memory section */
+
+  .rtc.force_fast :
+  {
+    . = ALIGN(4);
+    _rtc_force_fast_start = ABSOLUTE(.);
 
+    *(.rtc.force_fast .rtc.force_fast.*)
+    . = ALIGN(4);
+    _rtc_force_fast_end = ABSOLUTE(.);
   } > lp_ram_seg AT > ROM
 
   /* RTC BSS section. */
 
   .rtc.bss (NOLOAD) :
   {
+    _rtc_bss_start = ABSOLUTE(.);
     *(.rtc.bss)
+    _rtc_bss_end = ABSOLUTE(.);
+  } > lp_ram_seg
+
+
+  /* RTC NOINIT section. */
+
+  .rtc_noinit (NOLOAD) :
+  {
+    . = ALIGN(4);
+    _rtc_noinit_start = ABSOLUTE(.);
+    *(.rtc_noinit .rtc_noinit.*)
+    . = ALIGN(4) ;
+    _rtc_noinit_end = ABSOLUTE(.);
   } > lp_ram_seg
 
+  /* RTC slow memory section */
+
+  .rtc.force_slow :
+  {
+    . = ALIGN(4);
+    _rtc_force_slow_start = ABSOLUTE(.);
+    *(.rtc.force_slow .rtc.force_slow.*)
+    . = ALIGN(4);
+    _rtc_force_slow_end = ABSOLUTE(.);
+  } > lp_ram_seg AT > ROM
+
   .rtc.data :
   {
     _rtc_data_start = ABSOLUTE(.);
diff --git a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld 
b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld
index 06375668a3f..677d916f363 100644
--- a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld
+++ b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld
@@ -558,6 +558,19 @@ SECTIONS
     *(.rtc.entry.text)
 
     *(.rtc.literal .rtc.text)
+    _rtc_text_end = ABSOLUTE(.);
+  } >rtc_iram_seg
+
+  /* RTC fast memory section */
+
+  .rtc.force_fast :
+  {
+    . = ALIGN(4);
+    _rtc_force_fast_start = ABSOLUTE(.);
+
+    *(.rtc.force_fast .rtc.force_fast.*)
+    . = ALIGN(4);
+    _rtc_force_fast_end = ABSOLUTE(.);
   } >rtc_iram_seg
 
   /* RTC BSS section. */
@@ -577,6 +590,28 @@ SECTIONS
     *(.rtc.rodata.*)
   } >rtc_iram_seg
 
+  /* RTC NOINIT section. */
+
+  .rtc_noinit (NOLOAD) :
+  {
+    . = ALIGN(4);
+    _rtc_noinit_start = ABSOLUTE(.);
+    *(.rtc_noinit .rtc_noinit.*)
+    . = ALIGN(4) ;
+    _rtc_noinit_end = ABSOLUTE(.);
+  } >rtc_iram_seg
+
+  /* RTC slow memory section */
+
+  .rtc.force_slow :
+  {
+    . = ALIGN(4);
+    _rtc_force_slow_start = ABSOLUTE(.);
+    *(.rtc.force_slow .rtc.force_slow.*)
+    . = ALIGN(4);
+    _rtc_force_slow_end = ABSOLUTE(.);
+  } >rtc_iram_seg
+
   /* This section holds RTC data that should have fixed addresses.
    * The data are not initialized at power-up and are retained during deep 
sleep.
    */

Reply via email to