#pragma once namespace mcp23017 { enum class reg : uint8_t { iodira, iodirb, ipola, ipolb, gpintena, gpintenb, defvala, defvalb, intcona, intconb, iocona, ioconb, gppua, gppub, intfa, intfb, intcapa, intcapb, gpioa, gpiob, olata, olatb, }; enum class direction { out, in }; class extender { public: extender(uint8_t addr); bool init(); void set_direction(unsigned bank, unsigned pin, direction dir); void set_polarity(unsigned bank, unsigned pin, bool reversed); void set_pullup(unsigned bank, unsigned pin, bool enabled); void set_irq(unsigned bank, unsigned pin, bool enabled); void set_gpio(unsigned bank, unsigned pin, bool on); void set_gpios(unsigned bank, uint8_t values); bool get_gpio(unsigned bank, unsigned pin); uint8_t get_gpios(unsigned bank); private: template void set_field(unsigned bank, unsigned pin, Value value, uint8_t (¤t)[2]); int write(reg r, uint8_t value); int read(reg r, uint8_t *value, unsigned count); uint8_t m_addr; uint8_t m_direction[2]; uint8_t m_polarity[2]; uint8_t m_pullup[2]; uint8_t m_irq[2]; }; } // namespace mcp23017