mirror of
https://github.com/esphome/esphome.git
synced 2025-09-12 00:02:21 +01: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