/*************************************************** 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 #include #include "Adafruit_MCP23017.h" #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif // minihelper static inline void wiresend(uint8_t x) { #if ARDUINO >= 100 Wire.write((uint8_t)x); #else Wire.send(x); #endif } static inline uint8_t wirerecv(void) { #if ARDUINO >= 100 return Wire.read(); #else return Wire.receive(); #endif } //////////////////////////////////////////////////////////////////////////////// void Adafruit_MCP23017::begin(uint8_t addr) { if (addr > 7) { addr = 7; } i2caddr = addr; Wire.begin(); // set defaults! Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(MCP23017_IODIRA); wiresend(0xFF); // all inputs on port A Wire.endTransmission(); Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(MCP23017_IODIRB); wiresend(0xFF); // all inputs on port B Wire.endTransmission(); } void Adafruit_MCP23017::begin(void) { begin(0); } void Adafruit_MCP23017::pinMode(uint8_t p, uint8_t d) { uint8_t iodir; uint8_t iodiraddr; // only 16 bits! if (p > 15) return; if (p < 8) iodiraddr = MCP23017_IODIRA; else { iodiraddr = MCP23017_IODIRB; p -= 8; } // read the current IODIR Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(iodiraddr); Wire.endTransmission(); Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1); iodir = wirerecv(); // set the pin and direction if (d == INPUT) { iodir |= 1 << p; } else { iodir &= ~(1 << p); } // write the new IODIR Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(iodiraddr); wiresend(iodir); Wire.endTransmission(); } uint16_t Adafruit_MCP23017::readGPIOAB() { uint16_t ba = 0; uint8_t a; // read the current GPIO output latches Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(MCP23017_GPIOA); Wire.endTransmission(); Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 2); a = wirerecv(); ba = wirerecv(); ba <<= 8; ba |= a; return ba; } void Adafruit_MCP23017::writeGPIOAB(uint16_t ba) { Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(MCP23017_GPIOA); wiresend(ba & 0xFF); wiresend(ba >> 8); Wire.endTransmission(); } void Adafruit_MCP23017::digitalWrite(uint8_t p, uint8_t d) { uint8_t gpio; uint8_t gpioaddr, olataddr; // only 16 bits! if (p > 15) 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 Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(olataddr); Wire.endTransmission(); Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1); gpio = wirerecv(); // set the pin and direction if (d == HIGH) { gpio |= 1 << p; } else { gpio &= ~(1 << p); } // write the new GPIO Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(gpioaddr); wiresend(gpio); Wire.endTransmission(); } void Adafruit_MCP23017::pullUp(uint8_t p, uint8_t d) { uint8_t gppu; uint8_t gppuaddr; // only 16 bits! if (p > 15) return; if (p < 8) gppuaddr = MCP23017_GPPUA; else { gppuaddr = MCP23017_GPPUB; p -= 8; } // read the current pullup resistor set Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(gppuaddr); Wire.endTransmission(); Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1); gppu = wirerecv(); // set the pin and direction if (d == HIGH) { gppu |= 1 << p; } else { gppu &= ~(1 << p); } // write the new GPIO Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(gppuaddr); wiresend(gppu); Wire.endTransmission(); } uint8_t Adafruit_MCP23017::digitalRead(uint8_t p) { uint8_t gpioaddr; // only 16 bits! if (p > 15) return 0; if (p < 8) gpioaddr = MCP23017_GPIOA; else { gpioaddr = MCP23017_GPIOB; p -= 8; } // read the current GPIO Wire.beginTransmission(MCP23017_ADDRESS | i2caddr); wiresend(gpioaddr); Wire.endTransmission(); Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1); return (wirerecv() >> p) & 0x1; }