Merge branch 'feature/bringup_esp32c6_deepsleep_support_master' into 'master'

esp32c6: bringup deepsleep examples

Closes IDF-6051, IDF-6052, IDF-5349, IDF-5924, and WIFI-5352

See merge request espressif/esp-idf!22300
This commit is contained in:
Wu Zheng Hui
2023-03-03 23:53:10 +08:00
56 changed files with 642 additions and 275 deletions

View File

@@ -22,6 +22,10 @@
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#if (SOC_RTCIO_PIN_COUNT > 0)
#include "hal/rtc_io_hal.h"
#endif
static const char *GPIO_TAG = "gpio"; static const char *GPIO_TAG = "gpio";
#define GPIO_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, GPIO_TAG, "%s", str) #define GPIO_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, GPIO_TAG, "%s", str)
@@ -730,6 +734,7 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
return ret; return ret;
} }
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
void gpio_deep_sleep_hold_en(void) void gpio_deep_sleep_hold_en(void)
{ {
portENTER_CRITICAL(&gpio_context.gpio_spinlock); portENTER_CRITICAL(&gpio_context.gpio_spinlock);
@@ -743,9 +748,9 @@ void gpio_deep_sleep_hold_dis(void)
gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal); gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal);
portEXIT_CRITICAL(&gpio_context.gpio_spinlock); portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
} }
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
#if SOC_GPIO_SUPPORT_FORCE_HOLD #if SOC_GPIO_SUPPORT_FORCE_HOLD
esp_err_t IRAM_ATTR gpio_force_hold_all() esp_err_t IRAM_ATTR gpio_force_hold_all()
{ {
#if SOC_RTCIO_HOLD_SUPPORTED #if SOC_RTCIO_HOLD_SUPPORTED
@@ -767,7 +772,7 @@ esp_err_t IRAM_ATTR gpio_force_unhold_all()
#endif #endif
return ESP_OK; return ESP_OK;
} }
#endif #endif //SOC_GPIO_SUPPORT_FORCE_HOLD
void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx) void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx)
{ {

View File

@@ -374,10 +374,9 @@ esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *stren
* in output mode: the output level of the GPIO will be locked and can not be changed. * in output mode: the output level of the GPIO will be locked and can not be changed.
* in input mode: the input read value can still reflect the changes of the input signal. * in input mode: the input read value can still reflect the changes of the input signal.
* *
* However, this function cannot be used to hold the state of a digital GPIO during Deep-sleep. Even if this * However, on ESP32/S2/C3/S3/C2, this function cannot be used to hold the state of a digital GPIO during Deep-sleep.
* function is enabled, the digital GPIO will be reset to its default state when the chip wakes up from * Even if this function is enabled, the digital GPIO will be reset to its default state when the chip wakes up from
* Deep-sleep. If you want to hold the state of a digital GPIO during Deep-sleep, please call * Deep-sleep. If you want to hold the state of a digital GPIO during Deep-sleep, please call `gpio_deep_sleep_hold_en`.
* `gpio_deep_sleep_hold_en`.
* *
* Power down or call `gpio_hold_dis` will disable this function. * Power down or call `gpio_hold_dis` will disable this function.
* *
@@ -408,6 +407,7 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num);
*/ */
esp_err_t gpio_hold_dis(gpio_num_t gpio_num); esp_err_t gpio_hold_dis(gpio_num_t gpio_num);
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/** /**
* @brief Enable all digital gpio pads hold function during Deep-sleep. * @brief Enable all digital gpio pads hold function during Deep-sleep.
* *
@@ -426,6 +426,7 @@ void gpio_deep_sleep_hold_en(void);
* @brief Disable all digital gpio pads hold function during Deep-sleep. * @brief Disable all digital gpio pads hold function during Deep-sleep.
*/ */
void gpio_deep_sleep_hold_dis(void); void gpio_deep_sleep_hold_dis(void);
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/** /**
* @brief Set pad input to a peripheral signal through the IOMUX. * @brief Set pad input to a peripheral signal through the IOMUX.

View File

@@ -326,10 +326,9 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]")
ESP_LOGI(TAG, "RTCIO hold test over"); ESP_LOGI(TAG, "RTCIO hold test over");
} }
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6) // TODO: IDF-5349 Remove when deep sleep is supported on ESP32C6
// It is not necessary to test every rtcio pin, it will take too much ci testing time for deep sleep // It is not necessary to test every rtcio pin, it will take too much ci testing time for deep sleep
// Only tests on s_test_map[TEST_RTCIO_DEEP_SLEEP_PIN_INDEX] pin // Only tests on s_test_map[TEST_RTCIO_DEEP_SLEEP_PIN_INDEX] pin
// (ESP32: IO25, ESP32S2, S3: IO6) these pads' default configuration is low level // (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5) these pads' default configuration is low level
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 #define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5
static void rtcio_deep_sleep_hold_test_first_stage(void) static void rtcio_deep_sleep_hold_test_first_stage(void)
@@ -375,5 +374,4 @@ static void rtcio_deep_sleep_hold_test_second_stage(void)
TEST_CASE_MULTIPLE_STAGES("RTCIO_deep_sleep_output_hold_test", "[rtcio]", TEST_CASE_MULTIPLE_STAGES("RTCIO_deep_sleep_output_hold_test", "[rtcio]",
rtcio_deep_sleep_hold_test_first_stage, rtcio_deep_sleep_hold_test_first_stage,
rtcio_deep_sleep_hold_test_second_stage) rtcio_deep_sleep_hold_test_second_stage)
#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) #endif //SOC_RTCIO_HOLD_SUPPORTED
#endif // #if SOC_RTCIO_HOLD_SUPPORTED

View File

@@ -110,6 +110,7 @@ if(NOT BOOTLOADER_BUILD)
"sleep_cpu.c" # TODO: IDF-6267 "sleep_cpu.c" # TODO: IDF-6267
"sleep_modes.c" # TODO: IDF-6267 "sleep_modes.c" # TODO: IDF-6267
"sleep_wake_stub.c" # TODO: IDF-6267 "sleep_wake_stub.c" # TODO: IDF-6267
"sleep_gpio.c" # TODO: IDF-6267
) )
endif() endif()
else() else()

View File

@@ -37,6 +37,14 @@ extern "C" {
#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17)
#define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature
#if SOC_PM_SUPPORT_EXT0_WAKEUP
#define RTC_EXT0_TRIG_EN PMU_EXT0_WAKEUP_EN //!< EXT0 wakeup
#else
#define RTC_EXT0_TRIG_EN 0
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
#define RTC_EXT1_TRIG_EN PMU_EXT1_WAKEUP_EN //!< EXT1 wakeup
#endif
#define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup #define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup
#define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup #define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup
#define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only) #define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only)
@@ -60,6 +68,12 @@ extern "C" {
RTC_USB_TRIG_EN | \ RTC_USB_TRIG_EN | \
RTC_BROWNOUT_DET_TRIG_EN) RTC_BROWNOUT_DET_TRIG_EN)
#if SOC_PM_SUPPORT_EXT0_WAKEUP
#define PMU_EXT0_WAKEUP_EN BIT(0)
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
#define PMU_EXT1_WAKEUP_EN BIT(1)
#endif
#define PMU_GPIO_WAKEUP_EN BIT(2) #define PMU_GPIO_WAKEUP_EN BIT(2)
#define PMU_WIFI_BEACON_WAKEUP_EN BIT(3) #define PMU_WIFI_BEACON_WAKEUP_EN BIT(3)
@@ -82,6 +96,7 @@ extern "C" {
#define PMU_SLEEP_PD_MEM_G1 BIT(7) #define PMU_SLEEP_PD_MEM_G1 BIT(7)
#define PMU_SLEEP_PD_MEM_G2 BIT(8) #define PMU_SLEEP_PD_MEM_G2 BIT(8)
#define PMU_SLEEP_PD_MEM_G3 BIT(9) #define PMU_SLEEP_PD_MEM_G3 BIT(9)
#define PMU_SLEEP_PD_MEM (PMU_SLEEP_PD_MEM_G0|PMU_SLEEP_PD_MEM_G1|PMU_SLEEP_PD_MEM_G2|PMU_SLEEP_PD_MEM_G3)
#define PMU_SLEEP_PD_XTAL BIT(10) #define PMU_SLEEP_PD_XTAL BIT(10)
#define PMU_SLEEP_PD_RC_FAST BIT(11) #define PMU_SLEEP_PD_RC_FAST BIT(11)
#define PMU_SLEEP_PD_XTAL32K BIT(12) #define PMU_SLEEP_PD_XTAL32K BIT(12)

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -21,8 +21,7 @@ extern "C" {
*/ */
void esp_sleep_enable_adc_tsens_monitor(bool enable); void esp_sleep_enable_adc_tsens_monitor(bool enable);
// TODO: IDF-6051, IDF-6052 #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
#if !CONFIG_IDF_TARGET_ESP32H4 && !CONFIG_IDF_TARGET_ESP32C6
/** /**
* @brief Isolate all digital IOs except those that are held during deep sleep * @brief Isolate all digital IOs except those that are held during deep sleep
* *

View File

@@ -193,8 +193,7 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void);
*/ */
bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num); bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num);
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
/** /**
* @brief Enable wakeup using a pin * @brief Enable wakeup using a pin
* *
@@ -223,7 +222,9 @@ bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num);
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict * - ESP_ERR_INVALID_STATE if wakeup triggers conflict
*/ */
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level); esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
#endif // SOC_PM_SUPPORT_EXT0_WAKEUP
#if SOC_PM_SUPPORT_EXT1_WAKEUP
/** /**
* @brief Enable wakeup using multiple pins * @brief Enable wakeup using multiple pins
* *
@@ -249,6 +250,7 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
* - ESP32: 0, 2, 4, 12-15, 25-27, 32-39; * - ESP32: 0, 2, 4, 12-15, 25-27, 32-39;
* - ESP32-S2: 0-21; * - ESP32-S2: 0-21;
* - ESP32-S3: 0-21. * - ESP32-S3: 0-21.
* - ESP32-C6: 0-7.
* @param mode select logic function used to determine wakeup condition: * @param mode select logic function used to determine wakeup condition:
* - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low * - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
* - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
@@ -259,7 +261,7 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
*/ */
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode); esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode);
#endif // SOC_PM_SUPPORT_EXT_WAKEUP #endif // SOC_PM_SUPPORT_EXT1_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
/** /**
@@ -475,6 +477,11 @@ typedef void (*esp_deep_sleep_wake_stub_fn_t)(void);
*/ */
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub); void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub);
/**
* @brief Set wake stub entry to default `esp_wake_stub_entry`
*/
void esp_set_deep_sleep_wake_stub_default_entry(void);
/** /**
* @brief Get current wake from deep sleep stub * @brief Get current wake from deep sleep stub
* @return Return current wake from deep sleep stub, or NULL if * @return Return current wake from deep sleep stub, or NULL if

View File

@@ -14,6 +14,7 @@
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
#include "hal/lp_aon_hal.h"
#include "esp_private/esp_pmu.h" #include "esp_private/esp_pmu.h"
#define HP(state) (PMU_MODE_HP_ ## state) #define HP(state) (PMU_MODE_HP_ ## state)
@@ -152,11 +153,9 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->digital = digital_default; config->digital = digital_default;
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
if (!(pd_flags & PMU_SLEEP_PD_MODEM)){ if (!(pd_flags & PMU_SLEEP_PD_TOP) || !(pd_flags & PMU_SLEEP_PD_MODEM)){
analog_default.hp_sys.analog.slp_logic_dbias += 2; analog_default.hp_sys.analog.xpd = 1;
} analog_default.hp_sys.analog.dbias = 2;
if (!(pd_flags & PMU_SLEEP_PD_TOP)){
analog_default.hp_sys.analog.slp_logic_dbias += 2;
} }
config->analog = analog_default; config->analog = analog_default;
} }
@@ -200,10 +199,13 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias); pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b); pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_xpd);
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias); pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.xpd);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias); pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b); pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b);
pmu_ll_lp_set_dbg_atten (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbg_atten);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur); pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep); pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd); pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd);
@@ -248,6 +250,9 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{ {
assert(PMU_instance()->hal); assert(PMU_instance()->hal);
lp_aon_hal_inform_wakeup_type(dslp);
pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt); pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt);
pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt); pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt);

View File

@@ -172,14 +172,14 @@ typedef struct {
#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ #define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \ .hp_sys = { \
.analog = { \ .analog = { \
.xpd_bias = 0x0, \ .xpd_bias = 0, \
.dbg_atten = 0x0, \ .dbg_atten = 0, \
.pd_cur = 1, \ .pd_cur = 1, \
.bias_sleep = 1, \ .bias_sleep = 1, \
.slp_mem_xpd = 1, \ .slp_mem_xpd = 1, \
.slp_logic_xpd = 1, \ .slp_logic_xpd = 1, \
.slp_mem_dbias = 0x4, \ .slp_mem_dbias = 4, \
.slp_logic_dbias = 0x4, \ .slp_logic_dbias = 4, \
.xpd = 0, \ .xpd = 0, \
.dbias = 0, \ .dbias = 0, \
.drv_b = 0 \ .drv_b = 0 \
@@ -188,23 +188,23 @@ typedef struct {
.lp_sys[PMU_MODE_LP_ACTIVE] = { \ .lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \ .analog = { \
.slp_xpd = 0, \ .slp_xpd = 0, \
.slp_dbias = 0xc, \ .slp_dbias = 0, \
.xpd = 1, \ .xpd = 1, \
.dbias = 0x1a, \ .dbias = 26, \
.drv_b = 0x0 \ .drv_b = 0 \
} \ } \
}, \ }, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \ .lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \ .analog = { \
.xpd_bias = 0, \ .xpd_bias = 0, \
.dbg_atten = 0x0, \ .dbg_atten = 0, \
.pd_cur = 1, \ .pd_cur = 1, \
.bias_sleep = 1, \ .bias_sleep = 1, \
.xpd = 0, \ .xpd = 0, \
.dbias = 0x1c, \ .dbias = 28, \
.slp_xpd = 1, \ .slp_xpd = 1, \
.slp_dbias = 0x3, \ .slp_dbias = 3, \
.drv_b = 0x0 \ .drv_b = 0 \
} \ } \
} \ } \
} }
@@ -213,37 +213,37 @@ typedef struct {
.hp_sys = { \ .hp_sys = { \
.analog = { \ .analog = { \
.xpd_bias = 0, \ .xpd_bias = 0, \
.dbg_atten = 0x3, \ .dbg_atten = 0, \
.pd_cur = 1, \ .pd_cur = 0, \
.bias_sleep = 1, \ .bias_sleep = 0, \
.slp_mem_xpd = 0, \
.slp_logic_xpd = 0, \
.slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \
.xpd = 0, \ .xpd = 0, \
.dbias = 0x15, \ .dbias = 0, \
.slp_mem_xpd = 1, \ .drv_b = 0 \
.slp_mem_dbias = 0xc, \
.slp_logic_xpd = 1, \
.slp_logic_dbias = 0x5, \
.drv_b = 0x18c \
} \ } \
}, \ }, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \ .lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \ .analog = { \
.xpd = 1, \
.dbias = 0x1a, \
.slp_xpd = 0, \ .slp_xpd = 0, \
.slp_dbias = 0, \ .slp_dbias = 0, \
.drv_b = 0x7 \ .xpd = 1, \
.dbias = 26, \
.drv_b = 0 \
} \ } \
}, \ }, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \ .lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \ .analog = { \
.xpd_bias = 0, \ .xpd_bias = 0, \
.dbg_atten = 0xe, \ .dbg_atten = 14, \
.pd_cur = 1, \ .pd_cur = 1, \
.bias_sleep = 1, \ .bias_sleep = 1, \
.xpd = 0, \ .xpd = 0, \
.dbias = 0, \ .dbias = 0, \
.slp_xpd = 1, \ .slp_xpd = 1, \
.slp_dbias = 0xe, \ .slp_dbias = 14, \
.drv_b = 0 \ .drv_b = 0 \
} \ } \
} \ } \

View File

@@ -565,7 +565,6 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
{ {
RvCoreCriticalSleepFrame * frame = rv_core_critical_regs_save(); RvCoreCriticalSleepFrame * frame = rv_core_critical_regs_save();
if ((frame->pmufunc & 0x3) == 0x1) { if ((frame->pmufunc & 0x3) == 0x1) {
REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
} }

View File

@@ -21,7 +21,9 @@
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "hal/rtc_io_hal.h" #include "hal/rtc_io_hal.h"
#if !SOC_PMU_SUPPORTED #if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#include "hal/rtc_hal.h" #include "hal/rtc_hal.h"
#endif #endif
@@ -107,8 +109,7 @@ void esp_sleep_enable_gpio_switch(bool enable)
} }
} }
// TODO: IDF-6051, IDF-6052 #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
#if !CONFIG_IDF_TARGET_ESP32H4 && !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2
IRAM_ATTR void esp_sleep_isolate_digital_gpio(void) IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
{ {
gpio_hal_context_t gpio_hal = { gpio_hal_context_t gpio_hal = {
@@ -146,11 +147,11 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
} }
} }
} }
#endif #endif // !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
void esp_deep_sleep_wakeup_io_reset(void) void esp_deep_sleep_wakeup_io_reset(void)
{ {
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT1_WAKEUP
uint32_t rtc_io_mask = rtc_hal_ext1_get_wakeup_pins(); uint32_t rtc_io_mask = rtc_hal_ext1_get_wakeup_pins();
// Disable ext1 wakeup before releasing hold, such that wakeup status can reflect the correct wakeup pin // Disable ext1 wakeup before releasing hold, such that wakeup status can reflect the correct wakeup pin
rtc_hal_ext1_clear_wakeup_pins(); rtc_hal_ext1_clear_wakeup_pins();

View File

@@ -25,7 +25,9 @@
#include "driver/rtc_io.h" #include "driver/rtc_io.h"
#include "hal/rtc_io_hal.h" #include "hal/rtc_io_hal.h"
#if !SOC_PMU_SUPPORTED #if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#include "hal/rtc_cntl_ll.h" #include "hal/rtc_cntl_ll.h"
#include "hal/rtc_hal.h" #include "hal/rtc_hal.h"
#endif #endif
@@ -156,12 +158,16 @@ typedef struct {
portMUX_TYPE lock; portMUX_TYPE lock;
uint64_t sleep_duration; uint64_t sleep_duration;
uint32_t wakeup_triggers : 15; uint32_t wakeup_triggers : 15;
#if SOC_PM_SUPPORT_EXT1_WAKEUP
uint32_t ext1_trigger_mode : 1; uint32_t ext1_trigger_mode : 1;
uint32_t ext1_rtc_gpio_mask : 22; //22 is the maximum RTCIO number in all chips uint32_t ext1_rtc_gpio_mask : 22; // 22 is the maximum RTCIO number in all chips
#endif
#if SOC_PM_SUPPORT_EXT0_WAKEUP
uint32_t ext0_trigger_level : 1; uint32_t ext0_trigger_level : 1;
uint32_t ext0_rtc_gpio_num : 5; uint32_t ext0_rtc_gpio_num : 5;
uint32_t gpio_wakeup_mask : 6; #endif
uint32_t gpio_trigger_mode : 6; uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup
uint32_t gpio_trigger_mode : 8;
uint32_t sleep_time_adjustment; uint32_t sleep_time_adjustment;
uint32_t ccount_ticks_record; uint32_t ccount_ticks_record;
uint32_t sleep_time_overhead_out; uint32_t sleep_time_overhead_out;
@@ -207,8 +213,10 @@ void esp_sleep_periph_use_8m(bool use_or_not)
} }
static uint32_t get_power_down_flags(void); static uint32_t get_power_down_flags(void);
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
static void ext0_wakeup_prepare(void); static void ext0_wakeup_prepare(void);
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
static void ext1_wakeup_prepare(void); static void ext1_wakeup_prepare(void);
#endif #endif
static void timer_wakeup_prepare(void); static void timer_wakeup_prepare(void);
@@ -235,14 +243,19 @@ static void RTC_IRAM_ATTR __attribute__((used, noinline)) esp_wake_stub_start(vo
* must be simple enough to ensure that there is no litteral data before the * must be simple enough to ensure that there is no litteral data before the
* wake stub entry, otherwise, the litteral data before the wake stub entry * wake stub entry, otherwise, the litteral data before the wake stub entry
* will not be CRC checked. */ * will not be CRC checked. */
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150
static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void) static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void)
{ {
#define _SYM2STR(s) # s #define _SYM2STR(s) # s
#define SYM2STR(s) _SYM2STR(s) #define SYM2STR(s) _SYM2STR(s)
#ifdef __riscv #ifdef __riscv
__asm__ __volatile__ ("call " SYM2STR(esp_wake_stub_start) "\n"); __asm__ __volatile__ (
"addi sp, sp, -16 \n"
"sw ra, 0(sp) \n"
"jal ra, " SYM2STR(esp_wake_stub_start) "\n"
"lw ra, 0(sp) \n"
"addi sp, sp, 16 \n"
);
#else #else
// call4 has a larger effective addressing range (-524284 to 524288 bytes), // call4 has a larger effective addressing range (-524284 to 524288 bytes),
// which is sufficient for instruction addressing in RTC fast memory. // which is sufficient for instruction addressing in RTC fast memory.
@@ -250,7 +263,19 @@ static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void
#endif #endif
} }
#endif // !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150
void RTC_IRAM_ATTR esp_set_deep_sleep_wake_stub_default_entry(void)
{
extern char _rtc_text_start[];
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
extern char _rtc_noinit_end[];
size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start;
#else
extern char _rtc_force_fast_end[];
size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start;
#endif
esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length);
}
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
/* Wake from deep sleep stub /* Wake from deep sleep stub
@@ -269,7 +294,13 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void)
return stub_ptr; return stub_ptr;
} }
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) #if CONFIG_IDF_TARGET_ESP32
/* APP core of esp32 can't access to RTC FAST MEMORY, do not define it with RTC_IRAM_ATTR */
void
#else
void RTC_IRAM_ATTR
#endif
esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
{ {
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
wake_stub_fn_handler = new_stub; wake_stub_fn_handler = new_stub;
@@ -433,11 +464,13 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
rtc_clk_cpu_freq_get_config(&cpu_freq_config); rtc_clk_cpu_freq_get_config(&cpu_freq_config);
rtc_clk_cpu_freq_set_xtal(); rtc_clk_cpu_freq_set_xtal();
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
// Configure pins for external wakeup // Configure pins for external wakeup
if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
ext0_wakeup_prepare(); ext0_wakeup_prepare();
} }
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) { if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) {
ext1_wakeup_prepare(); ext1_wakeup_prepare();
} }
@@ -529,24 +562,18 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
uint32_t result; uint32_t result;
if (deep_sleep) { if (deep_sleep) {
// TODO: IDF-6051, IDF-6052 #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
#if !CONFIG_IDF_TARGET_ESP32H4 && !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2
esp_sleep_isolate_digital_gpio(); esp_sleep_isolate_digital_gpio();
#endif #endif
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
extern char _rtc_text_start[]; esp_set_deep_sleep_wake_stub_default_entry();
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM // Enter Deep Sleep
extern char _rtc_noinit_end[]; #if SOC_PMU_SUPPORTED
size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start; result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
#else #else
extern char _rtc_force_fast_end[];
size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start;
#endif
esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length);
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep); result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
#endif
#else #else
#if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
/* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */ /* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
@@ -560,9 +587,6 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
#endif #endif
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
#else
result = ESP_OK;
#endif
} else { } else {
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
@@ -646,7 +670,14 @@ void IRAM_ATTR esp_deep_sleep_start(void)
// Correct the sleep time // Correct the sleep time
s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
#if SOC_PMU_SUPPORTED
uint32_t force_pd_flags = PMU_SLEEP_PD_TOP | PMU_SLEEP_PD_VDDSDIO | PMU_SLEEP_PD_MODEM | PMU_SLEEP_PD_HP_PERIPH \
| PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_MEM | PMU_SLEEP_PD_XTAL | PMU_SLEEP_PD_RC_FAST \
| PMU_SLEEP_PD_XTAL32K |PMU_SLEEP_PD_RC32K;
#else
uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL; uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL;
#endif
#if SOC_PM_SUPPORT_WIFI_PD #if SOC_PM_SUPPORT_WIFI_PD
force_pd_flags |= RTC_SLEEP_PD_WIFI; force_pd_flags |= RTC_SLEEP_PD_WIFI;
@@ -928,11 +959,13 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) { } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) {
s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN; s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
s_config.sleep_duration = 0; s_config.sleep_duration = 0;
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) { } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) {
s_config.ext0_rtc_gpio_num = 0; s_config.ext0_rtc_gpio_num = 0;
s_config.ext0_trigger_level = 0; s_config.ext0_trigger_level = 0;
s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN; s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN;
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) { } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) {
s_config.ext1_rtc_gpio_mask = 0; s_config.ext1_rtc_gpio_mask = 0;
s_config.ext1_trigger_mode = 0; s_config.ext1_trigger_mode = 0;
@@ -1071,8 +1104,7 @@ bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num)
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
} }
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
{ {
if (level < 0 || level > 1) { if (level < 0 || level > 1) {
@@ -1101,7 +1133,9 @@ static void ext0_wakeup_prepare(void)
rtcio_hal_function_select(rtc_gpio_num, RTCIO_FUNC_RTC); rtcio_hal_function_select(rtc_gpio_num, RTCIO_FUNC_RTC);
rtcio_hal_input_enable(rtc_gpio_num); rtcio_hal_input_enable(rtc_gpio_num);
} }
#endif // SOC_PM_SUPPORT_EXT0_WAKEUP
#if SOC_PM_SUPPORT_EXT1_WAKEUP
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode) esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode)
{ {
if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) { if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
@@ -1185,25 +1219,20 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
return gpio_mask; return gpio_mask;
} }
#endif // SOC_PM_SUPPORT_EXT_WAKEUP #endif // SOC_PM_SUPPORT_EXT1_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
uint64_t esp_sleep_get_gpio_wakeup_status(void) uint64_t esp_sleep_get_gpio_wakeup_status(void)
{ {
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349
return 0;
#else
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) { if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
return 0; return 0;
} }
return rtc_hal_gpio_get_wakeup_status(); return rtc_hal_gpio_get_wakeup_status();
#endif
} }
static void gpio_deep_sleep_wakeup_prepare(void) static void gpio_deep_sleep_wakeup_prepare(void)
{ {
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349
for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) { for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) {
if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) { if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
continue; continue;
@@ -1219,7 +1248,6 @@ static void gpio_deep_sleep_wakeup_prepare(void)
} }
// Clear state from previous wakeup // Clear state from previous wakeup
rtc_hal_gpio_clear_wakeup_status(); rtc_hal_gpio_clear_wakeup_status();
#endif
} }
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode) esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
@@ -1339,9 +1367,11 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
return ESP_SLEEP_WAKEUP_GPIO; return ESP_SLEEP_WAKEUP_GPIO;
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) { } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
return ESP_SLEEP_WAKEUP_UART; return ESP_SLEEP_WAKEUP_UART;
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
} else if (wakeup_cause & RTC_EXT0_TRIG_EN) { } else if (wakeup_cause & RTC_EXT0_TRIG_EN) {
return ESP_SLEEP_WAKEUP_EXT0; return ESP_SLEEP_WAKEUP_EXT0;
#endif
#if SOC_PM_SUPPORT_EXT1_WAKEUP
} else if (wakeup_cause & RTC_EXT1_TRIG_EN) { } else if (wakeup_cause & RTC_EXT1_TRIG_EN) {
return ESP_SLEEP_WAKEUP_EXT1; return ESP_SLEEP_WAKEUP_EXT1;
#endif #endif

View File

@@ -11,6 +11,7 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_sleep.h" #include "esp_sleep.h"
#include "esp_cpu.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/rtc.h" #include "soc/rtc.h"
@@ -50,31 +51,38 @@
void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub) void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub)
{ {
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
extern char _rtc_text_start[]; #if CONFIG_IDF_TARGET_ESP32
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM // Since the app core of esp32 does not support access to RTC_FAST_MEMORY,
extern char _rtc_noinit_end[]; // `esp_set_deep_sleep_wake_stub` is not declared in RTC_FAST_MEMORY,
size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start; // so we cannot call it here
#else
extern char _rtc_force_fast_end[];
size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start;
#endif // CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)new_stub, rtc_fast_length);
#else
// Set the pointer of the wake stub function.
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub);
#else
esp_set_deep_sleep_wake_stub(new_stub);
#endif
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
esp_set_deep_sleep_wake_stub_default_entry();
#else
set_rtc_memory_crc(); set_rtc_memory_crc();
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM
// Go to sleep. // Go to sleep.
#if SOC_PMU_SUPPORTED #if SOC_PMU_SUPPORTED
pmu_ll_hp_clear_wakeup_intr_status(&PMU);
pmu_ll_hp_clear_reject_intr_status(&PMU);
pmu_ll_hp_clear_reject_cause(&PMU);
pmu_ll_hp_set_sleep_enable(&PMU); pmu_ll_hp_set_sleep_enable(&PMU);
#else #else
rtc_cntl_ll_sleep_enable(); rtc_cntl_ll_sleep_enable();
#endif #endif
// A few CPU cycles may be necessary for the sleep to start... // A few CPU cycles may be necessary for the sleep to start...
while (true) {}; #if __XTENSA__
xt_utils_wait_for_intr();
#else
rv_utils_wait_for_intr();
#endif // __XTENSA__
// never reaches here. // never reaches here.
} }
@@ -87,8 +95,15 @@ void RTC_IRAM_ATTR esp_wake_stub_set_wakeup_time(uint64_t time_in_us)
{ {
#if SOC_LP_TIMER_SUPPORTED #if SOC_LP_TIMER_SUPPORTED
uint64_t rtc_count_delta = lp_timer_ll_time_to_count(time_in_us); uint64_t rtc_count_delta = lp_timer_ll_time_to_count(time_in_us);
uint64_t rtc_curr_count = lp_timer_hal_get_cycle_count(0);
lp_timer_hal_set_alarm_target(0, rtc_curr_count + rtc_count_delta); lp_timer_ll_counter_snapshot(&LP_TIMER);
uint32_t lo = lp_timer_ll_get_counter_value_low(&LP_TIMER, 0);
uint32_t hi = lp_timer_ll_get_counter_value_high(&LP_TIMER, 0);
uint64_t rtc_curr_count = (uint64_t)hi << 32 | lo;
lp_timer_ll_clear_alarm_intr_status(&LP_TIMER);
lp_timer_ll_set_alarm_target(&LP_TIMER, 0, rtc_curr_count + rtc_count_delta);
lp_timer_ll_set_target_enable(&LP_TIMER, 0, true);
#else #else
uint64_t rtc_count_delta = rtc_cntl_ll_time_to_count(time_in_us); uint64_t rtc_count_delta = rtc_cntl_ll_time_to_count(time_in_us);
uint64_t rtc_curr_count = rtc_cntl_ll_get_rtc_time(); uint64_t rtc_curr_count = rtc_cntl_ll_get_rtc_time();

View File

@@ -178,6 +178,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @brief Read stored RTC wake function address
* *
* Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid.
* valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values
* and the crc check passes
* *
* @param None * @param None
* *
@@ -191,8 +193,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void);
* Set a new RTC wake address function. If a non-NULL function pointer is set then the function * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * memory is calculated and stored also.
* *
* @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * if NULL length will be ignored and all registers are cleared to 0.
*
* @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes.
* otherwise all registers are cleared to 0.
* *
* @return None * @return None
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -175,6 +175,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @brief Read stored RTC wake function address
* *
* Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid.
* valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values
* and the crc check passes
* *
* @param None * @param None
* *
@@ -188,8 +190,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void);
* Set a new RTC wake address function. If a non-NULL function pointer is set then the function * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * memory is calculated and stored also.
* *
* @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * if NULL length will be ignored and all registers are cleared to 0.
*
* @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes.
* otherwise all registers are cleared to 0.
* *
* @return None * @return None
*/ */

