This commit is contained in:
Dave Williams | DitroniX | G8PUO
2026-06-13 08:41:07 +01:00
3 changed files with 18 additions and 53 deletions
+1 -3
View File
@@ -3,15 +3,12 @@
#### Welcome to the DitroniX Home Asssitant Integration
[![DitroniX WiKi Pages](https://github.com/DitroniX/Home-Assistant-Dev/blob/main/Datasheets%20and%20Information/GitHub%20WiKi.png?raw=true)](https://github.com/DitroniX/Home-Assistant-Dev/wiki)
This repository is for integration of DitroniX boards into Home Assistant using the ESPHome Components.
The development and integration repository is work in progress as various projects evolve. It will also expand on route.
[![DitroniX Wiki Pages](https://github.com/DitroniX/Home-Assistant-Dev/blob/main/Datasheets%20and%20Information/GitHub%20WiKi.png?raw=true)](https://github.com/DitroniX/Home-Assistant-Dev/wiki)
[![DitroniX Discussions](https://github.com/DitroniX/DitroniX/blob/main/Files/GitHub%20Discussions.png?raw=true)](https://github.com/DitroniX/Home-Assistant-Dev/discussions)
#### User contributions
@@ -74,6 +71,7 @@ An example guide has been put together which should help get your boards up and
## Versions
- 260613 - Added TCA6408 for Dev Testing
- 260529 - Refresh Information
- 251217 - Initial upload of the ATM90E36 Component for EPEM E36. Could also be adapted for IPEM E36
+14 -47
View File
@@ -14,21 +14,9 @@ static const uint8_t TCA6408_CONFIG_PORT = 0x03;
void TCA6408Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up TCA6408 at address 0x%02X...", this->address_);
// Initialize registers to known state
if (this->write_register(TCA6408_POLARITY_PORT, 0x00) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Failed to write polarity register");
this->mark_failed();
return;
}
if (this->write_register(TCA6408_CONFIG_PORT, this->mode_mask_) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Failed to write config register");
this->mark_failed();
return;
}
if (!this->read_gpio_outputs_()) {
ESP_LOGE(TAG, "Failed to read output register");
if (this->write_register(TCA6408_POLARITY_PORT, 0x00) != i2c::ERROR_OK ||
this->write_register(TCA6408_CONFIG_PORT, this->mode_mask_) != i2c::ERROR_OK ||
!this->read_gpio_outputs_()) {
this->mark_failed();
return;
}
@@ -36,16 +24,13 @@ void TCA6408Component::setup() {
if (this->interrupt_pin_ != nullptr) {
this->interrupt_pin_->setup();
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
this->interrupt_pin_->attach_interrupt(&TCA6408Component::gpio_intr, this,
gpio::INTERRUPT_FALLING_EDGE);
this->interrupt_pin_->attach_interrupt(&TCA6408Component::gpio_intr, this, gpio::INTERRUPT_FALLING_EDGE);
this->set_invalidate_on_read_(false);
ESP_LOGCONFIG(TAG, " Interrupt mode enabled (active-low INT)");
ESP_LOGCONFIG(TAG, " Interrupt mode enabled (active-low)");
} else {
this->enable_loop();
ESP_LOGCONFIG(TAG, " Polling mode enabled");
}
ESP_LOGCONFIG(TAG, " Setup complete");
}
void IRAM_ATTR TCA6408Component::gpio_intr(TCA6408Component *arg) {
@@ -56,12 +41,9 @@ void IRAM_ATTR TCA6408Component::gpio_intr(TCA6408Component *arg) {
void TCA6408Component::loop() {
if (this->interrupt_triggered_) {
this->interrupt_triggered_ = false;
// Reading input port clears the interrupt on TCA6408
this->digital_read_hw(0); // pin number is ignored, reads all 8 bits
this->digital_read_hw(0);
this->reset_pin_cache_();
// If INT line is high again, disable loop until next interrupt
if (this->interrupt_pin_ && this->interrupt_pin_->digital_read()) {
this->disable_loop();
}
@@ -73,8 +55,6 @@ void TCA6408Component::dump_config() {
LOG_I2C_DEVICE(this);
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
ESP_LOGCONFIG(TAG, " Mode Mask: 0x%02X (1=input)", this->mode_mask_);
ESP_LOGCONFIG(TAG, " Polarity Mask: 0x%02X", this->polarity_mask_);
}
bool TCA6408Component::read_gpio_outputs_() {
@@ -91,7 +71,6 @@ bool TCA6408Component::read_gpio_outputs_() {
bool TCA6408Component::digital_read_hw(uint8_t pin) {
if (this->is_failed()) return false;
uint8_t data = 0;
if (this->read_register(TCA6408_INPUT_PORT, &data) != i2c::ERROR_OK) {
this->status_set_warning();
@@ -104,13 +83,11 @@ bool TCA6408Component::digital_read_hw(uint8_t pin) {
void TCA6408Component::digital_write_hw(uint8_t pin, bool value) {
if (this->is_failed()) return;
if (value) {
this->output_mask_ |= (1U << pin);
} else {
this->output_mask_ &= ~(1U << pin);
}
if (this->write_register(TCA6408_OUTPUT_PORT, this->output_mask_) != i2c::ERROR_OK) {
this->status_set_warning();
} else {
@@ -120,12 +97,10 @@ void TCA6408Component::digital_write_hw(uint8_t pin, bool value) {
void TCA6408Component::pin_mode(uint8_t pin, gpio::Flags flags) {
if (flags & gpio::FLAG_OUTPUT) {
this->mode_mask_ &= ~(1U << pin); // 0 = output
this->mode_mask_ &= ~(1U << pin);
} else {
this->mode_mask_ |= (1U << pin); // 1 = input
if (this->interrupt_pin_ == nullptr) {
this->enable_loop();
}
this->mode_mask_ |= (1U << pin);
if (this->interrupt_pin_ == nullptr) this->enable_loop();
}
this->write_register(TCA6408_CONFIG_PORT, this->mode_mask_);
}
@@ -141,27 +116,19 @@ void TCA6408Component::set_polarity_inversion(uint8_t pin, bool inverted) {
bool TCA6408Component::digital_read_cache(uint8_t pin) {
bool value = (this->input_mask_ & (1U << pin)) != 0;
// Apply hardware polarity inversion if set
if (this->polarity_mask_ & (1U << pin)) {
value = !value;
}
if (this->polarity_mask_ & (1U << pin)) value = !value;
return value;
}
// ====================== TCA6408GPIOPin ======================
// TCA6408GPIOPin
void TCA6408GPIOPin::setup() {
this->pin_mode(this->flags_);
if (this->inverted_) {
this->parent_->set_polarity_inversion(this->pin_, true);
}
if (this->inverted_) this->parent_->set_polarity_inversion(this->pin_, true);
}
void TCA6408GPIOPin::set_inverted(bool inverted) {
this->inverted_ = inverted;
if (this->parent_ != nullptr) {
this->parent_->set_polarity_inversion(this->pin_, inverted);
}
if (this->parent_) this->parent_->set_polarity_inversion(this->pin_, inverted);
}
void TCA6408GPIOPin::pin_mode(gpio::Flags flags) {
@@ -178,7 +145,7 @@ void TCA6408GPIOPin::digital_write(bool value) {
}
size_t TCA6408GPIOPin::dump_summary(char *buffer, size_t len) const {
return snprintf(buffer, len, "%u via TCA6408@0x%02X", this->pin_, this->parent_->address_);
return snprintf(buffer, len, "%u via TCA6408", this->pin_);
}
} // namespace tca6408
+1 -1
View File
@@ -33,7 +33,7 @@ class TCA6408Component : public Component,
uint8_t mode_mask_{0xFF}; // 1 = input, 0 = output
uint8_t output_mask_{0x00};
uint8_t input_mask_{0x00};
uint8_t polarity_mask_{0x00}; // 1 = inverted (for inputs)
uint8_t polarity_mask_{0x00}; // 1 = inverted (hardware polarity for inputs)
InternalGPIOPin *interrupt_pin_{nullptr};
bool interrupt_triggered_{false};