Merge branch 'bringup/esp32h2_deep_sleep_for_rebase' into 'master'

esp32h2: support deep_sleep

Closes IDF-6268, IDF-6572, and IDF-7406

See merge request espressif/esp-idf!24438
This commit is contained in:
Lou Tian Hao 2023-07-24 10:47:51 +08:00
commit 57c6c0a1a3
20 changed files with 416 additions and 93 deletions

View File

@ -122,12 +122,6 @@ if(NOT BOOTLOADER_BUILD)
if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED)
list(APPEND srcs "sleep_wake_stub.c")
endif()
if(CONFIG_IDF_TARGET_ESP32H2)
list(REMOVE_ITEM srcs
"sleep_wake_stub.c" # TODO: IDF-6268
)
endif()
else()
# Requires "_esp_error_check_failed()" function
list(APPEND priv_requires "esp_system")

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -26,10 +26,21 @@ typedef void (*esp_deep_sleep_cb_t)(void);
/**
* @brief Logic function used for EXT1 wakeup mode.
*/
#if SOC_PM_SUPPORT_EXT1_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
typedef enum {
ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low
ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high
} esp_sleep_ext1_wakeup_mode_t;
#else
typedef enum {
ESP_EXT1_WAKEUP_ANY_LOW = 0, //!< Wake the chip when any of the selected GPIOs go low
ESP_EXT1_WAKEUP_ANY_HIGH = 1, //!< Wake the chip when any of the selected GPIOs go high
ESP_EXT1_WAKEUP_ALL_LOW __attribute__((deprecated("wakeup mode \"ALL_LOW\" is no longer supported after ESP32, \
please use ESP_EXT1_WAKEUP_ANY_LOW instead"))) = ESP_EXT1_WAKEUP_ANY_LOW
} esp_sleep_ext1_wakeup_mode_t;
#endif
#endif
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
typedef enum {

View File

@ -14,6 +14,7 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/pmu_struct.h"
#include "hal/lp_aon_hal.h"
#include "esp_private/esp_pmu.h"
#define HP(state) (PMU_MODE_HP_ ## state)
@ -218,6 +219,8 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
{
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_reject_enable(PMU_instance()->hal->dev, reject_opt);

View File

@ -337,34 +337,33 @@ typedef struct {
.pd_cur = 1, \
.bias_sleep = 1, \
.xpd = 0, \
.dbias = 0x15, \
.slp_mem_xpd = 1, \
.slp_mem_dbias = 0xc, \
.slp_logic_xpd = 1, \
.slp_logic_dbias = 0x5, \
.drv_b = 0x18c \
.dbias = 0, \
.slp_mem_xpd = 0, \
.slp_mem_dbias = 0, \
.slp_logic_xpd = 0, \
.slp_logic_dbias = 0, \
.drv_b = 0xFFFFFF \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.analog = { \
.xpd = 1, \
.dbias = 0x1a, \
.dbias = 0xe, \
.slp_xpd = 0, \
.slp_dbias = 0, \
.drv_b = 0x7 \
.drv_b = 0 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.xpd_bias = 0, \
.dbg_atten = 0xe, \
.pd_cur = 1, \
.bias_sleep = 1, \
.xpd = 0, \
.dbias = 0, \
.slp_xpd = 1, \
.slp_dbias = 0xe, \
.drv_b = 0 \
.slp_dbias = 5, \
.drv_b = 7 \
} \
} \
}

View File

@ -20,14 +20,13 @@
#include "driver/gpio.h"
#include "hal/gpio_hal.h"
#include "hal/rtc_io_hal.h"
#include "soc/rtc_io_periph.h"
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#if !CONFIG_IDF_TARGET_ESP32H2
#include "hal/rtc_hal.h"
#endif
#endif
#include "esp_private/gpio.h"
#include "esp_private/sleep_gpio.h"

View File

@ -32,11 +32,9 @@
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#if !CONFIG_IDF_TARGET_ESP32H2
#include "hal/rtc_cntl_ll.h"
#include "hal/rtc_hal.h"
#endif
#endif
#include "driver/uart.h"
@ -90,6 +88,7 @@
#include "esp32h2/rom/cache.h"
#include "esp32h2/rom/rtc.h"
#include "soc/extmem_reg.h"
#include "hal/gpio_ll.h"
#endif
#if SOC_LP_TIMER_SUPPORTED
@ -260,7 +259,6 @@ static void touch_wakeup_prepare(void);
static void gpio_deep_sleep_wakeup_prepare(void);
#endif
#if !CONFIG_IDF_TARGET_ESP32H2
#if SOC_RTC_FAST_MEM_SUPPORTED
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL;
@ -366,7 +364,6 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
#endif // SOC_RTC_FAST_MEM_SUPPORTED
#endif // !CONFIG_IDF_TARGET_ESP32H2
void esp_deep_sleep(uint64_t time_in_us)
{
@ -641,7 +638,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
}
#endif
misc_modules_sleep_prepare(deep_sleep);
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
@ -681,7 +677,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
if (periph_using_8m) {
sleep_flags |= RTC_SLEEP_DIG_USE_8M;
}
// Enter sleep
esp_err_t result;
#if SOC_PMU_SUPPORTED
@ -721,7 +716,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
esp_sleep_isolate_digital_gpio();
#endif
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
esp_set_deep_sleep_wake_stub_default_entry();
// Enter Deep Sleep
@ -742,9 +736,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
#endif
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
#else // !CONFIG_IDF_TARGET_ESP32H2
result = ESP_OK;
#endif // !CONFIG_IDF_TARGET_ESP32H2
} else {
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
In order to avoid the leakage of the SPI cs pin, hold it here */
@ -1425,20 +1416,23 @@ static void ext1_wakeup_prepare(void)
rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC);
// set input enable in sleep mode
rtcio_hal_input_enable(rtc_pin);
#endif
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
// Pad configuration depends on RTC_PERIPH state in sleep mode
if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) {
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
// RTC_PERIPH will be powered down, so RTC_IO_ registers will
// loose their state. Lock pad configuration.
// Pullups/pulldowns also need to be disabled.
rtcio_hal_pullup_disable(rtc_pin);
rtcio_hal_pulldown_disable(rtc_pin);
#endif
rtcio_hal_hold_enable(rtc_pin);
}
#endif
#else
/* ESP32H2 use hp iomux to config rtcio, and there is no complete
* rtcio functionality. In the case of EXT1 wakeup, rtcio only provides
* a pathway to EXT1. */
// Route pad to DIGITAL
rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_DIGITAL);
// set input enable
gpio_ll_input_enable(&GPIO, gpio);
// hold rtc_pin to use it during sleep state
rtcio_hal_hold_enable(rtc_pin);
#endif
// Keep track of pins which are processed to bail out early
rtc_gpio_mask &= ~BIT(rtc_pin);
@ -1446,7 +1440,7 @@ static void ext1_wakeup_prepare(void)
// Clear state from previous wakeup
rtc_hal_ext1_clear_wakeup_status();
// Set RTC IO pins and mode (any high, all low) to be used for wakeup
// Set RTC IO pins and mode to be used for wakeup
rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode);
}
@ -1476,20 +1470,14 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
uint64_t esp_sleep_get_gpio_wakeup_status(void)
{
#if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
return 0;
#else
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
return 0;
}
return rtc_hal_gpio_get_wakeup_status();
#endif // !CONFIG_IDF_TARGET_ESP32H2
}
static void gpio_deep_sleep_wakeup_prepare(void)
{
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
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) {
continue;
@ -1505,7 +1493,6 @@ static void gpio_deep_sleep_wakeup_prepare(void)
}
// Clear state from previous wakeup
rtc_hal_gpio_clear_wakeup_status();
#endif // !CONFIG_IDF_TARGET_ESP32H2
}
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)

