mirror of
https://github.com/esphome/esphome.git
synced 2026-05-30 23:54:04 +08:00
[io_expanders] Self-heal interrupt-driven expanders when INT stays asserted across the read (#15923)
This commit is contained in:
@@ -37,7 +37,10 @@ void IRAM_ATTR MCP23016::gpio_intr(MCP23016 *arg) { arg->enable_loop_soon_any_co
|
|||||||
void MCP23016::loop() {
|
void MCP23016::loop() {
|
||||||
// Invalidate cache at the start of each loop
|
// Invalidate cache at the start of each loop
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ template<uint8_t N> class MCP23XXXBase : public Component, public gpio_expander:
|
|||||||
|
|
||||||
void loop() override {
|
void loop() override {
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ void IRAM_ATTR PCA6416AComponent::gpio_intr(PCA6416AComponent *arg) { arg->enabl
|
|||||||
void PCA6416AComponent::loop() {
|
void PCA6416AComponent::loop() {
|
||||||
// Invalidate cache at the start of each loop
|
// Invalidate cache at the start of each loop
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,10 @@ void IRAM_ATTR PCA9554Component::gpio_intr(PCA9554Component *arg) { arg->enable_
|
|||||||
void PCA9554Component::loop() {
|
void PCA9554Component::loop() {
|
||||||
// Invalidate the cache so the next digital_read() triggers a fresh I2C read
|
// Invalidate the cache so the next digital_read() triggers a fresh I2C read
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
// Interrupt-driven: disable loop until next interrupt fires
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,10 @@ void IRAM_ATTR PCF8574Component::gpio_intr(PCF8574Component *arg) { arg->enable_
|
|||||||
void PCF8574Component::loop() {
|
void PCF8574Component::loop() {
|
||||||
// Invalidate the cache so the next digital_read() triggers a fresh I2C read
|
// Invalidate the cache so the next digital_read() triggers a fresh I2C read
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
// Interrupt-driven: disable loop until next interrupt fires
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,10 @@ void PI4IOE5V6408Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
|||||||
|
|
||||||
void PI4IOE5V6408Component::loop() {
|
void PI4IOE5V6408Component::loop() {
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,10 @@ void TCA9555Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
|||||||
}
|
}
|
||||||
void TCA9555Component::loop() {
|
void TCA9555Component::loop() {
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
if (this->interrupt_pin_ != nullptr) {
|
// Only disable the loop once INT has actually gone HIGH. Input transitions that straddle the
|
||||||
|
// I2C read leave INT asserted without re-firing a falling edge, which would strand us with
|
||||||
|
// stale state forever; keep looping until the line is released so we self-heal.
|
||||||
|
if (this->interrupt_pin_ != nullptr && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user