ESPHome 2025.9.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}
29 ESP_LOGCONFIG(TAG, "TCA9555:");
30 LOG_I2C_DEVICE(this)
31 if (this->is_failed()) {
32 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
33 }
34}
35void TCA9555Component::pin_mode(uint8_t pin, gpio::Flags flags) {
36 if (flags == gpio::FLAG_INPUT) {
37 // Set mode mask bit
38 this->mode_mask_ |= 1 << pin;
39 } else if (flags == gpio::FLAG_OUTPUT) {
40 // Clear mode mask bit
41 this->mode_mask_ &= ~(1 << pin);
42 }
43 // Write GPIO to enable input mode
44 this->write_gpio_modes_();
45}
47
49 if (this->is_failed())
50 return false;
51 uint8_t data[2];
52 if (!this->read_bytes(TCA9555_OUTPUT_PORT_REGISTER_0, data, 2)) {
53 this->status_set_warning("Failed to read output register");
54 return false;
55 }
56 this->output_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
58 return true;
59}
60
62 if (this->is_failed())
63 return false;
64 uint8_t data[2];
65 bool success = this->read_bytes(TCA9555_CONFIGURATION_PORT_0, data, 2);
66 if (!success) {
67 this->status_set_warning("Failed to read mode register");
68 return false;
69 }
70 this->mode_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
71
73 return true;
74}
76 if (this->is_failed())
77 return false;
78 uint8_t data;
79 uint8_t bank_number = pin < 8 ? 0 : 1;
80 uint8_t register_to_read = bank_number ? TCA9555_INPUT_PORT_REGISTER_1 : TCA9555_INPUT_PORT_REGISTER_0;
81 if (!this->read_bytes(register_to_read, &data, 1)) {
82 this->status_set_warning("Failed to read input register");
83 return false;
84 }
85 uint8_t second_half = this->input_mask_ >> 8;
86 uint8_t first_half = this->input_mask_;
87 if (bank_number) {
88 this->input_mask_ = (data << 8) | (uint16_t(first_half) << 0);
89 } else {
90 this->input_mask_ = (uint16_t(second_half) << 8) | (data << 0);
91 }
92
94 return true;
95}
96
97void TCA9555Component::digital_write_hw(uint8_t pin, bool value) {
98 if (this->is_failed())
99 return;
100
101 if (value) {
102 this->output_mask_ |= (1 << pin);
103 } else {
104 this->output_mask_ &= ~(1 << pin);
105 }
106
107 uint8_t data[2];
108 data[0] = this->output_mask_;
109 data[1] = this->output_mask_ >> 8;
110 if (!this->write_bytes(TCA9555_OUTPUT_PORT_REGISTER_0, data, 2)) {
111 this->status_set_warning("Failed to write output register");
112 return;
113 }
114
115 this->status_clear_warning();
116}
117
119 if (this->is_failed())
120 return false;
121 uint8_t data[2];
122
123 data[0] = this->mode_mask_;
124 data[1] = this->mode_mask_ >> 8;
125 if (!this->write_bytes(TCA9555_CONFIGURATION_PORT_0, data, 2)) {
126 this->status_set_warning("Failed to write mode register");
127 return false;
128 }
129 this->status_clear_warning();
130 return true;
131}
132
133bool TCA9555Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
134
136
137void TCA9555GPIOPin::setup() { this->pin_mode(this->flags_); }
138void TCA9555GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
139bool TCA9555GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
140void TCA9555GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
141std::string TCA9555GPIOPin::dump_summary() const { return str_sprintf("%u via TCA9555", this->pin_); }
142
143} // namespace tca9555
144} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
void status_clear_warning()
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition i2c.h:252
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:216
bool digital_read_hw(uint8_t pin) override
Definition tca9555.cpp:75
bool digital_read_cache(uint8_t pin) override
Definition tca9555.cpp:133
uint16_t mode_mask_
Mask for the pin mode - 1 means output, 0 means input.
Definition tca9555.h:33
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:37
float get_setup_priority() const override
Definition tca9555.cpp:135
uint16_t output_mask_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition tca9555.h:35
void digital_write_hw(uint8_t pin, bool value) override
Definition tca9555.cpp:97
void pin_mode(uint8_t pin, gpio::Flags flags)
Definition tca9555.cpp:35
void digital_write(bool value) override
Definition tca9555.cpp:140
void pin_mode(gpio::Flags flags) override
Definition tca9555.cpp:138
std::string dump_summary() const override
Definition tca9555.cpp:141
@ FLAG_OUTPUT
Definition gpio.h:19
@ FLAG_INPUT
Definition gpio.h:18
const float IO
For components that represent GPIO pins like PCF8573.
Definition component.cpp:48
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string str_sprintf(const char *fmt,...)
Definition helpers.cpp:208