View File

@ -51,6 +51,7 @@ extern "C" {
* LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY
* LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC
* LP_AON_STORE8_REG Store light sleep wake stub addr
* LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep)
*************************************************************************************
*/
@ -63,6 +64,7 @@ extern "C" {
#define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG
#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG
#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG
#define SLEEP_MODE_REG LP_AON_STORE9_REG
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.

View File

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

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -419,7 +419,11 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ign
{
// This test needs external pullup
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
#if CONFIG_IDF_TARGET_ESP32
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
#else
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_LOW));
#endif
esp_deep_sleep_start();
}
@ -439,7 +443,11 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][igno
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
#if CONFIG_IDF_TARGET_ESP32
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
#else
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_LOW));
#endif
esp_deep_sleep_start();
}
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP

View File

@ -8,17 +8,10 @@
#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 rtc_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status()
#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status()
#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode)
#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins()
#define rtc_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

@ -40,7 +40,7 @@ static inline void lp_aon_ll_ext1_clear_wakeup_status(void)
/**
* @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
* @param mode 0: Wake the chip when any of the 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)

View File

@ -0,0 +1,17 @@
/*
* 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_ll_ext1_get_wakeup_status()
#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status()
#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode)
#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins()
#define rtc_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-H2 LP_AON register operations
#pragma once
#include <stdlib.h>
#include "soc/soc.h"
#include "soc/lp_aon_struct.h"
#include "hal/misc.h"
#include "esp32h2/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 any of the 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

@ -203,7 +203,10 @@
/*-------------------------- RTCIO CAPS --------------------------------------*/
#define SOC_RTCIO_PIN_COUNT 8
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // The target has separate LP(RTC) IOMUX
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature,
* so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.)
* when the pins are switched to RTC function.
*/
#define SOC_RTCIO_HOLD_SUPPORTED 1
#define SOC_RTCIO_WAKE_SUPPORTED 1

