From 4870cd29215dbc7deed8a5d2c40cfa3aa3acdab7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 18 Jun 2025 12:28:49 +0200 Subject: [PATCH] use enable_loop_soon_from_isr --- .../gpio/binary_sensor/gpio_binary_sensor.cpp | 12 ++++++++++-- .../gpio/binary_sensor/gpio_binary_sensor.h | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp index 160c657c24..8832ed02c3 100644 --- a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +++ b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp @@ -12,12 +12,17 @@ void IRAM_ATTR GPIOBinarySensorStore::gpio_intr(GPIOBinarySensorStore *arg) { arg->state_ = new_state; arg->last_state_ = new_state; arg->changed_ = true; + // Wake up the component from its disabled loop state + if (arg->component_ != nullptr) { + arg->component_->enable_loop_soon_from_isr(); + } } } -void GPIOBinarySensorStore::setup(InternalGPIOPin *pin, gpio::InterruptType type) { +void GPIOBinarySensorStore::setup(InternalGPIOPin *pin, gpio::InterruptType type, Component *component) { pin->setup(); this->isr_pin_ = pin->to_isr(); + this->component_ = component; // Read initial state this->last_state_ = pin->digital_read(); @@ -35,7 +40,7 @@ void GPIOBinarySensor::setup() { if (this->use_interrupt_) { auto *internal_pin = static_cast(this->pin_); - this->store_.setup(internal_pin, this->interrupt_type_); + this->store_.setup(internal_pin, this->interrupt_type_, this); this->publish_initial_state(this->store_.get_state()); } else { this->pin_->setup(); @@ -78,6 +83,9 @@ void GPIOBinarySensor::loop() { // we'll process the new change on the next loop iteration bool state = this->store_.get_state(); this->publish_state(state); + } else { + // No changes, disable the loop until the next interrupt + this->disable_loop(); } } else { this->publish_state(this->pin_->digital_read()); diff --git a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h index 43ae5aa23c..e2802252d5 100644 --- a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +++ b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h @@ -11,7 +11,7 @@ namespace gpio { // Store class for ISR data (no vtables, ISR-safe) class GPIOBinarySensorStore { public: - void setup(InternalGPIOPin *pin, gpio::InterruptType type); + void setup(InternalGPIOPin *pin, gpio::InterruptType type, Component *component); static void gpio_intr(GPIOBinarySensorStore *arg); @@ -36,6 +36,7 @@ class GPIOBinarySensorStore { volatile bool state_{false}; volatile bool last_state_{false}; volatile bool changed_{false}; + Component *component_{nullptr}; // Pointer to the component for enable_loop_soon_from_isr() }; class GPIOBinarySensor : public binary_sensor::BinarySensor, public Component {