Jurica Resetar / MCP23017

Dependents:   acd52832_beep_buzzer_ints

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 
00034 union {
00035     uint8_t  value8[2];
00036     uint16_t value16;
00037 } tmp_data;
00038 
00039 /*-----------------------------------------------------------------------------
00040  *
00041  */
00042 MCP23017::MCP23017(PinName sda, PinName scl, int i2cAddress)  : _i2c(sda, scl) {
00043     MCP23017_i2cAddress = i2cAddress;
00044     reset();                                  // initialise chip to power-on condition
00045 }
00046 
00047 /*-----------------------------------------------------------------------------
00048  * reset
00049  * Set configuration (IOCON) and direction(IODIR) registers to initial state
00050  */
00051 void MCP23017::reset() {
00052 //
00053 // First make sure that the device is in BANK=0 mode
00054 //
00055     writeRegister(0x05, (unsigned char)0x00);
00056 //
00057 // set direction registers to inputs
00058 //
00059     writeRegister(IODIR, (unsigned short)0xFFFF);
00060 //
00061 // set all other registers to zero (last of 10 registers is OLAT)
00062 //
00063     for (int reg_addr = 2 ; reg_addr <= OLAT ; reg_addr+=2) {
00064         writeRegister(reg_addr, (unsigned short)0x0000);
00065     }
00066 //
00067 // Set the shadow registers to power-on state
00068 //
00069     shadow_IODIR = 0xFFFF;
00070     shadow_GPIO  = 0;
00071     shadow_GPPU  = 0;
00072     shadow_IPOL  = 0;
00073 }
00074 
00075 /*-----------------------------------------------------------------------------
00076  * write_bit
00077  * Write a 1/0 to a single bit of the 16-bit port
00078  */
00079 void MCP23017::write_bit(int value, int bit_number) {
00080     if (value == 0) {
00081         shadow_GPIO &= ~(1 << bit_number);
00082     } else {
00083         shadow_GPIO |= 1 << bit_number;
00084     }
00085     writeRegister(GPIO, (unsigned short)shadow_GPIO);
00086 }
00087 
00088 /*-----------------------------------------------------------------------------
00089  * Write a combination of bits to the 16-bit port
00090  */
00091 void MCP23017::write_mask(unsigned short data, unsigned short mask) {
00092     shadow_GPIO = (shadow_GPIO & ~mask) | data;
00093     writeRegister(GPIO, (unsigned short)shadow_GPIO);
00094 }
00095 
00096 /*-----------------------------------------------------------------------------
00097  * read_bit
00098  * Read a single bit from the 16-bit port
00099  */
00100 int  MCP23017::read_bit(int bit_number) {
00101     shadow_GPIO = readRegister(GPIO);
00102     return  ((shadow_GPIO >> bit_number) & 0x0001);
00103 }
00104 
00105 /*-----------------------------------------------------------------------------
00106  * read_mask
00107  */
00108 int  MCP23017::read_mask(unsigned short mask) {
00109     shadow_GPIO = readRegister(GPIO);
00110     return (shadow_GPIO & mask);
00111 }
00112 
00113 /*-----------------------------------------------------------------------------
00114  * Config
00115  * set direction and pull-up registers
00116  */
00117 void MCP23017::config(unsigned short dir_config, unsigned short pullup_config,  unsigned short polarity_config) {
00118     shadow_IODIR = dir_config;
00119     writeRegister(IODIR, (unsigned short)shadow_IODIR);
00120     shadow_GPPU = pullup_config;
00121     writeRegister(GPPU, (unsigned short)shadow_GPPU);
00122     shadow_IPOL = polarity_config;
00123     writeRegister(IPOL, (unsigned short)shadow_IPOL);
00124 }
00125 
00126 /*-----------------------------------------------------------------------------
00127  * writeRegister
00128  * write a byte
00129  */
00130 void MCP23017::writeRegister(int regAddress, unsigned char data) {
00131     char  buffer[2];
00132 
00133     buffer[0] = regAddress;
00134     buffer[1] = data;
00135     _i2c.write(MCP23017_i2cAddress, buffer, 2);
00136 }
00137 
00138 /*----------------------------------------------------------------------------
00139  * write Register
00140  * write two bytes
00141  */ 
00142 void MCP23017::writeRegister(int regAddress, unsigned short data) {
00143     char  buffer[3];
00144 
00145     buffer[0] = regAddress;
00146     tmp_data.value16 = data;
00147     buffer[1] = tmp_data.value8[0];
00148     buffer[2] = tmp_data.value8[1];
00149 
00150     _i2c.write(MCP23017_i2cAddress, buffer, 3);
00151 }
00152 
00153 /*-----------------------------------------------------------------------------
00154  * readRegister
00155  */
00156 int MCP23017::readRegister(int regAddress) {
00157     char buffer[2];
00158 
00159     buffer[0] = regAddress;
00160     _i2c.write(MCP23017_i2cAddress, buffer, 1);
00161     _i2c.read(MCP23017_i2cAddress, buffer, 2);
00162 
00163     return ((int)(buffer[0] + (buffer[1]<<8)));
00164 }
00165 
00166 /*-----------------------------------------------------------------------------
00167  * pinMode
00168  */
00169 void MCP23017::pinMode(int pin, int mode) {
00170     if (DIR_INPUT) {
00171         shadow_IODIR |= 1 << pin;
00172     } else {
00173         shadow_IODIR &= ~(1 << pin);
00174     }
00175     writeRegister(IODIR, (unsigned short)shadow_IODIR);
00176 }
00177 
00178 /*-----------------------------------------------------------------------------
00179  * digitalRead
00180  */
00181 int MCP23017::digitalRead(int pin) {
00182     shadow_GPIO = readRegister(GPIO);
00183     if ( shadow_GPIO & (1 << pin)) {
00184         return 1;
00185     } else {
00186         return 0;
00187     }
00188 }
00189 
00190 /*-----------------------------------------------------------------------------
00191  * digitalWrite
00192  */
00193 void MCP23017::digitalWrite(int pin, int val) {
00194     //If this pin is an INPUT pin, a write here will
00195     //enable the internal pullup
00196     //otherwise, it will set the OUTPUT voltage
00197     //as appropriate.
00198     bool isOutput = !(shadow_IODIR & 1<<pin);
00199 
00200     if (isOutput) {
00201         //This is an output pin so just write the value
00202         if (val) shadow_GPIO |= 1 << pin;
00203         else shadow_GPIO &= ~(1 << pin);
00204         writeRegister(GPIO, (unsigned short)shadow_GPIO);
00205     } else {
00206         //This is an input pin, so we need to enable the pullup
00207         if (val) {
00208             shadow_GPPU |= 1 << pin;
00209         } else {
00210             shadow_GPPU &= ~(1 << pin);
00211         }
00212         writeRegister(GPPU, (unsigned short)shadow_GPPU);
00213     }
00214 }
00215 
00216 /*-----------------------------------------------------------------------------
00217  * digitalWordRead
00218  */
00219 unsigned short MCP23017::digitalWordRead() {
00220     shadow_GPIO = readRegister(GPIO);
00221     return shadow_GPIO;
00222 }
00223 
00224 /*-----------------------------------------------------------------------------
00225  * digitalWordWrite
00226  */
00227 void MCP23017::digitalWordWrite(unsigned short w) {
00228     shadow_GPIO = w;
00229     writeRegister(GPIO, (unsigned short)shadow_GPIO);
00230 }
00231 
00232 /*-----------------------------------------------------------------------------
00233  * inputPolarityMask
00234  */
00235 void MCP23017::inputPolarityMask(unsigned short mask) {
00236     writeRegister(IPOL, mask);
00237 }
00238 
00239 /*-----------------------------------------------------------------------------
00240  * inputoutputMask
00241  */
00242 void MCP23017::inputOutputMask(unsigned short mask) {
00243     shadow_IODIR = mask;
00244     writeRegister(IODIR, (unsigned short)shadow_IODIR);
00245 }
00246 
00247 /*-----------------------------------------------------------------------------
00248  * internalPullupMask
00249  */
00250 void MCP23017::internalPullupMask(unsigned short mask) {
00251     shadow_GPPU = mask;
00252     writeRegister(GPPU, (unsigned short)shadow_GPPU);
00253 }
00254