From 7975f12d60ddb85cdd0bfd7ea6bc61a51a686b0b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 28 Sep 2025 22:31:27 -0500 Subject: [PATCH 1/3] [esp32] deep sleep fixes to align with variant support --- esphome/components/deep_sleep/__init__.py | 11 ++- .../deep_sleep/deep_sleep_component.h | 24 +++--- .../deep_sleep/deep_sleep_esp32.cpp | 78 ++++++++++++------- .../deep_sleep/common-esp32-all.yaml | 14 ++++ .../deep_sleep/common-esp32-ext1.yaml | 12 +++ .../deep_sleep/test.esp32-c2-idf.yaml | 10 +++ .../deep_sleep/test.esp32-c6-idf.yaml | 2 +- .../deep_sleep/test.esp32-h2-idf.yaml | 16 ++++ .../components/deep_sleep/test.esp32-idf.yaml | 2 +- .../deep_sleep/test.esp32-s2-idf.yaml | 2 +- .../deep_sleep/test.esp32-s3-idf.yaml | 2 +- .../build_components_base.esp32-c2-idf.yaml | 17 ++++ .../build_components_base.esp32-h2-idf.yaml | 17 ++++ 13 files changed, 163 insertions(+), 44 deletions(-) create mode 100644 tests/components/deep_sleep/common-esp32-all.yaml create mode 100644 tests/components/deep_sleep/common-esp32-ext1.yaml create mode 100644 tests/components/deep_sleep/test.esp32-c2-idf.yaml create mode 100644 tests/components/deep_sleep/test.esp32-h2-idf.yaml create mode 100644 tests/test_build_components/build_components_base.esp32-c2-idf.yaml create mode 100644 tests/test_build_components/build_components_base.esp32-h2-idf.yaml diff --git a/esphome/components/deep_sleep/__init__.py b/esphome/components/deep_sleep/__init__.py index 05ae60239d..19fb726016 100644 --- a/esphome/components/deep_sleep/__init__.py +++ b/esphome/components/deep_sleep/__init__.py @@ -197,7 +197,8 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_ESP32_EXT1_WAKEUP): cv.All( cv.only_on_esp32, esp32.only_on_variant( - unsupported=[VARIANT_ESP32C3], msg_prefix="Wakeup from ext1" + unsupported=[VARIANT_ESP32C2, VARIANT_ESP32C3], + msg_prefix="Wakeup from ext1", ), cv.Schema( { @@ -214,7 +215,13 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_TOUCH_WAKEUP): cv.All( cv.only_on_esp32, esp32.only_on_variant( - unsupported=[VARIANT_ESP32C3], msg_prefix="Wakeup from touch" + unsupported=[ + VARIANT_ESP32C2, + VARIANT_ESP32C3, + VARIANT_ESP32C6, + VARIANT_ESP32H2, + ], + msg_prefix="Wakeup from touch", ), cv.boolean, ), diff --git a/esphome/components/deep_sleep/deep_sleep_component.h b/esphome/components/deep_sleep/deep_sleep_component.h index 7a640b9ea5..38744163c7 100644 --- a/esphome/components/deep_sleep/deep_sleep_component.h +++ b/esphome/components/deep_sleep/deep_sleep_component.h @@ -34,7 +34,7 @@ enum WakeupPinMode { WAKEUP_PIN_MODE_INVERT_WAKEUP, }; -#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) +#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) struct Ext1Wakeup { uint64_t mask; esp_sleep_ext1_wakeup_mode_t wakeup_mode; @@ -50,7 +50,7 @@ struct WakeupCauseToRunDuration { uint32_t gpio_cause; }; -#endif +#endif // USE_ESP32 template class EnterDeepSleepAction; @@ -73,20 +73,22 @@ class DeepSleepComponent : public Component { void set_wakeup_pin(InternalGPIOPin *pin) { this->wakeup_pin_ = pin; } void set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode); -#endif +#endif // USE_ESP32 #if defined(USE_ESP32) -#if !defined(USE_ESP32_VARIANT_ESP32C3) - +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) void set_ext1_wakeup(Ext1Wakeup ext1_wakeup); - - void set_touch_wakeup(bool touch_wakeup); - #endif + +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \ + !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2) + void set_touch_wakeup(bool touch_wakeup); +#endif + // Set the duration in ms for how long the code should run before entering // deep sleep mode, according to the cause the ESP32 has woken. void set_run_duration(WakeupCauseToRunDuration wakeup_cause_to_run_duration); -#endif +#endif // USE_ESP32 /// Set a duration in ms for how long the code should run before entering deep sleep mode. void set_run_duration(uint32_t time_ms); @@ -117,13 +119,13 @@ class DeepSleepComponent : public Component { InternalGPIOPin *wakeup_pin_; WakeupPinMode wakeup_pin_mode_{WAKEUP_PIN_MODE_IGNORE}; -#if !defined(USE_ESP32_VARIANT_ESP32C3) +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) optional ext1_wakeup_; #endif optional touch_wakeup_; optional wakeup_cause_to_run_duration_; -#endif +#endif // USE_ESP32 optional run_duration_; bool next_enter_deep_sleep_{false}; bool prevent_{false}; diff --git a/esphome/components/deep_sleep/deep_sleep_esp32.cpp b/esphome/components/deep_sleep/deep_sleep_esp32.cpp index e9d0a4981f..b93d9ce601 100644 --- a/esphome/components/deep_sleep/deep_sleep_esp32.cpp +++ b/esphome/components/deep_sleep/deep_sleep_esp32.cpp @@ -7,6 +7,26 @@ namespace esphome { namespace deep_sleep { +// Deep Sleep feature support matrix for ESP32 variants: +// +// | Variant | ext0 | ext1 | Touch | GPIO wakeup | +// |-----------|------|------|-------|-------------| +// | ESP32 | ✓ | ✓ | ✓ | | +// | ESP32-S2 | ✓ | ✓ | ✓ | | +// | ESP32-S3 | ✓ | ✓ | ✓ | | +// | ESP32-C2 | | | | ✓ | +// | ESP32-C3 | | | | ✓ | +// | ESP32-C5 | | (✓) | | (✓) | +// | ESP32-C6 | | ✓ | | ✓ | +// | ESP32-H2 | | ✓ | | | +// +// Notes: +// - (✓) = Supported by hardware but not yet implemented in ESPHome +// - ext0: Single pin wakeup using RTC GPIO (esp_sleep_enable_ext0_wakeup) +// - ext1: Multiple pin wakeup (esp_sleep_enable_ext1_wakeup) +// - Touch: Touch pad wakeup (esp_sleep_enable_touchpad_wakeup) +// - GPIO wakeup: GPIO wakeup for non-RTC pins (esp_deep_sleep_enable_gpio_wakeup) + static const char *const TAG = "deep_sleep"; optional DeepSleepComponent::get_run_duration_() const { @@ -30,13 +50,13 @@ void DeepSleepComponent::set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode) { this->wakeup_pin_mode_ = wakeup_pin_mode; } -#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) void DeepSleepComponent::set_ext1_wakeup(Ext1Wakeup ext1_wakeup) { this->ext1_wakeup_ = ext1_wakeup; } - -#if !defined(USE_ESP32_VARIANT_ESP32H2) -void DeepSleepComponent::set_touch_wakeup(bool touch_wakeup) { this->touch_wakeup_ = touch_wakeup; } #endif +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \ + !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2) +void DeepSleepComponent::set_touch_wakeup(bool touch_wakeup) { this->touch_wakeup_ = touch_wakeup; } #endif void DeepSleepComponent::set_run_duration(WakeupCauseToRunDuration wakeup_cause_to_run_duration) { @@ -72,9 +92,13 @@ bool DeepSleepComponent::prepare_to_sleep_() { } void DeepSleepComponent::deep_sleep_() { -#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2) + // Timer wakeup - all variants support this if (this->sleep_duration_.has_value()) esp_sleep_enable_timer_wakeup(*this->sleep_duration_); + + // Single pin wakeup (ext0) - ESP32, S2, S3 only +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \ + !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2) if (this->wakeup_pin_ != nullptr) { const auto gpio_pin = gpio_num_t(this->wakeup_pin_->get_pin()); if (this->wakeup_pin_->get_flags() & gpio::FLAG_PULLUP) { @@ -95,32 +119,15 @@ void DeepSleepComponent::deep_sleep_() { } esp_sleep_enable_ext0_wakeup(gpio_pin, level); } - if (this->ext1_wakeup_.has_value()) { - esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode); - } - - if (this->touch_wakeup_.has_value() && *(this->touch_wakeup_)) { - esp_sleep_enable_touchpad_wakeup(); - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - } #endif -#if defined(USE_ESP32_VARIANT_ESP32H2) - if (this->sleep_duration_.has_value()) - esp_sleep_enable_timer_wakeup(*this->sleep_duration_); - if (this->ext1_wakeup_.has_value()) { - esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode); - } -#endif - -#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) - if (this->sleep_duration_.has_value()) - esp_sleep_enable_timer_wakeup(*this->sleep_duration_); + // GPIO wakeup - C2, C3, C6 only +#if defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) if (this->wakeup_pin_ != nullptr) { const auto gpio_pin = gpio_num_t(this->wakeup_pin_->get_pin()); - if (this->wakeup_pin_->get_flags() && gpio::FLAG_PULLUP) { + if (this->wakeup_pin_->get_flags() & gpio::FLAG_PULLUP) { gpio_sleep_set_pull_mode(gpio_pin, GPIO_PULLUP_ONLY); - } else if (this->wakeup_pin_->get_flags() && gpio::FLAG_PULLDOWN) { + } else if (this->wakeup_pin_->get_flags() & gpio::FLAG_PULLDOWN) { gpio_sleep_set_pull_mode(gpio_pin, GPIO_PULLDOWN_ONLY); } gpio_sleep_set_direction(gpio_pin, GPIO_MODE_INPUT); @@ -138,9 +145,26 @@ void DeepSleepComponent::deep_sleep_() { static_cast(level)); } #endif + + // Multiple pin wakeup (ext1) - All except C2, C3 +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) + if (this->ext1_wakeup_.has_value()) { + esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode); + } +#endif + + // Touch wakeup - ESP32, S2, S3 only +#if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \ + !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2) + if (this->touch_wakeup_.has_value() && *(this->touch_wakeup_)) { + esp_sleep_enable_touchpad_wakeup(); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + } +#endif + esp_deep_sleep_start(); } } // namespace deep_sleep } // namespace esphome -#endif +#endif // USE_ESP32 diff --git a/tests/components/deep_sleep/common-esp32-all.yaml b/tests/components/deep_sleep/common-esp32-all.yaml new file mode 100644 index 0000000000..b97eec76b9 --- /dev/null +++ b/tests/components/deep_sleep/common-esp32-all.yaml @@ -0,0 +1,14 @@ +deep_sleep: + run_duration: + default: 10s + gpio_wakeup_reason: 30s + touch_wakeup_reason: 15s + sleep_duration: 50s + wakeup_pin: ${wakeup_pin} + wakeup_pin_mode: INVERT_WAKEUP + esp32_ext1_wakeup: + pins: + - number: GPIO2 + - number: GPIO13 + mode: ANY_HIGH + touch_wakeup: true diff --git a/tests/components/deep_sleep/common-esp32-ext1.yaml b/tests/components/deep_sleep/common-esp32-ext1.yaml new file mode 100644 index 0000000000..9ed4279a33 --- /dev/null +++ b/tests/components/deep_sleep/common-esp32-ext1.yaml @@ -0,0 +1,12 @@ +deep_sleep: + run_duration: + default: 10s + gpio_wakeup_reason: 30s + sleep_duration: 50s + wakeup_pin: ${wakeup_pin} + wakeup_pin_mode: INVERT_WAKEUP + esp32_ext1_wakeup: + pins: + - number: GPIO2 + - number: GPIO5 + mode: ANY_HIGH diff --git a/tests/components/deep_sleep/test.esp32-c2-idf.yaml b/tests/components/deep_sleep/test.esp32-c2-idf.yaml new file mode 100644 index 0000000000..7023bf67d6 --- /dev/null +++ b/tests/components/deep_sleep/test.esp32-c2-idf.yaml @@ -0,0 +1,10 @@ +substitutions: + wakeup_pin: GPIO4 + +<<: !include common.yaml + +deep_sleep: + run_duration: 10s + sleep_duration: 50s + wakeup_pin: ${wakeup_pin} + wakeup_pin_mode: INVERT_WAKEUP diff --git a/tests/components/deep_sleep/test.esp32-c6-idf.yaml b/tests/components/deep_sleep/test.esp32-c6-idf.yaml index 10c17af0f5..11abe70711 100644 --- a/tests/components/deep_sleep/test.esp32-c6-idf.yaml +++ b/tests/components/deep_sleep/test.esp32-c6-idf.yaml @@ -2,4 +2,4 @@ substitutions: wakeup_pin: GPIO4 <<: !include common.yaml -<<: !include common-esp32.yaml +<<: !include common-esp32-ext1.yaml diff --git a/tests/components/deep_sleep/test.esp32-h2-idf.yaml b/tests/components/deep_sleep/test.esp32-h2-idf.yaml new file mode 100644 index 0000000000..e3c46c5176 --- /dev/null +++ b/tests/components/deep_sleep/test.esp32-h2-idf.yaml @@ -0,0 +1,16 @@ +substitutions: + wakeup_pin: GPIO9 + +<<: !include common.yaml + +deep_sleep: + run_duration: + default: 10s + gpio_wakeup_reason: 30s + sleep_duration: 50s + esp32_ext1_wakeup: + pins: + - number: GPIO7 + - number: GPIO8 + - number: GPIO9 + mode: ANY_HIGH diff --git a/tests/components/deep_sleep/test.esp32-idf.yaml b/tests/components/deep_sleep/test.esp32-idf.yaml index 10c17af0f5..e45eb08349 100644 --- a/tests/components/deep_sleep/test.esp32-idf.yaml +++ b/tests/components/deep_sleep/test.esp32-idf.yaml @@ -2,4 +2,4 @@ substitutions: wakeup_pin: GPIO4 <<: !include common.yaml -<<: !include common-esp32.yaml +<<: !include common-esp32-all.yaml diff --git a/tests/components/deep_sleep/test.esp32-s2-idf.yaml b/tests/components/deep_sleep/test.esp32-s2-idf.yaml index 10c17af0f5..e45eb08349 100644 --- a/tests/components/deep_sleep/test.esp32-s2-idf.yaml +++ b/tests/components/deep_sleep/test.esp32-s2-idf.yaml @@ -2,4 +2,4 @@ substitutions: wakeup_pin: GPIO4 <<: !include common.yaml -<<: !include common-esp32.yaml +<<: !include common-esp32-all.yaml diff --git a/tests/components/deep_sleep/test.esp32-s3-idf.yaml b/tests/components/deep_sleep/test.esp32-s3-idf.yaml index 10c17af0f5..e45eb08349 100644 --- a/tests/components/deep_sleep/test.esp32-s3-idf.yaml +++ b/tests/components/deep_sleep/test.esp32-s3-idf.yaml @@ -2,4 +2,4 @@ substitutions: wakeup_pin: GPIO4 <<: !include common.yaml -<<: !include common-esp32.yaml +<<: !include common-esp32-all.yaml diff --git a/tests/test_build_components/build_components_base.esp32-c2-idf.yaml b/tests/test_build_components/build_components_base.esp32-c2-idf.yaml new file mode 100644 index 0000000000..a0ae9e3a46 --- /dev/null +++ b/tests/test_build_components/build_components_base.esp32-c2-idf.yaml @@ -0,0 +1,17 @@ +esphome: + name: componenttestesp32c2idf + friendly_name: $component_name + +esp32: + board: esp32-c2-devkitm-1 + framework: + type: esp-idf + +logger: + level: VERY_VERBOSE + +packages: + component_under_test: !include + file: $component_test_file + vars: + component_test_file: $component_test_file diff --git a/tests/test_build_components/build_components_base.esp32-h2-idf.yaml b/tests/test_build_components/build_components_base.esp32-h2-idf.yaml new file mode 100644 index 0000000000..5e668a9a97 --- /dev/null +++ b/tests/test_build_components/build_components_base.esp32-h2-idf.yaml @@ -0,0 +1,17 @@ +esphome: + name: componenttestesp32h2idf + friendly_name: $component_name + +esp32: + board: esp32-h2-devkitm-1 + framework: + type: esp-idf + +logger: + level: VERY_VERBOSE + +packages: + component_under_test: !include + file: $component_test_file + vars: + component_test_file: $component_test_file From b11a52fd1ed824b287ef7dce9fdb99d8b59835ad Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Sep 2025 14:38:54 -0500 Subject: [PATCH 2/3] Remove C2 and H2 from component test matrix to avoid CI disk space issues --- .../build_components_base.esp32-c2-idf.yaml | 17 ----------------- .../build_components_base.esp32-h2-idf.yaml | 17 ----------------- 2 files changed, 34 deletions(-) delete mode 100644 tests/test_build_components/build_components_base.esp32-c2-idf.yaml delete mode 100644 tests/test_build_components/build_components_base.esp32-h2-idf.yaml diff --git a/tests/test_build_components/build_components_base.esp32-c2-idf.yaml b/tests/test_build_components/build_components_base.esp32-c2-idf.yaml deleted file mode 100644 index a0ae9e3a46..0000000000 --- a/tests/test_build_components/build_components_base.esp32-c2-idf.yaml +++ /dev/null @@ -1,17 +0,0 @@ -esphome: - name: componenttestesp32c2idf - friendly_name: $component_name - -esp32: - board: esp32-c2-devkitm-1 - framework: - type: esp-idf - -logger: - level: VERY_VERBOSE - -packages: - component_under_test: !include - file: $component_test_file - vars: - component_test_file: $component_test_file diff --git a/tests/test_build_components/build_components_base.esp32-h2-idf.yaml b/tests/test_build_components/build_components_base.esp32-h2-idf.yaml deleted file mode 100644 index 5e668a9a97..0000000000 --- a/tests/test_build_components/build_components_base.esp32-h2-idf.yaml +++ /dev/null @@ -1,17 +0,0 @@ -esphome: - name: componenttestesp32h2idf - friendly_name: $component_name - -esp32: - board: esp32-h2-devkitm-1 - framework: - type: esp-idf - -logger: - level: VERY_VERBOSE - -packages: - component_under_test: !include - file: $component_test_file - vars: - component_test_file: $component_test_file From c2d9d66bb014f3902ded0b2ffe1685b4a7c2eb20 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Sep 2025 14:39:56 -0500 Subject: [PATCH 3/3] Remove C2 and H2 from component test matrix to avoid CI disk space issues --- .../components/deep_sleep/test.esp32-c2-idf.yaml | 10 ---------- .../components/deep_sleep/test.esp32-h2-idf.yaml | 16 ---------------- 2 files changed, 26 deletions(-) delete mode 100644 tests/components/deep_sleep/test.esp32-c2-idf.yaml delete mode 100644 tests/components/deep_sleep/test.esp32-h2-idf.yaml diff --git a/tests/components/deep_sleep/test.esp32-c2-idf.yaml b/tests/components/deep_sleep/test.esp32-c2-idf.yaml deleted file mode 100644 index 7023bf67d6..0000000000 --- a/tests/components/deep_sleep/test.esp32-c2-idf.yaml +++ /dev/null @@ -1,10 +0,0 @@ -substitutions: - wakeup_pin: GPIO4 - -<<: !include common.yaml - -deep_sleep: - run_duration: 10s - sleep_duration: 50s - wakeup_pin: ${wakeup_pin} - wakeup_pin_mode: INVERT_WAKEUP diff --git a/tests/components/deep_sleep/test.esp32-h2-idf.yaml b/tests/components/deep_sleep/test.esp32-h2-idf.yaml deleted file mode 100644 index e3c46c5176..0000000000 --- a/tests/components/deep_sleep/test.esp32-h2-idf.yaml +++ /dev/null @@ -1,16 +0,0 @@ -substitutions: - wakeup_pin: GPIO9 - -<<: !include common.yaml - -deep_sleep: - run_duration: - default: 10s - gpio_wakeup_reason: 30s - sleep_duration: 50s - esp32_ext1_wakeup: - pins: - - number: GPIO7 - - number: GPIO8 - - number: GPIO9 - mode: ANY_HIGH