View File

@@ -175,6 +175,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @brief Read stored RTC wake function address
* *
* Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid.
* valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values
* and the crc check passes
* *
* @param None * @param None
* *
@@ -188,8 +190,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void);
* Set a new RTC wake address function. If a non-NULL function pointer is set then the function * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * memory is calculated and stored also.
* *
* @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * if NULL length will be ignored and all registers are cleared to 0.
*
* @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes.
* otherwise all registers are cleared to 0.
* *
* @return None * @return None
*/ */

View File

@@ -173,6 +173,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @brief Read stored RTC wake function address
* *
* Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid.
* valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values
* and the crc check passes
* *
* @param None * @param None
* *
@@ -186,8 +188,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void);
* Set a new RTC wake address function. If a non-NULL function pointer is set then the function * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * memory is calculated and stored also.
* *
* @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * if NULL length will be ignored and all registers are cleared to 0.
*
* @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes.
* otherwise all registers are cleared to 0.
* *
* @return None * @return None
*/ */

View File

@@ -17,6 +17,8 @@ SECTIONS
{ {
. = ALIGN(4); . = ALIGN(4);
_rtc_fast_start = ABSOLUTE(.); _rtc_fast_start = ABSOLUTE(.);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.entry.text)
mapping[rtc_text] mapping[rtc_text]

View File

@@ -541,10 +541,12 @@ void IRAM_ATTR call_start_cpu0(void)
#endif #endif
#endif #endif
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
// Need to unhold the IOs that were hold right before entering deep sleep, which are used as wakeup pins // Need to unhold the IOs that were hold right before entering deep sleep, which are used as wakeup pins
if (rst_reas[0] == RESET_REASON_CORE_DEEP_SLEEP) { if (rst_reas[0] == RESET_REASON_CORE_DEEP_SLEEP) {
esp_deep_sleep_wakeup_io_reset(); esp_deep_sleep_wakeup_io_reset();
} }
#endif
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
esp_cache_err_int_init(); esp_cache_err_int_init();

View File

@@ -386,7 +386,7 @@ TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub from stack in RTC RAM", "[dee
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP
TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]") TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
{ {
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
@@ -404,7 +404,9 @@ TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]")
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_LOW)); ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_LOW));
esp_deep_sleep_start(); esp_deep_sleep_start();
} }
#endif // SOC_PM_SUPPORT_EXT0_WAKEUP
#if SOC_PM_SUPPORT_EXT1_WAKEUP
TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ignore]") TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ignore]")
{ {
// This test needs external pulldown // This test needs external pulldown
@@ -440,7 +442,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][igno
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
esp_deep_sleep_start(); esp_deep_sleep_start();
} }
#endif // SOC_PM_SUPPORT_EXT_WAKEUP #endif // SOC_PM_SUPPORT_EXT1_WAKEUP
__attribute__((unused)) static float get_time_ms(void) __attribute__((unused)) static float get_time_ms(void)
{ {

View File

@@ -20,7 +20,8 @@
#include "soc/gpio_periph.h" #include "soc/gpio_periph.h"
#include "soc/gpio_struct.h" #include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_reg.h" #include "soc/lp_io_struct.h"
#include "soc/pmu_struct.h"
#include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_reg.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/clk_tree_defs.h" #include "soc/clk_tree_defs.h"
@@ -354,26 +355,6 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
} }
/**
* @brief Enable all digital gpio pads hold function during Deep-sleep.
*
* @param hw Peripheral GPIO hardware instance address.
*/
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_HIGH_HP_PAD_HOLD_ALL);
}
/**
* @brief Disable all digital gpio pads hold function during Deep-sleep.
*
* @param hw Peripheral GPIO hardware instance address.
*/
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_LOW_HP_PAD_HOLD_ALL);
}
/** /**
* @brief Enable gpio pad hold function. * @brief Enable gpio pad hold function.
* *
@@ -396,6 +377,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num]; LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num];
} }
/**
* @brief Get digital gpio pad hold status.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number, only support output GPIOs
*
* @note caller must ensure that gpio_num is a digital io pad
*
* @return
* - true digital gpio pad is held
* - false digital gpio pad is unheld
*/
__attribute__((always_inline))
static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
{
return !!(LP_AON.gpio_hold0.gpio_hold0 & GPIO_HOLD_MASK[gpio_num]);
}
/** /**
* @brief Set pad input to a peripheral signal through the IOMUX. * @brief Set pad input to a peripheral signal through the IOMUX.
* *
@@ -478,6 +477,26 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
} }
} }
/**
* @brief Force hold digital io pad.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
*/
static inline void gpio_ll_force_hold_all(void)
{
// WT flag, it gets self-cleared after the configuration is done
PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1;
}
/**
* @brief Force unhold digital io pad.
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
*/
static inline void gpio_ll_force_unhold_all(void)
{
// WT flag, it gets self-cleared after the configuration is done
PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1;
}
/** /**
* @brief Enable GPIO pin to use sleep mode pin functions during light sleep. * @brief Enable GPIO pin to use sleep mode pin functions during light sleep.
* *
@@ -589,63 +608,6 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
} }
/**
* @brief Enable GPIO deep-sleep wake-up function.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number.
* @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used.
*/
static inline void gpio_ll_deepsleep_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
LP_AON.ext_wakeup_cntl.ext_wakeup_filter = 1;
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
wakeup_sel_mask |= BIT(gpio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask);
bool trigger_level = (intr_type == GPIO_INTR_LOW_LEVEL) ? 0 : 1;
uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv);
if (trigger_level) {
wakeup_level_mask |= BIT(gpio_num);
} else {
wakeup_level_mask &= ~BIT(gpio_num);
}
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, wakeup_level_mask);
}
/**
* @brief Disable GPIO deep-sleep wake-up function.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
*/
static inline void gpio_ll_deepsleep_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
wakeup_sel_mask &= ~BIT(gpio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask);
}
/**
* @brief Get the status of whether an IO is used for deep-sleep wake-up.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
* @return True if the pin is enabled to wake up from deep-sleep
*/
static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
return wakeup_sel_mask & BIT(gpio_num);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "hal/lp_aon_ll.h"
#define rtc_hal_ext1_get_wakeup_status() lp_aon_hal_ext1_get_wakeup_status()
#define rtc_hal_ext1_clear_wakeup_status() lp_aon_hal_ext1_clear_wakeup_status()
#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_hal_ext1_set_wakeup_pins(mask, mode)
#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_hal_ext1_clear_wakeup_pins()
#define rtc_hal_ext1_get_wakeup_pins() lp_aon_hal_ext1_get_wakeup_pins()
#define lp_aon_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status()
#define lp_aon_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status()
#define lp_aon_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode)
#define lp_aon_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins()
#define lp_aon_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins()
#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp)

