29template <
class WireType>
32 : wire(&wire), address(I2C_BASE_ADDRESS | addressOffset),
33 interruptPin(interruptPin) {
39template <
class WireType>
42 pinModesDirty |= bufferedPinModes.get(pin) == 0;
43 pullupsDirty |= bufferedPullups.get(pin) == 1;
44 bufferedPinModes.set(pin);
45 bufferedPullups.clear(pin);
46 }
else if (mode ==
OUTPUT) {
47 pinModesDirty |= bufferedPinModes.get(pin) == 1;
48 bufferedPinModes.clear(pin);
50 pinModesDirty |= bufferedPinModes.get(pin) == 0;
51 pullupsDirty |= bufferedPullups.get(pin) == 0;
52 bufferedPinModes.set(pin);
53 bufferedPullups.set(pin);
57template <
class WireType>
59 bool boolstate = status ==
HIGH;
60 outputsDirty |= bufferedOutputs.get(pin) != boolstate;
61 bufferedOutputs.set(pin, boolstate);
64template <
class WireType>
66 return bufferedInputs.get(pin) ?
HIGH :
LOW;
69template <
class WireType>
71 return bufferedInputs.get(pin) ? 1023 : 0;
74template <
class WireType>
79template <
class WireType>
81 if (interruptPin !=
NO_PIN)
96template <
class WireType>
98 updateBufferedPinModes();
102 bufferedOutputs.getByte(0),
103 bufferedOutputs.getByte(1));
104 outputsDirty =
false;
107template <
class WireType>
116 wire->requestFrom(address, uint8_t(2));
117 bufferedInputs.setByte(0, wire->read());
118 bufferedInputs.setByte(1, wire->read());
121template <
class WireType>
125 bufferedPinModes.getByte(0),
126 bufferedPinModes.getByte(1));
128 bufferedPinModes.getByte(0),
129 bufferedPinModes.getByte(1));
130 pinModesDirty =
false;
134 bufferedPullups.getByte(0),
135 bufferedPullups.getByte(1));
136 pullupsDirty =
false;
140template <
class WireType>
142 return bufferedPinModes.getByte(0) != 0 || bufferedPinModes.getByte(1) != 0;
145template <
class WireType>
148 this->wire->beginTransmission(address);
149 this->wire->write(values, N);
150 this->wire->endTransmission();
153template <
class WireType>
154template <
class... Args>
156 const uint8_t v[] = {addr,
static_cast<uint8_t
>(values)...};
constexpr PinStatus_t LOW
constexpr PinMode_t INPUT
constexpr PinStatus_t HIGH
AH::function_traits< decltype(::pinMode)>::argument_t< 1 > PinMode_t
AH::function_traits< decltype(::digitalWrite)>::argument_t< 1 > PinStatus_t
constexpr PinMode_t INPUT_PULLUP
constexpr PinMode_t OUTPUT
uint16_t analog_t
The type returned from analogRead and similar functions.
constexpr pin_t NO_PIN
A special pin number that indicates an unused or invalid pin.
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).
#define BEGIN_AH_NAMESPACE
void setByte(uint16_t byteIndex, uint8_t value)
Set the byte at the given index.
MCP23017(WireType &wire, uint8_t addressOffset=0, pin_t interruptPin=NO_PIN)
Constructor.
void updateBufferedPinModes()
Send the new pin modes to the chip after calling pinModeBuffered.
void updateBufferedOutputs() override
Write the internal state to the physical outputs.
void analogWriteBuffered(pin_t, analog_t) override
Write an analog (or PWM) value to the software buffer given pin.
PinStatus_t digitalReadBuffered(pin_t pin) override
Read the state of the given pin from the software buffer.
void pinModeBuffered(pin_t pin, PinMode_t mode) override
Set the mode of a given pin in the software buffer.
void updateBufferedInputs() override
Read the physical state into the input buffers.
void begin() override
Initialize the extended IO element.
analog_t analogReadBuffered(pin_t pin) override
Read the analog value of the given pin from the software buffer.
bool hasInputs() const
Check if any of the pins are configured as inputs.
void digitalWriteBuffered(pin_t pin, PinStatus_t status) override
Set the output of a given pin in the software buffer.
BitArray< 16 > bufferedPinModes
void writeI2C(const uint8_t(&values)[N])
Write any data to the MCP23017.
void digitalWriteBuffered(pin_t pin, PinStatus_t val)
A buffered ExtIO version of the Arduino function.
void pinMode(pin_t pin, PinMode_t mode)
An ExtIO version of the Arduino function.
PinStatus_t digitalRead(pin_t pin)
An ExtIO version of the Arduino function.