mirror of
https://github.com/esphome/esphome.git
synced 2025-10-29 22:24:26 +00:00
Merge branch 'integration' into memory_api
This commit is contained in:
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -70,7 +70,7 @@ jobs:
|
||||
pip3 install build
|
||||
python3 -m build
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@v1.12.4
|
||||
uses: pypa/gh-action-pypi-publish@v1.13.0
|
||||
with:
|
||||
skip-existing: true
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from esphome.const import (
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
|
||||
@@ -22,14 +22,29 @@ void MCP23016::setup() {
|
||||
this->write_reg_(MCP23016_IODIR0, 0xFF);
|
||||
this->write_reg_(MCP23016_IODIR1, 0xFF);
|
||||
}
|
||||
bool MCP23016::digital_read(uint8_t pin) {
|
||||
uint8_t bit = pin % 8;
|
||||
|
||||
void MCP23016::loop() {
|
||||
// Invalidate cache at the start of each loop
|
||||
this->reset_pin_cache_();
|
||||
}
|
||||
bool MCP23016::digital_read_hw(uint8_t pin) {
|
||||
uint8_t reg_addr = pin < 8 ? MCP23016_GP0 : MCP23016_GP1;
|
||||
uint8_t value = 0;
|
||||
this->read_reg_(reg_addr, &value);
|
||||
return value & (1 << bit);
|
||||
if (!this->read_reg_(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 MCP23016::digital_write(uint8_t pin, bool value) {
|
||||
|
||||
bool MCP23016::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
|
||||
void MCP23016::digital_write_hw(uint8_t pin, bool value) {
|
||||
uint8_t reg_addr = pin < 8 ? MCP23016_OLAT0 : MCP23016_OLAT1;
|
||||
this->update_reg_(pin, value, reg_addr);
|
||||
}
|
||||
@@ -41,7 +56,7 @@ void MCP23016::pin_mode(uint8_t pin, gpio::Flags flags) {
|
||||
this->update_reg_(pin, false, iodir);
|
||||
}
|
||||
}
|
||||
float MCP23016::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
float MCP23016::get_setup_priority() const { return setup_priority::IO; }
|
||||
bool MCP23016::read_reg_(uint8_t reg, uint8_t *value) {
|
||||
if (this->is_failed())
|
||||
return false;
|
||||
|
||||
@@ -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 mcp23016 {
|
||||
@@ -24,19 +25,22 @@ enum MCP23016GPIORegisters {
|
||||
MCP23016_IOCON1 = 0x0B,
|
||||
};
|
||||
|
||||
class MCP23016 : public Component, public i2c::I2CDevice {
|
||||
class MCP23016 : public Component, public i2c::I2CDevice, public gpio_expander::CachedGpioExpander<uint8_t, 16> {
|
||||
public:
|
||||
MCP23016() = default;
|
||||
|
||||
void setup() override;
|
||||
|
||||
bool digital_read(uint8_t pin);
|
||||
void digital_write(uint8_t pin, bool value);
|
||||
void loop() override;
|
||||
void pin_mode(uint8_t pin, gpio::Flags flags);
|
||||
|
||||
float get_setup_priority() const 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;
|
||||
|
||||
// read a given register
|
||||
bool read_reg_(uint8_t reg, uint8_t *value);
|
||||
// write a value to a given register
|
||||
@@ -46,6 +50,8 @@ class MCP23016 : public Component, public i2c::I2CDevice {
|
||||
|
||||
uint8_t olat_0_{0x00};
|
||||
uint8_t olat_1_{0x00};
|
||||
// Cache for input values (16-bit combined for both banks)
|
||||
uint16_t input_mask_{0x00};
|
||||
};
|
||||
|
||||
class MCP23016GPIOPin : public GPIOPin {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -25,7 +25,7 @@ CONF_SCAN_TIME = "scan_time"
|
||||
CONF_DEBOUNCE_TIME = "debounce_time"
|
||||
CONF_SX1509_ID = "sx1509_id"
|
||||
|
||||
AUTO_LOAD = ["key_provider"]
|
||||
AUTO_LOAD = ["key_provider", "gpio_expander"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -73,18 +76,20 @@ void SX1509Component::loop() {
|
||||
}
|
||||
}
|
||||
|
||||
bool SX1509Component::digital_read(uint8_t pin) {
|
||||
bool SX1509Component::digital_read_hw(uint8_t pin) {
|
||||
// Always read all pins when any input pin is accessed
|
||||
return this->read_byte_16(REG_DATA_B, &this->input_mask_);
|
||||
}
|
||||
|
||||
bool SX1509Component::digital_read_cache(uint8_t pin) {
|
||||
// Return cached value for input pins, false for output pins
|
||||
if (this->ddr_mask_ & (1 << pin)) {
|
||||
uint16_t temp_reg_data;
|
||||
if (!this->read_byte_16(REG_DATA_B, &temp_reg_data))
|
||||
return false;
|
||||
if (temp_reg_data & (1 << pin))
|
||||
return true;
|
||||
return this->input_mask_ & (1 << pin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SX1509Component::digital_write(uint8_t pin, bool bit_value) {
|
||||
void SX1509Component::digital_write_hw(uint8_t pin, bool bit_value) {
|
||||
if ((~this->ddr_mask_) & (1 << pin)) {
|
||||
// If the pin is an output, write high/low
|
||||
uint16_t temp_reg_data = 0;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/key_provider/key_provider.h"
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "sx1509_gpio_pin.h"
|
||||
@@ -30,7 +31,10 @@ class SX1509Processor {
|
||||
|
||||
class SX1509KeyTrigger : public Trigger<uint8_t> {};
|
||||
|
||||
class SX1509Component : public Component, public i2c::I2CDevice, public key_provider::KeyProvider {
|
||||
class SX1509Component : public Component,
|
||||
public i2c::I2CDevice,
|
||||
public gpio_expander::CachedGpioExpander<uint16_t, 16>,
|
||||
public key_provider::KeyProvider {
|
||||
public:
|
||||
SX1509Component() = default;
|
||||
|
||||
@@ -39,11 +43,9 @@ class SX1509Component : public Component, public i2c::I2CDevice, public key_prov
|
||||
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
void loop() override;
|
||||
|
||||
bool digital_read(uint8_t pin);
|
||||
uint16_t read_key_data();
|
||||
void set_pin_value(uint8_t pin, uint8_t i_on) { this->write_byte(REG_I_ON[pin], i_on); };
|
||||
void pin_mode(uint8_t pin, gpio::Flags flags);
|
||||
void digital_write(uint8_t pin, bool bit_value);
|
||||
uint32_t get_clock() { return this->clk_x_; };
|
||||
void set_rows_cols(uint8_t rows, uint8_t cols) {
|
||||
this->rows_ = rows;
|
||||
@@ -61,10 +63,15 @@ class SX1509Component : public Component, public i2c::I2CDevice, public key_prov
|
||||
void setup_led_driver(uint8_t pin);
|
||||
|
||||
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;
|
||||
|
||||
uint32_t clk_x_ = 2000000;
|
||||
uint8_t frequency_ = 0;
|
||||
uint16_t ddr_mask_ = 0x00;
|
||||
uint16_t input_mask_ = 0x00;
|
||||
uint16_t input_mask_ = 0x00; // Cache for input values (16-bit for all pins)
|
||||
uint16_t port_mask_ = 0x00;
|
||||
uint16_t output_state_ = 0x00;
|
||||
bool has_keypad_ = false;
|
||||
|
||||
Reference in New Issue
Block a user