View File

@@ -0,0 +1,97 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for ESP32-C6 LP_AON register operations
#pragma once
#include <stdlib.h>
#include "soc/soc.h"
#include "soc/lp_aon_struct.h"
#include "hal/misc.h"
#include "esp32c6/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get ext1 wakeup source status
* @return The lower 8 bits of the returned value are the bitmap of
* the wakeup source status, bit 0~7 corresponds to LP_IO 0~7
*/
static inline uint32_t lp_aon_ll_ext1_get_wakeup_status(void)
{
return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status);
}
/**
* @brief Clear the ext1 wakeup source status
*/
static inline void lp_aon_ll_ext1_clear_wakeup_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status_clr, 1);
}
/**
* @brief Set the wake-up LP_IO of the ext1 wake-up source
* @param mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7
* @param mode 0: Wake the chip when all selected GPIOs go low
* 1: Wake the chip when any of the selected GPIOs go high
*/
static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t mask, int mode)
{
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
wakeup_sel_mask |= mask;
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask);
uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv);
if (mode) {
wakeup_level_mask |= mask;
} else {
wakeup_level_mask &= ~mask;
}
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, wakeup_level_mask);
}
/**
* @brief Clear all ext1 wakup-source setting
*/
static inline void lp_aon_ll_ext1_clear_wakeup_pins(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, 0);
}
/**
* @brief Get ext1 wakeup source setting
* @return The lower 8 bits of the returned value are the bitmap of
* the wakeup source status, bit 0~7 corresponds to LP_IO 0~7
*/
static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void)
{
return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel);
}
/**
* @brief ROM obtains the wake-up type through LP_AON_STORE9_REG[0].
* Set the flag to inform
* @param true: deepsleep false: lightsleep
*/
static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
{
if (dslp) {
REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */
} else {
REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
}
}
#ifdef __cplusplus
}
#endif

