Revert "[gpio_expander] Remove loop() from all GPIO expander components"

This reverts commit 8403728d4a.
This commit is contained in:
J. Nick Koston
2026-04-04 08:10:27 -10:00
parent c579846b2e
commit e4e664a9e6
15 changed files with 38 additions and 12 deletions
+1 -12
View File
@@ -5,7 +5,6 @@
#include <cstring>
#include <limits>
#include <type_traits>
#include "esphome/core/application.h"
#include "esphome/core/hal.h"
namespace esphome::gpio_expander {
@@ -33,15 +32,6 @@ class CachedGpioExpander {
/// @param pin Pin number to read
/// @return Pin state
bool digital_read(P pin) {
// Invalidate cache once per loop iteration so we always get a fresh
// hardware read on the first access each loop, while still caching
// within the same iteration for other pins in the same bank.
const uint32_t now = App.get_loop_component_start_time();
if (now != this->last_loop_time_) {
this->last_loop_time_ = now;
this->reset_pin_cache_();
}
const P bank = pin / BANK_SIZE;
const T pin_mask = (1 << (pin % BANK_SIZE));
// Check if specific pin cache is valid
@@ -78,7 +68,7 @@ class CachedGpioExpander {
/// @param value Pin state to write (true = HIGH, false = LOW)
virtual void digital_write_hw(P pin, bool value) = 0;
/// @brief Invalidate all cached pin states, forcing the next digital_read() to read from hardware.
/// @brief Invalidate cache. This function should be called in component loop().
void reset_pin_cache_() { memset(this->read_cache_valid_, 0x00, CACHE_SIZE_BYTES); }
static constexpr uint16_t BITS_PER_BYTE = 8;
@@ -86,7 +76,6 @@ class CachedGpioExpander {
static constexpr size_t BANKS = N / BANK_SIZE;
static constexpr size_t CACHE_SIZE_BYTES = BANKS * sizeof(T);
uint32_t last_loop_time_{0};
T read_cache_valid_[BANKS]{0};
};
+4
View File
@@ -26,6 +26,10 @@ void MCP23016::setup() {
this->write_reg_(MCP23016_IODIR1, 0xFFFF);
}
void MCP23016::loop() {
// Invalidate cache at the start of each loop
this->reset_pin_cache_();
}
bool MCP23016::digital_read_hw(uint8_t pin) { return this->read_reg_(MCP23016_GP1, &this->input_mask_); }
bool MCP23016::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
+1
View File
@@ -30,6 +30,7 @@ class MCP23016 : public Component, public i2c::I2CDevice, public gpio_expander::
MCP23016() = default;
void setup() override;
void loop() override;
void pin_mode(uint8_t pin, gpio::Flags flags);
float get_setup_priority() const override;
@@ -17,6 +17,8 @@ template<uint8_t N> class MCP23XXXBase : public Component, public gpio_expander:
void set_open_drain_ints(const bool value) { this->open_drain_ints_ = value; }
float get_setup_priority() const override { return setup_priority::IO; }
void loop() override { this->reset_pin_cache_(); }
protected:
// read a given register
virtual bool read_reg(uint8_t reg, uint8_t *value) = 0;
+5
View File
@@ -51,6 +51,11 @@ void PCA6416AComponent::setup() {
this->status_has_error());
}
void PCA6416AComponent::loop() {
// Invalidate cache at the start of each loop
this->reset_pin_cache_();
}
void PCA6416AComponent::dump_config() {
if (this->has_pullup_) {
ESP_LOGCONFIG(TAG, "PCAL6416A:");
+1
View File
@@ -16,6 +16,7 @@ class PCA6416AComponent : public Component,
/// Check i2c availability and setup masks
void setup() override;
void loop() override;
/// Helper function to set the pin mode of a pin.
void pin_mode(uint8_t pin, gpio::Flags flags);
+6
View File
@@ -36,6 +36,12 @@ void PCA9554Component::setup() {
this->status_has_error());
}
void PCA9554Component::loop() {
// Invalidate the cache at the start of each loop.
// The actual read will happen on demand when digital_read() is called
this->reset_pin_cache_();
}
void PCA9554Component::dump_config() {
ESP_LOGCONFIG(TAG,
"PCA9554:\n"
+2
View File
@@ -16,6 +16,8 @@ class PCA9554Component : public Component,
/// Check i2c availability and setup masks
void setup() override;
/// Invalidate cache at start of each loop
void loop() override;
/// Helper function to set the pin mode of a pin.
void pin_mode(uint8_t pin, gpio::Flags flags);
+4
View File
@@ -16,6 +16,10 @@ void PCF8574Component::setup() {
this->write_gpio_();
this->read_gpio_();
}
void PCF8574Component::loop() {
// Invalidate the cache at the start of each loop
this->reset_pin_cache_();
}
void PCF8574Component::dump_config() {
ESP_LOGCONFIG(TAG,
"PCF8574:\n"
+2
View File
@@ -20,6 +20,8 @@ class PCF8574Component : public Component,
/// Check i2c availability and setup masks
void setup() override;
/// Invalidate cache at start of each loop
void loop() override;
/// Helper function to set the pin mode of a pin.
void pin_mode(uint8_t pin, gpio::Flags flags);
@@ -60,6 +60,8 @@ void PI4IOE5V6408Component::pin_mode(uint8_t pin, gpio::Flags flags) {
this->write_gpio_modes_();
}
void PI4IOE5V6408Component::loop() { this->reset_pin_cache_(); }
bool PI4IOE5V6408Component::read_gpio_outputs_() {
if (this->is_failed())
return false;
@@ -18,6 +18,7 @@ class PI4IOE5V6408Component : public Component,
float get_setup_priority() const override;
void dump_config() override;
void loop() override;
/// Indicate if the component should reset the state during setup
void set_reset(bool reset) { this->reset_ = reset; }
+3
View File
@@ -39,6 +39,9 @@ void SX1509Component::dump_config() {
}
void SX1509Component::loop() {
// Reset cache at the start of each loop
this->reset_pin_cache_();
if (this->has_keypad_) {
if (millis() - this->last_loop_timestamp_ < min_loop_period_)
return;
+2
View File
@@ -43,6 +43,8 @@ void TCA9555Component::pin_mode(uint8_t pin, gpio::Flags flags) {
// Write GPIO to enable input mode
this->write_gpio_modes_();
}
void TCA9555Component::loop() { this->reset_pin_cache_(); }
bool TCA9555Component::read_gpio_outputs_() {
if (this->is_failed())
return false;
+2
View File
@@ -22,6 +22,8 @@ class TCA9555Component : public Component,
void dump_config() override;
void loop() override;
protected:
bool digital_read_hw(uint8_t pin) override;
bool digital_read_cache(uint8_t pin) override;