ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
pi4ioe5v6408.cpp
Go to the documentation of this file.
1#include "pi4ioe5v6408.h"
3#include "esphome/core/log.h"
4
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
18ESPHOME_LOG_TAG(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(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
27 ESP_LOGE(TAG, "Failed to read GPIO modes");
28 return;
29 }
30 if (!this->read_gpio_outputs_()) {
31 this->mark_failed(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
32 ESP_LOGE(TAG, "Failed to read GPIO outputs");
33 return;
34 }
35 }
36
38}
40 ESP_LOGCONFIG(TAG, "PI4IOE5V6408:");
41 LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
42 LOG_I2C_DEVICE(this)
43}
46 // Set mode mask bit
47 this->mode_mask_ |= 1 << pin;
48 } else if (flags & gpio::FLAG_INPUT) {
49 // Clear mode mask bit
50 this->mode_mask_ &= ~(1 << pin);
52 this->pull_up_down_mask_ |= 1 << pin;
53 this->pull_enable_mask_ |= 1 << pin;
54 } else if (flags & gpio::FLAG_PULLDOWN) {
55 this->pull_up_down_mask_ &= ~(1 << pin);
56 this->pull_enable_mask_ |= 1 << pin;
57 }
59 }
60 // Write GPIO to enable input mode
61 this->write_gpio_modes_();
62}
63
65 if (this->is_failed())
66 return false;
67
68 uint8_t data{0};
69 if (!this->status_comm_result(this->read_byte(PI4IOE5V6408_REGISTER_OUT_SET, &data),
70 LOG_STR("Failed to read output register")))
71 return false;
72 this->output_mask_ = data;
73 return true;
74}
75
77 if (this->is_failed())
78 return false;
79
80 uint8_t data{0};
81 if (!this->status_comm_result(this->read_byte(PI4IOE5V6408_REGISTER_IO_DIR, &data),
82 LOG_STR("Failed to read GPIO modes")))
83 return false;
84#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
85 ESP_LOGV(TAG, "Read GPIO modes: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(data));
86#endif
87 this->mode_mask_ = data;
88 return true;
89}
90
92 if (this->is_failed())
93 return false;
94
95 uint8_t data{0};
96 if (!this->status_comm_result(this->read_byte(PI4IOE5V6408_REGISTER_IN_STATE, &data),
97 LOG_STR("Failed to read GPIO state")))
98 return false;
99 this->input_mask_ = data;
100 return true;
101}
102
103void PI4IOE5V6408Component::digital_write_hw(uint8_t pin, bool value) {
104 if (this->is_failed())
105 return;
106
107 assign_bits(this->output_mask_, 1 << pin, value);
108 if (!this->status_comm_result(this->write_byte(PI4IOE5V6408_REGISTER_OUT_SET, this->output_mask_),
109 LOG_STR("Failed to write output register")))
110 return;
111#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
112 ESP_LOGV(TAG, "Wrote GPIO output: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(this->output_mask_));
113#endif
114}
115
117 if (this->is_failed())
118 return false;
119
120 if (!this->write_byte(PI4IOE5V6408_REGISTER_IO_DIR, this->mode_mask_)) {
121 this->status_set_warning(LOG_STR("Failed to write GPIO modes"));
122 return false;
123 }
124 if (!this->write_byte(PI4IOE5V6408_REGISTER_PULL_SELECT, this->pull_up_down_mask_)) {
125 this->status_set_warning(LOG_STR("Failed to write GPIO pullup/pulldown"));
126 return false;
127 }
128 if (!this->write_byte(PI4IOE5V6408_REGISTER_PULL_ENABLE, this->pull_enable_mask_)) {
129 this->status_set_warning(LOG_STR("Failed to write GPIO pull enable"));
130 return false;
131 }
132 // Enable interrupts for input pins when interrupt pin is configured
133 // (input pins have mode_mask_ bit cleared)
134 if (this->interrupt_pin_ != nullptr &&
135 !this->write_byte(PI4IOE5V6408_REGISTER_INTERRUPT_ENABLE_MASK, static_cast<uint8_t>(~this->mode_mask_))) {
136 this->status_set_warning(LOG_STR("Failed to write interrupt enable mask"));
137 return false;
138 }
139#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
140 ESP_LOGV(TAG,
141 "Wrote GPIO config:\n"
142 " modes: 0b" BYTE_TO_BINARY_PATTERN "\n"
143 " pullup/pulldown: 0b" BYTE_TO_BINARY_PATTERN "\n"
144 " pull enable: 0b" BYTE_TO_BINARY_PATTERN,
145 BYTE_TO_BINARY(this->mode_mask_), BYTE_TO_BINARY(this->pull_up_down_mask_),
146 BYTE_TO_BINARY(this->pull_enable_mask_));
147#endif
148 this->status_clear_warning();
149 return true;
150}
151
152bool PI4IOE5V6408Component::digital_read_cache(uint8_t pin) { return (this->input_mask_ & (1 << pin)); }
153
154} // namespace esphome::pi4ioe5v6408
155
156ESPHOME_EXPANDER_PIN_SUMMARY(esphome::pi4ioe5v6408::PI4IOE5V6408Component, "%u via PI4IOE5V6408")
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:274
bool status_comm_result(bool ok)
Clears the warning when ok, else sets it with message (default "Communication failed"); returns ok.
void status_clear_warning()
Definition component.h:296
void enable_polling_loop_()
Call from pin_mode() for an input pin: without an interrupt pin the loop polls instead.
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:312
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:272
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:164
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)
uint16_t flags
ESPHOME_LOG_TAG(TAG, "pi4ioe5v6408")
ESPHOME_ALWAYS_INLINE constexpr void assign_bits(T &value, std::type_identity_t< T > mask, bool on)
Set the bits of mask in value when on is true, clear them otherwise.
Definition helpers.h:1072