ESPHome 2025.5.0
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 ESP_LOGCONFIG(TAG, "Setting up PCA6416A...");
28 // Test to see if device exists
29 uint8_t value;
30 if (!this->read_register_(PCA6416A_INPUT0, &value)) {
31 ESP_LOGE(TAG, "PCA6416A not available under 0x%02X", this->address_);
32 this->mark_failed();
33 return;
34 }
35
36 // Test to see if the device supports pull-up resistors
37 if (this->read_register(PCAL6416A_PULL_EN0, &value, 1, true) == i2c::ERROR_OK) {
38 this->has_pullup_ = true;
39 }
40
41 // No polarity inversion
44 // Set all pins to input
47 // Read current output register state
50
51 ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
52 this->status_has_error());
53}
54
56 if (this->has_pullup_) {
57 ESP_LOGCONFIG(TAG, "PCAL6416A:");
58 } else {
59 ESP_LOGCONFIG(TAG, "PCA6416A:");
60 }
61 LOG_I2C_DEVICE(this)
62 if (this->is_failed()) {
63 ESP_LOGE(TAG, "Communication with PCA6416A failed!");
64 }
65}
66
68 uint8_t bit = pin % 8;
69 uint8_t reg_addr = pin < 8 ? PCA6416A_INPUT0 : PCA6416A_INPUT1;
70 uint8_t value = 0;
71 this->read_register_(reg_addr, &value);
72 return value & (1 << bit);
73}
74
75void PCA6416AComponent::digital_write(uint8_t pin, bool value) {
76 uint8_t reg_addr = pin < 8 ? PCA6416A_OUTPUT0 : PCA6416A_OUTPUT1;
77 this->update_register_(pin, value, reg_addr);
78}
79
80void PCA6416AComponent::pin_mode(uint8_t pin, gpio::Flags flags) {
81 uint8_t io_dir = pin < 8 ? PCA6416A_CONFIG0 : PCA6416A_CONFIG1;
82 uint8_t pull_en = pin < 8 ? PCAL6416A_PULL_EN0 : PCAL6416A_PULL_EN1;
83 uint8_t pull_dir = pin < 8 ? PCAL6416A_PULL_DIR0 : PCAL6416A_PULL_DIR1;
84 if (flags == gpio::FLAG_INPUT) {
85 this->update_register_(pin, true, io_dir);
86 if (has_pullup_) {
87 this->update_register_(pin, true, pull_dir);
88 this->update_register_(pin, false, pull_en);
89 }
90 } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
91 this->update_register_(pin, true, io_dir);
92 if (has_pullup_) {
93 this->update_register_(pin, true, pull_dir);
94 this->update_register_(pin, true, pull_en);
95 } else {
96 ESP_LOGW(TAG, "Your PCA6416A does not support pull-up resistors");
97 }
98 } else if (flags == gpio::FLAG_OUTPUT) {
99 this->update_register_(pin, false, io_dir);
100 }
101}
102
103bool PCA6416AComponent::read_register_(uint8_t reg, uint8_t *value) {
104 if (this->is_failed()) {
105 ESP_LOGD(TAG, "Device marked failed");
106 return false;
107 }
108
109 this->last_error_ = this->read_register(reg, value, 1, true);
110 if (this->last_error_ != i2c::ERROR_OK) {
111 this->status_set_warning();
112 ESP_LOGE(TAG, "read_register_(): I2C I/O error: %d", (int) this->last_error_);
113 return false;
114 }
115
116 this->status_clear_warning();
117 return true;
118}
119
120bool PCA6416AComponent::write_register_(uint8_t reg, uint8_t value) {
121 if (this->is_failed()) {
122 ESP_LOGD(TAG, "Device marked failed");
123 return false;
124 }
125
126 this->last_error_ = this->write_register(reg, &value, 1, true);
127 if (this->last_error_ != i2c::ERROR_OK) {
128 this->status_set_warning();
129 ESP_LOGE(TAG, "write_register_(): I2C I/O error: %d", (int) this->last_error_);
130 return false;
131 }
132
133 this->status_clear_warning();
134 return true;
135}
136
137void PCA6416AComponent::update_register_(uint8_t pin, bool pin_value, uint8_t reg_addr) {
138 uint8_t bit = pin % 8;
139 uint8_t reg_value = 0;
140 if (reg_addr == PCA6416A_OUTPUT0) {
141 reg_value = this->output_0_;
142 } else if (reg_addr == PCA6416A_OUTPUT1) {
143 reg_value = this->output_1_;
144 } else {
145 this->read_register_(reg_addr, &reg_value);
146 }
147
148 if (pin_value) {
149 reg_value |= 1 << bit;
150 } else {
151 reg_value &= ~(1 << bit);
152 }
153
154 this->write_register_(reg_addr, reg_value);
155
156 if (reg_addr == PCA6416A_OUTPUT0) {
157 this->output_0_ = reg_value;
158 } else if (reg_addr == PCA6416A_OUTPUT1) {
159 this->output_1_ = reg_value;
160 }
161}
162
164
166void PCA6416AGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
167bool PCA6416AGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
168void PCA6416AGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
169std::string PCA6416AGPIOPin::dump_summary() const {
170 char buffer[32];
171 snprintf(buffer, sizeof(buffer), "%u via PCA6416A", pin_);
172 return buffer;
173}
174
175} // namespace pca6416a
176} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
bool status_has_warning() const
bool status_has_error() const
void status_set_warning(const char *message="unspecified")
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:75
bool write_register_(uint8_t reg, uint8_t value)
Definition pca6416a.cpp:120
bool read_register_(uint8_t reg, uint8_t *value)
Definition pca6416a.cpp:103
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:137
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:80
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:67
float get_setup_priority() const override
Definition pca6416a.cpp:163
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:168
PCA6416AComponent * parent_
Definition pca6416a.h:58
std::string dump_summary() const override
Definition pca6416a.cpp:169
void pin_mode(gpio::Flags flags) override
Definition pca6416a.cpp:166
@ 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:17
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7