mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	[pca6416a] Migrate to CachedGpioExpander to reduce I2C bus usage (#10587)
This commit is contained in:
		| @@ -14,6 +14,7 @@ from esphome.const import ( | ||||
|  | ||||
| CODEOWNERS = ["@Mat931"] | ||||
| DEPENDENCIES = ["i2c"] | ||||
| AUTO_LOAD = ["gpio_expander"] | ||||
| MULTI_CONF = True | ||||
| pca6416a_ns = cg.esphome_ns.namespace("pca6416a") | ||||
|  | ||||
|   | ||||
| @@ -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:"); | ||||
| @@ -63,15 +68,25 @@ void PCA6416AComponent::dump_config() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| bool PCA6416AComponent::digital_read(uint8_t pin) { | ||||
|   uint8_t bit = pin % 8; | ||||
| bool PCA6416AComponent::digital_read_hw(uint8_t pin) { | ||||
|   uint8_t reg_addr = pin < 8 ? PCA6416A_INPUT0 : PCA6416A_INPUT1; | ||||
|   uint8_t value = 0; | ||||
|   this->read_register_(reg_addr, &value); | ||||
|   return value & (1 << bit); | ||||
|   if (!this->read_register_(reg_addr, &value)) { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // Update the appropriate part of input_mask_ | ||||
|   if (pin < 8) { | ||||
|     this->input_mask_ = (this->input_mask_ & 0xFF00) | value; | ||||
|   } else { | ||||
|     this->input_mask_ = (this->input_mask_ & 0x00FF) | (uint16_t(value) << 8); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void PCA6416AComponent::digital_write(uint8_t pin, bool value) { | ||||
| bool PCA6416AComponent::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); } | ||||
|  | ||||
| void PCA6416AComponent::digital_write_hw(uint8_t pin, bool value) { | ||||
|   uint8_t reg_addr = pin < 8 ? PCA6416A_OUTPUT0 : PCA6416A_OUTPUT1; | ||||
|   this->update_register_(pin, value, reg_addr); | ||||
| } | ||||
|   | ||||
| @@ -3,20 +3,20 @@ | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/components/i2c/i2c.h" | ||||
| #include "esphome/components/gpio_expander/cached_gpio.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace pca6416a { | ||||
|  | ||||
| class PCA6416AComponent : public Component, public i2c::I2CDevice { | ||||
| class PCA6416AComponent : public Component, | ||||
|                           public i2c::I2CDevice, | ||||
|                           public gpio_expander::CachedGpioExpander<uint8_t, 16> { | ||||
|  public: | ||||
|   PCA6416AComponent() = default; | ||||
|  | ||||
|   /// Check i2c availability and setup masks | ||||
|   void setup() override; | ||||
|   /// Helper function to read the value of a pin. | ||||
|   bool digital_read(uint8_t pin); | ||||
|   /// Helper function to write the value of a pin. | ||||
|   void digital_write(uint8_t pin, bool value); | ||||
|   void loop() override; | ||||
|   /// Helper function to set the pin mode of a pin. | ||||
|   void pin_mode(uint8_t pin, gpio::Flags flags); | ||||
|  | ||||
| @@ -25,6 +25,11 @@ class PCA6416AComponent : public Component, public i2c::I2CDevice { | ||||
|   void dump_config() override; | ||||
|  | ||||
|  protected: | ||||
|   // Virtual methods from CachedGpioExpander | ||||
|   bool digital_read_hw(uint8_t pin) override; | ||||
|   bool digital_read_cache(uint8_t pin) override; | ||||
|   void digital_write_hw(uint8_t pin, bool value) override; | ||||
|  | ||||
|   bool read_register_(uint8_t reg, uint8_t *value); | ||||
|   bool write_register_(uint8_t reg, uint8_t value); | ||||
|   void update_register_(uint8_t pin, bool pin_value, uint8_t reg_addr); | ||||
| @@ -32,6 +37,8 @@ class PCA6416AComponent : public Component, public i2c::I2CDevice { | ||||
|   /// The mask to write as output state - 1 means HIGH, 0 means LOW | ||||
|   uint8_t output_0_{0x00}; | ||||
|   uint8_t output_1_{0x00}; | ||||
|   /// Cache for input values (16-bit combined for both banks) | ||||
|   uint16_t input_mask_{0x00}; | ||||
|   /// Storage for last I2C error seen | ||||
|   esphome::i2c::ErrorCode last_error_; | ||||
|   /// Only the PCAL6416A has pull-up resistors | ||||
|   | ||||
		Reference in New Issue
	
	Block a user