1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-03 10:32:21 +01:00

[deep_sleep] esp32 fixes to align with variant support (#10929)

This commit is contained in:
J. Nick Koston
2025-09-30 14:42:42 -05:00
committed by GitHub
parent f5e85a424f
commit 2a915e4efd
9 changed files with 103 additions and 44 deletions

View File

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

View File

@@ -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<typename... Ts> 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<Ext1Wakeup> ext1_wakeup_;
#endif
optional<bool> touch_wakeup_;
optional<WakeupCauseToRunDuration> wakeup_cause_to_run_duration_;
#endif
#endif // USE_ESP32
optional<uint32_t> run_duration_;
bool next_enter_deep_sleep_{false};
bool prevent_{false};

View File

@@ -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<uint32_t> 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<esp_deepsleep_gpio_wake_up_mode_t>(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