ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
tca9555.cpp
Go to the documentation of this file.
1#include "tca9555.h"
2#include "esphome/core/log.h"
3
4static const uint8_t TCA9555_INPUT_PORT_REGISTER_0 = 0x00;
5static const uint8_t TCA9555_INPUT_PORT_REGISTER_1 = 0x01;
6static const uint8_t TCA9555_OUTPUT_PORT_REGISTER_0 = 0x02;
7static const uint8_t TCA9555_OUTPUT_PORT_REGISTER_1 = 0x03;
8static const uint8_t TCA9555_POLARITY_REGISTER_0 = 0x04;
9static const uint8_t TCA9555_POLARITY_REGISTER_1 = 0x05;
10static const uint8_t TCA9555_CONFIGURATION_PORT_0 = 0x06;
11static const uint8_t TCA9555_CONFIGURATION_PORT_1 = 0x07;
12
13namespace esphome {
14namespace tca9555 {
15
16static const char *const TAG = "tca9555";
17
19 if (!this->read_gpio_modes_()) {
20 this->mark_failed();
21 return;
22 }
23 if (!this->read_gpio_outputs_()) {
24 this->mark_failed();
25 return;
26 }
27
28 if (this->interrupt_pin_ != nullptr) {
29 this->interrupt_pin_->setup();
31 this->set_invalidate_on_read_(false);
32 }
33 this->disable_loop();
34}
37 ESP_LOGCONFIG(TAG, "TCA9555:");
38 LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
39 LOG_I2C_DEVICE(this)
40 if (this->is_failed()) {
41 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
42 }
43}
45 if (flags == gpio::FLAG_INPUT) {
46 // Set mode mask bit
47 this->mode_mask_ |= 1 << pin;
48 if (this->interrupt_pin_ == nullptr) {
49 this->enable_loop();
50 }
51 } else if (flags == gpio::FLAG_OUTPUT) {
52 // Clear mode mask bit
53 this->mode_mask_ &= ~(1 << pin);
54 }
55 // Write GPIO to enable input mode
56 this->write_gpio_modes_();
57}
59 this->reset_pin_cache_();
60 if (this->interrupt_pin_ != nullptr) {
61 this->disable_loop();
62 }
63}
64
66 if (this->is_failed())
67 return false;
68 uint8_t data[2];
69 if (!this->read_bytes(TCA9555_OUTPUT_PORT_REGISTER_0, data, 2)) {
70 this->status_set_warning(LOG_STR("Failed to read output register"));
71 return false;
72 }
73 this->output_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
75 return true;
76}
77
79 if (this->is_failed())
80 return false;
81 uint8_t data[2];
82 bool success = this->read_bytes(TCA9555_CONFIGURATION_PORT_0, data, 2);
83 if (!success) {
84 this->status_set_warning(LOG_STR("Failed to read mode register"));
85 return false;
86 }
87 this->mode_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
88
90 return true;
91}
93 if (this->is_failed())
94 return false;
95 uint8_t data;
96 uint8_t bank_number = pin < 8 ? 0 : 1;
97 uint8_t register_to_read = bank_number ? TCA9555_INPUT_PORT_REGISTER_1 : TCA9555_INPUT_PORT_REGISTER_0;
98 if (!this->read_bytes(register_to_read, &data, 1)) {
99 this->status_set_warning(LOG_STR("Failed to read input register"));
100 return false;
101 }
102 uint8_t second_half = this->input_mask_ >> 8;
103 uint8_t first_half = this->input_mask_;
104 if (bank_number) {
105 this->input_mask_ = (data << 8) | (uint16_t(first_half) << 0);
106 } else {
107 this->input_mask_ = (uint16_t(second_half) << 8) | (data << 0);
108 }
109
110 this->status_clear_warning();
111 return true;
112}
113
114void TCA9555Component::digital_write_hw(uint8_t pin, bool value) {
115 if (this->is_failed())
116 return;
117
118 if (value) {
119 this->output_mask_ |= (1 << pin);
120 } else {
121 this->output_mask_ &= ~(1 << pin);
122 }
123
124 uint8_t data[2];
125 data[0] = this->output_mask_;
126 data[1] = this->output_mask_ >> 8;
127 if (!this->write_bytes(TCA9555_OUTPUT_PORT_REGISTER_0, data, 2)) {
128 this->status_set_warning(LOG_STR("Failed to write output register"));
129 return;
130 }
131
132 this->status_clear_warning();
133}
134
136 if (this->is_failed())
137 return false;
138 uint8_t data[2];
139
140 data[0] = this->mode_mask_;
141 data[1] = this->mode_mask_ >> 8;
142 if (!this->write_bytes(TCA9555_CONFIGURATION_PORT_0, data, 2)) {
143 this->status_set_warning(LOG_STR("Failed to write mode register"));
144 return false;
145 }
146 this->status_clear_warning();
147 return true;
148}
149
150bool TCA9555Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
151
153
154void TCA9555GPIOPin::setup() { this->pin_mode(this->flags_); }
155void TCA9555GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
156bool TCA9555GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
157void TCA9555GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
158size_t TCA9555GPIOPin::dump_summary(char *buffer, size_t len) const {
159 return buf_append_printf(buffer, len, 0, "%u via TCA9555", this->pin_);
160}
161
162} // namespace tca9555
163} // namespace esphome
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:284
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
void enable_loop()
Enable this component's loop.
Definition component.h:258
void disable_loop()
Disable this component's loop.
void status_clear_warning()
Definition component.h:306
virtual void setup()=0
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition gpio.h:107
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len) const
Definition i2c.h:251
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition i2c.h:217
bool digital_read_hw(uint8_t pin) override
Definition tca9555.cpp:92
bool digital_read_cache(uint8_t pin) override
Definition tca9555.cpp:150
uint16_t mode_mask_
Mask for the pin mode - 1 means output, 0 means input.
Definition tca9555.h:36
InternalGPIOPin * interrupt_pin_
Definition tca9555.h:46
void setup() override
Check i2c availability and setup masks.
Definition tca9555.cpp:18
uint16_t input_mask_
The state read in digital_read_hw - 1 means HIGH, 0 means LOW.
Definition tca9555.h:40
float get_setup_priority() const override
Definition tca9555.cpp:152
uint16_t output_mask_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition tca9555.h:38
void digital_write_hw(uint8_t pin, bool value) override
Definition tca9555.cpp:114
void pin_mode(uint8_t pin, gpio::Flags flags)
Definition tca9555.cpp:44
static void IRAM_ATTR gpio_intr(TCA9555Component *arg)
Definition tca9555.cpp:35
void digital_write(bool value) override
Definition tca9555.cpp:157
size_t dump_summary(char *buffer, size_t len) const override
Definition tca9555.cpp:158
void pin_mode(gpio::Flags flags) override
Definition tca9555.cpp:155
uint16_t flags
@ INTERRUPT_FALLING_EDGE
Definition gpio.h:51
@ FLAG_OUTPUT
Definition gpio.h:28
@ FLAG_INPUT
Definition gpio.h:27
constexpr float IO
For components that represent GPIO pins like PCF8573.
Definition component.h:38
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:1045