From dce6d5ab0ce830a1b905dd99eba1bac1025e526f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 9 Apr 2026 16:57:18 -1000 Subject: [PATCH] [sx1509] Only clear interrupt source when interrupt actually fired --- esphome/components/sx1509/sx1509.cpp | 16 +++++++++++----- esphome/components/sx1509/sx1509.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/esphome/components/sx1509/sx1509.cpp b/esphome/components/sx1509/sx1509.cpp index 81e0fc592f..9f842ddf36 100644 --- a/esphome/components/sx1509/sx1509.cpp +++ b/esphome/components/sx1509/sx1509.cpp @@ -41,7 +41,10 @@ void SX1509Component::setup() { } } -void IRAM_ATTR SX1509Component::gpio_intr(SX1509Component *arg) { arg->enable_loop_soon_any_context(); } +void IRAM_ATTR SX1509Component::gpio_intr(SX1509Component *arg) { + arg->interrupt_pending_ = true; + arg->enable_loop_soon_any_context(); +} void SX1509Component::dump_config() { ESP_LOGCONFIG(TAG, "SX1509:"); LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_); @@ -52,16 +55,19 @@ void SX1509Component::dump_config() { } void SX1509Component::loop() { - if (this->interrupt_pin_ != nullptr) { + if (this->interrupt_pending_) { + this->interrupt_pending_ = false; // Clear interrupt source before resetting cache to avoid losing // pin changes that occur between cache reset and interrupt clear uint16_t interrupt_source = 0; this->read_byte_16(REG_INTERRUPT_SOURCE_B, &interrupt_source); + this->reset_pin_cache_(); + if (!this->has_keypad_) { + this->disable_loop(); + } + return; } this->reset_pin_cache_(); - if (this->interrupt_pin_ != nullptr && !this->has_keypad_) { - this->disable_loop(); - } if (this->has_keypad_) { if (millis() - this->last_loop_timestamp_ < min_loop_period_) diff --git a/esphome/components/sx1509/sx1509.h b/esphome/components/sx1509/sx1509.h index d2aca3f9fb..e50bb6c99c 100644 --- a/esphome/components/sx1509/sx1509.h +++ b/esphome/components/sx1509/sx1509.h @@ -89,6 +89,7 @@ class SX1509Component : public Component, std::vector key_triggers_; InternalGPIOPin *interrupt_pin_{nullptr}; + volatile bool interrupt_pending_{false}; uint32_t last_loop_timestamp_ = 0; const uint32_t min_loop_period_ = 15; // ms