Skip to content

Instantly share code, notes, and snippets.

@marcboon
Last active December 17, 2015 11:59
Show Gist options
  • Save marcboon/5606961 to your computer and use it in GitHub Desktop.
Save marcboon/5606961 to your computer and use it in GitHub Desktop.
Encapsulates a MCP23008 I2C i/o expander for use with electric imp. Emulates the standard Pin class, allows easy moving of i/o from native pins to i/o expander pins.
// This class is compatible with the general Pin class
class MCP23008Pin {
device = null
gpio = null
constructor(device, gpio) {
this.device = device
this.gpio = gpio
}
function configure(mode) {
switch(mode) {
case DIGITAL_IN:
device.setDir(gpio, 1)
device.setPullUp(gpio, 0)
break
case DIGITAL_IN_PULLUP:
device.setDir(gpio, 1)
device.setPullUp(gpio, 1)
break
case DIGITAL_OUT:
device.setDir(gpio, 0)
device.setPullUp(gpio, 0)
break
default:
server.log("MCP23008Pin: Invalid mode")
}
}
function read() {
return device.getPin(gpio)
}
function write(level) {
device.setPin(gpio, level)
}
}
class MCP23008 {
BASE_ADDR = 0x20
REG_ADDR =
{
IODIR = 0x00
IOPOL = 0x01
GPINTEN = 0x02
DEFVAL = 0x03
INTCON = 0x04
IOCON = 0x05
GPPU = 0x06
INTF = 0x07
INTCAP = 0x08
GPIO = 0x09
OLAT = 0x0A
}
i2cPort = null
i2cAddr = null
pin1 = null
pin2 = null
pin3 = null
pin4 = null
pin5 = null
pin6 = null
pin7 = null
pin8 = null
constructor(i2cPort, deviceAddr) {
this.i2cPort = i2cPort
this.i2cAddr = (BASE_ADDR + deviceAddr) << 1
for(local gpio = 1; gpio <= 8; gpio++) {
this["pin" + gpio] = MCP23008Pin(this, gpio - 1)
}
}
// Read a byte
function read(reg)
{
local data = i2cPort.read(i2cAddr, format("%c", reg), 1);
if(data == null)
{
server.log("I2C Read Failure");
return -1;
}
return data[0];
}
// Write a byte
function write(reg, data)
{
i2cPort.write(i2cAddr, format("%c%c", reg, data));
}
// Write a bit to a register
function writeBit(reg, bitn, level)
{
local value = read(reg);
value = (level == 0)?(value & ~(1<<bitn)):(value | (1<<bitn));
write(reg, value);
}
function setValueForRegister(gpio, reg, value) {
writeBit(REG_ADDR[reg], gpio&7, value);
}
function getValueForRegister(gpio, reg) {
return (read(REG_ADDR[reg])&(1<<(gpio&7)))?1:0;
}
function setDir(gpio, input)
{
setValueForRegister(gpio, "IODIR", (input?1:0))
}
function setPullUp(gpio, pull_up)
{
setValueForRegister(gpio, "GPPU", pull_up?1:0);
}
function setPin(gpio, level)
{
setValueForRegister(gpio, "GPIO", level?1:0);
}
function getPin(gpio)
{
return getValueForRegister(gpio, "GPIO")
}
}
// Demo
hardware.i2c89.configure(CLOCK_SPEED_100_KHZ)
port <- MCP23008(hardware.i2c89, 0)
led <- port.pin1 // or hardware.pin1
led.configure(DIGITAL_OUT)
function blink() {
imp.wakeup(0.5, blink)
led.write(1 - led.read())
}
blink()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment