feat(pm/deepsleep): Support EXT1 wakeup for esp32h2 deep_sleep

This commit is contained in:
Lou Tianhao 2023-07-03 21:25:56 +08:00
parent 6768f098dc
commit b27e57db7b
10 changed files with 59 additions and 51 deletions

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,17 @@ typedef void (*esp_deep_sleep_cb_t)(void);
/**
* @brief Logic function used for EXT1 wakeup mode.
*/
#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_sleep_ext1_wakeup_mode_t;
#endif
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
typedef enum {

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
@ -832,8 +831,6 @@ void IRAM_ATTR esp_deep_sleep_start(void)
if (esp_get_deep_sleep_wake_stub() == NULL) {
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
}
// assert(0);
#endif // SOC_RTC_FAST_MEM_SUPPORTED
// Decide which power domains can be powered down
@ -1372,8 +1369,18 @@ 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
#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
#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) {
@ -1423,20 +1430,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;
@ -1452,7 +1453,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

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

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

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for ESP32-C6 LP_AON register operations
// The LL layer for ESP32-H2 LP_AON register operations
#pragma once

View File

@ -171,6 +171,10 @@ config SOC_LP_TIMER_SUPPORTED
bool
default y
config SOC_LP_AON_SUPPORTED
bool
default y
config SOC_PAU_SUPPORTED
bool
default y
@ -1075,14 +1079,14 @@ config SOC_PHY_DIG_REGS_MEM_SIZE
int
default 21
config SOC_PM_SUPPORT_EXT1_WAKEUP
bool
default n
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

@ -68,6 +68,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
@ -454,8 +455,8 @@
#define SOC_PHY_DIG_REGS_MEM_SIZE (21*4)
/*-------------------------- Power Management CAPS ----------------------------*/
#define SOC_PM_SUPPORT_EXT1_WAKEUP (0)
#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_MODEM_PD (1) /*!<modem includes BLE and 15.4 */
#define SOC_PM_SUPPORT_XTAL32K_PD (1)

View File

@ -60,11 +60,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,11 +33,16 @@ void example_deep_sleep_register_ext0_wakeup(void)
#if CONFIG_EXAMPLE_EXT1_WAKEUP
void example_deep_sleep_register_ext1_wakeup(void)
{
#if !CONFIG_IDF_TARGET_ESP32H2
const int ext_wakeup_pin_1 = 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;
#else
const int ext_wakeup_pin_1 = 10;
const int ext_wakeup_pin_2 = 11;
#endif
const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1;
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));
@ -44,11 +50,18 @@ void example_deep_sleep_register_ext1_wakeup(void)
* during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will
* increase some power comsumption. */
#if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
#if !CONFIG_IDF_TARGET_ESP32H2
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));
#else
gpio_pullup_dis(ext_wakeup_pin_1);
gpio_pulldown_en(ext_wakeup_pin_1);
gpio_pullup_dis(ext_wakeup_pin_2);
gpio_pulldown_en(ext_wakeup_pin_2);
#endif
#endif //CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
}