View File

@@ -13,12 +13,14 @@
#pragma once #pragma once
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include "soc/rtc_periph.h" #include "soc/rtc_periph.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/rtc_io_struct.h" #include "soc/rtc_io_struct.h"
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/assert.h"
#include "hal/gpio_types.h" #include "hal/gpio_types.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
@@ -28,8 +30,6 @@ extern "C" {
#define RTCIO_LL_PIN_FUNC 0 #define RTCIO_LL_PIN_FUNC 0
#define RTCIO_LL_PIN_MASK_ALL ((1 << SOC_RTCIO_PIN_COUNT) - 1)
typedef enum { typedef enum {
RTCIO_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ RTCIO_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
@@ -242,22 +242,6 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num)
LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num); LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num);
} }
/**
* @brief Enable all LP IO pads hold function during Deep-sleep
*/
static inline void rtcio_ll_deep_sleep_hold_en_all(void)
{
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
}
/**
* @brief Disable all LP IO pads hold function during Deep-sleep
*/
static inline void rtcio_ll_deep_sleep_hold_dis_all(void)
{
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
}
/** /**
* Enable force hold function for all RTC IO pads * Enable force hold function for all RTC IO pads
* *
@@ -268,8 +252,7 @@ static inline void rtcio_ll_deep_sleep_hold_dis_all(void)
*/ */
static inline void rtcio_ll_force_hold_all(void) static inline void rtcio_ll_force_hold_all(void)
{ {
// No such a 'hold_all' bit on C6, use bit hold instead PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
LP_AON.gpio_hold0.gpio_hold0 |= RTCIO_LL_PIN_MASK_ALL;
} }
/** /**
@@ -279,8 +262,7 @@ static inline void rtcio_ll_force_hold_all(void)
*/ */
static inline void rtcio_ll_force_unhold_all(void) static inline void rtcio_ll_force_unhold_all(void)
{ {
// No such a 'hold_all' bit on C6, use bit hold instead PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
LP_AON.gpio_hold0.gpio_hold0 &= ~RTCIO_LL_PIN_MASK_ALL;
} }
/** /**
@@ -366,6 +348,38 @@ static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num)
LP_IO.gpio[gpio_num].slp_sel = 0; LP_IO.gpio[gpio_num].slp_sel = 0;
} }
/**
* @brief Get the status of whether an IO is used for sleep wake-up.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
* @return True if the pin is enabled to wake up from deep-sleep
*/
static inline bool rtcio_ll_wakeup_is_enabled(gpio_num_t gpio_num)
{
HAL_ASSERT(gpio_num <= GPIO_NUM_7 && "gpio larger than 7 does not support deep sleep wake-up function");
// On ESP32-C6, (lp_io pin number) == (gpio pin number)
return LP_IO.pin[gpio_num].wakeup_enable;
}
/**
* @brief Get the rtc io interrupt status
*
* @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT.
*/
static inline uint32_t rtcio_ll_get_interrupt_status(void)
{
return (uint32_t)(LP_IO.status.status_interrupt);
}
/**
* @brief Clear all LP IO pads status
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_w1tc, 0xff);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -20,7 +20,7 @@
#include "soc/gpio_periph.h" #include "soc/gpio_periph.h"
#include "soc/gpio_struct.h" #include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_reg.h" #include "soc/pmu_struct.h"
#include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_reg.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/clk_tree_defs.h" #include "soc/clk_tree_defs.h"
@@ -398,26 +398,6 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, gpio_num_t gpio_
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
} }
/**
* @brief Enable all digital gpio pad hold function during Deep-sleep.
*
* @param hw Peripheral GPIO hardware instance address.
*/
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
{
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_HIGH_HP_PAD_HOLD_ALL);
}
/**
* @brief Disable all digital gpio pad hold function during Deep-sleep.
*
* @param hw Peripheral GPIO hardware instance address.
*/
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
{
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_LOW_HP_PAD_HOLD_ALL);
}
/** /**
* @brief Enable gpio pad hold function. * @brief Enable gpio pad hold function.
* *
@@ -522,6 +502,28 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
} }
} }
/**
* @brief Force hold all digital(VDDPST2) and lp(VDDPST1) io pads.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
*/
static inline void gpio_ll_force_hold_all(void)
{
// WT flags, they get self-cleared after the configuration is done
PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1;
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
}
/**
* @brief Force unhold all digital(VDDPST2) and lp(VDDPST1) io pads.
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
*/
static inline void gpio_ll_force_unhold_all(void)
{
// WT flags, they get self-cleared after the configuration is done
PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1;
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
}
/** /**
* @brief Enable GPIO pin to use sleep mode pin functions during light sleep. * @brief Enable GPIO pin to use sleep mode pin functions during light sleep.
* *

View File

@@ -270,6 +270,22 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
hw->pin[gpio_num].pin_pad_driver = 1; hw->pin[gpio_num].pin_pad_driver = 1;
} }
/**
* @brief Select a function for the pin in the IOMUX
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
* @param func Function to assign to the pin
*/
static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
{
// Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function
if (gpio_num == USB_DM_GPIO_NUM || gpio_num == USB_DP_GPIO_NUM) {
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
}
PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
}
/** /**
* @brief GPIO set output level * @brief GPIO set output level
* *
@@ -383,6 +399,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD); SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
} }
/**
* @brief Get deep sleep hold status
*
* @param hw Peripheral GPIO hardware instance address.
*
* @return
* - true deep sleep hold is enabled
* - false deep sleep hold is disabled
*/
__attribute__((always_inline))
static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
{
return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
}
/** /**
* @brief Enable gpio pad hold function. * @brief Enable gpio pad hold function.
* *
@@ -417,6 +448,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
} }
} }
/**
* @brief Get digital gpio pad hold status.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number, only support output GPIOs
*
* @note caller must ensure that gpio_num is a digital io pad
*
* @return
* - true digital gpio pad is held
* - false digital gpio pad is unheld
*/
__attribute__((always_inline))
static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
{
return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num));
}
/** /**
* @brief Set pad input to a peripheral signal through the IOMUX. * @brief Set pad input to a peripheral signal through the IOMUX.
* *

View File

@@ -242,8 +242,8 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
* in output mode: the output level of the pad will be force locked and can not be changed. * in output mode: the output level of the pad will be force locked and can not be changed.
* in input mode: the input value read will not change, regardless the changes of input signal. * in input mode: the input value read will not change, regardless the changes of input signal.
* *
* The state of digital gpio cannot be held during Deep-sleep, and it will resume the hold function * On ESP32/S2/C3/S3/C2, the state of digital gpio cannot be held during Deep-sleep, and it will resume the hold
* when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep, * function when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep,
* `gpio_deep_sleep_hold_en` should also be called. * `gpio_deep_sleep_hold_en` should also be called.
* *
* Power down or call gpio_hold_dis will disable this function. * Power down or call gpio_hold_dis will disable this function.
@@ -285,6 +285,7 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
*/ */
#define gpio_hal_is_digital_io_hold(hal, gpio_num) gpio_ll_is_digital_io_hold((hal)->dev, gpio_num) #define gpio_hal_is_digital_io_hold(hal, gpio_num) gpio_ll_is_digital_io_hold((hal)->dev, gpio_num)
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/** /**
* @brief Enable all digital gpio pad hold function during Deep-sleep. * @brief Enable all digital gpio pad hold function during Deep-sleep.
* *
@@ -315,6 +316,7 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
* - false deep sleep hold is disabled * - false deep sleep hold is disabled
*/ */
#define gpio_hal_deep_sleep_hold_is_en(hal) gpio_ll_deep_sleep_hold_is_en((hal)->dev) #define gpio_hal_deep_sleep_hold_is_en(hal) gpio_ll_deep_sleep_hold_is_en((hal)->dev)
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/** /**
* @brief Set pad input to a peripheral signal through the IOMUX. * @brief Set pad input to a peripheral signal through the IOMUX.
@@ -448,7 +450,7 @@ void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, uint32_t gpio_num
void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, uint32_t gpio_num); void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, uint32_t gpio_num);
#endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL #endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0)
/** /**
* @brief Enable GPIO deep-sleep wake-up function. * @brief Enable GPIO deep-sleep wake-up function.
* *

View File

@@ -39,7 +39,7 @@ typedef struct rtc_cntl_sleep_retent {
#define RTC_HAL_DMA_LINK_NODE_SIZE (16) #define RTC_HAL_DMA_LINK_NODE_SIZE (16)
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT1_WAKEUP
#define rtc_hal_ext1_get_wakeup_status() rtc_cntl_ll_ext1_get_wakeup_status() #define rtc_hal_ext1_get_wakeup_status() rtc_cntl_ll_ext1_get_wakeup_status()
@@ -51,9 +51,9 @@ typedef struct rtc_cntl_sleep_retent {
#define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins() #define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins()
#endif #endif // SOC_PM_SUPPORT_EXT1_WAKEUP
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0)
#define rtc_hal_gpio_get_wakeup_status() rtc_cntl_ll_gpio_get_wakeup_status() #define rtc_hal_gpio_get_wakeup_status() rtc_cntl_ll_gpio_get_wakeup_status()

View File

@@ -254,6 +254,36 @@ void rtcio_hal_isolate(int rtc_num);
#endif #endif
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT > 0)
#define gpio_hal_deepsleep_wakeup_enable(hal, gpio_num, intr_type) rtcio_hal_wakeup_enable(gpio_num, intr_type)
#define gpio_hal_deepsleep_wakeup_disable(hal, gpio_num) rtcio_hal_wakeup_disable(gpio_num)
#define gpio_hal_deepsleep_wakeup_is_enabled(hal, gpio_num) rtcio_hal_wakeup_is_enabled(gpio_num)
#define rtc_hal_gpio_get_wakeup_status() rtcio_hal_get_interrupt_status()
#define rtc_hal_gpio_clear_wakeup_status() rtcio_hal_clear_interrupt_status()
/**
* @brief Get the status of whether an IO is used for sleep wake-up.
*
* @param hw Peripheral GPIO hardware instance address.
* @param rtcio_num GPIO number
* @return True if the pin is enabled to wake up from deep-sleep
*/
#define rtcio_hal_wakeup_is_enabled(rtcio_num) rtcio_ll_wakeup_is_enabled(rtcio_num)
/**
* @brief Get the rtc io interrupt status
*
* @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT.
*/
#define rtcio_hal_get_interrupt_status() rtcio_ll_get_interrupt_status()
/**
* @brief Clear all LP IO pads status
*/
#define rtcio_hal_clear_interrupt_status() rtcio_ll_clear_interrupt_status()
#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -719,6 +719,14 @@ config SOC_PHY_DIG_REGS_MEM_SIZE
int int
default 21 default 21
config SOC_PM_SUPPORT_EXT0_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT1_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT_WAKEUP config SOC_PM_SUPPORT_EXT_WAKEUP
bool bool
default y default y

