transplanted from the original URL : https://github.com/adafruit/Adafruit-RGB-LCD-Shield-Library

Revision:
0:4f1c764a42d3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_MCP23017.cpp	Mon Nov 19 09:44:37 2018 +0000
@@ -0,0 +1,231 @@
+/***************************************************
+  This is a library for the MCP23017 i2c port expander
+
+  These displays use I2C to communicate, 2 pins are required to
+  interface
+  Adafruit invests time and resources providing this open source code,
+  please support Adafruit and open-source hardware by purchasing
+  products from Adafruit!
+
+  Written by Limor Fried/Ladyada for Adafruit Industries.
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+
+#include "Adafruit_MCP23017.h"
+
+Adafruit_MCP23017::Adafruit_MCP23017(I2C *master)
+{
+    _master = master;
+
+
+    // set defaults!
+    
+    _buffer = new char[2]();
+    _buffer[0] = MCP23017_IODIRA;
+    _buffer[1] = 0xFF;
+    _master->write(MCP23017_ADDRESS, _buffer, 2);  // all inputs on port A
+    _buffer[0] = MCP23017_IODIRB;
+    _buffer[1] = 0xFF;
+    _master->write(MCP23017_ADDRESS, _buffer, 2);  // all inputs on port B
+    delete[] _buffer;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void Adafruit_MCP23017::pinMode(uint8_t p, bool input_mode)
+{
+    uint8_t iodir;
+    uint8_t iodiraddr;
+
+    // only 16 bits!
+    if (p > 15){
+        error("mcp23017 : it is a pin number which is not defined.\r\n");
+        return;
+	}
+	
+    if (p < 8)
+        iodiraddr = MCP23017_IODIRA;
+    else {
+        iodiraddr = MCP23017_IODIRB;
+        p -= 8;
+    }
+
+    // read the current IODIR
+	_buffer = new char[1]();
+    _buffer[0] = iodiraddr;
+    _master->write(MCP23017_ADDRESS, _buffer, 1);
+    _buffer[0] = 0;
+    _master->read(MCP23017_ADDRESS, _buffer, 1);
+    iodir = _buffer[0];
+    delete[] _buffer;
+
+    // set the pin and direction
+    if (input_mode) {
+        iodir |= 1 << p;
+    } else {
+        iodir &= ~(1 << p);
+    }
+
+    // write the new IODIR
+    _buffer = new char[2]();
+    _buffer[0] = iodiraddr;
+    _buffer[1] = iodir;
+    _master->write(MCP23017_ADDRESS, _buffer, 2);
+    delete[] _buffer;
+}
+
+uint16_t Adafruit_MCP23017::readGPIOAB()
+{
+    uint16_t ba = 0;
+    uint8_t a;
+
+    // read the current GPIO output latches
+    _buffer = new char[1]();
+    _buffer[0] = MCP23017_GPIOA;
+    _master->write(MCP23017_ADDRESS, _buffer, 1);
+    delete[] _buffer;
+    
+    _buffer = new char[2]();
+    _master->read(MCP23017_ADDRESS, _buffer, 2);
+    a = _buffer[0];
+    ba = _buffer[1];
+    ba <<= 8;
+    ba |= a;
+    delete[] _buffer;
+
+    return ba;
+}
+
+void Adafruit_MCP23017::writeGPIOAB(uint16_t ba)
+{
+    _buffer = new char[3]();
+    _buffer[0] = MCP23017_GPIOA;
+    _buffer[1] = ba & 0xFF;
+    _buffer[2] = ba >> 8;
+    _master->write(MCP23017_ADDRESS, _buffer, 3);
+    delete[] _buffer;
+}
+
+void Adafruit_MCP23017::digitalWrite(uint8_t p, bool high)
+{
+    uint8_t gpio;
+    uint8_t gpioaddr, olataddr;
+
+    if (p > 15){
+        error("mcp23017 : it is a pin number which is not defined.\r\n");
+        return;
+	}
+
+    if (p < 8) {
+        olataddr = MCP23017_OLATA;
+        gpioaddr = MCP23017_GPIOA;
+    } else {
+        olataddr = MCP23017_OLATB;
+        gpioaddr = MCP23017_GPIOB;
+        p -= 8;
+    }
+
+    // read the current GPIO output latches
+    _buffer = new char[1]();
+    _buffer[0] = olataddr;
+    _master->write(MCP23017_ADDRESS,_buffer , 1);
+    delete[] _buffer;
+	
+	_buffer = new char[1]();
+    _master->read(MCP23017_ADDRESS, _buffer, 1);
+    gpio = _buffer[0];
+    delete[] _buffer;
+
+    // set the pin and direction
+    if (high) {
+        gpio |= 1 << p;
+    } else {
+        gpio &= ~(1 << p);
+    }
+
+    // write the new GPIO
+    _buffer = new char[2]();
+    _buffer[0] = gpioaddr;
+    _buffer[1] = gpio;
+    _master->write(MCP23017_ADDRESS, _buffer, 2);
+    delete[] _buffer;
+}
+
+void Adafruit_MCP23017::pullUp(uint8_t p, bool pullup_anable)
+{
+    uint8_t gppu;
+    uint8_t gppuaddr;
+
+    // only 16 bits!
+    if (p > 15){
+        error("mcp23017 : it is a pin number which is not defined.\r\n");
+        return;
+	}
+
+    if (p < 8)
+        gppuaddr = MCP23017_GPPUA;
+    else {
+        gppuaddr = MCP23017_GPPUB;
+        p -= 8;
+    }
+
+    // read the current pullup resistor set
+    _buffer = new char[1]();
+    _buffer[0] = gppuaddr;
+    _master->write(MCP23017_ADDRESS, _buffer, 1);
+	delete[] _buffer;
+	
+	_buffer = new char[1]();
+    _master->read(MCP23017_ADDRESS, _buffer, 1);
+    gppu = _buffer[0];
+    delete[] _buffer;
+
+    // set the pin and direction
+    if (pullup_anable) {
+        gppu |= 1 << p;
+    } else {
+        gppu &= ~(1 << p);
+    }
+
+    // write the new GPIO
+    _buffer = new char[2]();
+    _buffer[0] = gppuaddr;
+    _buffer[1] = gppu;
+    _master->write(MCP23017_ADDRESS, _buffer, 2);
+    delete[] _buffer;
+    
+}
+
+uint8_t Adafruit_MCP23017::digitalRead(uint8_t p)
+{
+    uint8_t gpioaddr;
+
+    // only 16 bits!
+    if (p > 15){
+        error("mcp23017 : it is a pin number which is not defined.\r\n");
+        return 0;
+	}
+	
+    if (p < 8)
+        gpioaddr = MCP23017_GPIOA;
+    else {
+        gpioaddr = MCP23017_GPIOB;
+        p -= 8;
+    }
+
+    // read the current GPIO
+    
+    _buffer = new char[1]();
+    _buffer[0] = gpioaddr;
+	_master->write(MCP23017_ADDRESS, _buffer, 1);
+    
+    _buffer[0] = 0;
+    
+	uint8_t gpio;
+  	_master->read(MCP23017_ADDRESS, _buffer, 1);
+    gpio = _buffer[0];
+    
+    delete[] _buffer;
+    return (gpio >> p) & 0x1;
+}
+