fix sx1509 use of pullup and pulldown (#3689)

Co-authored-by: Samuel Sieb <samuel@sieb.net>
This commit is contained in:
Samuel Sieb 2022-08-07 12:39:41 -07:00 committed by GitHub
parent 989b7be99b
commit 2deef16ebe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 27 deletions

View file

@ -9,6 +9,7 @@ from esphome.const import (
CONF_MODE, CONF_MODE,
CONF_INVERTED, CONF_INVERTED,
CONF_OUTPUT, CONF_OUTPUT,
CONF_PULLDOWN,
CONF_PULLUP, CONF_PULLUP,
) )
@ -74,6 +75,10 @@ def validate_mode(value):
raise cv.Invalid("Mode must be either input or output") raise cv.Invalid("Mode must be either input or output")
if value[CONF_PULLUP] and not value[CONF_INPUT]: if value[CONF_PULLUP] and not value[CONF_INPUT]:
raise cv.Invalid("Pullup only available with input") raise cv.Invalid("Pullup only available with input")
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]:
raise cv.Invalid("Can only have one of pullup or pulldown")
return value return value
@ -87,6 +92,7 @@ SX1509_PIN_SCHEMA = cv.All(
{ {
cv.Optional(CONF_INPUT, default=False): cv.boolean, cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, 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_OUTPUT, default=False): cv.boolean,
}, },
validate_mode, validate_mode,

View file

@ -70,26 +70,6 @@ void SX1509Component::digital_write(uint8_t pin, bool bit_value) {
temp_reg_data &= ~(1 << pin); temp_reg_data &= ~(1 << pin);
} }
this->write_byte_16(REG_DATA_B, temp_reg_data); this->write_byte_16(REG_DATA_B, temp_reg_data);
} else {
// Otherwise the pin is an input, pull-up/down
uint16_t temp_pullup = 0;
this->read_byte_16(REG_PULL_UP_B, &temp_pullup);
uint16_t temp_pull_down = 0;
this->read_byte_16(REG_PULL_DOWN_B, &temp_pull_down);
if (bit_value) {
// if HIGH, do pull-up, disable pull-down
temp_pullup |= (1 << pin);
temp_pull_down &= ~(1 << pin);
this->write_byte_16(REG_PULL_UP_B, temp_pullup);
this->write_byte_16(REG_PULL_DOWN_B, temp_pull_down);
} else {
// If LOW do pull-down, disable pull-up
temp_pull_down |= (1 << pin);
temp_pullup &= ~(1 << pin);
this->write_byte_16(REG_PULL_UP_B, temp_pullup);
this->write_byte_16(REG_PULL_DOWN_B, temp_pull_down);
}
} }
} }
@ -99,11 +79,28 @@ void SX1509Component::pin_mode(uint8_t pin, gpio::Flags flags) {
this->ddr_mask_ &= ~(1 << pin); this->ddr_mask_ &= ~(1 << pin);
} else { } else {
this->ddr_mask_ |= (1 << pin); this->ddr_mask_ |= (1 << pin);
uint16_t temp_pullup;
this->read_byte_16(REG_PULL_UP_B, &temp_pullup);
uint16_t temp_pulldown;
this->read_byte_16(REG_PULL_DOWN_B, &temp_pulldown);
if (flags & gpio::FLAG_PULLUP) {
temp_pullup |= (1 << pin);
} else {
temp_pullup &= ~(1 << pin);
}
if (flags & gpio::FLAG_PULLDOWN) {
temp_pulldown |= (1 << pin);
} else {
temp_pulldown &= ~(1 << pin);
}
this->write_byte_16(REG_PULL_UP_B, temp_pullup);
this->write_byte_16(REG_PULL_DOWN_B, temp_pulldown);
} }
this->write_byte_16(REG_DIR_B, this->ddr_mask_); this->write_byte_16(REG_DIR_B, this->ddr_mask_);
if (flags & gpio::FLAG_PULLUP)
digital_write(pin, true);
} }
void SX1509Component::setup_led_driver(uint8_t pin) { void SX1509Component::setup_led_driver(uint8_t pin) {
@ -114,10 +111,6 @@ void SX1509Component::setup_led_driver(uint8_t pin) {
temp_word |= (1 << pin); temp_word |= (1 << pin);
this->write_byte_16(REG_INPUT_DISABLE_B, temp_word); this->write_byte_16(REG_INPUT_DISABLE_B, temp_word);
this->read_byte_16(REG_PULL_UP_B, &temp_word);
temp_word &= ~(1 << pin);
this->write_byte_16(REG_PULL_UP_B, temp_word);
this->ddr_mask_ &= ~(1 << pin); // 0=output this->ddr_mask_ &= ~(1 << pin); // 0=output
this->write_byte_16(REG_DIR_B, this->ddr_mask_); this->write_byte_16(REG_DIR_B, this->ddr_mask_);