Knud Dalgaard / 310-TMC3-TestHW

Dependencies:   mbed

310-TMC3-TestHW/MCP23008/MCP23008.cpp

Committer:
knuderich
Date:
2014-05-09
Revision:
0:c92ca0229c9a

File content as of revision 0:c92ca0229c9a:

/*  MCP23017 library for Arduino
    Copyright (C) 2009 David Pye    <davidmpye@gmail.com
    Modified for use on the MBED ARM platform

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "MCP23008.h"
#include "mbed.h"

//===============================================================================================
// Init and setup functions
//===============================================================================================

/*-----------------------------------------------------------------------------
 *
 */
MCP23008::MCP23008(PinName sda, PinName scl, int i2cAddress)  : _i2c(sda, scl)
{
    MCP23008_i2cAddress = i2cAddress;
    reset();                                  // initialise chip to power-on condition
}

/*-----------------------------------------------------------------------------
 * reset
 * Set configuration (IOCON) and direction(IODIR) registers to initial state
 */
void MCP23008::reset()
{
    //
    // set direction registers to inputs
    //
    writeRegister(IODIR, (unsigned char)0xFF);
    //
    // set all other registers to zero (last of 10 registers is OLAT)
    //
    for (int reg_addr = IPOL ; reg_addr <= OLAT ; reg_addr++) {
        writeRegister(reg_addr, (unsigned char)0x00);
    }
    
    //
    // Set the shadow registers to power-on state
    //
    shadow_IODIR = 0xFF;
    shadow_GPIO  = 0;
    shadow_GPPU  = 0;
    shadow_IPOL  = 0;
}



/*-----------------------------------------------------------------------------
 * Config
 * set direction and pull-up registers
 */
void MCP23008::config(unsigned char dir_config, unsigned char pullup_config,  unsigned char polarity_config)
{
    shadow_IODIR = dir_config;
    writeRegister(IODIR, (unsigned char)shadow_IODIR);
    shadow_GPPU = pullup_config;
    writeRegister(GPPU, (unsigned char)shadow_GPPU);
    shadow_IPOL = polarity_config;
    writeRegister(IPOL, (unsigned char)shadow_IPOL);
}



/*-----------------------------------------------------------------------------
 * writeRegister
 * write a byte
 */
void MCP23008::writeRegister(int regAddress, unsigned char data)
{
    char  buffer[2];

    buffer[0] = regAddress;
    buffer[1] = data;
    _i2c.write(MCP23008_i2cAddress, buffer, 2);
}



/*-----------------------------------------------------------------------------
 * readRegister
 */
unsigned char MCP23008::readRegister(int regAddress)
{
    char buffer[1];

    buffer[0] = regAddress;
    _i2c.write(MCP23008_i2cAddress, buffer, 1);
    _i2c.read(MCP23008_i2cAddress, buffer, 1);

    return ( (unsigned char)buffer[0] );
}


//===============================================================================================
// User functions
//===============================================================================================

/*-----------------------------------------------------------------------------
 * Write a combination of bits to the 8-bit port
 */
void MCP23008::write_mask(unsigned char data, unsigned char mask)
{
    shadow_GPIO = (shadow_GPIO & ~mask) | data;
    writeRegister(GPIO, (unsigned char)shadow_GPIO);
}

/*-----------------------------------------------------------------------------
 * read_mask
 */
int  MCP23008::read_mask(unsigned char mask)
{
    shadow_GPIO = readRegister(GPIO);
    return (shadow_GPIO & mask);
}


/*-----------------------------------------------------------------------------
 * write_bit
 * Write a 1/0 to a single bit of the 16-bit port
 */
void MCP23008::write_bit(int value, int bit_number) {
    if (value == 0) {
        shadow_GPIO &= ~(1 << bit_number);
    } else {
        shadow_GPIO |= 1 << bit_number;
    }
    writeRegister(GPIO, (unsigned char)shadow_GPIO);
}


/*-----------------------------------------------------------------------------
 * read_bit
 * Read a single bit from the 16-bit port
 */
int  MCP23008::read_bit(int bit_number) {
    shadow_GPIO = readRegister(GPIO);
    return  ((shadow_GPIO >> bit_number) & 0x01);
}