diff --git a/README.md b/README.md index 18a2ac6..e7dc6a9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ This library provides full control over the Microchip's [MCP23017](https://www.m * Full interrupt support ## Usage -Unlike most Arduino library, no default instance is created when the library is included. It's up to you to create one with the appropriate chip I2C address. +Unlike most Arduino library, no default instance is created when the library is included. It's up to you to create one using the appropriate I2C address based on MCP23017 `A0`, `A1` and `A2` pins wirings. +Available addresses go from `0x20` to `0x27`, allowing up to 8 MCP23017 on the same I2C bus. ```cpp #include @@ -23,7 +24,11 @@ MCP23017 mcp = MCP23017(0x24); Additionaly, you can specify the `Wire` instance to use as a second argument. For instance `MCP23017(0x24, Wire1)`. See included examples for further usage. -## Remarks +## Warning about GPA7 & GPB7 + +GPA7 or GPB7 should not be used as inputs despite what the configuration registers allow. As [stated by Microchip](https://microchip.my.site.com/s/article/GPA7---GPB7-Cannot-Be-Used-as-Inputs-In-MCP23017), it can lead to SDA signal corruption or even malfunction in the host bus under some conditions. + +## Breaking changes in v2.0.0 Major renames have been performed in v2.0.0 to improve compatibility with a variety of platforms. Existing code *will* break when you update from version v1.x. | Name in v1.x | Name in v2.x | @@ -32,4 +37,4 @@ Major renames have been performed in v2.0.0 to improve compatibility with a vari | `MCP23017_REGISTER` | `MCP23017Register` | | `MCP23017_INTMODE` | `MCP23017InterruptMode` | -In addition to this, every member of the `MCP23017Register` enum were renamed to avoid possible conflicts with macro definitions. `GPIOA` was renamed to `GPIO_A`, `INTCAPA` to `INTCAP_A` and so on... \ No newline at end of file +In addition to this, every member of the `MCP23017Register` enum were renamed to avoid possible conflicts with macro definitions. `GPIOA` was renamed to `GPIO_A`, `INTCAPA` to `INTCAP_A` and so on... diff --git a/examples/PortCopy/PortCopy.ino b/examples/PortCopy/PortCopy.ino index 52ae28b..9c972fd 100644 --- a/examples/PortCopy/PortCopy.ino +++ b/examples/PortCopy/PortCopy.ino @@ -1,8 +1,8 @@ /** * On every loop, the state of the port B is copied to port A. * - * Use active low inputs on port A. Internal pullups are enabled by default by the library so there is no need for external resistors. - * Place LEDS on port B for instance. + * Use active low inputs on port B. Internal pullups are enabled by default by the library so there is no need for external resistors. + * Place LEDS on port A for instance. * When pressing a button, the corresponding led is shut down. * * You can also uncomment one line to invert the input (when pressing a button the corresponding led is lit) @@ -35,4 +35,4 @@ void loop() { currentB = mcp.readPort(MCP23017Port::B); mcp.writePort(MCP23017Port::A, currentB); -} \ No newline at end of file +} diff --git a/src/MCP23017.cpp b/src/MCP23017.cpp index 52bba9b..b7d6b53 100644 --- a/src/MCP23017.cpp +++ b/src/MCP23017.cpp @@ -5,6 +5,11 @@ MCP23017::MCP23017(uint8_t address, TwoWire& bus) { _bus = &bus; } +MCP23017::MCP23017(TwoWire& bus) { + _deviceAddr = MCP23017_I2C_ADDRESS; + _bus = &bus; +} + MCP23017::~MCP23017() {} void MCP23017::init() @@ -14,12 +19,23 @@ void MCP23017::init() //SEQOP = 1 : sequential operation disabled, address pointer does not increment //DISSLW = 0 : slew rate enabled //HAEN = 0 : hardware address pin is always enabled on 23017 - //ODR = 0 : open drain output + //ODR = 0 : active driver output (INTPOL bit sets the polarity.) + //INTPOL = 0 : interrupt active low + //UNIMPLMENTED 0 : unimplemented: Read as ‘0’ + writeRegister(MCP23017Register::IOCON, 0b00100000); +} - //enable all pull up resistors (will be effective for input pins only) - writeRegister(MCP23017Register::GPPU_A, 0xFF, 0xFF); +void MCP23017::begin() +{ + init(); +} + +void MCP23017::begin(uint8_t address) +{ + _deviceAddr = address; + begin(); } void MCP23017::portMode(MCP23017Port port, uint8_t directions, uint8_t pullups, uint8_t inverted) diff --git a/src/MCP23017.h b/src/MCP23017.h index e665108..b66df22 100644 --- a/src/MCP23017.h +++ b/src/MCP23017.h @@ -3,6 +3,7 @@ #include #include +#define MCP23017_I2C_ADDRESS 0x20 ///< The default I2C address of MCP23017. #define _MCP23017_INTERRUPT_SUPPORT_ ///< Enables support for MCP23017 interrupts. enum class MCP23017Port : uint8_t @@ -11,6 +12,28 @@ enum class MCP23017Port : uint8_t B = 1 }; +struct MCP23017Pin +{ + enum Names { + GPA0 = 0, + GPA1, + GPA2, + GPA3, + GPA4, + GPA5, + GPA6, + GPA7, + GPB0 = 8, + GPB1, + GPB2, + GPB3, + GPB4, + GPB5, + GPB6, + GPB7 + }; +}; + /** * Controls if the two interrupt pins mirror each other. * See "3.6 Interrupt Logic". @@ -65,10 +88,24 @@ class MCP23017 * Instantiates a new instance to interact with a MCP23017 at the specified address. */ MCP23017(uint8_t address, TwoWire& bus = Wire); + /** + * Instantiates a new instance to interact with a MCP23017 at the + * MCP23017_I2C_ADDRESS default. + */ + MCP23017(TwoWire& bus = Wire); ~MCP23017(); #ifdef _DEBUG void debug(); #endif + /** + * Uses the I2C address set during construction. Implicitly calls init(). + */ + void begin(); + /** + * Overrides the I2C address set by the constructor. Implicitly calls begin(). + + */ + void begin(uint8_t address); /** * Initializes the chip with the default configuration. * Enables Byte mode (IOCON.BANK = 0 and IOCON.SEQOP = 1). @@ -191,8 +228,8 @@ class MCP23017 /** * Controls how the interrupt pins act with each other. - * If intMode is SEPARATED, interrupt conditions on a port will cause its respective INT pin to active. - * If intMode is OR, interrupt pins are OR'ed so an interrupt on one of the port will cause both pints to active. + * If intMode is Separated, interrupt conditions on a port will cause its respective INT pin to active. + * If intMode is Or, interrupt pins are OR'ed so an interrupt on one of the port will cause both pints to active. * * Controls the IOCON.MIRROR bit. * See "3.5.6 Configuration register". @@ -221,4 +258,4 @@ class MCP23017 void clearInterrupts(uint8_t& portA, uint8_t& portB); #endif -}; \ No newline at end of file +};