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 <eren.terzioglu@espressif.com>
This commit is contained in:
Eren Terzioglu
2025-11-03 10:17:34 +01:00
committed by Xiang Xiao
parent d2c6eced38
commit d4c76b1f60
8 changed files with 187 additions and 6 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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(.);

View File

@@ -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.
*/