[max6956] Migrate to CachedGpioExpander to reduce I2C bus usage

This commit is contained in:
J. Nick Koston
2025-09-04 15:35:26 -05:00
parent e0617e01e0
commit 6e2c3f4981
3 changed files with 69 additions and 11 deletions
+1
View File
@@ -15,6 +15,7 @@ from esphome.const import (
CODEOWNERS = ["@looping40"]
DEPENDENCIES = ["i2c"]
AUTO_LOAD = ["gpio_expander"]
MULTI_CONF = True
CONF_BRIGHTNESS_MODE = "brightness_mode"
+49 -8
View File
@@ -40,14 +40,55 @@ void MAX6956::setup() {
ESP_LOGD(TAG, "setup reg[0x%.2X]=0x%.2X", MAX6956_CONFIGURATION, configuration);
}
bool MAX6956::digital_read(uint8_t pin) {
uint8_t reg_addr = MAX6956_1PORT_VALUE_START + pin;
uint8_t value = 0;
this->read_reg_(reg_addr, &value);
return (value & MASK_1PORT_VALUE);
void MAX6956::loop() {
// Invalidate cache at the start of each loop
this->reset_pin_cache_();
}
void MAX6956::digital_write(uint8_t pin, bool value) {
bool MAX6956::digital_read_hw(uint8_t pin) {
// MAX6956 pins start at MAX6956_MIN
if (pin < MAX6956_MIN || pin > MAX6956_MAX) {
return false;
}
// Calculate bank index
uint8_t bank_index = (pin - MAX6956_MIN) / MAX6956_BANK_SIZE;
// Register addresses for each bank
static const uint8_t bank_regs[4] = {
MAX6956_8PORTS_VALUE_START, // 0x44 - ports 4-11
MAX6956_8PORTS_12_19, // 0x4C - ports 12-19
MAX6956_8PORTS_20_27, // 0x54 - ports 20-27
MAX6956_8PORTS_24_31 // 0x58 - ports 24-31
};
// Read the 8-port bank register
uint8_t bank_value = 0;
if (!this->read_reg_(bank_regs[bank_index], &bank_value)) {
return false;
}
// Store the bank value in our cache
this->input_banks_[bank_index] = bank_value;
return true;
}
bool MAX6956::digital_read_cache(uint8_t pin) {
// MAX6956 pins start at MAX6956_MIN
if (pin < MAX6956_MIN || pin > MAX6956_MAX) {
return false;
}
// Calculate bank index and bit position
uint8_t adjusted_pin = pin - MAX6956_MIN;
uint8_t bank_index = adjusted_pin / MAX6956_BANK_SIZE;
uint8_t bit_position = adjusted_pin % MAX6956_BANK_SIZE;
return (this->input_banks_[bank_index] & (1 << bit_position)) != 0;
}
void MAX6956::digital_write_hw(uint8_t pin, bool value) {
uint8_t reg_addr = MAX6956_1PORT_VALUE_START + pin;
this->write_reg_(reg_addr, value);
}
@@ -159,8 +200,8 @@ void MAX6956::dump_config() {
**************************************/
void MAX6956GPIOPin::setup() { pin_mode(flags_); }
void MAX6956GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
bool MAX6956GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
void MAX6956GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
bool MAX6956GPIOPin::digital_read() { return this->parent_->read_pin_cached(this->pin_) != this->inverted_; }
void MAX6956GPIOPin::digital_write(bool value) { this->parent_->write_pin(this->pin_, value != this->inverted_); }
std::string MAX6956GPIOPin::dump_summary() const {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%u via Max6956", pin_);
+19 -3
View File
@@ -3,6 +3,7 @@
#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 max6956 {
@@ -21,6 +22,9 @@ enum MAX6956GPIORange : uint8_t {
MAX6956_MAX = 31,
};
/// Bank configuration for MAX6956
static constexpr uint8_t MAX6956_BANK_SIZE = 8;
enum MAX6956GPIORegisters {
MAX6956_GLOBAL_CURRENT = 0x02,
MAX6956_CONFIGURATION = 0x04,
@@ -30,20 +34,23 @@ enum MAX6956GPIORegisters {
MAX6956_CURRENT_START = 0x12, // Current054
MAX6956_1PORT_VALUE_START = 0x20, // Port 0 only (virtual port, no action)
MAX6956_8PORTS_VALUE_START = 0x44, // 8 ports 4-11 (data bits D0-D7)
// Additional 8-port bulk read registers
MAX6956_8PORTS_12_19 = 0x4C, // 8 ports 12-19
MAX6956_8PORTS_20_27 = 0x54, // 8 ports 20-27
MAX6956_8PORTS_24_31 = 0x58, // 8 ports 24-31
};
enum MAX6956GPIOFlag { FLAG_LED = 0x20 };
enum MAX6956CURRENTMODE { GLOBAL = 0x00, SEGMENT = 0x01 };
class MAX6956 : public Component, public i2c::I2CDevice {
class MAX6956 : public Component, public i2c::I2CDevice, public gpio_expander::CachedGpioExpander<uint8_t, 28> {
public:
MAX6956() = default;
void setup() override;
void loop() override;
bool digital_read(uint8_t pin);
void digital_write(uint8_t pin, bool value);
void pin_mode(uint8_t pin, gpio::Flags flags);
void pin_mode(uint8_t pin, max6956::MAX6956GPIOFlag flags);
@@ -58,6 +65,11 @@ class MAX6956 : public Component, public i2c::I2CDevice {
void write_brightness_global();
void write_brightness_mode();
// CachedGpioExpander implementation
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;
protected:
// read a given register
bool read_reg_(uint8_t reg, uint8_t *value);
@@ -66,6 +78,10 @@ class MAX6956 : public Component, public i2c::I2CDevice {
max6956::MAX6956CURRENTMODE brightness_mode_;
uint8_t global_brightness_;
// Cache for the 4 banks of 8 pins each
// Bank 0: pins 4-11, Bank 1: pins 12-19, Bank 2: pins 20-27, Bank 3: pins 24-31
uint8_t input_banks_[4] = {0, 0, 0, 0};
private:
int8_t prev_bright_[28] = {0};
};