View File

@@ -365,7 +365,10 @@
#define SOC_PHY_DIG_REGS_MEM_SIZE (21*4) #define SOC_PHY_DIG_REGS_MEM_SIZE (21*4)
/*-------------------------- Power Management CAPS ---------------------------*/ /*-------------------------- Power Management CAPS ---------------------------*/
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) #define SOC_PM_SUPPORT_EXT0_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) /*!<Compatible to the old version of IDF */
#define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP (1) /*!<Supports waking up from touch pad trigger */ #define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP (1) /*!<Supports waking up from touch pad trigger */
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) #define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)
#define SOC_PM_SUPPORT_RTC_FAST_MEM_PD (1) #define SOC_PM_SUPPORT_RTC_FAST_MEM_PD (1)

View File

@@ -171,6 +171,10 @@ config SOC_LP_TIMER_SUPPORTED
bool bool
default y default y
config SOC_LP_AON_SUPPORTED
bool
default y
config SOC_XTAL_SUPPORT_40M config SOC_XTAL_SUPPORT_40M
bool bool
default y default y
@@ -403,6 +407,14 @@ config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
hex hex
default 0x000000007FFFFF00 default 0x000000007FFFFF00
config SOC_GPIO_SUPPORT_FORCE_HOLD
bool
default y
config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
bool
default y
config SOC_RTCIO_PIN_COUNT config SOC_RTCIO_PIN_COUNT
int int
default 8 default 8
@@ -415,6 +427,10 @@ config SOC_RTCIO_HOLD_SUPPORTED
bool bool
default y default y
config SOC_RTCIO_WAKE_SUPPORTED
bool
default y
config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM
int int
default 8 default 8
@@ -1035,6 +1051,10 @@ config SOC_PM_SUPPORT_BT_WAKEUP
bool bool
default y default y
config SOC_PM_SUPPORT_EXT1_WAKEUP
bool
default y
config SOC_PM_SUPPORT_CPU_PD config SOC_PM_SUPPORT_CPU_PD
bool bool
default y default y