View File

@ -175,6 +175,10 @@ config SOC_LP_TIMER_SUPPORTED
bool
default y
config SOC_LP_AON_SUPPORTED
bool
default y
config SOC_PAU_SUPPORTED
bool
default y
@ -1103,6 +1107,10 @@ config SOC_PM_SUPPORT_BT_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT1_WAKEUP
bool
default y
config SOC_PM_SUPPORT_CPU_PD
bool
default y

View File

@ -69,6 +69,7 @@
#define SOC_APM_SUPPORTED 1
#define SOC_PMU_SUPPORTED 1
#define SOC_LP_TIMER_SUPPORTED 1
#define SOC_LP_AON_SUPPORTED 1
#define SOC_PAU_SUPPORTED 1
#define SOC_CLK_TREE_SUPPORTED 1
#define SOC_ASSIST_DEBUG_SUPPORTED 1
@ -463,7 +464,7 @@
/*-------------------------- Power Management CAPS ----------------------------*/
#define SOC_PM_SUPPORT_BT_WAKEUP (1)
// #define SOC_PM_SUPPORT_EXT1_WAKEUP (1) // TODO: IDF-6268
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
#define SOC_PM_SUPPORT_CPU_PD (1)
#define SOC_PM_SUPPORT_MODEM_PD (1) /*!<modem includes BLE and 15.4 */
#define SOC_PM_SUPPORT_XTAL32K_PD (1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -249,7 +249,10 @@
/*-------------------------- RTCIO CAPS --------------------------------------*/
#define SOC_RTCIO_PIN_COUNT 22
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // The target has separate RTC IOMUX
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature,
* so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.)
* when the pins are switched to RTC function.
*/
#define SOC_RTCIO_HOLD_SUPPORTED 1
#define SOC_RTCIO_WAKE_SUPPORTED 1

View File

@ -278,7 +278,10 @@
/*-------------------------- RTCIO CAPS --------------------------------------*/
#define SOC_RTCIO_PIN_COUNT 22
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // The target has separate RTC IOMUX
#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature,
* so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.)
* when the pins are switched to RTC function.
*/
#define SOC_RTCIO_HOLD_SUPPORTED 1
#define SOC_RTCIO_WAKE_SUPPORTED 1

View File

