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

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