mirror of
https://github.com/esphome/esphome.git
synced 2025-09-29 16:42:19 +01:00
Merge branch 'optimize_pcf8574' into integration
This commit is contained in:
@@ -11,6 +11,7 @@ from esphome.const import (
|
|||||||
CONF_OUTPUT,
|
CONF_OUTPUT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AUTO_LOAD = ["gpio_expander"]
|
||||||
DEPENDENCIES = ["i2c"]
|
DEPENDENCIES = ["i2c"]
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
|
|
||||||
|
@@ -17,9 +17,8 @@ void PCF8574Component::setup() {
|
|||||||
this->read_gpio_();
|
this->read_gpio_();
|
||||||
}
|
}
|
||||||
void PCF8574Component::loop() {
|
void PCF8574Component::loop() {
|
||||||
// Invalidate the cache at the start of each loop.
|
// Invalidate the cache at the start of each loop
|
||||||
// The actual read will happen on demand in digital_read()
|
this->reset_pin_cache_();
|
||||||
this->cache_valid_ = false;
|
|
||||||
}
|
}
|
||||||
void PCF8574Component::dump_config() {
|
void PCF8574Component::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "PCF8574:");
|
ESP_LOGCONFIG(TAG, "PCF8574:");
|
||||||
@@ -29,20 +28,21 @@ void PCF8574Component::dump_config() {
|
|||||||
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool PCF8574Component::digital_read(uint8_t pin) {
|
bool PCF8574Component::digital_read(uint8_t pin) { return this->get_pin_value_(pin); }
|
||||||
// Read the inputs once per loop on demand and cache the result
|
|
||||||
if (!this->cache_valid_ && this->read_gpio_()) {
|
bool PCF8574Component::digital_read_hw(uint8_t pin) {
|
||||||
this->cache_valid_ = true;
|
return this->read_gpio_() ? (this->input_mask_ & (1 << pin)) : false;
|
||||||
}
|
|
||||||
return this->input_mask_ & (1 << pin);
|
|
||||||
}
|
}
|
||||||
void PCF8574Component::digital_write(uint8_t pin, bool value) {
|
|
||||||
|
bool PCF8574Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
|
||||||
|
void PCF8574Component::digital_write(uint8_t pin, bool value) { this->set_pin_value_(pin, value); }
|
||||||
|
|
||||||
|
void PCF8574Component::digital_write_hw(uint8_t pin, bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this->output_mask_ |= (1 << pin);
|
this->output_mask_ |= (1 << pin);
|
||||||
} else {
|
} else {
|
||||||
this->output_mask_ &= ~(1 << pin);
|
this->output_mask_ &= ~(1 << pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->write_gpio_();
|
this->write_gpio_();
|
||||||
}
|
}
|
||||||
void PCF8574Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
void PCF8574Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
||||||
|
@@ -3,11 +3,16 @@
|
|||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
#include "esphome/components/i2c/i2c.h"
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/components/gpio_expander/cached_gpio.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace pcf8574 {
|
namespace pcf8574 {
|
||||||
|
|
||||||
class PCF8574Component : public Component, public i2c::I2CDevice {
|
// PCF8574(8 pins)/PCF8575(16 pins) always read/write all pins in a single I2C transaction
|
||||||
|
// so we use uint16_t as bank type to ensure all pins are in one bank and cached together
|
||||||
|
class PCF8574Component : public Component,
|
||||||
|
public i2c::I2CDevice,
|
||||||
|
public gpio_expander::CachedGpioExpander<uint16_t, 16> {
|
||||||
public:
|
public:
|
||||||
PCF8574Component() = default;
|
PCF8574Component() = default;
|
||||||
|
|
||||||
@@ -17,8 +22,6 @@ class PCF8574Component : public Component, public i2c::I2CDevice {
|
|||||||
void setup() override;
|
void setup() override;
|
||||||
/// Invalidate cache at start of each loop
|
/// Invalidate cache at start of each loop
|
||||||
void loop() override;
|
void loop() 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.
|
/// Helper function to write the value of a pin.
|
||||||
void digital_write(uint8_t pin, bool value);
|
void digital_write(uint8_t pin, bool value);
|
||||||
/// Helper function to set the pin mode of a pin.
|
/// Helper function to set the pin mode of a pin.
|
||||||
@@ -30,8 +33,11 @@ class PCF8574Component : public Component, public i2c::I2CDevice {
|
|||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool read_gpio_();
|
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_gpio_();
|
||||||
bool write_gpio_();
|
bool write_gpio_();
|
||||||
|
|
||||||
/// Mask for the pin mode - 1 means output, 0 means input
|
/// Mask for the pin mode - 1 means output, 0 means input
|
||||||
@@ -40,8 +46,6 @@ class PCF8574Component : public Component, public i2c::I2CDevice {
|
|||||||
uint16_t output_mask_{0x00};
|
uint16_t output_mask_{0x00};
|
||||||
/// The state read in read_gpio_ - 1 means HIGH, 0 means LOW
|
/// The state read in read_gpio_ - 1 means HIGH, 0 means LOW
|
||||||
uint16_t input_mask_{0x00};
|
uint16_t input_mask_{0x00};
|
||||||
/// Cache validity flag - true if we've read inputs this loop cycle
|
|
||||||
bool cache_valid_{false};
|
|
||||||
bool pcf8575_; ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574
|
bool pcf8575_; ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user