Erriez MCP23017 library for Arduino  1.0.0
This is a MCP23017 16-pin I2C IO-Expander library for Arduino by Erriez.
All Classes Files Functions Variables Macros Pages
ErriezMCP23017.h
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2020 Erriez
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
86 #ifndef ERRIEZ_MCP23017_H_
87 #define ERRIEZ_MCP23017_H_
88 
89 #include <Arduino.h>
90 #include <Wire.h>
91 
92 // Default configuration macro's
93 #define MCP23017_I2C_ADDRESS 0x20
94 
95 // Register defines
96 #define MCP23017_REG_IODIR 0x00
97 #define MCP23017_REG_IPOL 0x02
98 #define MCP23017_REG_GPINTEN 0x04
99 #define MCP23017_REG_DEFVAL 0x06
100 #define MCP23017_REG_INTCON 0x08
101 #define MCP23017_REG_IOCON 0x0A
102 #define MCP23017_REG_GPPU 0x0C
103 #define MCP23017_REG_INTF 0x0E
104 #define MCP23017_REG_INTCAP 0x10
105 #define MCP23017_REG_GPIO 0x12
106 #define MCP23017_REG_OLAT 0x14
107 
108 #define MCP23017_NUM_REGS 0x16
109 #define MCP23017_NUM_PINS 16
110 
111 // Bit masks
112 #define MCP23017_MASK_ALL_PINS 0xFFFF
113 #define MCP23017_MASK_REG_A 0x1E
114 
115 // Bit defines IOCON register
116 #define IOCON_BANK 7
117 #define IOCON_MIRROR 6
118 #define IOCON_SEQOP 5
119 #define IOCON_DISSLW 4
120 #define IOCON_ODR 2
121 #define IOCON_INTPOL 1
122 
123 #define REG_IOCON_VALUE \
125  ((0<<IOCON_BANK) | /* 1 = The registers associated with each port are separated into different banks. */ \
126  (1<<IOCON_MIRROR) | /* 1 = INTA and INTB pins are OR'ed to INTA (INTB disabled) */ \
127  (0<<IOCON_SEQOP) | /* 1 = Sequential operation disabled, address pointer does not increment. */ \
128  (0<<IOCON_DISSLW) | /* 1 = Slew rate disabled */ \
129  (0<<IOCON_ODR) | /* 1 = Open-drain output (overrides the INTPOL bit.) */ \
130  (0<<IOCON_INTPOL)) /* 1 = Active-high */
131 
136 {
137 public:
138  ErriezMCP23017(uint8_t i2cAddress=MCP23017_I2C_ADDRESS,
139  TwoWire *twoWire = &Wire);
140 
141  // Initialization
142  bool begin(bool reset=true);
143 
144  // Single pin control
145  void pinMode(uint8_t pin, uint8_t mode);
146  void digitalWrite(uint8_t pin, uint8_t level);
147  int digitalRead(uint8_t pin);
148 
149  // Set/get port direction input/output
150  void setPortDirection(uint16_t outputPins);
151  uint16_t getPortDirection();
152 
153  // Set/get port pull-up
154  void setPortPullup(uint16_t pullupPins);
155  uint16_t getPortPullup();
156 
157  // Pin read/write/toggle
158  void pinWrite(uint8_t pin, bool level);
159  void pinToggle(uint8_t pin);
160  bool pinRead(uint8_t pin);
161 
162  // Port read/write/toggle/mask
163  void portWrite(uint16_t value);
164  void portToggle(uint16_t value);
165  void portMask(uint16_t maskSet, uint16_t maskClear);
166  uint16_t portRead();
167 
168  // Set/get interrupt mask/status
169  void setInterruptPolarityINTA(bool activeHigh);
170  uint16_t getPortInterruptMask();
171  void setPortInterruptEnable(uint16_t pins);
172  void setPortInterruptDisable(uint16_t pins);
173  // Registers INTF and INTCAP can hold only one pin interrupt. A second
174  // incoming pin interrupt is not updated in these registers and will be
175  // lost. For this reason, reading these registers is useless and therefore
176  // not implemented.
177 
178  // Interrupt generated by INTA pin
179  bool interruptINTA();
180 
181  // Register access
182  uint16_t registerRead(uint8_t reg);
183  void registerWrite(uint8_t reg, uint16_t value);
184 
185  // I2C transfer status
186  uint8_t getI2CStatus();
187 
188  // Debug function
189  void dumpRegisters(HardwareSerial *serial);
190 
192  uint16_t portState;
193 
195  uint16_t pinsChanged;
196 
198  uint16_t pinsFalling;
199 
201  uint16_t pinsRising;
202 
203 private:
204  TwoWire *_wire;
205  uint8_t _i2cAddress;
206  uint8_t _i2cStatus;
207 
208  // Cached variables to speed-up I2C bus access without I2C reads
209  uint16_t _gpioPort;
210  uint16_t _gpioDir;
211  uint16_t _gpioPullup;
212  uint16_t _portStateLast;
213 };
214 
215 #endif // ERRIEZ_MCP23017_H_
bool pinRead(uint8_t pin)
Read state of a single pin (input and output pins)
void digitalWrite(uint8_t pin, uint8_t level)
Set state of a single pin.
void portMask(uint16_t maskSet, uint16_t maskClear)
Clear and set pin states.
void setPortDirection(uint16_t outputPins)
Set PORT direction all pins.
void pinMode(uint8_t pin, uint8_t mode)
Set direction of a single pin.
uint16_t portState
Port state since last portRead() call.
uint16_t pinsChanged
Pins change on interrupt enabled pins since last intPinChanged() call.
void pinToggle(uint8_t pin)
Toggle state of a single pin (only for output pins)
void dumpRegisters(HardwareSerial *serial)
Print I2C registers on serial port.
uint16_t getPortInterruptMask()
Get interrupt mask all pins.
void setInterruptPolarityINTA(bool activeHigh)
Set interrupt polarity INTA.
void registerWrite(uint8_t reg, uint16_t value)
MCP23017 I2C write register.
void portWrite(uint16_t value)
Set all pin states.
#define MCP23017_I2C_ADDRESS
Default MCP23017 I2C address.
uint16_t portRead()
Read PORT of all pins (input and output pins)
void setPortPullup(uint16_t pullupPins)
Set PORT pullup all pins.
uint16_t pinsFalling
Falling edge on interrupt enabled pins since last intPinChanged() call.
void pinWrite(uint8_t pin, bool level)
Set pin state.
bool begin(bool reset=true)
Initialize MCP23017.
uint16_t pinsRising
Rising edge on interrupt eanbled pins since last intPinChanged() call.
uint16_t getPortPullup()
Get PORT pullup all pins.
uint16_t registerRead(uint8_t reg)
MCP23017 I2C read register.
bool interruptINTA()
MCP23017 INTA pin changed.
void setPortInterruptDisable(uint16_t pins)
Disable interrupt on pins.
void setPortInterruptEnable(uint16_t pins)
Enable interrupt change on pins.
void portToggle(uint16_t value)
Toggle pin states (output pins only)
uint8_t getI2CStatus()
Return status of the last I2C write, returned by Wire endTransfer()
int digitalRead(uint8_t pin)
Get state of a single pin.
ErriezMCP23017(uint8_t i2cAddress=MCP23017_I2C_ADDRESS, TwoWire *twoWire=&Wire)
ErriezMCP23017 Constructor.
uint16_t getPortDirection()
Get PORT direction all pins.
Erriez MCP23017 I2C IO-Expander class.