26#include "../functors.h"
27#include "../i2c_device.h"
28#include "../i2c_device_utilities.h"
55 namespace mcp23017_traits
57 template<MCP23017Port PORT_>
struct Port_trait
60 static constexpr uint8_t shift(uint8_t reg)
69 static constexpr uint8_t shift(uint8_t reg)
78 static constexpr uint8_t shift(uint8_t reg)
86 using TYPE = uint16_t;
87 static constexpr uint8_t shift(uint8_t reg)
101 template<
typename MANAGER>
106 template<
typename OUT,
typename IN>
using FUTURE =
typename PARENT::template FUTURE<OUT, IN>;
108 template<MCP23017Port P>
using TRAIT = mcp23017_traits::Port_trait<P>;
109 template<MCP23017Port P>
using T =
typename TRAIT<P>::TYPE;
112 template<MCP23017Port P, u
int8_t REGISTER>
114 template<MCP23017Port P, u
int8_t REGISTER>
120 static constexpr const uint8_t BASE_ADDRESS = 0x20;
123 static constexpr const uint8_t IODIR_A = 0x00;
124 static constexpr const uint8_t IODIR_B = 0x01;
125 static constexpr const uint8_t IPOL_A = 0x02;
126 static constexpr const uint8_t IPOL_B = 0x03;
128 static constexpr const uint8_t GPINTEN_A = 0x04;
129 static constexpr const uint8_t GPINTEN_B = 0x05;
130 static constexpr const uint8_t DEFVAL_A = 0x06;
131 static constexpr const uint8_t DEFVAL_B = 0x07;
132 static constexpr const uint8_t INTCON_A = 0x08;
133 static constexpr const uint8_t INTCON_B = 0x09;
135 static constexpr const uint8_t IOCON = 0x0A;
137 static constexpr const uint8_t GPPU_A = 0x0C;
138 static constexpr const uint8_t GPPU_B = 0x0D;
140 static constexpr const uint8_t INTF_A = 0x0E;
141 static constexpr const uint8_t INTF_B = 0x0F;
142 static constexpr const uint8_t INTCAP_A = 0x10;
143 static constexpr const uint8_t INTCAP_B = 0x11;
145 static constexpr const uint8_t GPIO_A = 0x12;
146 static constexpr const uint8_t GPIO_B = 0x13;
147 static constexpr const uint8_t OLAT_A = 0x14;
148 static constexpr const uint8_t OLAT_B = 0x15;
151 static constexpr const uint8_t IOCON_BANK =
bits::BV8(7);
152 static constexpr const uint8_t IOCON_MIRROR =
bits::BV8(6);
153 static constexpr const uint8_t IOCON_SEQOP =
bits::BV8(5);
154 static constexpr const uint8_t IOCON_DISSLW =
bits::BV8(4);
155 static constexpr const uint8_t IOCON_HAEN =
bits::BV8(3);
156 static constexpr const uint8_t IOCON_ODR =
bits::BV8(2);
157 static constexpr const uint8_t IOCON_INTPOL =
bits::BV8(1);
159 static constexpr uint8_t compute_address(uint8_t address)
161 return uint8_t((uint8_t(BASE_ADDRESS) | uint8_t(address & 0x07U)) << 1);
173 :
PARENT{manager, compute_address(address),
i2c::I2C_FAST, true} {}
198 bool mirror_interrupts =
false,
247 template<MCP23017Port P_>
254 :
PARENT{direction, polarity, pullup} {}
305 template<MCP23017Port P_>
312 :
PARENT{int_pins, ref, compare_ref} {}
337 template<MCP23017Port P_>
357 template<MCP23017Port P_>
398 template<MCP23017Port P_>
439 template<MCP23017Port P_>
482 template<MCP23017Port P_>
531 bool begin(
bool mirror_interrupts =
false,
559 template<MCP23017Port P_>
bool configure_gpio(T<P_> direction, T<P_> pullup = T<P_>{}, T<P_> polarity = T<P_>{})
561 ConfigureGPIOFuture<P_>
future{direction, pullup, polarity};
586 template<MCP23017Port P_>
589 ConfigureInterruptsFuture<P_>
future{int_pins, ref, compare_ref};
608 template<MCP23017Port P_>
bool values(T<P_> value)
610 return this->
template sync_write<SetValuesFuture<P_>>(value);
627 return get_value<GetValuesFuture<P_>, T<P_>>();
645 return get_value<InterruptFlagsFuture<P_>, T<P_>>();
665 return get_value<CapturedValuesFuture<P_>, T<P_>>();
669 template<
typename F,
typename T> T get_value()
672 if (this->
template sync_read<F>(value))
680 return this->
write(byte_count,
false,
true);
683 static constexpr uint8_t build_IOCON(
bool mirror,
bool int_polarity)
685 return bits::ORIF8(mirror, IOCON_MIRROR, int_polarity, IOCON_INTPOL);
Create a future to be used by asynchronous method begin(BeginFuture&).
I2C device driver for Microchip MCP23017 support.
bool configure_gpio(T< P_ > direction, T< P_ > pullup=T< P_ >{}, T< P_ > polarity=T< P_ >{})
Configure GPIO on one or both ports of this MCP23017 chip.
T< P_ > values()
Get levels of pins on one or both ports of this MCP23017 chip.
bool begin(bool mirror_interrupts=false, InterruptPolarity interrupt_polarity=InterruptPolarity::ACTIVE_HIGH)
Initialize the chip before operation.
bool configure_interrupts(T< P_ > int_pins, T< P_ > ref=T< P_ >{}, T< P_ > compare_ref=T< P_ >{})
Configure interrupts on one or both ports of this MCP23017 chip.
int interrupt_flags(InterruptFlagsFuture< P_ > &future)
Get the pins that generated the latest interrupt on one or both ports of the MCP23017 chip.
int values(SetValuesFuture< P_ > &future)
Set output levels of output pins on one or both ports of this MCP23017 chip.
T< P_ > captured_values()
Get captured levels, at the time an interrupt was triggered, of pins on one or both ports of this MCP...
int values(GetValuesFuture< P_ > &future)
Get levels of pins on one or both ports of this MCP23017 chip.
int begin(BeginFuture &future)
Initialize the chip before operation.
T< P_ > interrupt_flags()
Get the pins that generated the latest interrupt on one or both ports of the MCP23017 chip.
bool values(T< P_ > value)
Set output levels of output pins on one or both ports of this MCP23017 chip.
int configure_gpio(ConfigureGPIOFuture< P_ > &future)
Configure GPIO on one or both ports of this MCP23017 chip.
int configure_interrupts(ConfigureInterruptsFuture< P_ > &future)
Configure interrupts on one or both ports of this MCP23017 chip.
MCP23017(MANAGER &manager, uint8_t address)
Create a new device driver for an MCP23017 chip.
int captured_values(CapturedValuesFuture< P_ > &future)
Get captured levels, at the time an interrupt was triggered, of pins on one or both ports of this MCP...
Base class for all I2C devices.
static constexpr I2CLightCommand write(uint8_t write_count=0, bool finish_future=false, bool stop=false)
Build a write I2CLightCommand that can be later pushed to the I2C Manager for proper handling.
int async_write(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing only one write...
int async_multi_write(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing several regist...
MANAGER MANAGER
the type of I2C Manager that can handle this device.
int async_read(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing one write foll...
Light atomic I2C command as prepared by an I2C device.
Generic Future that can be used to read an I2C device register.
Generic Future that can be used to write to several I2C device registers.
Generic Future that can be used to write to an I2C device register.
API to handle the MCP23008/23017 chips (8 & 16-Bit I/O Expanders with I2C interface).
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
static constexpr uint8_t ORIF8(bool flag1, uint8_t val1, bool flag2, uint8_t val2)
Create a uint8_t bitwise OR boolean operation between uint8_t operands, conditioned by bool flags.
Defines the API for MCP23008/MCP23017 chips support.
MCP23017Port
The port(s) to use in MCP23017 API.
@ PORT_AB
Both A and B ports of MCP23017.
@ PORT_A
The A port of MCP23017.
@ PORT_B
The B port of MCP23017.
InterruptPolarity
The polarity of the MCP23008/MCP23017 INT pins.
@ ACTIVE_HIGH
The INT pins shall be active high, ie they are low by default, and changed to high when an interrupt ...
Contains the API around Future implementation.
@ READY
The status of a Future once its output value has been fully set by a provider.
Define API to define and manage I2C devices.