Permalink
Browse files

include the mcp23017 library

  • Loading branch information...
1 parent a3590fb commit 74c512950df38e153e83f6444ba0cb28ce93f5d8 @ladyada ladyada committed Feb 20, 2012
Showing with 293 additions and 0 deletions.
  1. +230 −0 Adafruit_MCP23017.cpp
  2. +63 −0 Adafruit_MCP23017.h
View
@@ -0,0 +1,230 @@
+/***************************************************
+ 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 <Wire.h>
+#include <avr/pgmspace.h>
+#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;
+}
View
@@ -0,0 +1,63 @@
+/***************************************************
+ 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
+ ****************************************************/
+
+#ifndef _Adafruit_MCP23017_H_
+#define _Adafruit_MCP23017_H_
+
+// Don't forget the Wire library
+class Adafruit_MCP23017 {
+public:
+ void begin(uint8_t addr);
+ void begin(void);
+
+ void pinMode(uint8_t p, uint8_t d);
+ void digitalWrite(uint8_t p, uint8_t d);
+ void pullUp(uint8_t p, uint8_t d);
+ uint8_t digitalRead(uint8_t p);
+
+ void writeGPIOAB(uint16_t);
+ uint16_t readGPIOAB();
+
+ private:
+ uint8_t i2caddr;
+};
+
+#define MCP23017_ADDRESS 0x20
+
+// registers
+#define MCP23017_IODIRA 0x00
+#define MCP23017_IPOLA 0x02
+#define MCP23017_GPINTENA 0x04
+#define MCP23017_DEFVALA 0x06
+#define MCP23017_INTCONA 0x08
+#define MCP23017_IOCONA 0x0A
+#define MCP23017_GPPUA 0x0C
+#define MCP23017_INTFA 0x0E
+#define MCP23017_INTCAPA 0x10
+#define MCP23017_GPIOA 0x12
+#define MCP23017_OLATA 0x14
+
+
+#define MCP23017_IODIRB 0x01
+#define MCP23017_IPOLB 0x03
+#define MCP23017_GPINTENB 0x05
+#define MCP23017_DEFVALB 0x07
+#define MCP23017_INTCONB 0x09
+#define MCP23017_IOCONB 0x0B
+#define MCP23017_GPPUB 0x0D
+#define MCP23017_INTFB 0x0F
+#define MCP23017_INTCAPB 0x11
+#define MCP23017_GPIOB 0x13
+#define MCP23017_OLATB 0x15
+
+#endif

1 comment on commit 74c5129

Hi

Currently I have an Arduino Due board with me. I tried to compile the Example of "HelloWorld", I get the error message "Adafruit_MCP23017.cpp:15: fatal error: avr/pgmspace.h: No such file or directory". May I get some advice on how to make the thing works?

Thanks

Please sign in to comment.