ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
mcp23x08_base.cpp
Go to the documentation of this file.
1#include "mcp23x08_base.h"
2#include "esphome/core/log.h"
3
5
6static const char *const TAG = "mcp23x08_base";
7
10 this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
11 return false;
12 }
13 return true;
14}
15
16void MCP23X08Base::digital_write_hw(uint8_t pin, bool value) {
17 uint8_t reg_addr = mcp23x08_base::MCP23X08_OLAT;
18 this->update_reg(pin, value, reg_addr);
19}
20
21bool MCP23X08Base::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
22
24 uint8_t iodir = mcp23x08_base::MCP23X08_IODIR;
25 uint8_t gppu = mcp23x08_base::MCP23X08_GPPU;
26 if (flags == gpio::FLAG_INPUT) {
27 this->update_reg(pin, true, iodir);
28 } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
29 this->update_reg(pin, true, iodir);
30 this->update_reg(pin, true, gppu);
31 } else if (flags == gpio::FLAG_OUTPUT) {
32 this->update_reg(pin, false, iodir);
33 }
34 // When interrupt_pin is configured, auto-enable CHANGE interrupt for input pins
35 // so the chip's INT output fires on any input state change
36 if (this->interrupt_pin_ != nullptr && (flags & gpio::FLAG_INPUT)) {
38 }
39 // Enable polling loop for input pins (not needed for interrupt-driven mode
40 // where the ISR handles re-enabling loop)
41 if (this->interrupt_pin_ == nullptr && (flags & gpio::FLAG_INPUT)) {
42 this->enable_loop();
43 }
44}
45
47 uint8_t gpinten = mcp23x08_base::MCP23X08_GPINTEN;
48 uint8_t intcon = mcp23x08_base::MCP23X08_INTCON;
49 uint8_t defval = mcp23x08_base::MCP23X08_DEFVAL;
50
51 switch (interrupt_mode) {
53 this->update_reg(pin, true, gpinten);
54 this->update_reg(pin, false, intcon);
55 break;
57 this->update_reg(pin, true, gpinten);
58 this->update_reg(pin, true, intcon);
59 this->update_reg(pin, false, defval);
60 break;
62 this->update_reg(pin, true, gpinten);
63 this->update_reg(pin, true, intcon);
64 this->update_reg(pin, true, defval);
65 break;
67 this->update_reg(pin, false, gpinten);
68 break;
69 }
70}
71
72void MCP23X08Base::update_reg(uint8_t pin, bool pin_value, uint8_t reg_addr) {
73 uint8_t bit = pin % 8;
74 uint8_t reg_value = 0;
75 if (reg_addr == mcp23x08_base::MCP23X08_OLAT) {
76 reg_value = this->olat_;
77 } else {
78 this->read_reg(reg_addr, &reg_value);
79 }
80
81 if (pin_value) {
82 reg_value |= 1 << bit;
83 } else {
84 reg_value &= ~(1 << bit);
85 }
86
87 this->write_reg(reg_addr, reg_value);
88
89 if (reg_addr == mcp23x08_base::MCP23X08_OLAT) {
90 this->olat_ = reg_value;
91 }
92}
93
94} // namespace esphome::mcp23x08_base
void enable_loop()
Enable this component's loop.
Definition component.h:258
void update_reg(uint8_t pin, bool pin_value, uint8_t reg_a) override
bool digital_read_cache(uint8_t pin) override
void pin_mode(uint8_t pin, gpio::Flags flags) override
bool digital_read_hw(uint8_t pin) override
void digital_write_hw(uint8_t pin, bool value) override
uint8_t input_mask_
State read in digital_read_hw.
void pin_interrupt_mode(uint8_t pin, mcp23xxx_base::MCP23XXXInterruptMode interrupt_mode) override
virtual bool read_reg(uint8_t reg, uint8_t *value)=0
virtual bool write_reg(uint8_t reg, uint8_t value)=0
uint16_t flags
@ FLAG_OUTPUT
Definition gpio.h:28
@ FLAG_PULLUP
Definition gpio.h:30
@ FLAG_INPUT
Definition gpio.h:27