From 2deef16ebec64b3f54669bd32016bf4a1ceac904 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 7 Aug 2022 12:39:41 -0700 Subject: [PATCH] fix sx1509 use of pullup and pulldown (#3689) Co-authored-by: Samuel Sieb --- esphome/components/sx1509/__init__.py | 6 ++++ esphome/components/sx1509/sx1509.cpp | 47 ++++++++++++--------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/esphome/components/sx1509/__init__.py b/esphome/components/sx1509/__init__.py index 879ced2fb3..faef940125 100644 --- a/esphome/components/sx1509/__init__.py +++ b/esphome/components/sx1509/__init__.py @@ -9,6 +9,7 @@ from esphome.const import ( CONF_MODE, CONF_INVERTED, CONF_OUTPUT, + CONF_PULLDOWN, CONF_PULLUP, ) @@ -74,6 +75,10 @@ def validate_mode(value): 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") + 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 @@ -87,6 +92,7 @@ SX1509_PIN_SCHEMA = 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, }, validate_mode, diff --git a/esphome/components/sx1509/sx1509.cpp b/esphome/components/sx1509/sx1509.cpp index 16540d0dbf..60cbae6aa6 100644 --- a/esphome/components/sx1509/sx1509.cpp +++ b/esphome/components/sx1509/sx1509.cpp @@ -70,26 +70,6 @@ void SX1509Component::digital_write(uint8_t pin, bool bit_value) { temp_reg_data &= ~(1 << pin); } 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); } else { 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_); - - if (flags & gpio::FLAG_PULLUP) - digital_write(pin, true); } void SX1509Component::setup_led_driver(uint8_t pin) { @@ -114,10 +111,6 @@ void SX1509Component::setup_led_driver(uint8_t pin) { temp_word |= (1 << pin); 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->write_byte_16(REG_DIR_B, this->ddr_mask_);