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

Adafruit_MCP23017.cpp

Committer:
Komazawa_sun
Date:
2018-11-19
Revision:
0:4f1c764a42d3

File content as of revision 0:4f1c764a42d3:

/***************************************************
  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;
}