@ -32,20 +32,192 @@ menu "Example Configuration"
floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating
pins may trigger a wake up.
config EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
bool "Use internal pull-up/downs for EXT1 wakeup source"
default n
depends on EXAMPLE_EXT1_WAKEUP
help
When using EXT1 wakeup source without external pull-up/downs, you may want to make use of the internal
ones.
menu "EXT1 wakeup configuration"
visible if EXAMPLE_EXT1_WAKEUP
However, the RTC IO reside in the RTC Periph power domain. Enable this option to force that power domain
ON during deep sleep. Note that this will increase some power comsumption, so it's still suggested to use
external ones instead.
config EXAMPLE_EXT1_WAKEUP_PIN_1
int "Enable wakeup from PIN_1"
depends on !IDF_TARGET_ESP32
default 2 if !IDF_TARGET_ESP32H2
default 10 if IDF_TARGET_ESP32H2
range 0 7 if IDF_TARGET_ESP32C6
range 7 14 if IDF_TARGET_ESP32H2
range 0 21 if IDF_TARGET_ESP32S2
range 0 21 if IDF_TARGET_ESP32S3
EXT0 wakeup source resides in the same power domain as RTCIO (RTC Periph), so internal pull-up/downs are
always available. There's no need to explicitly force it on for EXT0.
choice EXAMPLE_EXT1_WAKEUP_PIN_1_SEL
prompt "Enable wakeup from PIN_1"
default EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_2
depends on IDF_TARGET_ESP32
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_0
bool "GPIO 0"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_2
bool "GPIO 2"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_4
bool "GPIO 4"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_12
bool "GPIO 12"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_13
bool "GPIO 13"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_14
bool "GPIO 14"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_15
bool "GPIO 15"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_25
bool "GPIO 25"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_26
bool "GPIO 26"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_27
bool "GPIO 27"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_32
bool "GPIO 32"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_33
bool "GPIO 33"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_34
bool "GPIO 34"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_35
bool "GPIO 35"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_36
bool "GPIO 36"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_37
bool "GPIO 37"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_38
bool "GPIO 38"
config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_39
bool "GPIO 39"
endchoice
config EXAMPLE_EXT1_WAKEUP_PIN_1
int
depends on IDF_TARGET_ESP32
default 0 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_0
default 2 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_2
default 4 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_4
default 12 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_12
default 13 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_13
default 14 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_14
default 15 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_15
default 25 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_25
default 26 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_26
default 27 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_27
default 32 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_32
default 33 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_33
default 34 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_34
default 35 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_35
default 36 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_36
default 37 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_37
default 38 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_38
default 39 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_39
config EXAMPLE_EXT1_WAKEUP_PIN_2
int "Enable wakeup from PIN_2"
depends on !IDF_TARGET_ESP32
default 4 if !IDF_TARGET_ESP32H2
default 11 if IDF_TARGET_ESP32H2
range 0 7 if IDF_TARGET_ESP32C6
range 7 14 if IDF_TARGET_ESP32H2
range 0 21 if IDF_TARGET_ESP32S2
range 0 21 if IDF_TARGET_ESP32S3
choice EXAMPLE_EXT1_WAKEUP_PIN_2_SEL
prompt "Enable wakeup from PIN_2"
default EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_4
depends on IDF_TARGET_ESP32
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_0
bool "GPIO 0"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_2
bool "GPIO 2"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_4
bool "GPIO 4"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_12
bool "GPIO 12"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_13
bool "GPIO 13"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_14
bool "GPIO 14"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_15
bool "GPIO 15"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_25
bool "GPIO 25"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_26
bool "GPIO 26"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_27
bool "GPIO 27"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_32
bool "GPIO 32"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_33
bool "GPIO 33"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_34
bool "GPIO 34"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_35
bool "GPIO 35"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_36
bool "GPIO 36"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_37
bool "GPIO 37"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_38
bool "GPIO 38"
config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_39
bool "GPIO 39"
endchoice
config EXAMPLE_EXT1_WAKEUP_PIN_2
int
depends on IDF_TARGET_ESP32
default 0 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_0
default 2 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_2
default 4 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_4
default 12 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_12
default 13 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_13
default 14 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_14
default 15 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_15
default 25 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_25
default 26 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_26
default 27 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_27
default 32 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_32
default 33 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_33
default 34 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_34
default 35 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_35
default 36 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_36
default 37 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_37
default 38 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_38
default 39 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_39
choice EXAMPLE_EXT1_WAKEUP_MODE_SEL
prompt "Select wakeup mode from EXT1"
default ESP_EXT1_WAKEUP_ANY_HIGH
config ESP_EXT1_WAKEUP_ANY_LOW
bool "GPIO any low level"
depends on !IDF_TARGET_ESP32
config ESP_EXT1_WAKEUP_ALL_LOW
bool "GPIO all low level"
depends on IDF_TARGET_ESP32
config ESP_EXT1_WAKEUP_ANY_HIGH
bool "GPIO any high level"
endchoice
config EXAMPLE_EXT1_WAKEUP_MODE
int
default 0 if ESP_EXT1_WAKEUP_ANY_LOW
default 0 if ESP_EXT1_WAKEUP_ALL_LOW
default 1 if ESP_EXT1_WAKEUP_ANY_HIGH
config EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
bool "Use internal pull-up/downs for EXT1 wakeup source"
default n
depends on EXAMPLE_EXT1_WAKEUP
help
When using EXT1 wakeup source without external pull-up/downs, you may want to make use of
the internal ones.
if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH domain,
we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep.
but if we turn on the RTC_PERIPH domain, we don not need to use HOLD feature and this will
increase some power comsumption.
EXT0 wakeup source resides in the same power domain as RTCIO (RTC Periph), so internal
pull-up/downs are always available. There's no need to explicitly force it on for EXT0.
endmenu
config EXAMPLE_GPIO_WAKEUP
bool "Enable wakeup from GPIO"
@ -60,11 +232,9 @@ menu "Example Configuration"
config EXAMPLE_GPIO_WAKEUP_PIN
int "Enable wakeup from GPIO"
default 0 if !IDF_TARGET_ESP32H2
default 7 if IDF_TARGET_ESP32H2
default 0
range 0 7 if IDF_TARGET_ESP32C6
range 7 14 if IDF_TARGET_ESP32H2
range 0 5 if !IDF_TARGET_ESP32C6 && !IDF_TARGET_ESP32H2
range 0 5 if !IDF_TARGET_ESP32C6
config EXAMPLE_GPIO_WAKEUP_HIGH_LEVEL
bool "Enable GPIO high-level wakeup"

