ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
pca6416a.cpp
Go to the documentation of this file.
1#include "pca6416a.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace pca6416a {
6
23
24static const char *const TAG = "pca6416a";
25
27 // Test to see if device exists
28 uint8_t value;
29 if (!this->read_register_(PCA6416A_INPUT0, &value)) {
30 ESP_LOGE(TAG, "PCA6416A not available under 0x%02X", this->address_);
31 this->mark_failed();
32 return;
33 }
34
35 // Test to see if the device supports pull-up resistors
36 if (this->read_register(PCAL6416A_PULL_EN0, &value, 1, true) == i2c::ERROR_OK) {
37 this->has_pullup_ = true;
38 }
39
40 // No polarity inversion
43 // Set all pins to input
46 // Read current output register state
49
50 ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
51 this->status_has_error());
52}
53
55 if (this->has_pullup_) {
56 ESP_LOGCONFIG(TAG, "PCAL6416A:");
57 } else {
58 ESP_LOGCONFIG(TAG, "PCA6416A:");
59 }
60 LOG_I2C_DEVICE(this)
61 if (this->is_failed()) {
62 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
63 }
64}
65
67 uint8_t bit = pin % 8;
68 uint8_t reg_addr = pin < 8 ? PCA6416A_INPUT0 : PCA6416A_INPUT1;
69 uint8_t value = 0;
70 this->read_register_(reg_addr, &value);
71 return value & (1 << bit);
72}
73
74void PCA6416AComponent::digital_write(uint8_t pin, bool value) {
75 uint8_t reg_addr = pin < 8 ? PCA6416A_OUTPUT0 : PCA6416A_OUTPUT1;
76 this->update_register_(pin, value, reg_addr);
77}
78
79void PCA6416AComponent::pin_mode(uint8_t pin, gpio::Flags flags) {
80 uint8_t io_dir = pin < 8 ? PCA6416A_CONFIG0 : PCA6416A_CONFIG1;
81 uint8_t pull_en = pin < 8 ? PCAL6416A_PULL_EN0 : PCAL6416A_PULL_EN1;
82 uint8_t pull_dir = pin < 8 ? PCAL6416A_PULL_DIR0 : PCAL6416A_PULL_DIR1;
83 if (flags == gpio::FLAG_INPUT) {
84 this->update_register_(pin, true, io_dir);
85 if (has_pullup_) {
86 this->update_register_(pin, true, pull_dir);
87 this->update_register_(pin, false, pull_en);
88 }
89 } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
90 this->update_register_(pin, true, io_dir);
91 if (has_pullup_) {
92 this->update_register_(pin, true, pull_dir);
93 this->update_register_(pin, true, pull_en);
94 } else {
95 ESP_LOGW(TAG, "Your PCA6416A does not support pull-up resistors");
96 }
97 } else if (flags == gpio::FLAG_OUTPUT) {
98 this->update_register_(pin, false, io_dir);
99 }
100}
101
102bool PCA6416AComponent::read_register_(uint8_t reg, uint8_t *value) {
103 if (this->is_failed()) {
104 ESP_LOGD(TAG, "Device marked failed");
105 return false;
106 }
107
108 this->last_error_ = this->read_register(reg, value, 1, true);
109 if (this->last_error_ != i2c::ERROR_OK) {
110 this->status_set_warning();
111 ESP_LOGE(TAG, "read_register_(): I2C I/O error: %d", (int) this->last_error_);
112 return false;
113 }
114
115 this->status_clear_warning();
116 return true;
117}
118
119bool PCA6416AComponent::write_register_(uint8_t reg, uint8_t value) {
120 if (this->is_failed()) {
121 ESP_LOGD(TAG, "Device marked failed");
122 return false;
123 }
124
125 this->last_error_ = this->write_register(reg, &value, 1, true);
126 if (this->last_error_ != i2c::ERROR_OK) {
127 this->status_set_warning();
128 ESP_LOGE(TAG, "write_register_(): I2C I/O error: %d", (int) this->last_error_);
129 return false;
130 }
131
132 this->status_clear_warning();
133 return true;
134}
135
136void PCA6416AComponent::update_register_(uint8_t pin, bool pin_value, uint8_t reg_addr) {
137 uint8_t bit = pin % 8;
138 uint8_t reg_value = 0;
139 if (reg_addr == PCA6416A_OUTPUT0) {
140 reg_value = this->output_0_;
141 } else if (reg_addr == PCA6416A_OUTPUT1) {
142 reg_value = this->output_1_;
143 } else {
144 this->read_register_(reg_addr, &reg_value);
145 }
146
147 if (pin_value) {
148 reg_value |= 1 << bit;
149 } else {
150 reg_value &= ~(1 << bit);
151 }
152
153 this->write_register_(reg_addr, reg_value);
154
155 if (reg_addr == PCA6416A_OUTPUT0) {
156 this->output_0_ = reg_value;
157 } else if (reg_addr == PCA6416A_OUTPUT1) {
158 this->output_1_ = reg_value;
159 }
160}
161
163
165void PCA6416AGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
166bool PCA6416AGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
167void PCA6416AGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
168std::string PCA6416AGPIOPin::dump_summary() const {
169 char buffer[32];
170 snprintf(buffer, sizeof(buffer), "%u via PCA6416A", pin_);
171 return buffer;
172}
173
174} // namespace pca6416a
175} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
bool status_has_warning() const
bool status_has_error() const
void status_clear_warning()
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a specific register in the I²C device
Definition i2c.cpp:25
uint8_t address_
store the address of the device on the bus
Definition i2c.h:273
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:10
void digital_write(uint8_t pin, bool value)
Helper function to write the value of a pin.
Definition pca6416a.cpp:74
bool write_register_(uint8_t reg, uint8_t value)
Definition pca6416a.cpp:119
bool read_register_(uint8_t reg, uint8_t *value)
Definition pca6416a.cpp:102
esphome::i2c::ErrorCode last_error_
Storage for last I2C error seen.
Definition pca6416a.h:36
void update_register_(uint8_t pin, bool pin_value, uint8_t reg_addr)
Definition pca6416a.cpp:136
bool has_pullup_
Only the PCAL6416A has pull-up resistors.
Definition pca6416a.h:38
void pin_mode(uint8_t pin, gpio::Flags flags)
Helper function to set the pin mode of a pin.
Definition pca6416a.cpp:79
void setup() override
Check i2c availability and setup masks.
Definition pca6416a.cpp:26
bool digital_read(uint8_t pin)
Helper function to read the value of a pin.
Definition pca6416a.cpp:66
float get_setup_priority() const override
Definition pca6416a.cpp:162
uint8_t output_0_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition pca6416a.h:33
void digital_write(bool value) override
Definition pca6416a.cpp:167
PCA6416AComponent * parent_
Definition pca6416a.h:58
std::string dump_summary() const override
Definition pca6416a.cpp:168
void pin_mode(gpio::Flags flags) override
Definition pca6416a.cpp:165
@ FLAG_OUTPUT
Definition gpio.h:19
@ FLAG_PULLUP
Definition gpio.h:21
@ FLAG_INPUT
Definition gpio.h:18
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:13
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