From 6b8a75d3b8511a3b12199f7419df4e524a0c6100 Mon Sep 17 00:00:00 2001 From: tracestep <16390082+tracestep@users.noreply.github.com> Date: Wed, 25 Oct 2023 23:36:58 -0300 Subject: [PATCH] SX1509 output debounce fix (resolves esphome/issues#4402) (#4672) --- esphome/components/sx1509/sx1509.cpp | 14 ++++++++++++-- esphome/components/sx1509/sx1509.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/esphome/components/sx1509/sx1509.cpp b/esphome/components/sx1509/sx1509.cpp index d0a84b99ffe7..ee90e0e410b5 100644 --- a/esphome/components/sx1509/sx1509.cpp +++ b/esphome/components/sx1509/sx1509.cpp @@ -68,9 +68,18 @@ void SX1509Component::digital_write(uint8_t pin, bool bit_value) { uint16_t temp_reg_data = 0; this->read_byte_16(REG_DATA_B, &temp_reg_data); if (bit_value) { - temp_reg_data |= (1 << pin); + output_state_ |= (1 << pin); // set bit in shadow register } else { - temp_reg_data &= ~(1 << pin); + output_state_ &= ~(1 << pin); // reset bit shadow register + } + for (uint16_t b = 0x8000; b; b >>= 1) { + if ((~ddr_mask_) & b) { // transfer bits of outputs, but don't mess with inputs + if (output_state_ & b) { + temp_reg_data |= b; + } else { + temp_reg_data &= ~b; + } + } } this->write_byte_16(REG_DATA_B, temp_reg_data); } @@ -134,6 +143,7 @@ void SX1509Component::setup_led_driver(uint8_t pin) { this->read_byte_16(REG_DATA_B, &temp_word); temp_word &= ~(1 << pin); + output_state_ &= ~(1 << pin); this->write_byte_16(REG_DATA_B, temp_word); } diff --git a/esphome/components/sx1509/sx1509.h b/esphome/components/sx1509/sx1509.h index 8e3b41e233c4..9e4f31aab0d9 100644 --- a/esphome/components/sx1509/sx1509.h +++ b/esphome/components/sx1509/sx1509.h @@ -61,6 +61,7 @@ class SX1509Component : public Component, public i2c::I2CDevice { uint16_t ddr_mask_ = 0x00; uint16_t input_mask_ = 0x00; uint16_t port_mask_ = 0x00; + uint16_t output_state_ = 0x00; bool has_keypad_ = false; uint8_t rows_ = 0; uint8_t cols_ = 0;