View File

@@ -68,6 +68,7 @@
#define SOC_PMU_SUPPORTED 1 #define SOC_PMU_SUPPORTED 1
#define SOC_PAU_SUPPORTED 1 #define SOC_PAU_SUPPORTED 1
#define SOC_LP_TIMER_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1
#define SOC_LP_AON_SUPPORTED 1
/*-------------------------- XTAL CAPS ---------------------------------------*/ /*-------------------------- XTAL CAPS ---------------------------------------*/
#define SOC_XTAL_SUPPORT_40M 1 #define SOC_XTAL_SUPPORT_40M 1
@@ -186,11 +187,16 @@
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_8~GPIO_NUM_30) // digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_8~GPIO_NUM_30)
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000007FFFFF00ULL #define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000007FFFFF00ULL
// Support to force hold all IOs
#define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
// Support to hold a single digital I/O when the digital domain is powered off
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
/*-------------------------- RTCIO CAPS --------------------------------------*/ /*-------------------------- RTCIO CAPS --------------------------------------*/
#define SOC_RTCIO_PIN_COUNT 8 #define SOC_RTCIO_PIN_COUNT 8
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 #define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1
#define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_HOLD_SUPPORTED 1
// #define SOC_RTCIO_WAKE_SUPPORTED 1 // TODO: IDF-5645 #define SOC_RTCIO_WAKE_SUPPORTED 1
/*-------------------------- Dedicated GPIO CAPS -----------------------------*/ /*-------------------------- Dedicated GPIO CAPS -----------------------------*/
#define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */ #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */
@@ -439,6 +445,7 @@
/*-------------------------- Power Management CAPS ----------------------------*/ /*-------------------------- Power Management CAPS ----------------------------*/
#define SOC_PM_SUPPORT_WIFI_WAKEUP (1) #define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
#define SOC_PM_SUPPORT_BT_WAKEUP (1) #define SOC_PM_SUPPORT_BT_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
#define SOC_PM_SUPPORT_CPU_PD (1) #define SOC_PM_SUPPORT_CPU_PD (1)
#define SOC_PM_SUPPORT_MODEM_PD (1) #define SOC_PM_SUPPORT_MODEM_PD (1)
#define SOC_PM_SUPPORT_XTAL32K_PD (1) #define SOC_PM_SUPPORT_XTAL32K_PD (1)

View File

@@ -379,6 +379,14 @@ config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
hex hex
default 0x000000000FFF807F default 0x000000000FFF807F
config SOC_GPIO_SUPPORT_FORCE_HOLD
bool
default y
config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
bool
default y
config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM
int int
default 8 default 8

View File

@@ -184,6 +184,11 @@
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~6. GPIO_NUM_15~27) // digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~6. GPIO_NUM_15~27)
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000000FFF807FULL #define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000000FFF807FULL
// Support to force hold all IOs
#define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
// Support to hold a single digital I/O when the digital domain is powered off
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
/*-------------------------- Dedicated GPIO CAPS -----------------------------*/ /*-------------------------- Dedicated GPIO CAPS -----------------------------*/
#define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */ #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */
#define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */ #define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */

View File

@@ -319,6 +319,10 @@ config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
hex hex
default 0x000001FFFFFFFFC0 default 0x000001FFFFFFFFC0
config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
bool
default y
config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM
int int
default 8 default 8

View File

@@ -172,6 +172,12 @@
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x0000000003FFE07FULL #define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x0000000003FFE07FULL
#endif #endif
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
// Support to hold a single GPIO when the digital domain is powered off
// ESP32H4-BETA1 only supports hold all in deepsleep
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
#endif
/*-------------------------- Dedicated GPIO CAPS -----------------------------*/ /*-------------------------- Dedicated GPIO CAPS -----------------------------*/
#define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */ #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */
#define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */ #define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */

View File

@@ -951,6 +951,14 @@ config SOC_SPI_MEM_SUPPORT_WRAP
bool bool
default y default y
config SOC_PM_SUPPORT_EXT0_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT1_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT_WAKEUP config SOC_PM_SUPPORT_EXT_WAKEUP
bool bool
default y default y

