Merge branch 'feature/introduce_internal_sleep_sub_mode_configure_api' into 'master'

feat(esp_hw_support): introduce internal sleep sub mode configure api

Closes PM-216

See merge request espressif/esp-idf!30687
This commit is contained in:
Wu Zheng Hui 2024-09-11 17:01:59 +08:00
commit eab98765ad
11 changed files with 201 additions and 76 deletions

View File

@ -127,7 +127,7 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
sar_periph_ctrl_adc_oneshot_power_acquire();
} else {
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
esp_sleep_enable_adc_tsens_monitor(true);
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
#endif
}
@ -230,7 +230,7 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
sar_periph_ctrl_adc_oneshot_power_release();
} else {
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
esp_sleep_enable_adc_tsens_monitor(false);
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false);
#endif
}

View File

@ -19,6 +19,7 @@
#include "driver/ledc.h"
#include "esp_rom_gpio.h"
#include "clk_ctrl_os.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/gpio.h"
#include "esp_private/esp_gpio_reserve.h"
@ -561,6 +562,16 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
}
p_ledc_obj[speed_mode]->glb_clk_is_acquired[timer_num] = true;
if (p_ledc_obj[speed_mode]->glb_clk != glb_clk) {
#if SOC_LIGHT_SLEEP_SUPPORTED
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
if (glb_clk == LEDC_SLOW_CLK_RC_FAST) {
/* Keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_RC_FAST_MODE, true);
} else if (p_ledc_obj[speed_mode]->glb_clk == LEDC_SLOW_CLK_RC_FAST) {
/* No need to keep ESP_PD_DOMAIN_RC_FAST on during light sleep anymore */
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_RC_FAST_MODE, false);
}
#endif
// TODO: release old glb_clk (if not UNINIT), and acquire new glb_clk [clk_tree]
p_ledc_obj[speed_mode]->glb_clk = glb_clk;
LEDC_FUNC_CLOCK_ATOMIC() {
@ -571,12 +582,6 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
portEXIT_CRITICAL(&ledc_spinlock);
ESP_LOGD(LEDC_TAG, "In slow speed mode, global clk set: %d", glb_clk);
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
#if SOC_LIGHT_SLEEP_SUPPORTED
extern void esp_sleep_periph_use_8m(bool use_or_not);
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RC_FAST);
#endif
}
/* The divisor is correct, we can write in the hardware. */

View File

@ -9,7 +9,7 @@
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD (200)
#define TEST_MEMORY_LEAK_THRESHOLD (212)
void setUp(void)
{

View File

@ -31,13 +31,35 @@ typedef struct {
void esp_sleep_set_sleep_context(esp_sleep_context_t *sleep_ctx);
#endif
typedef enum {
ESP_SLEEP_RTC_USE_RC_FAST_MODE, //!< The mode requested by RTC peripherals to keep RC_FAST clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (Will override the RC_FAST domain config by esp_sleep_pd_config)
ESP_SLEEP_DIG_USE_RC_FAST_MODE, //!< The mode requested by digital peripherals to keep RC_FAST clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (!!! Only valid for lightsleep, will override the RC_FAST domain config by esp_sleep_pd_config)
ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, //!< Will enables the use of ADC and temperature sensor in monitor (ULP) mode.
ESP_SLEEP_ULTRA_LOW_MODE, //!< In ultra low mode, 2uA is saved, but RTC memory can't use at high temperature, and RTCIO can't be used as INPUT.
ESP_SLEEP_RTC_FAST_USE_XTAL_MODE, //!< The mode in which the crystal is used as the RTC_FAST clock source, need keep XTAL on in HP_SLEEP mode when ULP is working.
ESP_SLEEP_DIG_USE_XTAL_MODE, //!< The mode requested by digital peripherals to keep XTAL clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (!!! Only valid for lightsleep, will override the XTAL domain config by esp_sleep_pd_config)
ESP_SLEEP_MODE_MAX,
} esp_sleep_sub_mode_t;
/**
* @brief Enables the use of ADC and temperature sensor in monitor (ULP) mode
* @brief Set sub-sleep power mode in sleep, mode enabled status is maintained by reference count.
* This submode configuration will kept after deep sleep wakeup.
*
* @note This state is kept in RTC memory and will keep its value after a deep sleep wakeup
* @param mode sub-sleep mode type
* @param activate Activate or deactivate the sleep sub mode
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
*/
void esp_sleep_enable_adc_tsens_monitor(bool enable);
esp_err_t esp_sleep_sub_mode_config(esp_sleep_sub_mode_t mode, bool activate);
/**
* Dump the sub-sleep power mode enable status
* @param stream The stream to dump to, if NULL then nothing will be dumped
* @return return the reference count array pointer
*/
int32_t* esp_sleep_sub_mode_dump_config(FILE *stream);
#if SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/**

View File

@ -10,6 +10,7 @@
#include <stdlib.h>
#include "soc/rtc.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/esp_sleep_internal.h"
#include "soc/rtc_periph.h"
#include "soc/sens_reg.h"
#include "soc/soc_caps.h"
@ -273,15 +274,23 @@ void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
clk_ll_rtc_slow_set_src(clk_src);
#ifndef BOOTLOADER_BUILD
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
}
#endif
clk_ll_rtc_slow_set_src(clk_src);
// The logic should be moved to BT driver
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
clk_ll_xtal32k_digi_enable();
} else {
clk_ll_xtal32k_digi_disable();
}
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
}

