mirror of
https://github.com/esphome/esphome.git
synced 2026-10-19 04:32:50 +00:00
[gpio_expander][pcf8574][mpr121][ch422g][ch423][pcm5122][weikai] Move the GPIO expanders and pin providers onto the shared pin helpers (#20868)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
pre-commit-ci-lite[bot]
parent
ded5ad6cb1
commit
28e43235fa
@@ -7,7 +7,6 @@ from esphome.const import (
|
||||
CONF_I2C_ID,
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OPEN_DRAIN,
|
||||
@@ -18,6 +17,7 @@ from esphome.types import ConfigType
|
||||
|
||||
CODEOWNERS = ["@jesterret", "@clydebarrow"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
DOMAIN = "ch422g"
|
||||
MULTI_CONF = True
|
||||
ch422g_ns = cg.esphome_ns.namespace("ch422g")
|
||||
@@ -66,13 +66,10 @@ CH422G_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_CH422G, CH422G_PIN_SCHEMA, pin_mode_check)
|
||||
async def ch422g_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
var = await pins.new_parented_pin(config, CONF_CH422G)
|
||||
# The parent collects every pin's mode before its setup() writes the mode register
|
||||
parent = await cg.get_variable(config[CONF_CH422G])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
cg.add(
|
||||
parent.pin_mode(config[CONF_NUMBER], pins.gpio_flags_expr(config[CONF_MODE]))
|
||||
)
|
||||
return var
|
||||
|
||||
@@ -120,16 +120,6 @@ bool CH422GComponent::write_outputs_() {
|
||||
|
||||
float CH422GComponent::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
|
||||
|
||||
void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value ^ this->inverted_); }
|
||||
size_t CH422GGPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "EXIO%u via CH422G", this->pin_);
|
||||
}
|
||||
void CH422GGPIOPin::set_flags(gpio::Flags flags) {
|
||||
flags_ = flags;
|
||||
this->parent_->pin_mode(this->pin_, flags);
|
||||
}
|
||||
|
||||
} // namespace esphome::ch422g
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::ch422g::CH422GComponent, "EXIO%u via CH422G")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
@@ -42,26 +43,8 @@ class CH422GComponent final : public Component, public i2c::I2CDevice {
|
||||
};
|
||||
|
||||
/// Helper class to expose a CH422G pin as a GPIO pin.
|
||||
class CH422GGPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override{};
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(CH422GComponent *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags);
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
CH422GComponent *parent_{};
|
||||
uint8_t pin_{};
|
||||
bool inverted_{};
|
||||
gpio::Flags flags_{};
|
||||
};
|
||||
using CH422GGPIOPin = gpio_expander::ExpanderGPIOPin<CH422GComponent>;
|
||||
|
||||
} // namespace esphome::ch422g
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::ch422g::CH422GComponent);
|
||||
|
||||
@@ -7,7 +7,6 @@ from esphome.const import (
|
||||
CONF_I2C_ID,
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OPEN_DRAIN,
|
||||
@@ -19,6 +18,7 @@ from esphome.types import ConfigType
|
||||
|
||||
CODEOWNERS = ["@dwmw2"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
DOMAIN = "ch423"
|
||||
MULTI_CONF = True
|
||||
ch423_ns = cg.esphome_ns.namespace("ch423")
|
||||
@@ -93,13 +93,10 @@ CH423_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_CH423, CH423_PIN_SCHEMA, pin_mode_check)
|
||||
async def ch423_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
var = await pins.new_parented_pin(config, CONF_CH423)
|
||||
# The parent collects every pin's mode before its setup() writes the mode register
|
||||
parent = await cg.get_variable(config[CONF_CH423])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
cg.add(
|
||||
parent.pin_mode(config[CONF_NUMBER], pins.gpio_flags_expr(config[CONF_MODE]))
|
||||
)
|
||||
return var
|
||||
|
||||
@@ -123,16 +123,6 @@ bool CH423Component::write_outputs_() {
|
||||
|
||||
float CH423Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void CH423GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool CH423GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
|
||||
|
||||
void CH423GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value ^ this->inverted_); }
|
||||
size_t CH423GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return snprintf(buffer, len, "EXIO%u via CH423", this->pin_);
|
||||
}
|
||||
void CH423GPIOPin::set_flags(gpio::Flags flags) {
|
||||
flags_ = flags;
|
||||
this->parent_->pin_mode(this->pin_, flags);
|
||||
}
|
||||
|
||||
} // namespace esphome::ch423
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::ch423::CH423Component, "EXIO%u via CH423")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
@@ -41,26 +42,8 @@ class CH423Component final : public Component, public i2c::I2CDevice {
|
||||
};
|
||||
|
||||
/// Helper class to expose a CH423 pin as a GPIO pin.
|
||||
class CH423GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override{};
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(CH423Component *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags);
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
CH423Component *parent_{};
|
||||
uint8_t pin_{};
|
||||
bool inverted_{};
|
||||
gpio::Flags flags_{};
|
||||
};
|
||||
using CH423GPIOPin = gpio_expander::ExpanderGPIOPin<CH423Component>;
|
||||
|
||||
} // namespace esphome::ch423
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::ch423::CH423Component);
|
||||
|
||||
@@ -2,21 +2,14 @@ from esphome import automation, pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
CONF_PULLUP,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_INPUT, CONF_OUTPUT, CONF_PULLUP
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CODEOWNERS = ["@looping40"]
|
||||
DOMAIN = "max6956"
|
||||
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
@@ -56,23 +49,13 @@ async def to_code(config: ConfigType) -> None:
|
||||
cg.add(var.set_brightness_global(config[CONF_BRIGHTNESS_GLOBAL]))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_PULLUP] and not value[CONF_INPUT]:
|
||||
raise cv.Invalid("Pullup only available with input")
|
||||
return value
|
||||
|
||||
|
||||
CONF_MAX6956 = "max6956"
|
||||
|
||||
MAX6956_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
MAX6956GPIOPin,
|
||||
cv.int_range(min=4, max=31),
|
||||
modes=[CONF_INPUT, CONF_PULLUP, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output_pullup,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_MAX6956): pins.use_id_or_address(MAX6956),
|
||||
@@ -82,16 +65,7 @@ MAX6956_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MAX6956, MAX6956_PIN_SCHEMA)
|
||||
async def max6956_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_MAX6956])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_MAX6956)
|
||||
|
||||
|
||||
automation.register_apply_action(
|
||||
|
||||
@@ -155,15 +155,6 @@ void MAX6956::dump_config() {
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* MAX6956GPIOPin *
|
||||
**************************************/
|
||||
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_); }
|
||||
size_t MAX6956GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via Max6956", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::max6956
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::max6956::MAX6956, "%u via Max6956")
|
||||
|
||||
@@ -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/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::max6956 {
|
||||
|
||||
@@ -69,26 +70,8 @@ class MAX6956 final : public Component, public i2c::I2CDevice {
|
||||
int8_t prev_bright_[28] = {0};
|
||||
};
|
||||
|
||||
class MAX6956GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(MAX6956 *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
MAX6956 *parent_;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using MAX6956GPIOPin = gpio_expander::ExpanderGPIOPin<MAX6956>;
|
||||
|
||||
} // namespace esphome::max6956
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::max6956::MAX6956);
|
||||
|
||||
@@ -2,15 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import gpio_expander, i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_INPUT, CONF_INTERRUPT_PIN, CONF_OUTPUT
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -41,20 +33,12 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
CONF_MCP23016 = "mcp23016"
|
||||
MCP23016_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
MCP23016GPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
invertible=True,
|
||||
).extend(
|
||||
{
|
||||
@@ -65,13 +49,4 @@ MCP23016_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23016, MCP23016_PIN_SCHEMA)
|
||||
async def mcp23016_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_MCP23016])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_MCP23016)
|
||||
|
||||
@@ -92,12 +92,6 @@ void MCP23016::update_reg_(uint8_t pin, bool pin_value, uint8_t reg_addr) {
|
||||
}
|
||||
}
|
||||
|
||||
void MCP23016GPIOPin::setup() { pin_mode(flags_); }
|
||||
void MCP23016GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool MCP23016GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void MCP23016GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
size_t MCP23016GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via MCP23016", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::mcp23016
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::mcp23016::MCP23016, "%u via MCP23016")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::mcp23016 {
|
||||
|
||||
@@ -56,26 +57,8 @@ class MCP23016 final : public Component, public i2c::I2CDevice, public gpio_expa
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
class MCP23016GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(MCP23016 *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
MCP23016 *parent_;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using MCP23016GPIOPin = gpio_expander::ExpanderGPIOPin<MCP23016>;
|
||||
|
||||
} // namespace esphome::mcp23016
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::mcp23016::MCP23016);
|
||||
|
||||
@@ -7,9 +7,6 @@ from esphome.const import (
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OPEN_DRAIN_INTERRUPT,
|
||||
CONF_OUTPUT,
|
||||
CONF_PULLUP,
|
||||
@@ -51,23 +48,13 @@ async def register_mcp23xxx(config: ConfigType, num_pins: int) -> MockObj:
|
||||
return var
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_PULLUP] and not value[CONF_INPUT]:
|
||||
raise cv.Invalid("Pullup only available with input")
|
||||
return value
|
||||
|
||||
|
||||
CONF_MCP23XXX = "mcp23xxx"
|
||||
|
||||
MCP23XXX_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
MCP23XXXGPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT, CONF_PULLUP],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output_pullup,
|
||||
invertible=True,
|
||||
).extend(
|
||||
{
|
||||
@@ -82,16 +69,9 @@ MCP23XXX_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23XXX, MCP23XXX_PIN_SCHEMA)
|
||||
async def mcp23xxx_pin_to_code(config: ConfigType) -> MockObj:
|
||||
parent_id: ID = config[CONF_MCP23XXX]
|
||||
parent = await cg.get_variable(parent_id)
|
||||
|
||||
# Wait for the hub so its to_code has recorded the pin count
|
||||
await cg.get_variable(parent_id)
|
||||
num_pins = cg.TemplateArguments(CORE.data[CONF_MCP23XXX][parent_id.id])
|
||||
|
||||
var = cg.new_Pvariable(config[CONF_ID], num_pins)
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
var = await pins.new_parented_pin(config, CONF_MCP23XXX, num_pins)
|
||||
cg.add(var.set_interrupt_mode(config[CONF_INTERRUPT]))
|
||||
return var
|
||||
|
||||
@@ -7,8 +7,6 @@ from esphome.const import (
|
||||
CONF_CHANNEL,
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
@@ -24,12 +22,15 @@ CONF_MAX_TOUCH_CHANNEL = "max_touch_channel"
|
||||
CONF_MPR121 = "mpr121"
|
||||
CONF_MPR121_ID = "mpr121_id"
|
||||
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
DOMAIN = "mpr121"
|
||||
|
||||
mpr121_ns = cg.esphome_ns.namespace("mpr121")
|
||||
MPR121Component = mpr121_ns.class_("MPR121Component", cg.Component, i2c.I2CDevice)
|
||||
MPR121GPIOPin = mpr121_ns.class_("MPR121GPIOPin", cg.GPIOPin)
|
||||
MPR121GPIOPin = mpr121_ns.class_(
|
||||
"MPR121GPIOPin", cg.GPIOPin, cg.Parented.template(MPR121Component)
|
||||
)
|
||||
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = (
|
||||
@@ -85,12 +86,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if bool(value[CONF_INPUT]) == bool(value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
# https://www.nxp.com/docs/en/data-sheet/MPR121.pdf, page 4
|
||||
#
|
||||
# Among the 12 electrode inputs, 8 inputs are designed as multifunctional pins. When these pins are
|
||||
@@ -100,7 +95,7 @@ MPR121_GPIO_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
MPR121GPIOPin,
|
||||
cv.int_range(min=4, max=11),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_MPR121): cv.use_id(MPR121Component),
|
||||
@@ -121,13 +116,4 @@ def mpr121_pin_final_validate(
|
||||
CONF_MPR121, MPR121_GPIO_PIN_SCHEMA, mpr121_pin_final_validate
|
||||
)
|
||||
async def mpr121_gpio_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_MPR121])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_MPR121)
|
||||
|
||||
@@ -80,9 +80,10 @@ void MPR121Component::loop() {
|
||||
this->read_byte(MPR121_GPIODATA, &this->gpio_input_);
|
||||
}
|
||||
|
||||
bool MPR121Component::digital_read(uint8_t ionum) { return (this->gpio_input_ & (1 << ionum)) != 0; }
|
||||
bool MPR121Component::digital_read(uint8_t pin) { return (this->gpio_input_ & (1 << (pin - 4))) != 0; }
|
||||
|
||||
void MPR121Component::digital_write(uint8_t ionum, bool value) {
|
||||
void MPR121Component::digital_write(uint8_t pin, bool value) {
|
||||
const uint8_t ionum = pin - 4;
|
||||
if (value) {
|
||||
this->gpio_output_ |= (1 << ionum);
|
||||
} else {
|
||||
@@ -91,7 +92,8 @@ void MPR121Component::digital_write(uint8_t ionum, bool value) {
|
||||
this->flush_gpio_();
|
||||
}
|
||||
|
||||
void MPR121Component::pin_mode(uint8_t ionum, gpio::Flags flags) {
|
||||
void MPR121Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
||||
const uint8_t ionum = pin - 4;
|
||||
this->gpio_enable_ |= (1 << ionum);
|
||||
if (flags & gpio::FLAG_INPUT) {
|
||||
this->gpio_direction_ &= ~(1 << ionum);
|
||||
@@ -115,25 +117,6 @@ bool MPR121Component::flush_gpio_() {
|
||||
return this->status_comm_result(this->write_byte(MPR121_GPIODATA, this->gpio_output_));
|
||||
}
|
||||
|
||||
void MPR121GPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||
|
||||
void MPR121GPIOPin::pin_mode(gpio::Flags flags) {
|
||||
assert(this->pin_ >= 4);
|
||||
this->parent_->pin_mode(this->pin_ - 4, flags);
|
||||
}
|
||||
|
||||
bool MPR121GPIOPin::digital_read() {
|
||||
assert(this->pin_ >= 4);
|
||||
return this->parent_->digital_read(this->pin_ - 4) != this->inverted_;
|
||||
}
|
||||
|
||||
void MPR121GPIOPin::digital_write(bool value) {
|
||||
assert(this->pin_ >= 4);
|
||||
this->parent_->digital_write(this->pin_ - 4, value != this->inverted_);
|
||||
}
|
||||
|
||||
size_t MPR121GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "ELE%u on MPR121", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::mpr121
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::mpr121::MPR121Component, "ELE%u on MPR121")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -73,10 +74,10 @@ class MPR121Component final : public Component, public i2c::I2CDevice {
|
||||
|
||||
void set_max_touch_channel(uint8_t max_touch_channel) { this->max_touch_channel_ = max_touch_channel; }
|
||||
|
||||
// GPIO helper functions.
|
||||
bool digital_read(uint8_t ionum);
|
||||
void digital_write(uint8_t ionum, bool value);
|
||||
void pin_mode(uint8_t ionum, gpio::Flags flags);
|
||||
// GPIO helper functions; `pin` is the electrode number, 4 to 11, of the shared GPIO pins.
|
||||
bool digital_read(uint8_t pin);
|
||||
void digital_write(uint8_t pin, bool value);
|
||||
void pin_mode(uint8_t pin, gpio::Flags flags);
|
||||
|
||||
protected:
|
||||
std::vector<MPR121Channel *> channels_{};
|
||||
@@ -98,26 +99,8 @@ class MPR121Component final : public Component, public i2c::I2CDevice {
|
||||
};
|
||||
|
||||
/// Helper class to expose a MPR121 pin as an internal input GPIO pin.
|
||||
class MPR121GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(MPR121Component *parent) { this->parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
MPR121Component *parent_;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using MPR121GPIOPin = gpio_expander::ExpanderGPIOPin<MPR121Component>;
|
||||
|
||||
} // namespace esphome::mpr121
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::mpr121::MPR121Component);
|
||||
|
||||
@@ -6,9 +6,6 @@ from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
CONF_PULLUP,
|
||||
)
|
||||
@@ -45,43 +42,18 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_PULLUP] and not value[CONF_INPUT]:
|
||||
raise cv.Invalid("Pullup only available with input")
|
||||
return value
|
||||
|
||||
|
||||
PCA6416A_PIN_SCHEMA = cv.All(
|
||||
PCA6416A_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
PCA6416AGPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_PULLUP, CONF_OUTPUT],
|
||||
mode_validator=pins.gpio_validate_input_xor_output_pullup,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PCA6416AGPIOPin),
|
||||
cv.Required(CONF_PCA6416A): pins.use_id_or_address(PCA6416AComponent),
|
||||
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_MODE, default={}): cv.All(
|
||||
{
|
||||
cv.Optional(CONF_INPUT, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
|
||||
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
|
||||
},
|
||||
validate_mode,
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_PCA6416A, PCA6416A_PIN_SCHEMA)
|
||||
async def pca6416a_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_PCA6416A])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_PCA6416A)
|
||||
|
||||
@@ -187,12 +187,6 @@ void PCA6416AComponent::update_register_(uint8_t pin, bool pin_value, uint8_t re
|
||||
|
||||
float PCA6416AComponent::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void PCA6416AGPIOPin::setup() { pin_mode(flags_); }
|
||||
void PCA6416AGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool PCA6416AGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void PCA6416AGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
size_t PCA6416AGPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via PCA6416A", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::pca6416a
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::pca6416a::PCA6416AComponent, "%u via PCA6416A")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::pca6416a {
|
||||
|
||||
@@ -48,27 +49,8 @@ class PCA6416AComponent final : public Component,
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
/// Helper class to expose a PCA6416A pin as an internal input GPIO pin.
|
||||
class PCA6416AGPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(PCA6416AComponent *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
PCA6416AComponent *parent_;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using PCA6416AGPIOPin = gpio_expander::ExpanderGPIOPin<PCA6416AComponent>;
|
||||
|
||||
} // namespace esphome::pca6416a
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::pca6416a::PCA6416AComponent);
|
||||
|
||||
@@ -2,15 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import gpio_expander, i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_INPUT, CONF_INTERRUPT_PIN, CONF_OUTPUT
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -45,19 +37,11 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
PCA9505_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
PCA9505GPIOPin,
|
||||
cv.int_range(min=0, max=39),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_PCA9505): cv.use_id(PCA9505Component),
|
||||
@@ -67,10 +51,4 @@ PCA9505_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_PCA9505, PCA9505_PIN_SCHEMA)
|
||||
async def pca9505_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_parented(var, config[CONF_PCA9505])
|
||||
|
||||
cg.add(var.set_pin(config[CONF_NUMBER]))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_PCA9505)
|
||||
|
||||
@@ -135,16 +135,6 @@ bool PCA9505Component::write_all_banks_(uint8_t reg, uint8_t value) {
|
||||
|
||||
float PCA9505Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void PCA9505GPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||
|
||||
void PCA9505GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
|
||||
bool PCA9505GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
|
||||
void PCA9505GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
|
||||
size_t PCA9505GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via PCA9505", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::pca9505
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::pca9505::PCA9505Component, "%u via PCA9505")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
namespace esphome::pca9505 {
|
||||
@@ -49,24 +50,8 @@ class PCA9505Component final : public Component,
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
class PCA9505GPIOPin final : public GPIOPin, public Parented<PCA9505Component> {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
uint8_t pin_{0};
|
||||
bool inverted_{false};
|
||||
gpio::Flags flags_{};
|
||||
};
|
||||
using PCA9505GPIOPin = gpio_expander::ExpanderGPIOPin<PCA9505Component>;
|
||||
|
||||
} // namespace esphome::pca9505
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::pca9505::PCA9505Component);
|
||||
|
||||
@@ -6,8 +6,6 @@ from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
@@ -51,19 +49,11 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
PCA9554_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
PCA9554GPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_PCA9554): pins.use_id_or_address(PCA9554Component),
|
||||
@@ -83,13 +73,4 @@ def pca9554_pin_final_validate(
|
||||
CONF_PCA9554, PCA9554_PIN_SCHEMA, pca9554_pin_final_validate
|
||||
)
|
||||
async def pca9554_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_PCA9554])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_PCA9554)
|
||||
|
||||
@@ -135,12 +135,6 @@ bool PCA9554Component::write_register_(uint8_t reg, uint16_t value) {
|
||||
|
||||
float PCA9554Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void PCA9554GPIOPin::setup() { pin_mode(flags_); }
|
||||
void PCA9554GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool PCA9554GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void PCA9554GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
size_t PCA9554GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via PCA9554", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::pca9554
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::pca9554::PCA9554Component, "%u via PCA9554")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::pca9554 {
|
||||
|
||||
@@ -52,30 +53,8 @@ class PCA9554Component final : public Component,
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
/// Helper class to expose a PCA9554 pin as an internal input GPIO pin.
|
||||
class PCA9554GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) PCA9554GPIOPin()` would zero-fill .bss that is already zero.
|
||||
PCA9554GPIOPin() {}
|
||||
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(PCA9554Component *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
PCA9554Component *parent_{nullptr};
|
||||
uint8_t pin_{0};
|
||||
bool inverted_{false};
|
||||
gpio::Flags flags_{};
|
||||
};
|
||||
using PCA9554GPIOPin = gpio_expander::ExpanderGPIOPin<PCA9554Component>;
|
||||
|
||||
} // namespace esphome::pca9554
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::pca9554::PCA9554Component);
|
||||
|
||||
@@ -6,7 +6,6 @@ from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
@@ -23,7 +22,9 @@ MULTI_CONF = True
|
||||
pcf8574_ns = cg.esphome_ns.namespace("pcf8574")
|
||||
|
||||
PCF8574Component = pcf8574_ns.class_("PCF8574Component", cg.Component, i2c.I2CDevice)
|
||||
PCF8574GPIOPin = pcf8574_ns.class_("PCF8574GPIOPin", cg.GPIOPin)
|
||||
PCF8574GPIOPin = pcf8574_ns.class_(
|
||||
"PCF8574GPIOPin", cg.GPIOPin, cg.Parented.template(PCF8574Component)
|
||||
)
|
||||
|
||||
CONF_PCF8574 = "pcf8574"
|
||||
CONF_PCF8575 = "pcf8575"
|
||||
@@ -51,19 +52,11 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
PCF8574_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
PCF8574GPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
invertible=True,
|
||||
).extend(
|
||||
{
|
||||
@@ -74,13 +67,8 @@ PCF8574_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_PCF8574, PCF8574_PIN_SCHEMA)
|
||||
async def pcf8574_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_PCF8574])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
var = await pins.new_parented_pin(config, CONF_PCF8574)
|
||||
if config[CONF_MODE][CONF_INPUT]:
|
||||
parent = await cg.get_variable(config[CONF_PCF8574])
|
||||
cg.add(parent.register_input_pin(config[CONF_NUMBER]))
|
||||
return var
|
||||
|
||||
@@ -109,17 +109,6 @@ bool PCF8574Component::write_gpio_() {
|
||||
}
|
||||
float PCF8574Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void PCF8574GPIOPin::setup() { pin_mode(flags_); }
|
||||
void PCF8574GPIOPin::set_flags(gpio::Flags flags) {
|
||||
this->flags_ = flags;
|
||||
if (flags & gpio::FLAG_INPUT)
|
||||
this->parent_->register_input_pin(this->pin_);
|
||||
}
|
||||
void PCF8574GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool PCF8574GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void PCF8574GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
size_t PCF8574GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via PCF8574", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::pcf8574
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::pcf8574::PCF8574Component, "%u via PCF8574")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::pcf8574 {
|
||||
|
||||
@@ -56,31 +57,8 @@ class PCF8574Component final : public Component,
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
/// Helper class to expose a PCF8574 pin as an internal input GPIO pin.
|
||||
class PCF8574GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) PCF8574GPIOPin()` would zero-fill .bss that is already zero.
|
||||
PCF8574GPIOPin() {}
|
||||
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(PCF8574Component *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
// Call after set_parent() and set_pin(): input flags register the pin with the parent.
|
||||
void set_flags(gpio::Flags flags);
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
PCF8574Component *parent_{nullptr};
|
||||
uint8_t pin_{0};
|
||||
bool inverted_{false};
|
||||
gpio::Flags flags_{};
|
||||
};
|
||||
using PCF8574GPIOPin = gpio_expander::ExpanderGPIOPin<PCF8574Component>;
|
||||
|
||||
} // namespace esphome::pcf8574
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::pcf8574::PCF8574Component);
|
||||
|
||||
@@ -6,9 +6,7 @@ import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BITS_PER_SAMPLE,
|
||||
CONF_ENABLE_PIN,
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
@@ -92,14 +90,6 @@ CONFIG_SCHEMA = cv.All(
|
||||
)
|
||||
|
||||
|
||||
def _validate_pin_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output, not both")
|
||||
return value
|
||||
|
||||
|
||||
def _validate_pin(value: ConfigType) -> ConfigType:
|
||||
if value[CONF_MODE][CONF_INPUT] and value[CONF_NUMBER] == 6:
|
||||
raise cv.Invalid("GPIO6 cannot be used as input on the PCM5122")
|
||||
@@ -111,7 +101,7 @@ PIN_SCHEMA = cv.All(
|
||||
PCM5122GPIOPin,
|
||||
cv.int_range(min=3, max=6),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=_validate_pin_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_PCM5122): cv.use_id(PCM5122),
|
||||
@@ -123,13 +113,7 @@ PIN_SCHEMA = cv.All(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_PCM5122, PIN_SCHEMA)
|
||||
async def pcm5122_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_parented(var, config[CONF_PCM5122])
|
||||
|
||||
cg.add(var.set_pin(config[CONF_NUMBER]))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_PCM5122)
|
||||
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
|
||||
@@ -6,9 +6,6 @@ from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
CONF_PULLDOWN,
|
||||
CONF_PULLUP,
|
||||
@@ -52,14 +49,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
PI4IOE5V6408_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
PI4IOE5V6408GPIOPin,
|
||||
cv.int_range(min=0, max=7),
|
||||
@@ -69,7 +58,7 @@ PI4IOE5V6408_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
CONF_PULLUP,
|
||||
CONF_PULLDOWN,
|
||||
],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_PI4IOE5V6408): pins.use_id_or_address(PI4IOE5V6408Component),
|
||||
@@ -79,10 +68,4 @@ PI4IOE5V6408_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_PI4IOE5V6408, PI4IOE5V6408_PIN_SCHEMA)
|
||||
async def pi4ioe5v6408_pin_schema(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_parented(var, config[CONF_PI4IOE5V6408])
|
||||
|
||||
cg.add(var.set_pin(config[CONF_NUMBER]))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_PI4IOE5V6408)
|
||||
|
||||
@@ -182,14 +182,6 @@ bool PI4IOE5V6408Component::digital_read_cache(uint8_t pin) { return (this->inpu
|
||||
|
||||
float PI4IOE5V6408Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void PI4IOE5V6408GPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||
void PI4IOE5V6408GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool PI4IOE5V6408GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void PI4IOE5V6408GPIOPin::digital_write(bool value) {
|
||||
this->parent_->digital_write(this->pin_, value != this->inverted_);
|
||||
}
|
||||
size_t PI4IOE5V6408GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via PI4IOE5V6408", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::pi4ioe5v6408
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::pi4ioe5v6408::PI4IOE5V6408Component, "%u via PI4IOE5V6408")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
@@ -49,24 +50,8 @@ class PI4IOE5V6408Component final : public Component,
|
||||
bool read_gpio_outputs_();
|
||||
};
|
||||
|
||||
class PI4IOE5V6408GPIOPin final : public GPIOPin, public Parented<PI4IOE5V6408Component> {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using PI4IOE5V6408GPIOPin = gpio_expander::ExpanderGPIOPin<PI4IOE5V6408Component>;
|
||||
|
||||
} // namespace esphome::pi4ioe5v6408
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::pi4ioe5v6408::PI4IOE5V6408Component);
|
||||
|
||||
@@ -4,11 +4,7 @@ from esphome.components import i2c, key_provider
|
||||
from esphome.components.const import CONF_KEYS
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_ON_KEY,
|
||||
CONF_OPEN_DRAIN,
|
||||
CONF_OUTPUT,
|
||||
@@ -113,12 +109,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_PULLUP] and not value[CONF_INPUT]:
|
||||
raise cv.Invalid("Pullup only available with input")
|
||||
pins.gpio_validate_input_xor_output_pullup(value)
|
||||
if value[CONF_PULLDOWN] and not value[CONF_INPUT]:
|
||||
raise cv.Invalid("Pulldown only available with input")
|
||||
if value[CONF_PULLUP] and value[CONF_PULLDOWN]:
|
||||
@@ -129,34 +120,18 @@ def validate_mode(value: ConfigType) -> ConfigType:
|
||||
|
||||
|
||||
CONF_SX1509 = "sx1509"
|
||||
SX1509_PIN_SCHEMA = cv.All(
|
||||
SX1509_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
SX1509GPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_PULLUP, CONF_PULLDOWN, CONF_OUTPUT, CONF_OPEN_DRAIN],
|
||||
mode_validator=validate_mode,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(SX1509GPIOPin),
|
||||
cv.Required(CONF_SX1509): pins.use_id_or_address(SX1509Component),
|
||||
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_MODE, default={}): cv.All(
|
||||
{
|
||||
cv.Optional(CONF_INPUT, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
|
||||
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
|
||||
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
|
||||
},
|
||||
validate_mode,
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_SX1509, SX1509_PIN_SCHEMA)
|
||||
async def sx1509_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_SX1509])
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_SX1509)
|
||||
|
||||
@@ -312,3 +312,5 @@ void SX1509Component::set_debounce_keypad_(uint8_t time, uint8_t num_rows, uint8
|
||||
}
|
||||
|
||||
} // namespace esphome::sx1509
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::sx1509::SX1509Component, "%u via sx1509")
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "sx1509_gpio_pin.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "sx1509_registers.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -97,4 +97,8 @@ class SX1509Component final : public Component,
|
||||
void clock_(uint8_t osc_source = 2, uint8_t osc_pin_function = 1, uint8_t osc_freq_out = 0, uint8_t osc_divider = 0);
|
||||
};
|
||||
|
||||
using SX1509GPIOPin = gpio_expander::ExpanderGPIOPin<SX1509Component>;
|
||||
|
||||
} // namespace esphome::sx1509
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::sx1509::SX1509Component);
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "sx1509.h"
|
||||
#include "sx1509_gpio_pin.h"
|
||||
|
||||
namespace esphome::sx1509 {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "sx1509_gpio_pin");
|
||||
|
||||
void SX1509GPIOPin::setup() { pin_mode(flags_); }
|
||||
void SX1509GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool SX1509GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void SX1509GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
size_t SX1509GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via sx1509", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::sx1509
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/gpio.h"
|
||||
|
||||
namespace esphome::sx1509 {
|
||||
|
||||
class SX1509Component;
|
||||
|
||||
class SX1509GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_parent(SX1509Component *parent) { this->parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
SX1509Component *parent_;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
|
||||
} // namespace esphome::sx1509
|
||||
@@ -2,15 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import gpio_expander, i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INTERRUPT_PIN,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_INPUT, CONF_INTERRUPT_PIN, CONF_OUTPUT
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -44,19 +36,11 @@ async def to_code(config: ConfigType) -> None:
|
||||
await cg.add_pin(var.set_interrupt_pin, config.get(CONF_INTERRUPT_PIN))
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
TCA9555_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
TCA9555GPIOPin,
|
||||
cv.int_range(min=0, max=15),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
invertible=True,
|
||||
).extend(
|
||||
{
|
||||
@@ -67,10 +51,4 @@ TCA9555_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_TCA9555, TCA9555_PIN_SCHEMA)
|
||||
async def tca9555_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_parented(var, config[CONF_TCA9555])
|
||||
|
||||
cg.add(var.set_pin(config[CONF_NUMBER]))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_TCA9555)
|
||||
|
||||
@@ -129,12 +129,6 @@ bool TCA9555Component::digital_read_cache(uint8_t pin) { return this->input_mask
|
||||
|
||||
float TCA9555Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void TCA9555GPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||
void TCA9555GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool TCA9555GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void TCA9555GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
size_t TCA9555GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via TCA9555", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::tca9555
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::tca9555::TCA9555Component, "%u via TCA9555")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
@@ -46,25 +47,8 @@ class TCA9555Component final : public Component,
|
||||
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||
};
|
||||
|
||||
/// Helper class to expose a TCA9555 pin as an internal input GPIO pin.
|
||||
class TCA9555GPIOPin final : public GPIOPin, public Parented<TCA9555Component> {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using TCA9555GPIOPin = gpio_expander::ExpanderGPIOPin<TCA9555Component>;
|
||||
|
||||
} // namespace esphome::tca9555
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::tca9555::TCA9555Component);
|
||||
|
||||
@@ -2,14 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_INPUT, CONF_OUTPUT
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -48,19 +41,11 @@ async def to_code(config: ConfigType) -> None:
|
||||
await i2c.new_i2c_component(config)
|
||||
|
||||
|
||||
def validate_mode(value: ConfigType) -> ConfigType:
|
||||
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
return value
|
||||
|
||||
|
||||
WAVESHARE_IO_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
WaveshareIOCH32V003GPIOPin,
|
||||
cv.int_range(min=0, max=7),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
invertible=True,
|
||||
).extend(
|
||||
{
|
||||
@@ -73,13 +58,4 @@ WAVESHARE_IO_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_WAVESHARE_IO_CH32V003, WAVESHARE_IO_PIN_SCHEMA)
|
||||
async def waveshare_io_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_WAVESHARE_IO_CH32V003])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_WAVESHARE_IO_CH32V003)
|
||||
|
||||
@@ -124,16 +124,6 @@ void WaveshareIOCH32V003Component::digital_write_hw(uint8_t pin, bool value) {
|
||||
bool WaveshareIOCH32V003Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
|
||||
float WaveshareIOCH32V003Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void WaveshareIOCH32V003GPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||
void WaveshareIOCH32V003GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool WaveshareIOCH32V003GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
|
||||
|
||||
void WaveshareIOCH32V003GPIOPin::digital_write(bool value) {
|
||||
this->parent_->digital_write(this->pin_, value ^ this->inverted_);
|
||||
}
|
||||
|
||||
size_t WaveshareIOCH32V003GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "EXIO%u via WaveshareIO", this->pin_);
|
||||
}
|
||||
|
||||
} // namespace esphome::waveshare_io_ch32v003
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::waveshare_io_ch32v003::WaveshareIOCH32V003Component, "EXIO%u via WaveshareIO")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::waveshare_io_ch32v003 {
|
||||
|
||||
@@ -27,8 +28,6 @@ class WaveshareIOCH32V003Component : public Component,
|
||||
void set_pwm_value(uint8_t value); // 0 - 255
|
||||
|
||||
protected:
|
||||
friend class WaveshareIOCH32V003GPIOPin;
|
||||
|
||||
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;
|
||||
@@ -41,25 +40,8 @@ class WaveshareIOCH32V003Component : public Component,
|
||||
bool write_gpio_outputs_();
|
||||
};
|
||||
|
||||
/// Helper class to expose a WaveshareIO pin as a GPIO pin.
|
||||
class WaveshareIOCH32V003GPIOPin : public GPIOPin, public Parented<WaveshareIOCH32V003Component> {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
protected:
|
||||
uint8_t pin_{};
|
||||
bool inverted_{};
|
||||
gpio::Flags flags_{};
|
||||
};
|
||||
using WaveshareIOCH32V003GPIOPin = gpio_expander::ExpanderGPIOPin<WaveshareIOCH32V003Component>;
|
||||
|
||||
} // namespace esphome::waveshare_io_ch32v003
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::waveshare_io_ch32v003::WaveshareIOCH32V003Component);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import uart
|
||||
from esphome.components.const import CONF_DATA_BITS, CONF_PARITY, CONF_STOP_BITS
|
||||
@@ -90,10 +91,7 @@ async def register_weikai(var: MockObj, config: ConfigType) -> None:
|
||||
|
||||
def validate_pin_mode(value: ConfigType) -> ConfigType:
|
||||
"""Checks input/output mode inconsistency"""
|
||||
if not (value[CONF_MODE][CONF_INPUT] or value[CONF_MODE][CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
if value[CONF_MODE][CONF_INPUT] and value[CONF_MODE][CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be either input or output")
|
||||
pins.gpio_validate_input_xor_output(value[CONF_MODE])
|
||||
return value
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c, weikai
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_MODE, CONF_NUMBER
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -52,11 +52,4 @@ WK2168_PIN_SCHEMA = cv.All(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_WK2168_I2C, WK2168_PIN_SCHEMA)
|
||||
async def sc16is75x_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_WK2168_I2C])
|
||||
cg.add(var.set_parent(parent))
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_WK2168_I2C)
|
||||
|
||||
@@ -2,7 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import spi, weikai
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_MODE, CONF_NUMBER
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -50,11 +50,4 @@ WK2168_PIN_SCHEMA = cv.All(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_WK2168_SPI, WK2168_PIN_SCHEMA)
|
||||
async def sc16is75x_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_WK2168_SPI])
|
||||
cg.add(var.set_parent(parent))
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_WK2168_SPI)
|
||||
|
||||
@@ -2,7 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c, weikai
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_MODE, CONF_NUMBER
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -52,11 +52,4 @@ WK2212_PIN_SCHEMA = cv.All(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_WK2212_I2C, WK2212_PIN_SCHEMA)
|
||||
async def sc16is75x_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_WK2212_I2C])
|
||||
cg.add(var.set_parent(parent))
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_WK2212_I2C)
|
||||
|
||||
@@ -2,7 +2,7 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import spi, weikai
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_MODE, CONF_NUMBER
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -50,11 +50,4 @@ WK2212_PIN_SCHEMA = cv.All(
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_WK2212_SPI, WK2212_PIN_SCHEMA)
|
||||
async def sc16is75x_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_WK2212_SPI])
|
||||
cg.add(var.set_parent(parent))
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_WK2212_SPI)
|
||||
|
||||
@@ -2,19 +2,13 @@ from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_INPUT, CONF_OUTPUT
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CONF_XL9535 = "xl9535"
|
||||
|
||||
AUTO_LOAD = ["gpio_expander"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
CODEOWNERS = ["@mreditor97"]
|
||||
DOMAIN = "xl9535"
|
||||
@@ -36,45 +30,24 @@ async def to_code(config: ConfigType) -> None:
|
||||
await i2c.new_i2c_component(config)
|
||||
|
||||
|
||||
def validate_mode(mode: ConfigType) -> ConfigType:
|
||||
if not (mode[CONF_INPUT] or mode[CONF_OUTPUT]) or (
|
||||
mode[CONF_INPUT] and mode[CONF_OUTPUT]
|
||||
):
|
||||
raise cv.Invalid("Mode must be either a input or a output")
|
||||
return mode
|
||||
|
||||
|
||||
def validate_pin(pin: int) -> int:
|
||||
if pin in (8, 9):
|
||||
raise cv.Invalid(f"pin {pin} doesn't exist")
|
||||
return pin
|
||||
|
||||
|
||||
XL9535_PIN_SCHEMA = cv.All(
|
||||
XL9535_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
XL9535GPIOPin,
|
||||
cv.All(cv.int_range(min=0, max=17), validate_pin),
|
||||
modes=[CONF_INPUT, CONF_OUTPUT],
|
||||
mode_validator=pins.gpio_validate_input_xor_output,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(XL9535GPIOPin),
|
||||
cv.Required(CONF_XL9535): pins.use_id_or_address(XL9535Component),
|
||||
cv.Required(CONF_NUMBER): cv.All(cv.int_range(min=0, max=17), validate_pin),
|
||||
cv.Optional(CONF_MODE, default={}): cv.All(
|
||||
{
|
||||
cv.Optional(CONF_INPUT, default=False): cv.boolean,
|
||||
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
|
||||
},
|
||||
validate_mode,
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_XL9535, XL9535_PIN_SCHEMA)
|
||||
async def xl9535_pin_to_code(config: ConfigType) -> MockObj:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_XL9535])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
cg.add(var.set_pin(config[CONF_NUMBER]))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
|
||||
return var
|
||||
return await pins.new_parented_pin(config, CONF_XL9535)
|
||||
|
||||
@@ -103,14 +103,6 @@ void XL9535Component::pin_mode(uint8_t pin, gpio::Flags mode) {
|
||||
}
|
||||
}
|
||||
|
||||
void XL9535GPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||
|
||||
size_t XL9535GPIOPin::dump_summary(char *buffer, size_t len) const {
|
||||
return buf_append_printf(buffer, len, 0, "%u via XL9535", this->pin_);
|
||||
}
|
||||
|
||||
void XL9535GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||
bool XL9535GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||
void XL9535GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
|
||||
} // namespace esphome::xl9535
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY(esphome::xl9535::XL9535Component, "%u via XL9535")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/gpio_expander/expander_gpio_pin.h"
|
||||
|
||||
namespace esphome::xl9535 {
|
||||
|
||||
@@ -28,27 +29,8 @@ class XL9535Component final : public Component, public i2c::I2CDevice {
|
||||
float get_setup_priority() const override { return setup_priority::IO; }
|
||||
};
|
||||
|
||||
class XL9535GPIOPin final : public GPIOPin {
|
||||
public:
|
||||
void set_parent(XL9535Component *parent) { this->parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
void set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
|
||||
|
||||
gpio::Flags get_flags() const override { return this->flags_; }
|
||||
|
||||
void setup() override;
|
||||
size_t dump_summary(char *buffer, size_t len) const override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
|
||||
protected:
|
||||
XL9535Component *parent_;
|
||||
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
using XL9535GPIOPin = gpio_expander::ExpanderGPIOPin<XL9535Component>;
|
||||
|
||||
} // namespace esphome::xl9535
|
||||
|
||||
ESPHOME_EXPANDER_PIN_SUMMARY_DECL(esphome::xl9535::XL9535Component);
|
||||
|
||||
@@ -50,10 +50,8 @@ class PCF8574ResetTest : public ::testing::TestWithParam<bool> {
|
||||
}
|
||||
|
||||
void configure_input_(uint8_t number) {
|
||||
PCF8574GPIOPin pin;
|
||||
pin.set_parent(&this->component_);
|
||||
pin.set_pin(number);
|
||||
pin.set_flags(gpio::FLAG_INPUT);
|
||||
// Codegen registers input pins with the parent before setup()
|
||||
this->component_.register_input_pin(number);
|
||||
EXPECT_EQ(this->bus_.writes, 0);
|
||||
EXPECT_EQ(this->bus_.reads, 0);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,14 @@ from unittest.mock import AsyncMock, Mock, patch
|
||||
import pytest
|
||||
|
||||
from esphome.components import pcf8574
|
||||
from esphome.const import CONF_ID, CONF_RESET
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
CONF_RESET,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -31,3 +38,33 @@ async def test_reset_configuration(options: dict, expected: bool) -> None:
|
||||
var.set_reset.assert_not_called()
|
||||
else:
|
||||
var.set_reset.assert_called_once_with(False)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"number, is_input",
|
||||
[
|
||||
(0, True),
|
||||
(15, True),
|
||||
(0, False),
|
||||
(15, False),
|
||||
],
|
||||
)
|
||||
async def test_pin_registers_inputs_only(number: int, is_input: bool) -> None:
|
||||
config = {
|
||||
CONF_NUMBER: number,
|
||||
CONF_MODE: {CONF_INPUT: is_input, CONF_OUTPUT: not is_input},
|
||||
pcf8574.CONF_PCF8574: "hub",
|
||||
}
|
||||
parent = Mock()
|
||||
with (
|
||||
patch.object(pcf8574.pins, "new_parented_pin", new_callable=AsyncMock),
|
||||
patch.object(pcf8574.cg, "get_variable", AsyncMock(return_value=parent)),
|
||||
patch.object(pcf8574.cg, "add"),
|
||||
):
|
||||
await pcf8574.pcf8574_pin_to_code(config)
|
||||
|
||||
if is_input:
|
||||
parent.register_input_pin.assert_called_once_with(number)
|
||||
else:
|
||||
parent.register_input_pin.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user