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