[sx1509] Output open drain pin mode (#6788)

This commit is contained in:
Penny Wood 2024-05-23 05:31:56 +08:00 committed by GitHub
parent 9a6fde21ee
commit 7f9383c83b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 155 additions and 13 deletions

View file

@ -11,6 +11,7 @@ from esphome.const import (
CONF_OUTPUT, CONF_OUTPUT,
CONF_PULLDOWN, CONF_PULLDOWN,
CONF_PULLUP, CONF_PULLUP,
CONF_OPEN_DRAIN,
) )
CONF_KEYPAD = "keypad" CONF_KEYPAD = "keypad"
@ -79,6 +80,8 @@ def validate_mode(value):
raise cv.Invalid("Pulldown only available with input") raise cv.Invalid("Pulldown only available with input")
if value[CONF_PULLUP] and value[CONF_PULLDOWN]: if value[CONF_PULLUP] and value[CONF_PULLDOWN]:
raise cv.Invalid("Can only have one of pullup or pulldown") raise cv.Invalid("Can only have one of pullup or pulldown")
if value[CONF_OPEN_DRAIN] and not value[CONF_OUTPUT]:
raise cv.Invalid("Open drain available only with output")
return value return value
@ -94,6 +97,7 @@ SX1509_PIN_SCHEMA = cv.All(
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_PULLDOWN, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean, cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
}, },
validate_mode, validate_mode,
), ),

View file

