From 6196c96805f504707e6d23b12a5021a0f73a350e Mon Sep 17 00:00:00 2001 From: Bertrand Lemasle Date: Wed, 16 Dec 2020 23:31:44 +0100 Subject: [PATCH 1/8] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 18a2ac6..c5a77ff 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 @@ -32,4 +33,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... From e2bd5b1219ef4f8804a429db69770bc59988d675 Mon Sep 17 00:00:00 2001 From: Caspar Date: Fri, 31 Dec 2021 15:28:19 +0100 Subject: [PATCH 2/8] Update PortCopy.ino correct mixup of port names --- examples/PortCopy/PortCopy.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 +} From 710e76762781e9237cdc444db0d0e2a28af41148 Mon Sep 17 00:00:00 2001 From: Luke Park Date: Sun, 22 May 2022 21:38:07 +0100 Subject: [PATCH 3/8] Correct ICON Register init ICON.ORD is set as 0 which denotes active driver rather than open-drain. Added extra unimplemented bit comment to avoid confusion around how the 7 used bits map to the byte. --- src/MCP23017.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/MCP23017.cpp b/src/MCP23017.cpp index 52bba9b..b36cb8f 100644 --- a/src/MCP23017.cpp +++ b/src/MCP23017.cpp @@ -14,8 +14,11 @@ 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) From 05f4c6d6214a7c2180b15c9854b7a3b8d7906057 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" <19971886+dok-net@users.noreply.github.com> Date: Sat, 4 Jun 2022 21:17:51 +0200 Subject: [PATCH 4/8] Add begin() method (#27) * Add begin() method usual for Arduino driver libs and the supporting ctor. * Begin without address argument shall use the ctor provided address, not reset it. * Apply suggestions from code review Cascade from `begin` with I2C address argument to `begin` w/o argument, it's clearer than calling `init()` from both places. Co-authored-by: Bertrand Lemasle Co-authored-by: Bertrand Lemasle --- src/MCP23017.cpp | 16 ++++++++++++++++ src/MCP23017.h | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/MCP23017.cpp b/src/MCP23017.cpp index b36cb8f..edd69cd 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() @@ -25,6 +30,17 @@ void MCP23017::init() 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) { writeRegister(MCP23017Register::IODIR_A + port, directions); diff --git a/src/MCP23017.h b/src/MCP23017.h index e665108..3427261 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 @@ -65,10 +66,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). @@ -221,4 +236,4 @@ class MCP23017 void clearInterrupts(uint8_t& portA, uint8_t& portB); #endif -}; \ No newline at end of file +}; From af722789049610330476a61747077a0570ddbba4 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" <19971886+dok-net@users.noreply.github.com> Date: Sat, 4 Jun 2022 21:23:02 +0200 Subject: [PATCH 5/8] Fix enumerator case in comment. (#29) --- src/MCP23017.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MCP23017.h b/src/MCP23017.h index 3427261..880f938 100644 --- a/src/MCP23017.h +++ b/src/MCP23017.h @@ -206,8 +206,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". From 7a0b1ba078768d587868ef4fb799d11ea036af77 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" <19971886+dok-net@users.noreply.github.com> Date: Sat, 4 Jun 2022 21:25:58 +0200 Subject: [PATCH 6/8] Add enumeration with pin values for digitalWrite etc (#28) * Add enumeration with pin values for digitalWrite etc * It is recommended not to use enum class if implicit cast to value is required. C++23 is said to provide a standard library helper, until then, for scoping, wrapping in a struct is recommended. Co-authored-by: Bertrand Lemasle --- src/MCP23017.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/MCP23017.h b/src/MCP23017.h index 880f938..b66df22 100644 --- a/src/MCP23017.h +++ b/src/MCP23017.h @@ -12,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". From 208c34cd14635328a9fb01f98c41b924d1ad7b44 Mon Sep 17 00:00:00 2001 From: rolgordijn Date: Sun, 19 Feb 2023 16:39:17 +0100 Subject: [PATCH 7/8] Disable pullups on init (#32) --- src/MCP23017.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/MCP23017.cpp b/src/MCP23017.cpp index edd69cd..b7d6b53 100644 --- a/src/MCP23017.cpp +++ b/src/MCP23017.cpp @@ -25,9 +25,6 @@ void MCP23017::init() //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() From 02076b387157db25d3ca30b7e8b089c6da52c563 Mon Sep 17 00:00:00 2001 From: Bertrand Lemasle Date: Sat, 18 Nov 2023 13:43:53 +0100 Subject: [PATCH 8/8] Added a warning about GPA7 & GPB7. closes #33 --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c5a77ff..e7dc6a9 100644 --- a/README.md +++ b/README.md @@ -24,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 |