View File

@ -9,6 +9,7 @@
#include "sdkconfig.h"
#include "driver/rtc_io.h"
#if CONFIG_EXAMPLE_EXT0_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
const int ext_wakeup_pin_0 = 25;
@ -32,24 +33,46 @@ void example_deep_sleep_register_ext0_wakeup(void)
#if CONFIG_EXAMPLE_EXT1_WAKEUP
void example_deep_sleep_register_ext1_wakeup(void)
{
const int ext_wakeup_pin_1 = 2;
const int ext_wakeup_pin_1 = CONFIG_EXAMPLE_EXT1_WAKEUP_PIN_1;
const int ext_wakeup_pin_2 = CONFIG_EXAMPLE_EXT1_WAKEUP_PIN_2;
const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1;
const int ext_wakeup_pin_2 = 4;
const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2;
printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2);
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH));
const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE;
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ext_wakeup_mode));
/* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO
* 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. However, if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH
* domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep.*/
#if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
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_pullup_dis(ext_wakeup_pin_2));
ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_2));
#endif //CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
if (ext_wakeup_mode) {
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_pullup_dis(ext_wakeup_pin_2));
ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_2));
} else {
ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_1));
ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_1));
ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_2));
ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_2));
}
#else
if (ext_wakeup_mode) {
ESP_ERROR_CHECK(gpio_pullup_dis(ext_wakeup_pin_1));
ESP_ERROR_CHECK(gpio_pulldown_en(ext_wakeup_pin_1));
ESP_ERROR_CHECK(gpio_pullup_dis(ext_wakeup_pin_2));
ESP_ERROR_CHECK(gpio_pulldown_en(ext_wakeup_pin_2));
} else {
ESP_ERROR_CHECK(gpio_pulldown_dis(ext_wakeup_pin_1));
ESP_ERROR_CHECK(gpio_pullup_en(ext_wakeup_pin_1));
ESP_ERROR_CHECK(gpio_pulldown_dis(ext_wakeup_pin_2));
ESP_ERROR_CHECK(gpio_pullup_en(ext_wakeup_pin_2));
}
#endif
#endif // CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
}
#endif // CONFIG_EXAMPLE_EXT1_WAKEUP