Mindstorms 3rd Party ROBOTC Drivers RobotC
[Home] [Download] [Submit a bug/suggestion] [ROBOTC Forums] [Blog] [Support this project]

MCP23008-driver.h

Go to the documentation of this file.
00001 /*!@addtogroup other
00002  * @{
00003  * @defgroup mcp23008 Microchip MCP23008
00004  * Microchip MCP23008
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: MCP23008-driver.h 46 2011-01-16 16:56:49Z xander $
00010  */
00011 
00012 
00013 #ifndef __MCP23008_H__
00014 #define __MCP23008_H__
00015 /** \file MCP23008-driver.h
00016  * \brief Microchip MCP23008 driver
00017  *
00018  * MCP23008-driver.h provides an API for the MCP23008 8 port IO expander.
00019  *
00020  * Changelog:
00021  * - 0.3 Rewrite to make use of standard common.h framework.
00022  * - 0.4 Renamed functions to be inline with new naming standard
00023  *
00024  * License: You may use this code as you wish, provided you give credit where it's due.
00025  *
00026  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 2.00 AND HIGHER.
00027  * \author Xander Soldaat
00028  * \date 18 June 2009
00029  * \version 0.4
00030  */
00031 
00032 #pragma systemFile
00033 
00034 #ifndef __COMMON_H__
00035 #include "common.h"
00036 #endif
00037 
00038 // Registers
00039 #define MCP_REG_IODIR   0x00    /*!< I/O DIRECTION REGISTER */
00040 #define MCP_REG_IPOL    0x01    /*!< INPUT POLARITY REGISTER */
00041 #define MCP_REG_GPINTEN 0x02    /*!< INTERRUPT-ON-CHANGE CONTROL REGISTER */
00042 #define MCP_REG_DEFVAL  0x03    /*!< DEFAULT COMPARE REGISTER FOR INTERRUPT-ONCHANGE */
00043 #define MCP_REG_INTCON  0x04    /*!< INTERRUPT CONTROL REGISTER */
00044 #define MCP_REG_IOCON   0x05    /*!< CONFIGURATION REGISTER */
00045 #define MCP_REG_GPPU    0x06    /*!< PULL-UP RESISTOR CONFIGURATION REGISTER */
00046 #define MCP_REG_INTF    0x07    /*!< INTERRUPT FLAG (INTF)REGISTER */
00047 #define MCP_REG_INTCAP  0x08    /*!< INTERRUPT CAPTURE REGISTER */
00048 #define MCP_REG_GPIO    0x09    /*!< PORT REGISTER */
00049 #define MCP_REG_OLAT    0x0A    /*!< OUTPUT LATCH REGISTER */
00050 
00051 // Special bits in the IOCON register
00052 #define MCP_BIT_INTPOL  1       /*!< This bit sets the polarity of the INT output pin */
00053 #define MCP_BIT_ODR     2       /*!< This bit configures the INT pin as an open-drain output */
00054 #define MCP_BIT_DISSLW  4       /*!< Slew Rate control bit for SDA output */
00055 #define MCP_BIT_SREAD   5       /*!< Sequential Operation mode bit */
00056 
00057 #define MCP_I2C_ADDR    0x40    /*!< Default base address (A0-A2 tied to gnd) */
00058 
00059 tByteArray MCP23008_I2CRequest;    /*!< Array to hold I2C command data */
00060 tByteArray MCP23008_I2CReply;      /*!< Array to hold I2C reply data */
00061 
00062 bool MCP23008setupIO(tSensors link, byte addr, byte mask, byte pullup);
00063 bool MCP23008setupIO(tSensors link, byte addr, byte mask);
00064 byte MCP23008readIO(tSensors link, byte addr, byte mask);
00065 byte MCP23008readIO(tSensors link, byte addr);
00066 bool MCP23008writeIO(tSensors link, byte addr, byte mask);
00067 
00068 bool MCP23008writeReg(tSensors link, byte addr, byte reg, byte data);
00069 byte MCP23008readReg(tSensors link, byte addr, byte reg);
00070 
00071 /**
00072  * Write data to the device at the specified register.
00073  *
00074  * Note: this is an internal function and should not be called directly.
00075  * @param link the sensor port number
00076  * @param addr the address of the MCP23008
00077  * @param reg the register to write to
00078  * @param data the data to be written (single byte)
00079  * @return true if no error occured, false if it did
00080  */
00081 bool MCP23008writeReg(tSensors link, byte addr, byte reg, byte data) {
00082   memset(MCP23008_I2CRequest, 0, sizeof(tByteArray));
00083 
00084   MCP23008_I2CRequest[0] = 3;     // Message size
00085   MCP23008_I2CRequest[1] = addr;  //I2C Address
00086   MCP23008_I2CRequest[1] = reg;   // Register address
00087   MCP23008_I2CRequest[1] = data;  // Data to be sent
00088 
00089   return writeI2C(link, MCP23008_I2CRequest, 0);
00090 }
00091 
00092 /**
00093  * Read from the device at the specified register.
00094  *
00095  * Note: this is an internal function and should not be called directly.
00096  * @param link the sensor port number
00097  * @param addr the address of the MCP23008
00098  * @param reg the register to write to
00099  * @return true if no error occured, false if it did
00100  */
00101 byte MCP23008readReg(tSensors link, byte addr, byte reg) {
00102   memset(MCP23008_I2CRequest, 0, sizeof(tByteArray));
00103 
00104   MCP23008_I2CRequest[0] = 2;     // Message size
00105   MCP23008_I2CRequest[1] = addr;  //I2C Address
00106   MCP23008_I2CRequest[1] = reg;   // Register address
00107 
00108   writeI2C(link, MCP23008_I2CRequest, 0);
00109   readI2C(link, MCP23008_I2CReply, 1);
00110 
00111   return MCP23008_I2CReply[0];
00112 }
00113 
00114 /**
00115  * Setup the pins as either inputs or outputs as specified by the mask.
00116  * 0 is input, 1 is output
00117  * @param link the sensor port number
00118  * @param addr the address of the MCP23008
00119  * @param mask the pins to change the configuration for
00120  * @param pullup the pins to change the internal pullup resistor for
00121  * @return true if no error occured, false if it did
00122  */
00123 bool MCP23008setupIO(tSensors link, byte addr, byte mask, byte pullup) {
00124   if (!MCP23008writeReg(link, addr, MCP_REG_IODIR, mask))
00125     return false;
00126 
00127   if (!MCP23008writeReg(link, addr, MCP_REG_GPPU, pullup))
00128     return false;
00129 
00130   return true;
00131 }
00132 
00133 /**
00134  * Setup the pins as either inputs or outputs as specified by the mask.
00135  * 0 is input, 1 is output
00136  * @param link the sensor port number
00137  * @param addr the address of the MCP23008
00138  * @param mask the pins to change the configuration for
00139  * @return true if no error occured, false if it did
00140  */
00141 bool MCP23008setupIO(tSensors link, byte addr, byte mask) {
00142   if (!MCP23008writeReg(link, addr, MCP_REG_IODIR, mask))
00143     return false;
00144 
00145   return true;
00146 }
00147 
00148 /**
00149  * Read the states of the pins as specified by the mask
00150  *
00151  * @param link the sensor port number
00152  * @param addr the address of the MCP23008
00153  * @param mask the pins to get the status for
00154  * @return the value of the pins
00155  */
00156 byte MCP23008readIO(tSensors link, byte addr, byte mask) {
00157   return MCP23008readReg(link, addr, MCP_REG_GPIO) & mask;
00158 }
00159 
00160 /**
00161  * Read the states of all of the pins
00162  *
00163  * @param link the sensor port number
00164  * @param addr the address of the MCP23008
00165  * @return the value of the pins
00166  */
00167 byte MCP23008readIO(tSensors link, byte addr) {
00168   return MCP23008readReg(link, addr, MCP_REG_GPIO);
00169 }
00170 
00171 /**
00172  * Write to the pins specified specified by the mask.
00173  *
00174  * @param link the sensor port number
00175  * @param addr the address of the MCP23008
00176  * @param mask the state of the pins that is to be written
00177  * @return the value of the pins
00178  */
00179 bool MCP23008writeIO(tSensors link, byte addr, byte mask) {
00180   if (!MCP23008writeReg(link, addr, MCP_REG_OLAT, mask))
00181     return false;
00182 
00183   return true;
00184 }
00185 
00186 #endif // __MCP23008_H__
00187 
00188 /*
00189  * $Id: MCP23008-driver.h 46 2011-01-16 16:56:49Z xander $
00190  */
00191 /* @} */
00192 /* @} */