ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
mcp23x08_base.cpp
Go to the documentation of this file.
1#include "mcp23x08_base.h"
3#include "esphome/core/log.h"
4
6
7ESPHOME_LOG_TAG(TAG, "mcp23x08_base");
8
11 this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
12 return false;
13 }
14 return true;
15}
16
17void MCP23X08Base::digital_write_hw(uint8_t pin, bool value) {
18 uint8_t reg_addr = mcp23x08_base::MCP23X08_OLAT;
19 this->update_reg(pin, value, reg_addr);
20}
21
22bool MCP23X08Base::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
23
25 uint8_t iodir = mcp23x08_base::MCP23X08_IODIR;
26 uint8_t gppu = mcp23x08_base::MCP23X08_GPPU;
27 if (flags == gpio::FLAG_INPUT) {
28 this->update_reg(pin, true, iodir);
29 } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
30 this->update_reg(pin, true, iodir);
31 this->update_reg(pin, true, gppu);
32 } else if (flags == gpio::FLAG_OUTPUT) {
33 this->update_reg(pin, false, iodir);
34 }
35 if (flags & gpio::FLAG_INPUT) {
36 // With an interrupt pin, INT fires on any change of an input
37 if (this->interrupt_pin_ != nullptr)
40 }
41}
42
44 uint8_t gpinten = mcp23x08_base::MCP23X08_GPINTEN;
45 uint8_t intcon = mcp23x08_base::MCP23X08_INTCON;
46 uint8_t defval = mcp23x08_base::MCP23X08_DEFVAL;
47
48 switch (interrupt_mode) {
50 this->update_reg(pin, true, gpinten);
51 this->update_reg(pin, false, intcon);
52 break;
54 this->update_reg(pin, true, gpinten);
55 this->update_reg(pin, true, intcon);
56 this->update_reg(pin, false, defval);
57 break;
59 this->update_reg(pin, true, gpinten);
60 this->update_reg(pin, true, intcon);
61 this->update_reg(pin, true, defval);
62 break;
64 this->update_reg(pin, false, gpinten);
65 break;
66 }
67}
68
69void MCP23X08Base::update_reg(uint8_t pin, bool pin_value, uint8_t reg_addr) {
70 uint8_t bit = pin % 8;
71 uint8_t reg_value = 0;
72 if (reg_addr == mcp23x08_base::MCP23X08_OLAT) {
73 reg_value = this->olat_;
74 } else {
75 this->read_reg(reg_addr, &reg_value);
76 }
77
78 assign_bits(reg_value, 1 << bit, pin_value);
79
80 this->write_reg(reg_addr, reg_value);
81
82 if (reg_addr == mcp23x08_base::MCP23X08_OLAT) {
83 this->olat_ = reg_value;
84 }
85}
86
87} // namespace esphome::mcp23x08_base
void enable_polling_loop_()
Call from pin_mode() for an input pin: without an interrupt pin the loop polls instead.
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
ESPHOME_LOG_TAG(TAG, "mcp23x08_base")
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