mirror of
https://github.com/esphome/esphome.git
synced 2025-11-01 23:51:47 +00:00
Compare commits
9 Commits
climate_st
...
max6956_gp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd616872a1 | ||
|
|
0272b53a17 | ||
|
|
2b2fb5958d | ||
|
|
3f6a490cf4 | ||
|
|
b424c16dde | ||
|
|
dd861ab9b6 | ||
|
|
938a3d8188 | ||
|
|
bdc299789f | ||
|
|
6e2c3f4981 |
@@ -15,6 +15,7 @@ from esphome.const import (
|
||||
CODEOWNERS = ["@looping40"]
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_BRIGHTNESS_MODE = "brightness_mode"
|
||||
|
||||
@@ -40,14 +40,59 @@ 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 based on the base class view (no offset adjustment)
|
||||
uint8_t bank_index = pin / MAX6956_BANK_SIZE;
|
||||
|
||||
static const uint8_t BANK_REGS[4] = {
|
||||
MAX6956_4PORTS_4_7, // Bank 0: 4 ports 4-7 (bits D0-D3, D4-D7 read as 0)
|
||||
MAX6956_8PORTS_8_15, // Bank 1: 8 ports 8-15 (bits D0-D7)
|
||||
MAX6956_8PORTS_16_23, // Bank 2: 8 ports 16-23 (bits D0-D7)
|
||||
MAX6956_8PORTS_24_31, // Bank 3: 8 ports 24-31 (bits D0-D7)
|
||||
};
|
||||
|
||||
// Read the appropriate register
|
||||
uint8_t value = 0;
|
||||
if (!this->read_reg_(BANK_REGS[bank_index], &value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store in cache with proper alignment
|
||||
if (bank_index == 0) {
|
||||
// Special case for bank 0: pins 4-7 are in bits D0-D3, shift them to bits 4-7
|
||||
this->input_banks_[0] = value << MAX6956_BANK0_SHIFT;
|
||||
} else {
|
||||
// Banks 1-3 map directly
|
||||
this->input_banks_[bank_index] = 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;
|
||||
}
|
||||
|
||||
// Use the base class's view of banks (no offset adjustment)
|
||||
uint8_t bank_index = pin / MAX6956_BANK_SIZE;
|
||||
uint8_t bit_position = 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);
|
||||
}
|
||||
|
||||
@@ -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,29 +22,39 @@ enum MAX6956GPIORange : uint8_t {
|
||||
MAX6956_MAX = 31,
|
||||
};
|
||||
|
||||
/// Bank configuration for MAX6956
|
||||
static constexpr uint8_t MAX6956_BANK_SIZE = 8;
|
||||
static constexpr uint8_t MAX6956_TOTAL_PINS = 32; // Includes pins 0-3 (unused) for cache alignment
|
||||
static constexpr uint8_t MAX6956_BANK0_SHIFT = 4;
|
||||
|
||||
enum MAX6956GPIORegisters {
|
||||
MAX6956_GLOBAL_CURRENT = 0x02,
|
||||
MAX6956_CONFIGURATION = 0x04,
|
||||
MAX6956_TRANSITION_DETECT_MASK = 0x06,
|
||||
MAX6956_DISPLAY_TEST = 0x07,
|
||||
MAX6956_PORT_CONFIG_START = 0x09, // Port Configuration P7, P6, P5, P4
|
||||
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)
|
||||
MAX6956_PORT_CONFIG_START = 0x09, // Port Configuration P7, P6, P5, P4
|
||||
MAX6956_CURRENT_START = 0x12, // Current054
|
||||
MAX6956_1PORT_VALUE_START = 0x20, // Port 0 only (virtual port, no action)
|
||||
// 8-port bulk read registers aligned with base class banks
|
||||
MAX6956_4PORTS_4_7 = 0x40, // 4 ports 4-7 (bits D0-D3, D4-D7 read as 0)
|
||||
MAX6956_8PORTS_8_15 = 0x48, // 8 ports 8-15 (bits D0-D7)
|
||||
MAX6956_8PORTS_16_23 = 0x50, // 8 ports 16-23 (bits D0-D7)
|
||||
MAX6956_8PORTS_24_31 = 0x58, // 8 ports 24-31 (bits D0-D7)
|
||||
};
|
||||
|
||||
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, MAX6956_TOTAL_PINS> {
|
||||
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 +69,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 +82,13 @@ class MAX6956 : public Component, public i2c::I2CDevice {
|
||||
max6956::MAX6956CURRENTMODE brightness_mode_;
|
||||
uint8_t global_brightness_;
|
||||
|
||||
// Cache for the 4 banks of 8 pins each (aligned with base class view)
|
||||
// Bank 0: bits 0-7 (bits 0-3 unused as MAX6956 pins start at 4, bits 4-7 = pins 4-7)
|
||||
// Bank 1: bits 8-15 (pins 8-15)
|
||||
// Bank 2: bits 16-23 (pins 16-23)
|
||||
// Bank 3: bits 24-31 (pins 24-31)
|
||||
uint8_t input_banks_[4] = {0, 0, 0, 0};
|
||||
|
||||
private:
|
||||
int8_t prev_bright_[28] = {0};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user