ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
pi4ioe5v6408.cpp
Go to the documentation of this file.
1#include "pi4ioe5v6408.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace pi4ioe5v6408 {
6
7static const uint8_t PI4IOE5V6408_REGISTER_DEVICE_ID = 0x01;
8static const uint8_t PI4IOE5V6408_REGISTER_IO_DIR = 0x03;
9static const uint8_t PI4IOE5V6408_REGISTER_OUT_SET = 0x05;
10static const uint8_t PI4IOE5V6408_REGISTER_OUT_HIGH_IMPEDENCE = 0x07;
11static const uint8_t PI4IOE5V6408_REGISTER_IN_DEFAULT_STATE = 0x09;
12static const uint8_t PI4IOE5V6408_REGISTER_PULL_ENABLE = 0x0B;
13static const uint8_t PI4IOE5V6408_REGISTER_PULL_SELECT = 0x0D;
14static const uint8_t PI4IOE5V6408_REGISTER_IN_STATE = 0x0F;
15static const uint8_t PI4IOE5V6408_REGISTER_INTERRUPT_ENABLE_MASK = 0x11;
16static const uint8_t PI4IOE5V6408_REGISTER_INTERRUPT_STATUS = 0x13;
17
18static const char *const TAG = "pi4ioe5v6408";
19
21 if (this->reset_) {
22 this->reg(PI4IOE5V6408_REGISTER_DEVICE_ID) |= 0b00000001;
23 this->reg(PI4IOE5V6408_REGISTER_OUT_HIGH_IMPEDENCE) = 0b00000000;
24 } else {
25 if (!this->read_gpio_modes_()) {
26 this->mark_failed();
27 ESP_LOGE(TAG, "Failed to read GPIO modes");
28 return;
29 }
30 if (!this->read_gpio_outputs_()) {
31 this->mark_failed();
32 ESP_LOGE(TAG, "Failed to read GPIO outputs");
33 return;
34 }
35 }
36
37 // No need to clear latched interrupts before attaching the ISR — if INT is
38 // already low the ISR fires immediately, loop runs, cache invalidates, and
39 // the read clears the latch. One harmless extra read at most.
40 if (this->interrupt_pin_ != nullptr) {
41 this->interrupt_pin_->setup();
43 this->set_invalidate_on_read_(false);
44 }
45 // Disable loop until an input pin is configured via pin_mode()
46 // For interrupt-driven mode, loop is re-enabled by the ISR
47 // For polling mode, loop is re-enabled when pin_mode() registers an input pin
48 this->disable_loop();
49}
52 ESP_LOGCONFIG(TAG, "PI4IOE5V6408:");
53 LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
54 LOG_I2C_DEVICE(this)
55 if (this->is_failed()) {
56 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
57 }
58}
61 // Set mode mask bit
62 this->mode_mask_ |= 1 << pin;
63 } else if (flags & gpio::FLAG_INPUT) {
64 // Clear mode mask bit
65 this->mode_mask_ &= ~(1 << pin);
67 this->pull_up_down_mask_ |= 1 << pin;
68 this->pull_enable_mask_ |= 1 << pin;
69 } else if (flags & gpio::FLAG_PULLDOWN) {
70 this->pull_up_down_mask_ &= ~(1 << pin);
71 this->pull_enable_mask_ |= 1 << pin;
72 }
73 // Enable polling loop for input pins (not needed for interrupt-driven mode
74 // where the ISR handles re-enabling loop)
75 if (this->interrupt_pin_ == nullptr) {
76 this->enable_loop();
77 }
78 }
79 // Write GPIO to enable input mode
80 this->write_gpio_modes_();
81}
82
84 this->reset_pin_cache_();
85 if (this->interrupt_pin_ != nullptr) {
86 this->disable_loop();
87 }
88}
89
91 if (this->is_failed())
92 return false;
93
94 uint8_t data;
95 if (!this->read_byte(PI4IOE5V6408_REGISTER_OUT_SET, &data)) {
96 this->status_set_warning(LOG_STR("Failed to read output register"));
97 return false;
98 }
99 this->output_mask_ = data;
100 this->status_clear_warning();
101 return true;
102}
103
105 if (this->is_failed())
106 return false;
107
108 uint8_t data;
109 if (!this->read_byte(PI4IOE5V6408_REGISTER_IO_DIR, &data)) {
110 this->status_set_warning(LOG_STR("Failed to read GPIO modes"));
111 return false;
112 }
113#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
114 ESP_LOGV(TAG, "Read GPIO modes: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(data));
115#endif
116 this->mode_mask_ = data;
117 this->status_clear_warning();
118 return true;
119}
120
122 if (this->is_failed())
123 return false;
124
125 uint8_t data;
126 if (!this->read_byte(PI4IOE5V6408_REGISTER_IN_STATE, &data)) {
127 this->status_set_warning(LOG_STR("Failed to read GPIO state"));
128 return false;
129 }
130 this->input_mask_ = data;
131 this->status_clear_warning();
132 return true;
133}
134
135void PI4IOE5V6408Component::digital_write_hw(uint8_t pin, bool value) {
136 if (this->is_failed())
137 return;
138
139 if (value) {
140 this->output_mask_ |= (1 << pin);
141 } else {
142 this->output_mask_ &= ~(1 << pin);
143 }
144 if (!this->write_byte(PI4IOE5V6408_REGISTER_OUT_SET, this->output_mask_)) {
145 this->status_set_warning(LOG_STR("Failed to write output register"));
146 return;
147 }
148#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
149 ESP_LOGV(TAG, "Wrote GPIO output: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(this->output_mask_));
150#endif
151 this->status_clear_warning();
152}
153
155 if (this->is_failed())
156 return false;
157
158 if (!this->write_byte(PI4IOE5V6408_REGISTER_IO_DIR, this->mode_mask_)) {
159 this->status_set_warning(LOG_STR("Failed to write GPIO modes"));
160 return false;
161 }
162 if (!this->write_byte(PI4IOE5V6408_REGISTER_PULL_SELECT, this->pull_up_down_mask_)) {
163 this->status_set_warning(LOG_STR("Failed to write GPIO pullup/pulldown"));
164 return false;
165 }
166 if (!this->write_byte(PI4IOE5V6408_REGISTER_PULL_ENABLE, this->pull_enable_mask_)) {
167 this->status_set_warning(LOG_STR("Failed to write GPIO pull enable"));
168 return false;
169 }
170 // Enable interrupts for input pins when interrupt pin is configured
171 // (input pins have mode_mask_ bit cleared)
172 if (this->interrupt_pin_ != nullptr &&
173 !this->write_byte(PI4IOE5V6408_REGISTER_INTERRUPT_ENABLE_MASK, static_cast<uint8_t>(~this->mode_mask_))) {
174 this->status_set_warning(LOG_STR("Failed to write interrupt enable mask"));
175 return false;
176 }
177#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
178 ESP_LOGV(TAG,
179 "Wrote GPIO config:\n"
180 " modes: 0b" BYTE_TO_BINARY_PATTERN "\n"
181 " pullup/pulldown: 0b" BYTE_TO_BINARY_PATTERN "\n"
182 " pull enable: 0b" BYTE_TO_BINARY_PATTERN,
183 BYTE_TO_BINARY(this->mode_mask_), BYTE_TO_BINARY(this->pull_up_down_mask_),
184 BYTE_TO_BINARY(this->pull_enable_mask_));
185#endif
186 this->status_clear_warning();
187 return true;
188}
189
190bool PI4IOE5V6408Component::digital_read_cache(uint8_t pin) { return (this->input_mask_ & (1 << pin)); }
191
193
195void PI4IOE5V6408GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
196bool PI4IOE5V6408GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
198 this->parent_->digital_write(this->pin_, value != this->inverted_);
199}
200size_t PI4IOE5V6408GPIOPin::dump_summary(char *buffer, size_t len) const {
201 return buf_append_printf(buffer, len, 0, "%u via PI4IOE5V6408", this->pin_);
202}
203
204} // namespace pi4ioe5v6408
205} // 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_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:265
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:240
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:152
static void IRAM_ATTR gpio_intr(PI4IOE5V6408Component *arg)
uint8_t pull_enable_mask_
The mask to write as input buffer state - 1 means enabled, 0 means disabled.
uint8_t output_mask_
The mask to write as output state - 1 means HIGH, 0 means LOW.
uint8_t pull_up_down_mask_
The mask to write as pullup state - 1 means pullup, 0 means pulldown.
bool digital_read_cache(uint8_t pin) override
void digital_write_hw(uint8_t pin, bool value) override
uint8_t input_mask_
The state read in digital_read_hw - 1 means HIGH, 0 means LOW.
uint8_t mode_mask_
Mask for the pin mode - 1 means output, 0 means input.
void pin_mode(uint8_t pin, gpio::Flags flags)
void pin_mode(gpio::Flags flags) override
size_t dump_summary(char *buffer, size_t len) const override
uint16_t flags
@ INTERRUPT_FALLING_EDGE
Definition gpio.h:51
@ FLAG_OUTPUT
Definition gpio.h:28
@ FLAG_PULLUP
Definition gpio.h:30
@ FLAG_INPUT
Definition gpio.h:27
@ FLAG_PULLDOWN
Definition gpio.h:31
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