View File

@@ -414,7 +414,10 @@
#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_SPI_MEM_SUPPORT_WRAP (1)
/*-------------------------- Power Management CAPS ---------------------------*/ /*-------------------------- Power Management CAPS ---------------------------*/
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) #define SOC_PM_SUPPORT_EXT0_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) /*!<Compatible to the old version of IDF */
#define SOC_PM_SUPPORT_WIFI_WAKEUP (1) #define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
#define SOC_PM_SUPPORT_WIFI_PD (1) #define SOC_PM_SUPPORT_WIFI_PD (1)
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) #define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)

View File

@@ -983,6 +983,14 @@ config SOC_AES_SUPPORT_AES_256
bool bool
default y default y
config SOC_PM_SUPPORT_EXT0_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT1_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT_WAKEUP config SOC_PM_SUPPORT_EXT_WAKEUP
bool bool
default y default y

View File

@@ -404,7 +404,10 @@
/*-------------------------- Power Management CAPS ---------------------------*/ /*-------------------------- Power Management CAPS ---------------------------*/
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) #define SOC_PM_SUPPORT_EXT0_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) /*!<Compatible to the old version of IDF */
#define SOC_PM_SUPPORT_WIFI_WAKEUP (1) #define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
#define SOC_PM_SUPPORT_BT_WAKEUP (1) #define SOC_PM_SUPPORT_BT_WAKEUP (1)
#define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP (1) /*!<Supports waking up from touch pad trigger */ #define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP (1) /*!<Supports waking up from touch pad trigger */

View File

@@ -36,7 +36,6 @@ api-reference/network/esp-wifi-mesh
api-reference/network/esp_smartconfig api-reference/network/esp_smartconfig
api-reference/network/esp_wifi api-reference/network/esp_wifi
api-reference/network/index api-reference/network/index
api-reference/system/sleep_modes
api-reference/system/ulp_macros api-reference/system/ulp_macros
api-reference/system/ulp api-reference/system/ulp
api-reference/system/efuse api-reference/system/efuse

View File

@@ -42,7 +42,7 @@ Dynamic frequency scaling (DFS) and automatic light sleep can be enabled in an a
In light sleep, peripherals are clock gated, and interrupts (from GPIOs and internal peripherals) will not be generated. A wakeup source described in the :doc:`sleep_modes` documentation can be used to trigger wakeup from the light sleep state. In light sleep, peripherals are clock gated, and interrupts (from GPIOs and internal peripherals) will not be generated. A wakeup source described in the :doc:`sleep_modes` documentation can be used to trigger wakeup from the light sleep state.
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP
For example, the EXT0 and EXT1 wakeup sources can be used to wake up the chip via a GPIO. For example, the EXT0 and EXT1 wakeup sources can be used to wake up the chip via a GPIO.

View File

@@ -71,7 +71,7 @@ RTC peripherals or RTC memories don't need to be powered on during sleep in this
:cpp:func:`esp_sleep_enable_touchpad_wakeup` function can be used to enable this wakeup source. :cpp:func:`esp_sleep_enable_touchpad_wakeup` function can be used to enable this wakeup source.
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP
External Wakeup (ext0) External Wakeup (ext0)
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
@@ -127,11 +127,11 @@ RTC peripherals or RTC memories don't need to be powered on during sleep in this
GPIO Wakeup (Light-sleep Only) GPIO Wakeup (Light-sleep Only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: (SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP)
In addition to EXT0 and EXT1 wakeup sources described above, one more method of wakeup from external inputs is available in Light-sleep mode. With this wakeup source, each pin can be individually configured to trigger wakeup on high or low level using :cpp:func:`gpio_wakeup_enable` function. Unlike EXT0 and EXT1 wakeup sources, which can only be used with RTC IOs, this wakeup source can be used with any IO (RTC or digital). In addition to EXT0 and EXT1 wakeup sources described above, one more method of wakeup from external inputs is available in Light-sleep mode. With this wakeup source, each pin can be individually configured to trigger wakeup on high or low level using :cpp:func:`gpio_wakeup_enable` function. Unlike EXT0 and EXT1 wakeup sources, which can only be used with RTC IOs, this wakeup source can be used with any IO (RTC or digital).
.. only:: not SOC_PM_SUPPORT_EXT_WAKEUP .. only:: not (SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP)
One more method of wakeup from external inputs is available in Light-sleep mode. With this wakeup source, each pin can be individually configured to trigger wakeup on high or low level using :cpp:func:`gpio_wakeup_enable` function. This wakeup source can be used with any IO (RTC or digital). One more method of wakeup from external inputs is available in Light-sleep mode. With this wakeup source, each pin can be individually configured to trigger wakeup on high or low level using :cpp:func:`gpio_wakeup_enable` function. This wakeup source can be used with any IO (RTC or digital).
@@ -257,7 +257,7 @@ Checking Sleep Wakeup Cause
For touchpad, it is possible to identify which touch pin has caused wakeup using :cpp:func:`esp_sleep_get_touchpad_wakeup_status` functions. For touchpad, it is possible to identify which touch pin has caused wakeup using :cpp:func:`esp_sleep_get_touchpad_wakeup_status` functions.
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT1_WAKEUP
For ext1 wakeup sources, it is possible to identify which touch pin has caused wakeup using :cpp:func:`esp_sleep_get_ext1_wakeup_status` functions. For ext1 wakeup sources, it is possible to identify which touch pin has caused wakeup using :cpp:func:`esp_sleep_get_ext1_wakeup_status` functions.

View File

@@ -42,7 +42,7 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
Light-sleep 状态下,外设设有时钟门控,不会产生来自 GPIO 和内部外设的中断。:doc:`sleep_modes` 文档中所提到的唤醒源可用于从 Light-sleep 状态触发唤醒。 Light-sleep 状态下,外设设有时钟门控,不会产生来自 GPIO 和内部外设的中断。:doc:`sleep_modes` 文档中所提到的唤醒源可用于从 Light-sleep 状态触发唤醒。
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP
例如EXT0 和 EXT1 唤醒源可以通过 GPIO 唤醒芯片。 例如EXT0 和 EXT1 唤醒源可以通过 GPIO 唤醒芯片。

View File

@@ -71,7 +71,7 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒
可调用 :cpp:func:`esp_sleep_enable_touchpad_wakeup` 函数来启用该唤醒源。 可调用 :cpp:func:`esp_sleep_enable_touchpad_wakeup` 函数来启用该唤醒源。
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP
外部唤醒 (ext0) 外部唤醒 (ext0)
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
@@ -127,11 +127,11 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒
GPIO 唤醒(仅适用于 Light-sleep 模式) GPIO 唤醒(仅适用于 Light-sleep 模式)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP
除了上述 EXT0 和 EXT1 唤醒源之外,还有一种从外部唤醒 Light-sleep 模式的方法——使用函数 :cpp:func:`gpio_wakeup_enable`。启用该唤醒源后可将每个管脚单独配置为在高电平或低电平时唤醒。EXT0 和 EXT1 唤醒源只能用于 RTC IO但此唤醒源既可以用于 RTC IO可也用于数字 IO。 除了上述 EXT0 和 EXT1 唤醒源之外,还有一种从外部唤醒 Light-sleep 模式的方法——使用函数 :cpp:func:`gpio_wakeup_enable`。启用该唤醒源后可将每个管脚单独配置为在高电平或低电平时唤醒。EXT0 和 EXT1 唤醒源只能用于 RTC IO但此唤醒源既可以用于 RTC IO可也用于数字 IO。
.. only:: not SOC_PM_SUPPORT_EXT_WAKEUP .. only:: not (SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP)
此外,还有一种从外部唤醒 Light-sleep 模式的方法。启用该唤醒源后,可将每个管脚单独配置为在高电平或低电平时调用 :cpp:func:`gpio_wakeup_enable` 函数触发唤醒。此唤醒源既可以用于 RTC IO可也用于数字 IO。 此外,还有一种从外部唤醒 Light-sleep 模式的方法。启用该唤醒源后,可将每个管脚单独配置为在高电平或低电平时调用 :cpp:func:`gpio_wakeup_enable` 函数触发唤醒。此唤醒源既可以用于 RTC IO可也用于数字 IO。
@@ -257,7 +257,7 @@ UART 输出处理
对于触摸传感器唤醒源,可以调用函数 :cpp:func:`esp_sleep_get_touchpad_wakeup_status` 来确认触发唤醒的触摸管脚。 对于触摸传感器唤醒源,可以调用函数 :cpp:func:`esp_sleep_get_touchpad_wakeup_status` 来确认触发唤醒的触摸管脚。
.. only:: SOC_PM_SUPPORT_EXT_WAKEUP .. only:: SOC_PM_SUPPORT_EXT1_WAKEUP
对于 ext1 唤醒源,可以调用函数 :cpp:func:`esp_sleep_get_ext1_wakeup_status` 来确认触发唤醒的触摸管脚。 对于 ext1 唤醒源,可以调用函数 :cpp:func:`esp_sleep_get_ext1_wakeup_status` 来确认触发唤醒的触摸管脚。

View File

@@ -216,7 +216,7 @@ static int deep_sleep(int argc, char **argv)
ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level", ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level",
io_num, level ? "HIGH" : "LOW"); io_num, level ? "HIGH" : "LOW");
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT1_WAKEUP
ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) ); ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
#endif #endif
} }

View File

@@ -40,13 +40,13 @@ examples/system/console/basic:
examples/system/deep_sleep: examples/system/deep_sleep:
disable: disable:
- if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"] - if: IDF_TARGET in ["esp32c2", "esp32h2"]
temporary: true temporary: true
reason: target(s) not supported yet reason: target(s) not supported yet # IDF-5432 / IDF-6268
examples/system/deep_sleep_wake_stub: examples/system/deep_sleep_wake_stub:
disable: disable:
- if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"] - if: IDF_TARGET in ["esp32c2", "esp32h2"]
temporary: true temporary: true
reason: target(s) is not supported yet reason: target(s) is not supported yet