@ -86,33 +86,63 @@ void SX1509Component::digital_write(uint8_t pin, bool bit_value) {
} }
void SX1509Component::pin_mode(uint8_t pin, gpio::Flags flags) { void SX1509Component::pin_mode(uint8_t pin, gpio::Flags flags) {
ESP_LOGI(TAG, "Configuring pin %u with flags %x", pin, flags);
uint16_t temp_word = 0;
this->read_byte_16(REG_DIR_B, &this->ddr_mask_); this->read_byte_16(REG_DIR_B, &this->ddr_mask_);
if (flags == gpio::FLAG_OUTPUT) { if (flags & gpio::FLAG_OUTPUT) {
// Always disable input buffer
this->read_byte_16(REG_INPUT_DISABLE_B, &temp_word);
temp_word |= (1 << pin);
this->write_byte_16(REG_INPUT_DISABLE_B, temp_word);
if (flags & gpio::FLAG_OPEN_DRAIN) {
// Pullup must be disabled for open drain mode
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->read_byte_16(REG_OPEN_DRAIN_B, &temp_word);
temp_word |= (1 << pin);
this->write_byte_16(REG_OPEN_DRAIN_B, temp_word);
ESP_LOGD(TAG, "Open drain output mode set for %u", pin);
} else {
ESP_LOGD(TAG, "Output Mode for %u", pin);
}
// Set direction to output
this->ddr_mask_ &= ~(1 << pin); this->ddr_mask_ &= ~(1 << pin);
this->write_byte_16(REG_DIR_B, this->ddr_mask_);
} else { } else {
this->ddr_mask_ |= (1 << pin); ESP_LOGD(TAG, "Input Mode for %u", pin);
uint16_t temp_pullup; // Always enable input buffer
this->read_byte_16(REG_PULL_UP_B, &temp_pullup); this->read_byte_16(REG_INPUT_DISABLE_B, &temp_word);
uint16_t temp_pulldown; temp_word &= ~(1 << pin);
this->read_byte_16(REG_PULL_DOWN_B, &temp_pulldown); this->write_byte_16(REG_INPUT_DISABLE_B, temp_word);
// Pullup
this->read_byte_16(REG_PULL_UP_B, &temp_word);
if (flags & gpio::FLAG_PULLUP) { if (flags & gpio::FLAG_PULLUP) {
temp_pullup |= (1 << pin); temp_word |= (1 << pin);
} else { } else {
temp_pullup &= ~(1 << pin); temp_word &= ~(1 << pin);
} }
this->write_byte_16(REG_PULL_UP_B, temp_word);
// Pulldown
this->read_byte_16(REG_PULL_DOWN_B, &temp_word);
if (flags & gpio::FLAG_PULLDOWN) { if (flags & gpio::FLAG_PULLDOWN) {
temp_pulldown |= (1 << pin); temp_word |= (1 << pin);
} else { } else {
temp_pulldown &= ~(1 << pin); temp_word &= ~(1 << pin);
} }
this->write_byte_16(REG_PULL_DOWN_B, temp_word);
this->write_byte_16(REG_PULL_UP_B, temp_pullup); // Set direction to input
this->write_byte_16(REG_PULL_DOWN_B, temp_pulldown); this->ddr_mask_ |= (1 << pin);
this->write_byte_16(REG_DIR_B, this->ddr_mask_);
} }
this->write_byte_16(REG_DIR_B, this->ddr_mask_);
} }
void SX1509Component::setup_led_driver(uint8_t pin) { void SX1509Component::setup_led_driver(uint8_t pin) {

View file

@ -13,3 +13,21 @@ binary_sensor:
pin: pin:
sx1509: sx1509_hub sx1509: sx1509_hub
number: 3 number: 3
switch:
- platform: gpio
name: GPIO SX1509 Test Out Open Drain
pin:
sx1509: sx1509_hub
number: 0
mode:
output: true
open_drain: true
- platform: gpio
name: GPIO SX1509 Test Out Standard
pin:
sx1509: sx1509_hub
number: 1
mode:
output: true

View file

@ -13,3 +13,21 @@ binary_sensor:
pin: pin:
sx1509: sx1509_hub sx1509: sx1509_hub
number: 3 number: 3
switch:
- platform: gpio
name: GPIO SX1509 Test Out Open Drain
pin:
sx1509: sx1509_hub
number: 0
mode:
output: true
open_drain: true
- platform: gpio
name: GPIO SX1509 Test Out Standard
pin:
sx1509: sx1509_hub
number: 1
mode:
output: true

View file

@ -13,3 +13,21 @@ binary_sensor:
pin: pin:
sx1509: sx1509_hub sx1509: sx1509_hub
number: 3 number: 3
switch:
- platform: gpio
name: GPIO SX1509 Test Out Open Drain
pin:
sx1509: sx1509_hub
number: 0
mode:
output: true
open_drain: true
- platform: gpio
name: GPIO SX1509 Test Out Standard
pin:
sx1509: sx1509_hub
number: 1
mode:
output: true

View file

@ -13,3 +13,21 @@ binary_sensor:
pin: pin:
sx1509: sx1509_hub sx1509: sx1509_hub
number: 3 number: 3
switch:
- platform: gpio
name: GPIO SX1509 Test Out Open Drain
pin:
sx1509: sx1509_hub
number: 0
mode:
output: true
open_drain: true
- platform: gpio
name: GPIO SX1509 Test Out Standard
pin:
sx1509: sx1509_hub
number: 1
mode:
output: true

View file

@ -13,3 +13,21 @@ binary_sensor:
pin: pin:
sx1509: sx1509_hub sx1509: sx1509_hub
number: 3 number: 3
switch:
- platform: gpio
name: GPIO SX1509 Test Out Open Drain
pin:
sx1509: sx1509_hub
number: 0
mode:
output: true
open_drain: true
- platform: gpio
name: GPIO SX1509 Test Out Standard
pin:
sx1509: sx1509_hub
number: 1
mode:
output: true

View file

@ -13,3 +13,21 @@ binary_sensor:
pin: pin:
sx1509: sx1509_hub sx1509: sx1509_hub
number: 3 number: 3
switch:
- platform: gpio
name: GPIO SX1509 Test Out Open Drain
pin:
sx1509: sx1509_hub
number: 0
mode:
output: true
open_drain: true
- platform: gpio
name: GPIO SX1509 Test Out Standard
pin:
sx1509: sx1509_hub
number: 1
mode:
output: true