aconno dev team / MCP23017

Dependents:   tof100 gaasgjdvas LED_GAME11 tof100

Fork of MCP23017 by jim herd

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCP23017.cpp Source File

MCP23017.cpp

00001 /*  MCP23017 library for Arduino
00002     Copyright (C) 2009 David Pye    <davidmpye@gmail.com
00003     Modified for use on the MBED ARM platform
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 #include "MCP23017.h"
00020 #include "mbed.h"
00021 
00022 bool interrupt = 0;
00023 
00024 void setInt(){
00025     interrupt = 1;
00026 }
00027 void clearInt(){
00028     interrupt = 0;
00029 }
00030 bool getInt(){
00031     return interrupt;
00032 }
00033 union {
00034     uint8_t  value8[2];
00035     uint16_t value16;
00036 } tmp_data;
00037 
00038 /*-----------------------------------------------------------------------------
00039  *
00040  */
00041 MCP23017::MCP23017(PinName sda, PinName scl, int i2cAddress)  : _i2c(sda, scl) {
00042     MCP23017_i2cAddress = i2cAddress;
00043     reset();                                  // initialise chip to power-on condition
00044 }
00045 
00046 /*-----------------------------------------------------------------------------
00047  * reset
00048  * Set configuration (IOCON) and direction(IODIR) registers to initial state
00049  */
00050 void MCP23017::reset() {
00051 //
00052 // First make sure that the device is in BANK=0 mode
00053 //
00054     writeRegister(0x05, (unsigned char)0x00);
00055 //
00056 // set direction registers to inputs
00057 //
00058     writeRegister(IODIR, (unsigned short)0xFFFF);
00059 //
00060 // set all other registers to zero (last of 10 registers is OLAT)
00061 //
00062     for (int reg_addr = 2 ; reg_addr <= OLAT ; reg_addr+=2) {
00063         writeRegister(reg_addr, (unsigned short)0x0000);
00064     }
00065 //
00066 // Set the shadow registers to power-on state
00067 //
00068     shadow_IODIR = 0xFFFF;
00069     shadow_GPIO  = 0;
00070     shadow_GPPU  = 0;
00071     shadow_IPOL  = 0;
00072 }
00073 
00074 /*-----------------------------------------------------------------------------
00075  * write_bit
00076  * Write a 1/0 to a single bit of the 16-bit port
00077  */
00078 void MCP23017::write_bit(int value, int bit_number) {
00079     if (value == 0) {
00080         shadow_GPIO &= ~(1 << bit_number);
00081     } else {
00082         shadow_GPIO |= 1 << bit_number;
00083     }
00084     writeRegister(GPIO, (unsigned short)shadow_GPIO);
00085 }
00086 
00087 /*-----------------------------------------------------------------------------
00088  * Write a combination of bits to the 16-bit port
00089  */
00090 void MCP23017::write_mask(unsigned short data, unsigned short mask) {
00091     shadow_GPIO = (shadow_GPIO & ~mask) | data;
00092     writeRegister(GPIO, (unsigned short)shadow_GPIO);
00093 }
00094 
00095 /*-----------------------------------------------------------------------------
00096  * read_bit
00097  * Read a single bit from the 16-bit port
00098  */
00099 int  MCP23017::read_bit(int bit_number) {
00100     shadow_GPIO = readRegister(GPIO);
00101     return  ((shadow_GPIO >> bit_number) & 0x0001);
00102 }
00103 
00104 /*-----------------------------------------------------------------------------
00105  * read_mask
00106  */
00107 int  MCP23017::read_mask(unsigned short mask) {
00108     shadow_GPIO = readRegister(GPIO);
00109     return (shadow_GPIO & mask);
00110 }
00111 
00112 /*-----------------------------------------------------------------------------
00113  * Config
00114  * set direction and pull-up registers
00115  */
00116 void MCP23017::config(unsigned short dir_config, unsigned short pullup_config,  unsigned short polarity_config) {
00117     shadow_IODIR = dir_config;
00118     writeRegister(IODIR, (unsigned short)shadow_IODIR);
00119     shadow_GPPU = pullup_config;
00120     writeRegister(GPPU, (unsigned short)shadow_GPPU);
00121     shadow_IPOL = polarity_config;
00122     writeRegister(IPOL, (unsigned short)shadow_IPOL);
00123 }
00124 
00125 /*-----------------------------------------------------------------------------
00126  * writeRegister
00127  * write a byte
00128  */
00129 void MCP23017::writeRegister(int regAddress, unsigned char data) {
00130     char  buffer[2];
00131 
00132     buffer[0] = regAddress;
00133     buffer[1] = data;
00134     _i2c.write(MCP23017_i2cAddress, buffer, 2);
00135 }
00136 
00137 /*----------------------------------------------------------------------------
00138  * write Register
00139  * write two bytes
00140  */ 
00141 void MCP23017::writeRegister(int regAddress, unsigned short data) {
00142     char  buffer[3];
00143 
00144     buffer[0] = regAddress;
00145     tmp_data.value16 = data;
00146     buffer[1] = tmp_data.value8[0];
00147     buffer[2] = tmp_data.value8[1];
00148 
00149     _i2c.write(MCP23017_i2cAddress, buffer, 3);
00150 }
00151 
00152 /*-----------------------------------------------------------------------------
00153  * readRegister
00154  */
00155 int MCP23017::readRegister(int regAddress) {
00156     char buffer[2];
00157 
00158     buffer[0] = regAddress;
00159     _i2c.write(MCP23017_i2cAddress, buffer, 1);
00160     _i2c.read(MCP23017_i2cAddress, buffer, 2);
00161 
00162     return ((int)(buffer[0] + (buffer[1]<<8)));
00163 }
00164 
00165 /*-----------------------------------------------------------------------------
00166  * pinMode
00167  */
00168 void MCP23017::pinMode(int pin, int mode) {
00169     if (DIR_INPUT) {
00170         shadow_IODIR |= 1 << pin;
00171     } else {
00172         shadow_IODIR &= ~(1 << pin);
00173     }
00174     writeRegister(IODIR, (unsigned short)shadow_IODIR);
00175 }
00176 
00177 /*-----------------------------------------------------------------------------
00178  * digitalRead
00179  */
00180 int MCP23017::digitalRead(int pin) {
00181     shadow_GPIO = readRegister(GPIO);
00182     if ( shadow_GPIO & (1 << pin)) {
00183         return 1;
00184     } else {
00185         return 0;
00186     }
00187 }
00188 
00189 /*-----------------------------------------------------------------------------
00190  * digitalWrite
00191  */
00192 void MCP23017::digitalWrite(int pin, int val) {
00193     //If this pin is an INPUT pin, a write here will
00194     //enable the internal pullup
00195     //otherwise, it will set the OUTPUT voltage
00196     //as appropriate.
00197     bool isOutput = !(shadow_IODIR & 1<<pin);
00198 
00199     if (isOutput) {
00200         //This is an output pin so just write the value
00201         if (val) shadow_GPIO |= 1 << pin;
00202         else shadow_GPIO &= ~(1 << pin);
00203         writeRegister(GPIO, (unsigned short)shadow_GPIO);
00204     } else {
00205         //This is an input pin, so we need to enable the pullup
00206         if (val) {
00207             shadow_GPPU |= 1 << pin;
00208         } else {
00209             shadow_GPPU &= ~(1 << pin);
00210         }
00211         writeRegister(GPPU, (unsigned short)shadow_GPPU);
00212     }
00213 }
00214 
00215 /*-----------------------------------------------------------------------------
00216  * digitalWordRead
00217  */
00218 unsigned short MCP23017::digitalWordRead() {
00219     shadow_GPIO = readRegister(GPIO);
00220     return shadow_GPIO;
00221 }
00222 
00223 /*-----------------------------------------------------------------------------
00224  * digitalWordWrite
00225  */
00226 void MCP23017::digitalWordWrite(unsigned short w) {
00227     shadow_GPIO = w;
00228     writeRegister(GPIO, (unsigned short)shadow_GPIO);
00229 }
00230 
00231 /*-----------------------------------------------------------------------------
00232  * inputPolarityMask
00233  */
00234 void MCP23017::inputPolarityMask(unsigned short mask) {
00235     writeRegister(IPOL, mask);
00236 }
00237 
00238 /*-----------------------------------------------------------------------------
00239  * inputoutputMask
00240  */
00241 void MCP23017::inputOutputMask(unsigned short mask) {
00242     shadow_IODIR = mask;
00243     writeRegister(IODIR, (unsigned short)shadow_IODIR);
00244 }
00245 
00246 /*-----------------------------------------------------------------------------
00247  * internalPullupMask
00248  */
00249 void MCP23017::internalPullupMask(unsigned short mask) {
00250     shadow_GPPU = mask;
00251     writeRegister(GPPU, (unsigned short)shadow_GPPU);
00252 }
00253