View File

@@ -224,7 +224,7 @@ static void register_tasks(void)
static struct { static struct {
struct arg_int *wakeup_time; struct arg_int *wakeup_time;
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
struct arg_int *wakeup_gpio_num; struct arg_int *wakeup_gpio_num;
struct arg_int *wakeup_gpio_level; struct arg_int *wakeup_gpio_level;
#endif #endif
@@ -245,7 +245,7 @@ static int deep_sleep(int argc, char **argv)
ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) ); ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
} }
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT1_WAKEUP
if (deep_sleep_args.wakeup_gpio_num->count) { if (deep_sleep_args.wakeup_gpio_num->count) {
int io_num = deep_sleep_args.wakeup_gpio_num->ival[0]; int io_num = deep_sleep_args.wakeup_gpio_num->ival[0];
if (!esp_sleep_is_valid_wakeup_gpio(io_num)) { if (!esp_sleep_is_valid_wakeup_gpio(io_num)) {
@@ -266,7 +266,7 @@ static int deep_sleep(int argc, char **argv)
ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) ); ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
ESP_LOGE(TAG, "GPIO wakeup from deep sleep currently unsupported on ESP32-C3"); ESP_LOGE(TAG, "GPIO wakeup from deep sleep currently unsupported on ESP32-C3");
} }
#endif // SOC_PM_SUPPORT_EXT_WAKEUP #endif // SOC_PM_SUPPORT_EXT1_WAKEUP
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
rtc_gpio_isolate(GPIO_NUM_12); rtc_gpio_isolate(GPIO_NUM_12);
@@ -280,7 +280,7 @@ static void register_deep_sleep(void)
int num_args = 1; int num_args = 1;
deep_sleep_args.wakeup_time = deep_sleep_args.wakeup_time =
arg_int0("t", "time", "<t>", "Wake up time, ms"); arg_int0("t", "time", "<t>", "Wake up time, ms");
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
deep_sleep_args.wakeup_gpio_num = deep_sleep_args.wakeup_gpio_num =
arg_int0(NULL, "io", "<n>", arg_int0(NULL, "io", "<n>",
"If specified, wakeup using GPIO with given number"); "If specified, wakeup using GPIO with given number");
@@ -293,7 +293,7 @@ static void register_deep_sleep(void)
const esp_console_cmd_t cmd = { const esp_console_cmd_t cmd = {
.command = "deep_sleep", .command = "deep_sleep",
.help = "Enter deep sleep mode. " .help = "Enter deep sleep mode. "
#if SOC_PM_SUPPORT_EXT_WAKEUP #if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
"Two wakeup modes are supported: timer and GPIO. " "Two wakeup modes are supported: timer and GPIO. "
#else #else
"Timer wakeup mode is supported. " "Timer wakeup mode is supported. "

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- |
# Deep Sleep Example # Deep Sleep Example
@@ -11,7 +11,7 @@ The following wake up sources are demonstrated in this example (refer to the [Wa
- **Timer:** An RTC timer that can be programmed to trigger a wake up after a preset time. This example will trigger a wake up every 20 seconds. - **Timer:** An RTC timer that can be programmed to trigger a wake up after a preset time. This example will trigger a wake up every 20 seconds.
- **EXT0:** External wake up 0 can trigger wakeup when one predefined RTC GPIO is at a predefined logic level. This example uses GPIO25 in ESP32 or GPIO3 in ESP32-S2/S3 to trigger a wake up when the pin is HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.) - **EXT0:** External wake up 0 can trigger wakeup when one predefined RTC GPIO is at a predefined logic level. This example uses GPIO25 in ESP32 or GPIO3 in ESP32-S2/S3 to trigger a wake up when the pin is HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.)
- **EXT1:** External wake up 1 which is tied to multiple RTC GPIOs. This example uses GPIO2 and GPIO4 to trigger a wake up with any one of the two pins are HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.) - **EXT1:** External wake up 1 which is tied to multiple RTC GPIOs. This example uses GPIO2 and GPIO4 to trigger a wake up with any one of the two pins are HIGH. (This wake up source is available on ESP32, ESP32-S2, ESP32-S3 and ESP32-C6.)
- **GPIO:** Pads powered by VDD3P3_RTC can be used to trigger a wake up from deep sleep. You may choose the pin and trigger level in menuconfig. (This wake up source is unavailable on ESP32, ESP32-S2, and ESP32-S3.) - **GPIO:** Pads powered by VDD3P3_RTC can be used to trigger a wake up from deep sleep. You may choose the pin and trigger level in menuconfig. (This wake up source is unavailable on ESP32, ESP32-S2, and ESP32-S3.)
- **Touch:** Touch pad sensor interrupt. This example uses touch pads connected to GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2/S3 to trigger a wake up when any of the pads are pressed. - **Touch:** Touch pad sensor interrupt. This example uses touch pads connected to GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2/S3 to trigger a wake up when any of the pads are pressed.
- **ULP:** Ultra Low Power Coprocessor which can continue to run during deep sleep. This example utilizes the ULP and constantly sample the chip's temperature and trigger a wake up if the chips temperature exceeds ~5 degrees Celsius. - **ULP:** Ultra Low Power Coprocessor which can continue to run during deep sleep. This example utilizes the ULP and constantly sample the chip's temperature and trigger a wake up if the chips temperature exceeds ~5 degrees Celsius.

View File

@@ -15,7 +15,7 @@ menu "Example Configuration"
bool "Enable wakeup from GPIO (ext0)" bool "Enable wakeup from GPIO (ext0)"
default y if !IDF_TARGET_ESP32 default y if !IDF_TARGET_ESP32
default n if IDF_TARGET_ESP32 default n if IDF_TARGET_ESP32
depends on SOC_PM_SUPPORT_EXT_WAKEUP depends on SOC_PM_SUPPORT_EXT0_WAKEUP
help help
This option enables wake up from deep sleep from GPIO25(ESP32)/GPIO3(ESP32S2,S3). The pin should be This option enables wake up from deep sleep from GPIO25(ESP32)/GPIO3(ESP32S2,S3). The pin should be
connected to LOW to avoid being in a floating state. When triggering a wake up, connect the pin to HIGH. connected to LOW to avoid being in a floating state. When triggering a wake up, connect the pin to HIGH.
@@ -26,7 +26,7 @@ menu "Example Configuration"
config EXAMPLE_EXT1_WAKEUP config EXAMPLE_EXT1_WAKEUP
bool "Enable wakeup from GPIO (ext1)" bool "Enable wakeup from GPIO (ext1)"
default y default y
depends on SOC_PM_SUPPORT_EXT_WAKEUP depends on SOC_PM_SUPPORT_EXT1_WAKEUP
help help
This option enables wake up from deep sleep from GPIO2 and GPIO4. They should be connected to LOW to avoid This option enables wake up from deep sleep from GPIO2 and GPIO4. They should be connected to LOW to avoid
floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating
@@ -62,6 +62,7 @@ menu "Example Configuration"
int "Enable wakeup from GPIO" int "Enable wakeup from GPIO"
default 0 if !IDF_TARGET_ESP32H4_BETA_VERSION_2 default 0 if !IDF_TARGET_ESP32H4_BETA_VERSION_2
default 7 if IDF_TARGET_ESP32H4_BETA_VERSION_2 default 7 if IDF_TARGET_ESP32H4_BETA_VERSION_2
range 0 7 if IDF_TARGET_ESP32C6
range 0 5 if !IDF_TARGET_ESP32H4_BETA_VERSION_2 range 0 5 if !IDF_TARGET_ESP32H4_BETA_VERSION_2
range 7 12 if IDF_TARGET_ESP32H4_BETA_VERSION_2 range 7 12 if IDF_TARGET_ESP32H4_BETA_VERSION_2

View File

@@ -133,7 +133,9 @@ void app_main(void)
* during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will * during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will
* increase some power comsumption. */ * increase some power comsumption. */
# if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS # if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
#endif
ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_1)); ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_1));
ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_1)); ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_1));
ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_2)); ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_2));

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
import logging import logging
@@ -12,7 +12,7 @@ touch_wake_up_support = ['esp32', 'esp32s2']
CONFIGS = [ CONFIGS = [
pytest.param('esp32_singlecore', marks=[pytest.mark.esp32]), pytest.param('esp32_singlecore', marks=[pytest.mark.esp32]),
pytest.param('basic', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3]), pytest.param('basic', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3, pytest.mark.esp32c6]),
] ]

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | | ----------------- | ----- | -------- | -------- | -------- | -------- |
# Deep Sleep Wake Stub Example # Deep Sleep Wake Stub Example

View File

@@ -43,7 +43,6 @@ void app_main(void)
rtc_gpio_isolate(GPIO_NUM_12); rtc_gpio_isolate(GPIO_NUM_12);
#endif #endif
// Set the wake stub function
esp_set_deep_sleep_wake_stub(&wake_stub_example); esp_set_deep_sleep_wake_stub(&wake_stub_example);
printf("Entering deep sleep\n"); printf("Entering deep sleep\n");

View File

@@ -12,6 +12,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32c3 @pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.generic @pytest.mark.generic
@pytest.mark.parametrize('config', ['default',], indirect=True) @pytest.mark.parametrize('config', ['default',], indirect=True)
def test_deep_sleep_wake_stub(config: str, dut: Dut) -> None: def test_deep_sleep_wake_stub(config: str, dut: Dut) -> None: