ESPHome  2024.12.2
tca9555.cpp
Go to the documentation of this file.
1 #include "tca9555.h"
2 #include "esphome/core/log.h"
3 
4 static const uint8_t TCA9555_INPUT_PORT_REGISTER_0 = 0x00;
5 static const uint8_t TCA9555_INPUT_PORT_REGISTER_1 = 0x01;
6 static const uint8_t TCA9555_OUTPUT_PORT_REGISTER_0 = 0x02;
7 static const uint8_t TCA9555_OUTPUT_PORT_REGISTER_1 = 0x03;
8 static const uint8_t TCA9555_POLARITY_REGISTER_0 = 0x04;
9 static const uint8_t TCA9555_POLARITY_REGISTER_1 = 0x05;
10 static const uint8_t TCA9555_CONFIGURATION_PORT_0 = 0x06;
11 static const uint8_t TCA9555_CONFIGURATION_PORT_1 = 0x07;
12 
13 namespace esphome {
14 namespace tca9555 {
15 
16 static const char *const TAG = "tca9555";
17 
19  ESP_LOGCONFIG(TAG, "Setting up TCA9555...");
20  if (!this->read_gpio_modes_()) {
21  this->mark_failed();
22  return;
23  }
24  if (!this->read_gpio_outputs_()) {
25  this->mark_failed();
26  return;
27  }
28 }
30  ESP_LOGCONFIG(TAG, "TCA9555:");
31  LOG_I2C_DEVICE(this)
32  if (this->is_failed()) {
33  ESP_LOGE(TAG, "Communication with TCA9555 failed!");
34  }
35 }
37  if (flags == gpio::FLAG_INPUT) {
38  // Set mode mask bit
39  this->mode_mask_ |= 1 << pin;
40  } else if (flags == gpio::FLAG_OUTPUT) {
41  // Clear mode mask bit
42  this->mode_mask_ &= ~(1 << pin);
43  }
44  // Write GPIO to enable input mode
45  this->write_gpio_modes_();
46 }
48 
50  if (this->is_failed())
51  return false;
52  uint8_t data[2];
53  if (!this->read_bytes(TCA9555_OUTPUT_PORT_REGISTER_0, data, 2)) {
54  this->status_set_warning("Failed to read output register");
55  return false;
56  }
57  this->output_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
58  this->status_clear_warning();
59  return true;
60 }
61 
63  if (this->is_failed())
64  return false;
65  uint8_t data[2];
66  bool success = this->read_bytes(TCA9555_CONFIGURATION_PORT_0, data, 2);
67  if (!success) {
68  this->status_set_warning("Failed to read mode register");
69  return false;
70  }
71  this->mode_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
72 
73  this->status_clear_warning();
74  return true;
75 }
77  if (this->is_failed())
78  return false;
79  bool success;
80  uint8_t data[2];
81  success = this->read_bytes(TCA9555_INPUT_PORT_REGISTER_0, data, 2);
82  this->input_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
83 
84  if (!success) {
85  this->status_set_warning("Failed to read input register");
86  return false;
87  }
88 
89  this->status_clear_warning();
90  return true;
91 }
92 
93 void TCA9555Component::digital_write_hw(uint8_t pin, bool value) {
94  if (this->is_failed())
95  return;
96 
97  if (value) {
98  this->output_mask_ |= (1 << pin);
99  } else {
100  this->output_mask_ &= ~(1 << pin);
101  }
102 
103  uint8_t data[2];
104  data[0] = this->output_mask_;
105  data[1] = this->output_mask_ >> 8;
106  if (!this->write_bytes(TCA9555_OUTPUT_PORT_REGISTER_0, data, 2)) {
107  this->status_set_warning("Failed to write output register");
108  return;
109  }
110 
111  this->status_clear_warning();
112 }
113 
115  if (this->is_failed())
116  return false;
117  uint8_t data[2];
118 
119  data[0] = this->mode_mask_;
120  data[1] = this->mode_mask_ >> 8;
121  if (!this->write_bytes(TCA9555_CONFIGURATION_PORT_0, data, 2)) {
122  this->status_set_warning("Failed to write mode register");
123  return false;
124  }
125  this->status_clear_warning();
126  return true;
127 }
128 
129 bool TCA9555Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
130 
132 
133 void TCA9555GPIOPin::setup() { this->pin_mode(this->flags_); }
134 void TCA9555GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
135 bool TCA9555GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
136 void TCA9555GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
137 std::string TCA9555GPIOPin::dump_summary() const { return str_sprintf("%u via TCA9555", this->pin_); }
138 
139 } // namespace tca9555
140 } // namespace esphome
void pin_mode(gpio::Flags flags) override
Definition: tca9555.cpp:134
uint16_t input_mask_
The state read in digital_read_hw - 1 means HIGH, 0 means LOW.
Definition: tca9555.h:37
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
bool digital_read_hw(uint8_t pin) override
Definition: tca9555.cpp:76
bool is_failed() const
Definition: component.cpp:143
uint16_t mode_mask_
Mask for the pin mode - 1 means output, 0 means input.
Definition: tca9555.h:33
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:212
float get_setup_priority() const override
Definition: tca9555.cpp:131
void pin_mode(uint8_t pin, gpio::Flags flags)
Definition: tca9555.cpp:36
bool digital_read_cache(uint8_t pin) override
Definition: tca9555.cpp:129
void digital_write_hw(uint8_t pin, bool value) override
Definition: tca9555.cpp:93
std::string str_sprintf(const char *fmt,...)
Definition: helpers.cpp:320
void status_clear_warning()
Definition: component.cpp:166
uint16_t output_mask_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition: tca9555.h:35
const uint32_t flags
Definition: stm32flash.h:85
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
const float IO
For components that represent GPIO pins like PCF8573.
Definition: component.cpp:17
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void digital_write(bool value) override
Definition: tca9555.cpp:136
std::string dump_summary() const override
Definition: tca9555.cpp:137
void setup() override
Check i2c availability and setup masks.
Definition: tca9555.cpp:18
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition: i2c.h:248