ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
mcp23016.cpp
Go to the documentation of this file.
1#include "mcp23016.h"
3#include "esphome/core/log.h"
4#include <cstdio>
5
7
8ESPHOME_LOG_TAG(TAG, "mcp23016");
9
11 uint16_t iocon;
12 // MCP23016 registers operate as paired 16-bit registers. Addressing the
13 // odd register (e.g. IOCON1) reads/writes that register first, then wraps
14 // to the even register (IOCON0) in the same pair. Starting from the odd
15 // address gives the correct byte order for 1 << pin mapping:
16 // high byte = port 1 (pins 8-15), low byte = port 0 (pins 0-7).
17 if (!this->read_reg_(MCP23016_IOCON1, &iocon)) {
18 this->mark_failed();
19 return;
20 }
21
22 // Read current output register state
23 this->read_reg_(MCP23016_OLAT1, &this->olat_);
24
25 // all pins input
26 this->write_reg_(MCP23016_IODIR1, 0xFFFF);
27
29}
30
31bool MCP23016::digital_read_hw(uint8_t pin) { return this->read_reg_(MCP23016_GP1, &this->input_mask_); }
32
33bool MCP23016::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
34void MCP23016::digital_write_hw(uint8_t pin, bool value) { this->update_reg_(pin, value, MCP23016_OLAT1); }
36 if (flags == gpio::FLAG_INPUT) {
37 this->update_reg_(pin, true, MCP23016_IODIR1);
39 } else if (flags == gpio::FLAG_OUTPUT) {
40 this->update_reg_(pin, false, MCP23016_IODIR1);
41 }
42}
43bool MCP23016::read_reg_(uint8_t reg, uint16_t *value) {
44 if (this->is_failed())
45 return false;
46
47 return this->read_byte_16(reg, value);
48}
49bool MCP23016::write_reg_(uint8_t reg, uint16_t value) {
50 if (this->is_failed())
51 return false;
52
53 return this->write_byte_16(reg, value);
54}
55void MCP23016::update_reg_(uint8_t pin, bool pin_value, uint8_t reg_addr) {
56 uint16_t reg_value = 0;
57
58 if (reg_addr == MCP23016_OLAT1) {
59 reg_value = this->olat_;
60 } else {
61 this->read_reg_(reg_addr, &reg_value);
62 }
63
64 assign_bits(reg_value, 1 << pin, pin_value);
65
66 this->write_reg_(reg_addr, reg_value);
67
68 if (reg_addr == MCP23016_OLAT1) {
69 this->olat_ = reg_value;
70 }
71}
72
73} // namespace esphome::mcp23016
74
75ESPHOME_EXPANDER_PIN_SUMMARY(esphome::mcp23016::MCP23016, "%u via MCP23016")
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:274
void enable_polling_loop_()
Call from pin_mode() for an input pin: without an interrupt pin the loop polls instead.
bool read_byte_16(uint8_t a_register, uint16_t *data)
Definition i2c.h:281
bool write_byte_16(uint8_t a_register, uint16_t data) const
Definition i2c.cpp:101
void pin_mode(uint8_t pin, gpio::Flags flags)
Definition mcp23016.cpp:35
bool digital_read_cache(uint8_t pin) override
Definition mcp23016.cpp:33
void digital_write_hw(uint8_t pin, bool value) override
Definition mcp23016.cpp:34
bool digital_read_hw(uint8_t pin) override
Definition mcp23016.cpp:31
void update_reg_(uint8_t pin, bool pin_value, uint8_t reg_a)
Definition mcp23016.cpp:55
bool read_reg_(uint8_t reg, uint16_t *value)
Definition mcp23016.cpp:43
bool write_reg_(uint8_t reg, uint16_t value)
Definition mcp23016.cpp:49
uint16_t flags
ESPHOME_LOG_TAG(TAG, "mcp23016")
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