Merge branch 'main' of https://github.com/DitroniX/Home-Assistant-Dev
This commit is contained in:
@@ -3,15 +3,12 @@
|
|||||||
|
|
||||||
#### Welcome to the DitroniX Home Asssitant Integration
|
#### Welcome to the DitroniX Home Asssitant Integration
|
||||||
|
|
||||||
[](https://github.com/DitroniX/Home-Assistant-Dev/wiki)
|
|
||||||
|
|
||||||
This repository is for integration of DitroniX boards into Home Assistant using the ESPHome Components.
|
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.
|
The development and integration repository is work in progress as various projects evolve. It will also expand on route.
|
||||||
|
|
||||||
[](https://github.com/DitroniX/Home-Assistant-Dev/wiki)
|
[](https://github.com/DitroniX/Home-Assistant-Dev/wiki)
|
||||||
|
|
||||||
[](https://github.com/DitroniX/Home-Assistant-Dev/discussions)
|
|
||||||
|
|
||||||
#### User contributions
|
#### User contributions
|
||||||
|
|
||||||
@@ -74,6 +71,7 @@ An example guide has been put together which should help get your boards up and
|
|||||||
## Versions
|
## Versions
|
||||||
|
|
||||||
|
|
||||||
|
- 260613 - Added TCA6408 for Dev Testing
|
||||||
- 260529 - Refresh Information
|
- 260529 - Refresh Information
|
||||||
- 251217 - Initial upload of the ATM90E36 Component for EPEM E36. Could also be adapted for IPEM E36
|
- 251217 - Initial upload of the ATM90E36 Component for EPEM E36. Could also be adapted for IPEM E36
|
||||||
|
|
||||||
|
|||||||
@@ -14,21 +14,9 @@ static const uint8_t TCA6408_CONFIG_PORT = 0x03;
|
|||||||
void TCA6408Component::setup() {
|
void TCA6408Component::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up TCA6408 at address 0x%02X...", this->address_);
|
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 ||
|
||||||
if (this->write_register(TCA6408_POLARITY_PORT, 0x00) != i2c::ERROR_OK) {
|
this->write_register(TCA6408_CONFIG_PORT, this->mode_mask_) != i2c::ERROR_OK ||
|
||||||
ESP_LOGE(TAG, "Failed to write polarity register");
|
!this->read_gpio_outputs_()) {
|
||||||
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");
|
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -36,16 +24,13 @@ void TCA6408Component::setup() {
|
|||||||
if (this->interrupt_pin_ != nullptr) {
|
if (this->interrupt_pin_ != nullptr) {
|
||||||
this->interrupt_pin_->setup();
|
this->interrupt_pin_->setup();
|
||||||
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
||||||
this->interrupt_pin_->attach_interrupt(&TCA6408Component::gpio_intr, this,
|
this->interrupt_pin_->attach_interrupt(&TCA6408Component::gpio_intr, this, gpio::INTERRUPT_FALLING_EDGE);
|
||||||
gpio::INTERRUPT_FALLING_EDGE);
|
|
||||||
this->set_invalidate_on_read_(false);
|
this->set_invalidate_on_read_(false);
|
||||||
ESP_LOGCONFIG(TAG, " Interrupt mode enabled (active-low INT)");
|
ESP_LOGCONFIG(TAG, " Interrupt mode enabled (active-low)");
|
||||||
} else {
|
} else {
|
||||||
this->enable_loop();
|
this->enable_loop();
|
||||||
ESP_LOGCONFIG(TAG, " Polling mode enabled");
|
ESP_LOGCONFIG(TAG, " Polling mode enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGCONFIG(TAG, " Setup complete");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR TCA6408Component::gpio_intr(TCA6408Component *arg) {
|
void IRAM_ATTR TCA6408Component::gpio_intr(TCA6408Component *arg) {
|
||||||
@@ -56,12 +41,9 @@ void IRAM_ATTR TCA6408Component::gpio_intr(TCA6408Component *arg) {
|
|||||||
void TCA6408Component::loop() {
|
void TCA6408Component::loop() {
|
||||||
if (this->interrupt_triggered_) {
|
if (this->interrupt_triggered_) {
|
||||||
this->interrupt_triggered_ = false;
|
this->interrupt_triggered_ = false;
|
||||||
|
this->digital_read_hw(0);
|
||||||
// Reading input port clears the interrupt on TCA6408
|
|
||||||
this->digital_read_hw(0); // pin number is ignored, reads all 8 bits
|
|
||||||
this->reset_pin_cache_();
|
this->reset_pin_cache_();
|
||||||
|
|
||||||
// If INT line is high again, disable loop until next interrupt
|
|
||||||
if (this->interrupt_pin_ && this->interrupt_pin_->digital_read()) {
|
if (this->interrupt_pin_ && this->interrupt_pin_->digital_read()) {
|
||||||
this->disable_loop();
|
this->disable_loop();
|
||||||
}
|
}
|
||||||
@@ -73,8 +55,6 @@ void TCA6408Component::dump_config() {
|
|||||||
LOG_I2C_DEVICE(this);
|
LOG_I2C_DEVICE(this);
|
||||||
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
|
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
|
||||||
LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
|
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_() {
|
bool TCA6408Component::read_gpio_outputs_() {
|
||||||
@@ -91,7 +71,6 @@ bool TCA6408Component::read_gpio_outputs_() {
|
|||||||
|
|
||||||
bool TCA6408Component::digital_read_hw(uint8_t pin) {
|
bool TCA6408Component::digital_read_hw(uint8_t pin) {
|
||||||
if (this->is_failed()) return false;
|
if (this->is_failed()) return false;
|
||||||
|
|
||||||
uint8_t data = 0;
|
uint8_t data = 0;
|
||||||
if (this->read_register(TCA6408_INPUT_PORT, &data) != i2c::ERROR_OK) {
|
if (this->read_register(TCA6408_INPUT_PORT, &data) != i2c::ERROR_OK) {
|
||||||
this->status_set_warning();
|
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) {
|
void TCA6408Component::digital_write_hw(uint8_t pin, bool value) {
|
||||||
if (this->is_failed()) return;
|
if (this->is_failed()) return;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this->output_mask_ |= (1U << pin);
|
this->output_mask_ |= (1U << pin);
|
||||||
} else {
|
} else {
|
||||||
this->output_mask_ &= ~(1U << pin);
|
this->output_mask_ &= ~(1U << pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->write_register(TCA6408_OUTPUT_PORT, this->output_mask_) != i2c::ERROR_OK) {
|
if (this->write_register(TCA6408_OUTPUT_PORT, this->output_mask_) != i2c::ERROR_OK) {
|
||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
} else {
|
} 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) {
|
void TCA6408Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
||||||
if (flags & gpio::FLAG_OUTPUT) {
|
if (flags & gpio::FLAG_OUTPUT) {
|
||||||
this->mode_mask_ &= ~(1U << pin); // 0 = output
|
this->mode_mask_ &= ~(1U << pin);
|
||||||
} else {
|
} else {
|
||||||
this->mode_mask_ |= (1U << pin); // 1 = input
|
this->mode_mask_ |= (1U << pin);
|
||||||
if (this->interrupt_pin_ == nullptr) {
|
if (this->interrupt_pin_ == nullptr) this->enable_loop();
|
||||||
this->enable_loop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this->write_register(TCA6408_CONFIG_PORT, this->mode_mask_);
|
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 TCA6408Component::digital_read_cache(uint8_t pin) {
|
||||||
bool value = (this->input_mask_ & (1U << pin)) != 0;
|
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;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================== TCA6408GPIOPin ======================
|
// TCA6408GPIOPin
|
||||||
|
|
||||||
void TCA6408GPIOPin::setup() {
|
void TCA6408GPIOPin::setup() {
|
||||||
this->pin_mode(this->flags_);
|
this->pin_mode(this->flags_);
|
||||||
if (this->inverted_) {
|
if (this->inverted_) this->parent_->set_polarity_inversion(this->pin_, true);
|
||||||
this->parent_->set_polarity_inversion(this->pin_, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCA6408GPIOPin::set_inverted(bool inverted) {
|
void TCA6408GPIOPin::set_inverted(bool inverted) {
|
||||||
this->inverted_ = inverted;
|
this->inverted_ = inverted;
|
||||||
if (this->parent_ != nullptr) {
|
if (this->parent_) this->parent_->set_polarity_inversion(this->pin_, inverted);
|
||||||
this->parent_->set_polarity_inversion(this->pin_, inverted);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCA6408GPIOPin::pin_mode(gpio::Flags flags) {
|
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 {
|
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
|
} // namespace tca6408
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class TCA6408Component : public Component,
|
|||||||
uint8_t mode_mask_{0xFF}; // 1 = input, 0 = output
|
uint8_t mode_mask_{0xFF}; // 1 = input, 0 = output
|
||||||
uint8_t output_mask_{0x00};
|
uint8_t output_mask_{0x00};
|
||||||
uint8_t input_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};
|
InternalGPIOPin *interrupt_pin_{nullptr};
|
||||||
bool interrupt_triggered_{false};
|
bool interrupt_triggered_{false};
|
||||||
|
|||||||
Reference in New Issue
Block a user