View File

@ -13,6 +13,7 @@
#include "esp32c2/rom/rtc.h"
#include "esp32c2/rom/uart.h"
#include "soc/rtc.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/rtc_clk.h"
#include "soc/io_mux_reg.h"
#include "soc/soc.h"
@ -66,6 +67,16 @@ bool rtc_clk_8md256_enabled(void)
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
#ifndef BOOTLOADER_BUILD
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
}
#endif
clk_ll_rtc_slow_set_src(clk_src);
/* Why we need to connect this clock to digital?
@ -76,7 +87,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
} else {
clk_ll_xtal32k_digi_disable();
}
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
}

View File

@ -13,6 +13,7 @@
#include "esp32c3/rom/rtc.h"
#include "soc/rtc.h"
#include "soc/io_mux_reg.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/rtc_clk.h"
#include "esp_hw_log.h"
#include "esp_rom_sys.h"
@ -99,8 +100,17 @@ bool rtc_clk_8md256_enabled(void)
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
clk_ll_rtc_slow_set_src(clk_src);
#ifndef BOOTLOADER_BUILD
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
}
#endif
clk_ll_rtc_slow_set_src(clk_src);
/* Why we need to connect this clock to digital?
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
*/
@ -109,7 +119,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
} else {
clk_ll_xtal32k_digi_disable();
}
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
}

View File

@ -13,6 +13,7 @@
#include "esp32s2/rom/rtc.h"
#include "soc/rtc.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/esp_sleep_internal.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/soc_caps.h"
@ -174,8 +175,17 @@ void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
clk_ll_rtc_slow_set_src(clk_src);
#ifndef BOOTLOADER_BUILD
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
}
#endif
clk_ll_rtc_slow_set_src(clk_src);
/* Why we need to connect this clock to digital?
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
*/
@ -184,7 +194,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
} else {
clk_ll_xtal32k_digi_disable();
}
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
}

View File

@ -13,6 +13,7 @@
#include "esp32s3/rom/rtc.h"
#include "soc/rtc.h"
#include "soc/io_mux_reg.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/rtc_clk.h"
#include "soc/rtc_io_reg.h"
#include "esp_rom_sys.h"
@ -114,8 +115,17 @@ bool rtc_clk_8md256_enabled(void)
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
clk_ll_rtc_slow_set_src(clk_src);
#ifndef BOOTLOADER_BUILD
soc_rtc_slow_clk_src_t clk_src_before_switch = clk_ll_rtc_slow_get_src();
// Keep the RTC8M_CLK on in sleep if RTC clock is rc_fast_d256.
if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch != SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch to RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, true);
} else if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 && clk_src_before_switch == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { // Switch away from RC_FAST_D256
esp_sleep_sub_mode_config(ESP_SLEEP_RTC_USE_RC_FAST_MODE, false);
}
#endif
clk_ll_rtc_slow_set_src(clk_src);
/* Why we need to connect this clock to digital?
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
*/
@ -124,7 +134,6 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
} else {
clk_ll_xtal32k_digi_disable();
}
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
}

View File

@ -8,6 +8,7 @@
#include <string.h>
#include <sys/lock.h>
#include <sys/param.h>
#include <inttypes.h>
#include "esp_attr.h"
#include "esp_rom_caps.h"
@ -279,16 +280,9 @@ static bool s_light_sleep_wakeup = false;
static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED;
static const char *TAG = "sleep";
static RTC_FAST_ATTR bool s_adc_tsen_enabled = false;
static RTC_FAST_ATTR int32_t s_sleep_sub_mode_ref_cnt[ESP_SLEEP_MODE_MAX] = { 0 };
//in this mode, 2uA is saved, but RTC memory can't use at high temperature, and RTCIO can't be used as INPUT.
static bool s_ultra_low_enabled = false;
static bool s_periph_use_8m_flag = false;
void esp_sleep_periph_use_8m(bool use_or_not)
{
s_periph_use_8m_flag = use_or_not;
}
static uint32_t get_power_down_flags(void);
#if SOC_PM_SUPPORT_EXT0_WAKEUP
@ -686,7 +680,7 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t pd_flags, bool deep_s
#if !CONFIG_IDF_TARGET_ESP32P4 && !CONFIG_IDF_TARGET_ESP32C61
// TODO: IDF-7370
if (!(deep_sleep && s_adc_tsen_enabled)){
if (!(deep_sleep && (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE] != 0))){
sar_periph_ctrl_power_disable();
}
#endif
@ -778,20 +772,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment;
#if SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256
//Keep the RTC8M_CLK on if RTC clock is rc_fast_d256.
bool rtc_using_8md256 = (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256);
#else
bool rtc_using_8md256 = false;
#endif
//Keep the RTC8M_CLK on if the ledc low-speed channel is clocked by RTC8M_CLK in lightsleep mode
bool periph_using_8m = !deep_sleep && s_periph_use_8m_flag;
//Override user-configured power modes.
if (rtc_using_8md256 || periph_using_8m) {
pd_flags &= ~RTC_SLEEP_PD_INT_8M;
}
// Sleep UART prepare
if (deep_sleep) {
flush_uarts();
@ -903,17 +883,31 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
reject_triggers |= sleep_modem_reject_triggers();
}
// Override user-configured FOSC power modes.
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_RTC_USE_RC_FAST_MODE]) {
pd_flags &= ~RTC_SLEEP_PD_INT_8M;
}
// Override user-configured XTAL power modes.
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_DIG_USE_XTAL_MODE] && !deep_sleep) {
pd_flags &= ~RTC_SLEEP_PD_XTAL;
}
//Append some flags in addition to power domains
uint32_t sleep_flags = pd_flags;
if (s_adc_tsen_enabled) {
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_DIG_USE_RC_FAST_MODE] && !deep_sleep) {
pd_flags &= ~RTC_SLEEP_PD_INT_8M;
sleep_flags |= RTC_SLEEP_DIG_USE_8M;
}
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE]) {
sleep_flags |= RTC_SLEEP_USE_ADC_TESEN_MONITOR;
}
if (!s_ultra_low_enabled) {
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_ULTRA_LOW_MODE] == 0) {
sleep_flags |= RTC_SLEEP_NO_ULTRA_LOW;
}
if (periph_using_8m) {
sleep_flags |= RTC_SLEEP_DIG_USE_8M;
}
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
@ -2178,6 +2172,42 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
return ESP_OK;
}
esp_err_t esp_sleep_sub_mode_config(esp_sleep_sub_mode_t mode, bool activate)
{
if (mode >= ESP_SLEEP_MODE_MAX) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&s_config.lock);
if (activate) {
s_sleep_sub_mode_ref_cnt[mode]++;
} else {
s_sleep_sub_mode_ref_cnt[mode]--;
}
assert(s_sleep_sub_mode_ref_cnt[mode] >= 0);
portEXIT_CRITICAL_SAFE(&s_config.lock);
return ESP_OK;
}
int32_t* esp_sleep_sub_mode_dump_config(FILE *stream) {
if (stream) {
for (uint32_t mode = 0; mode < ESP_SLEEP_MODE_MAX; mode++) {
fprintf(stream, LOG_COLOR_I "%s : %s (cnt = %" PRId32 ")\n" LOG_RESET_COLOR,
(const char*[]){
[ESP_SLEEP_RTC_USE_RC_FAST_MODE] = "ESP_SLEEP_RTC_USE_RC_FAST_MODE",
[ESP_SLEEP_DIG_USE_RC_FAST_MODE] = "ESP_SLEEP_DIG_USE_RC_FAST_MODE",
[ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE] = "ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE",
[ESP_SLEEP_ULTRA_LOW_MODE] = "ESP_SLEEP_ULTRA_LOW_MODE",
[ESP_SLEEP_RTC_FAST_USE_XTAL_MODE] = "ESP_SLEEP_RTC_FAST_USE_XTAL_MODE",
[ESP_SLEEP_DIG_USE_XTAL_MODE] = "ESP_SLEEP_DIG_USE_XTAL_MODE",
}[mode],
s_sleep_sub_mode_ref_cnt[mode] ? "ENABLED" : "DISABLED",
s_sleep_sub_mode_ref_cnt[mode]);
}
}
return s_sleep_sub_mode_ref_cnt;
}
/**
* The modules in the CPU and modem power domains still depend on the top power domain.
* To be safe, the CPU and Modem power domains must also be powered off and saved when
@ -2382,12 +2412,17 @@ esp_deep_sleep_disable_rom_logging(void)
rtc_suppress_rom_log();
}
void esp_sleep_enable_adc_tsens_monitor(bool enable)
__attribute__((deprecated("Please use esp_sleep_sub_mode_config instead"))) void esp_sleep_periph_use_8m(bool use_or_not)
{
s_adc_tsen_enabled = enable;
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_RC_FAST_MODE, use_or_not);
}
void rtc_sleep_enable_ultra_low(bool enable)
__attribute__((deprecated("Please use esp_sleep_sub_mode_config instead"))) void esp_sleep_enable_adc_tsens_monitor(bool enable)
{
s_ultra_low_enabled = enable;
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, enable);
}
__attribute__((deprecated("Please use esp_sleep_sub_mode_config instead"))) void rtc_sleep_enable_ultra_low(bool enable)
{
esp_sleep_sub_mode_config(ESP_SLEEP_ULTRA_LOW_MODE, enable);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -21,6 +21,11 @@
static const char TAG[] = "rtc_power";
static void check_deepsleep_reset(void)
{
TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
}
static void test_deepsleep(void)
{
esp_sleep_enable_timer_wakeup(2000000);
@ -28,33 +33,48 @@ static void test_deepsleep(void)
esp_deep_sleep_start();
}
// Deepsleep (with 8MD256 or ADC/TSEN in monitor)
TEST_CASE("Power Test: DSLP_8MD256", "[pm]")
{
esp_sleep_enable_adc_tsens_monitor(true);
test_deepsleep();
static void test_set_adc_tsen_monitor_mode(void) {
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
}
static void test_unset_adc_tesen_monitor_mode(void) {
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false);
TEST_ASSERT_EQUAL(0, esp_sleep_sub_mode_dump_config(NULL)[ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE]);
}
// Deepsleep (with 8MD256 or ADC/TSEN in monitor)
TEST_CASE_MULTIPLE_STAGES( "Power Test: DSLP_8MD256", "[pm]",
test_set_adc_tsen_monitor_mode,
test_deepsleep,
check_deepsleep_reset,
test_unset_adc_tesen_monitor_mode
)
#if !CONFIG_RTC_CLK_SRC_INT_8MD256
// Deepsleep (default)
TEST_CASE("Power Test: DSLP_DEFAULT", "[pm]")
{
esp_sleep_enable_adc_tsens_monitor(false); //This is the default option. Add this line to avoid the case executing this case directly after the DSLP_8MD256 case.
TEST_CASE_MULTIPLE_STAGES( "Power Test: DSLP_DEFAULT", "[pm]",
test_deepsleep,
check_deepsleep_reset
)
test_deepsleep();
static void test_set_ultra_low_mode(void) {
esp_sleep_sub_mode_config(ESP_SLEEP_ULTRA_LOW_MODE, true);
}
static void test_unset_ultra_low_mode(void) {
esp_sleep_sub_mode_config(ESP_SLEEP_ULTRA_LOW_MODE, false);
TEST_ASSERT_EQUAL(0, esp_sleep_sub_mode_dump_config(NULL)[ESP_SLEEP_ULTRA_LOW_MODE]);
}
// Deepsleep (ultra-low power)
TEST_CASE("Power Test: DSLP_ULTRA_LOW", "[pm]")
{
esp_sleep_enable_adc_tsens_monitor(false); //This is the default option. Add this line to avoid the case executing this case directly after the DSLP_8MD256 case.
TEST_CASE_MULTIPLE_STAGES( "Power Test: DSLP_ULTRA_LOW", "[pm]",
test_set_ultra_low_mode,
test_deepsleep,
check_deepsleep_reset,
test_unset_ultra_low_mode
)
extern void rtc_sleep_enable_ultra_low(bool);
rtc_sleep_enable_ultra_low(true);
test_deepsleep();
}
#endif //!CONFIG_RTC_CLK_SRC_INT_8MD256
static void test_lightsleep(void)
@ -125,17 +145,14 @@ TEST_CASE("Power Test: LSLP_8MD256", "[pm]")
// Lightsleep (with ADC/TSEN in monitor)
TEST_CASE("Power Test: LSLP_ADC_TSENS", "[pm]")
{
extern void esp_sleep_enable_adc_tsens_monitor(bool);
esp_sleep_enable_adc_tsens_monitor(true);
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
test_lightsleep();
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false);
}
// Lightsleep (default)
TEST_CASE("Power Test: LSLP_DEFAULT", "[pm]")
{
esp_sleep_enable_adc_tsens_monitor(false); //This is the default option. Add this line to avoid the case executing this case directly after the DSLP_8MD256 case.
test_lightsleep();
}
#endif //!CONFIG_RTC_CLK_SRC_INT_8MD256