1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-15 15:18:16 +00:00

Correction of pin inverted input output management and make DS2408 working

This commit is contained in:
Thierry DUVERNOY 2025-01-26 17:39:06 +01:00
parent 00fffd4e04
commit 076cdde42e
6 changed files with 58 additions and 18 deletions

View File

@ -26,7 +26,9 @@ def validate_mode(value):
CUSTOM_PIN_SCHEMA = cv.Schema(
{
cv.Required("number"): cv.one_of("PIOA", "PIOB", upper=True),
cv.Required("number"): cv.one_of(
"PIOA", "PIOB", "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", upper=True
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
cv.Optional(CONF_MODE, default={"input": True}): validate_mode,
}
@ -63,6 +65,10 @@ async def to_code(config):
cg.add(var.set_pin(0x01)) # PIOA assiociated to 0x01
elif pin_number == "PIOB":
cg.add(var.set_pin(0x02)) # PIOB assiociated to 0x02
elif pin_number.startswith("P"):
pin_index = int(pin_number[1:])
if 0 <= pin_index <= 7:
cg.add(var.set_pin(1 + pin_index))
cg.add(var.set_pin_inverted(pin_inverted))
cg.add(var.set_pin_mode(pin_mode.get("input", True), pin_mode.get("output", False)))
# cg.add(var.set_inverted(inverted))

View File

@ -147,6 +147,7 @@ bool DallasPio::ds2413_get_state_(uint8_t &state) {
return false;
break;
}
state = this->pin_inverted_ ? !state : state;
return true;
} // ds2413_get_state_
@ -326,6 +327,7 @@ bool DallasPio::ds2406_get_state_(uint8_t &state, bool use_crc = false) {
return false;
}
state = pio_sensed_level;
state = this->pin_inverted_ ? !state : state;
return true;
} // ds2406_get_state_
@ -497,7 +499,7 @@ bool DallasPio::ds2408_get_state_(uint8_t &state, bool use_crc = false) {
}
state = (current_state >> pin_index) & 0x01;
state = this->pin_inverted_ ? !state : state;
return true;
} // ds2408_get_state_
@ -509,15 +511,14 @@ void DallasPio::ds2408_write_state_(bool state, bool use_crc = false) {
// PIO Output Latch State Register Bitmap
// ADDR b7 b6 b5 b4 b3 b2 b1 b0
// 0x89 PL7 PL6 PL5 PL4 PL3 PL2 PL1 PL0
// Initialize One-Wire bus for this device
uint8_t current_state = 0;
// Be aware to pull up RSTZ pin to be able to write outputs !!
uint8_t ack = 0;
if (!this->ds2408_read_device_(current_state, use_crc)) {
this->status_set_warning();
return;
}
uint8_t new_state = state ? (current_state | (1 << this->pin_)) : (current_state & ~(1 << this->pin_));
uint8_t new_state = (state ^ this->pin_inverted_) ? (this->ds2408_write_current_state_ | (1 << (this->pin_ - 1)))
: (this->ds2408_write_current_state_ & ~(1 << (this->pin_ - 1)));
this->ds2408_write_current_state_ = new_state;
uint8_t read_after_write = 0;
bool read_state_after_write = true;
// ESP_LOGD(TAG, "new_state: 0x%04X this->pin_: %d state: %u", new_state, this->pin_, state);
if (!this->check_address_()) {
this->status_set_warning();
return;
@ -533,9 +534,22 @@ void DallasPio::ds2408_write_state_(bool state, bool use_crc = false) {
this->bus_->write8(new_state);
this->bus_->write8(~new_state);
ack = this->bus_->read8(); // 0xAA=success, 0xFF=failure
read_after_write = this->bus_->read8();
}
if (ack != DALLAS_DS2413_COMMAND_PIO_ACK_SUCCESS) {
ESP_LOGW(TAG, "Failed to write One-Wire bus.");
// ESP_LOGD(TAG, "ack: 0x%04X read_after_write: 0x%04X", ack, read_after_write);
if (ack != DALLAS_DS2408_COMMAND_PIO_ACK_SUCCESS) {
ESP_LOGW(TAG, "Failed to write One-Wire bus with ack: 0x%04X", ack);
this->status_set_warning();
return;
}
read_state_after_write = ((read_after_write & (1 << (this->pin_ - 1))) != 0);
if (read_state_after_write != state) {
ESP_LOGW(TAG, "Failed to write One-Wire bus write %u read %u", state, read_state_after_write);
this->status_set_warning();
return;
}
if (!this->bus_->reset()) {
ESP_LOGW(TAG, "Failed to reset One-Wire bus.");
this->status_set_warning();
return;
}

View File

@ -87,6 +87,7 @@ class DallasPio : public Component, public one_wire::OneWireDevice {
bool pin_inverted_;
uint8_t pio_output_register_;
uint16_t calculate_crc16_(const uint8_t *data, size_t length);
uint8_t ds2408_write_current_state_ = 0xFF;
};
} // namespace dallas_pio

View File

@ -14,17 +14,29 @@ CONF_REFERENCE = "reference"
CONF_CRC = "crc"
def validate_pin(value, reference=""):
reference = reference.upper()
if reference in ["DS2413", "DS2406"]:
return cv.one_of("PIOA", "PIOB", upper=True)(value)
elif reference == "DS2408":
return cv.one_of("P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", upper=True)(
value
)
raise cv.Invalid("Invalid pin configuration for the given reference.")
def validate_crc_option(config_list):
for conf in config_list:
reference = conf.get("reference", "").upper()
if not reference or reference == "DS2413":
if not reference:
continue
if reference in {"DS2406", "DS2408"} and "crc" not in conf:
crc_value = conf.get("crc", False)
if reference not in {"DS2413", "DS2406", "DS2408"}:
raise cv.Invalid(f"Unsupported reference: {reference}")
if crc_value and reference != "DS2406":
raise cv.Invalid(
"Option 'crc' is required when 'reference' is DS2406 or DS2408."
f"Option 'crc' can only be set to true for reference DS2406, not {reference}."
)
if reference not in {"DS2406", "DS2408"} and "crc" in conf:
raise cv.Invalid("Option 'crc' is not supported for this reference.")
return config_list

View File

@ -17,6 +17,7 @@ static const uint8_t DALLAS_DS2406_COMMAND_READ_STATUS = 0xAA;
static const uint8_t DALLAS_DS2406_COMMAND_WRITE_STATUS = 0x55;
static const uint8_t DALLAS_DS2408_COMMAND_READ_PIO_REGISTERS = 0xF0;
static const uint8_t DALLAS_DS2408_COMMAND_WRITE_PIO_REGISTERS = 0x5A;
static const uint8_t DALLAS_DS2408_COMMAND_PIO_ACK_SUCCESS = 0xAA;
} // namespace dallas_pio
} // namespace esphome

View File

@ -26,7 +26,9 @@ def validate_mode(value):
CUSTOM_PIN_SCHEMA = cv.Schema(
{
cv.Required("number"): cv.one_of("PIOA", "PIOB", upper=True),
cv.Required("number"): cv.one_of(
"PIOA", "PIOB", "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", upper=True
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
cv.Optional(CONF_MODE, default={"output": True}): validate_mode,
}
@ -62,6 +64,10 @@ async def to_code(config):
cg.add(var.set_pin(0x01)) # PIOA assiociated to 0x01
elif pin_number == "PIOB":
cg.add(var.set_pin(0x02)) # PIOB assiociated to 0x02
elif pin_number.startswith("P"):
pin_index = int(pin_number[1:])
if 0 <= pin_index <= 7:
cg.add(var.set_pin(1 + pin_index))
cg.add(var.set_pin_inverted(pin_inverted))
cg.add(var.set_pin_mode(pin_mode.get("input", False), pin_mode.get("output", True)))
if CONF_INVERTED in config: