Skip to content

Commit

Permalink
Added i2c support via MCP23008
Browse files Browse the repository at this point in the history
  • Loading branch information
ladyada committed Sep 2, 2010
1 parent ca7cc51 commit d7063fa
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
143 changes: 143 additions & 0 deletions MCP23008.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Code by Adafruit Industries/Limor Fried
// License: LGPL

#include <Wire.h>
#include <avr/pgmspace.h>
#include "MCP23008.h"
#include <WProgram.h>


////////////////////////////////////////////////////////////////////////////////
// RTC_DS1307 implementation

void MCP23008::begin(uint8_t addr) {
if (addr > 7) {
addr = 7;
}
i2caddr = addr;

Wire.begin();

// set defaults!
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_IODIR);
Wire.send(0xFF); // all inputs
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(0x00);
Wire.endTransmission();

}

void MCP23008::begin(void) {
begin(0);
}

void MCP23008::pinMode(uint8_t p, uint8_t d) {
uint8_t iodir;


// only 8 bits!
if (p > 7)
return;

// read the current IODIR
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_IODIR);
Wire.endTransmission();

Wire.requestFrom(MCP23008_ADDRESS | i2caddr, 1);
iodir = Wire.receive();

// set the pin and direction
if (d == INPUT) {
iodir |= 1 << p;
} else {
iodir &= ~(1 << p);
}

// write the new IODIR
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_IODIR);
Wire.send(iodir);
Wire.endTransmission();
}


void MCP23008::digitalWrite(uint8_t p, uint8_t d) {
uint8_t gpio;

// only 8 bits!
if (p > 7)
return;

// read the current GPIO output latches
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_OLAT);
Wire.endTransmission();

Wire.requestFrom(MCP23008_ADDRESS | i2caddr, 1);
gpio = Wire.receive();

// set the pin and direction
if (d == HIGH) {
gpio |= 1 << p;
} else {
gpio &= ~(1 << p);
}

// write the new GPIO
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_GPIO);
Wire.send(gpio);
Wire.endTransmission();
}

void MCP23008::pullUp(uint8_t p, uint8_t d) {
uint8_t gppu;

// only 8 bits!
if (p > 7)
return;

// read the current pullup resistor set
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_GPPU);
Wire.endTransmission();

Wire.requestFrom(MCP23008_ADDRESS | i2caddr, 1);
gppu = Wire.receive();

// set the pin and direction
if (d == HIGH) {
gppu |= 1 << p;
} else {
gppu &= ~(1 << p);
}

// write the new GPIO
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_GPPU);
Wire.send(gppu);
Wire.endTransmission();
}

uint8_t MCP23008::digitalRead(uint8_t p) {
// only 8 bits!
if (p > 7)
return 0;

// read the current GPIO
Wire.beginTransmission(MCP23008_ADDRESS | i2caddr);
Wire.send(MCP23008_GPIO);
Wire.endTransmission();

Wire.requestFrom(MCP23008_ADDRESS | i2caddr, 1);
return (Wire.receive() >> p) & 0x1;
}
34 changes: 34 additions & 0 deletions MCP23008.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// i2c expander library - slow I/O!

// also works with the MCP23009

// Don't forget the Wire library
class MCP23008 {
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);

private:
uint8_t i2caddr;
};

#define MCP23008_ADDRESS 0x20

// registers
#define MCP23008_IODIR 0x00
#define MCP23008_IPOL 0x01
#define MCP23008_GPINTEN 0x02
#define MCP23008_DEFVAL 0x03
#define MCP23008_INTCON 0x04
#define MCP23008_IOCON 0x05
#define MCP23008_GPPU 0x06
#define MCP23008_INTF 0x07
#define MCP23008_INTCAP 0x08
#define MCP23008_GPIO 0x09
#define MCP23008_OLAT 0x0A

0 comments on commit d7063fa

Please sign in to comment.