mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 09:17:46 +01:00
Remove PCF8574 input_pullup mode and cleanup (#828)
Fixes https://github.com/esphome/issues/issues/755 Closes https://github.com/esphome/esphome/pull/822 Fixes https://github.com/esphome/issues/issues/667 Closes https://github.com/esphome/esphome/pull/808 Co-Authored-By: Amish Vishwakarma <amishv@users.noreply.github.com> Co-Authored-By: S-Przybylski <s-przybylski@users.noreply.github.com>
This commit is contained in:
parent
65d3dc9cb8
commit
75275c4e93
3 changed files with 43 additions and 37 deletions
|
@ -11,7 +11,6 @@ pcf8574_ns = cg.esphome_ns.namespace('pcf8574')
|
||||||
PCF8574GPIOMode = pcf8574_ns.enum('PCF8574GPIOMode')
|
PCF8574GPIOMode = pcf8574_ns.enum('PCF8574GPIOMode')
|
||||||
PCF8674_GPIO_MODES = {
|
PCF8674_GPIO_MODES = {
|
||||||
'INPUT': PCF8574GPIOMode.PCF8574_INPUT,
|
'INPUT': PCF8574GPIOMode.PCF8574_INPUT,
|
||||||
'INPUT_PULLUP': PCF8574GPIOMode.PCF8574_INPUT_PULLUP,
|
|
||||||
'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT,
|
'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,16 +32,24 @@ def to_code(config):
|
||||||
cg.add(var.set_pcf8575(config[CONF_PCF8575]))
|
cg.add(var.set_pcf8575(config[CONF_PCF8575]))
|
||||||
|
|
||||||
|
|
||||||
|
def validate_pcf8574_gpio_mode(value):
|
||||||
|
value = cv.string(value)
|
||||||
|
if value.upper() == 'INPUT_PULLUP':
|
||||||
|
raise cv.Invalid("INPUT_PULLUP mode has been removed in 1.14 and been combined into "
|
||||||
|
"INPUT mode (they were the same thing). Please use INPUT instead.")
|
||||||
|
return cv.enum(PCF8674_GPIO_MODES, upper=True)(value)
|
||||||
|
|
||||||
|
|
||||||
PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({
|
PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||||
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
||||||
cv.Required(CONF_NUMBER): cv.int_,
|
cv.Required(CONF_NUMBER): cv.int_,
|
||||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(PCF8674_GPIO_MODES, upper=True),
|
cv.Optional(CONF_MODE, default="OUTPUT"): validate_pcf8574_gpio_mode,
|
||||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||||
})
|
})
|
||||||
PCF8574_INPUT_PIN_SCHEMA = cv.Schema({
|
PCF8574_INPUT_PIN_SCHEMA = cv.Schema({
|
||||||
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
||||||
cv.Required(CONF_NUMBER): cv.int_,
|
cv.Required(CONF_NUMBER): cv.int_,
|
||||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(PCF8674_GPIO_MODES, upper=True),
|
cv.Optional(CONF_MODE, default="INPUT"): validate_pcf8574_gpio_mode,
|
||||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ bool PCF8574Component::digital_read(uint8_t pin) {
|
||||||
}
|
}
|
||||||
void PCF8574Component::digital_write(uint8_t pin, bool value) {
|
void PCF8574Component::digital_write(uint8_t pin, bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this->port_mask_ |= (1 << pin);
|
this->output_mask_ |= (1 << pin);
|
||||||
} else {
|
} else {
|
||||||
this->port_mask_ &= ~(1 << pin);
|
this->output_mask_ &= ~(1 << pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->write_gpio_();
|
this->write_gpio_();
|
||||||
|
@ -41,16 +41,14 @@ void PCF8574Component::digital_write(uint8_t pin, bool value) {
|
||||||
void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {
|
void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PCF8574_INPUT:
|
case PCF8574_INPUT:
|
||||||
this->ddr_mask_ &= ~(1 << pin);
|
// Clear mode mask bit
|
||||||
this->port_mask_ &= ~(1 << pin);
|
this->mode_mask_ &= ~(1 << pin);
|
||||||
break;
|
// Write GPIO to enable input mode
|
||||||
case PCF8574_INPUT_PULLUP:
|
this->write_gpio_();
|
||||||
this->ddr_mask_ &= ~(1 << pin);
|
|
||||||
this->port_mask_ |= (1 << pin);
|
|
||||||
break;
|
break;
|
||||||
case PCF8574_OUTPUT:
|
case PCF8574_OUTPUT:
|
||||||
this->ddr_mask_ |= (1 << pin);
|
// Set mode mask bit
|
||||||
this->port_mask_ &= ~(1 << pin);
|
this->mode_mask_ |= 1 << pin;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -59,21 +57,20 @@ void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {
|
||||||
bool PCF8574Component::read_gpio_() {
|
bool PCF8574Component::read_gpio_() {
|
||||||
if (this->is_failed())
|
if (this->is_failed())
|
||||||
return false;
|
return false;
|
||||||
|
bool success;
|
||||||
|
uint8_t data[2];
|
||||||
if (this->pcf8575_) {
|
if (this->pcf8575_) {
|
||||||
if (!this->parent_->raw_receive_16(this->address_, &this->input_mask_, 1)) {
|
success = this->read_bytes_raw(data, 2);
|
||||||
this->status_set_warning();
|
this->input_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t data;
|
success = this->read_bytes_raw(data, 1);
|
||||||
if (!this->parent_->raw_receive(this->address_, &data, 1)) {
|
this->input_mask_ = data[0];
|
||||||
this->status_set_warning();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this->input_mask_ = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -81,20 +78,20 @@ bool PCF8574Component::write_gpio_() {
|
||||||
if (this->is_failed())
|
if (this->is_failed())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint16_t value = (this->input_mask_ & ~this->ddr_mask_) | this->port_mask_;
|
uint16_t value = 0;
|
||||||
|
// Pins in OUTPUT mode and where pin is HIGH.
|
||||||
|
value |= this->mode_mask_ & this->output_mask_;
|
||||||
|
// Pins in INPUT mode must also be set here
|
||||||
|
value |= ~this->mode_mask_;
|
||||||
|
|
||||||
this->parent_->raw_begin_transmission(this->address_);
|
uint8_t data[2];
|
||||||
uint8_t data = value & 0xFF;
|
data[0] = value;
|
||||||
this->parent_->raw_write(this->address_, &data, 1);
|
data[1] = value >> 8;
|
||||||
|
if (!this->write_bytes_raw(data, this->pcf8575_ ? 2 : 1)) {
|
||||||
if (this->pcf8575_) {
|
|
||||||
data = (value >> 8) & 0xFF;
|
|
||||||
this->parent_->raw_write(this->address_, &data, 1);
|
|
||||||
}
|
|
||||||
if (!this->parent_->raw_end_transmission(this->address_)) {
|
|
||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ namespace pcf8574 {
|
||||||
/// Modes for PCF8574 pins
|
/// Modes for PCF8574 pins
|
||||||
enum PCF8574GPIOMode : uint8_t {
|
enum PCF8574GPIOMode : uint8_t {
|
||||||
PCF8574_INPUT = INPUT,
|
PCF8574_INPUT = INPUT,
|
||||||
PCF8574_INPUT_PULLUP = INPUT_PULLUP,
|
|
||||||
PCF8574_OUTPUT = OUTPUT,
|
PCF8574_OUTPUT = OUTPUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,9 +37,12 @@ class PCF8574Component : public Component, public i2c::I2CDevice {
|
||||||
|
|
||||||
bool write_gpio_();
|
bool write_gpio_();
|
||||||
|
|
||||||
uint16_t ddr_mask_{0x00};
|
/// Mask for the pin mode - 1 means output, 0 means input
|
||||||
|
uint16_t mode_mask_{0x00};
|
||||||
|
/// The mask to write as output state - 1 means HIGH, 0 means LOW
|
||||||
|
uint16_t output_mask_{0x00};
|
||||||
|
/// The state read in read_gpio_ - 1 means HIGH, 0 means LOW
|
||||||
uint16_t input_mask_{0x00};
|
uint16_t input_mask_{0x00};
|
||||||
uint16_t port_mask_{0x00};
|
|
||||||
bool pcf8575_; ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574
|
bool pcf8575_; ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue