Nurbol Nurdaulet / MCP23017

Dependents:   state_machine_modes_1_12_11 state_machine_modes_1_12_11_11h

Committer:
Nurbol
Date:
Wed Nov 09 17:09:31 2011 +0000
Revision:
0:69c047b34ca6

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Nurbol 0:69c047b34ca6 1 /* MCP23017 library for Arduino
Nurbol 0:69c047b34ca6 2 Copyright (C) 2009 David Pye <davidmpye@gmail.com
Nurbol 0:69c047b34ca6 3 Modified for use on the MBED ARM platform
Nurbol 0:69c047b34ca6 4
Nurbol 0:69c047b34ca6 5 This program is free software: you can redistribute it and/or modify
Nurbol 0:69c047b34ca6 6 it under the terms of the GNU General Public License as published by
Nurbol 0:69c047b34ca6 7 the Free Software Foundation, either version 3 of the License, or
Nurbol 0:69c047b34ca6 8 (at your option) any later version.
Nurbol 0:69c047b34ca6 9
Nurbol 0:69c047b34ca6 10 This program is distributed in the hope that it will be useful,
Nurbol 0:69c047b34ca6 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
Nurbol 0:69c047b34ca6 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Nurbol 0:69c047b34ca6 13 GNU General Public License for more details.
Nurbol 0:69c047b34ca6 14
Nurbol 0:69c047b34ca6 15 You should have received a copy of the GNU General Public License
Nurbol 0:69c047b34ca6 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
Nurbol 0:69c047b34ca6 17 */
Nurbol 0:69c047b34ca6 18
Nurbol 0:69c047b34ca6 19 #include "MCP23017.h"
Nurbol 0:69c047b34ca6 20 #include "mbed.h"
Nurbol 0:69c047b34ca6 21
Nurbol 0:69c047b34ca6 22 union {
Nurbol 0:69c047b34ca6 23 uint8_t value8[2];
Nurbol 0:69c047b34ca6 24 uint16_t value16;
Nurbol 0:69c047b34ca6 25 } tmp_data;
Nurbol 0:69c047b34ca6 26
Nurbol 0:69c047b34ca6 27 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 28 *
Nurbol 0:69c047b34ca6 29 */
Nurbol 0:69c047b34ca6 30 MCP23017::MCP23017(PinName sda, PinName scl, int i2cAddress) : _i2c(sda, scl) {
Nurbol 0:69c047b34ca6 31 MCP23017_i2cAddress = i2cAddress;
Nurbol 0:69c047b34ca6 32 reset(); // initialise chip to power-on condition
Nurbol 0:69c047b34ca6 33 }
Nurbol 0:69c047b34ca6 34
Nurbol 0:69c047b34ca6 35 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 36 * reset
Nurbol 0:69c047b34ca6 37 * Set configuration (IOCON) and direction(IODIR) registers to initial state
Nurbol 0:69c047b34ca6 38 */
Nurbol 0:69c047b34ca6 39 void MCP23017::reset() {
Nurbol 0:69c047b34ca6 40 //
Nurbol 0:69c047b34ca6 41 // First make sure that the device is in BANK=0 mode
Nurbol 0:69c047b34ca6 42 //
Nurbol 0:69c047b34ca6 43 writeRegister(0x05, (unsigned char)0x00);
Nurbol 0:69c047b34ca6 44 //
Nurbol 0:69c047b34ca6 45 // set direction registers to inputs
Nurbol 0:69c047b34ca6 46 //
Nurbol 0:69c047b34ca6 47 writeRegister(IODIR, (unsigned short)0xFFFF);
Nurbol 0:69c047b34ca6 48 //
Nurbol 0:69c047b34ca6 49 // set all other registers to zero (last of 10 registers is OLAT)
Nurbol 0:69c047b34ca6 50 //
Nurbol 0:69c047b34ca6 51 for (int reg_addr = 2 ; reg_addr <= OLAT ; reg_addr+=2) {
Nurbol 0:69c047b34ca6 52 writeRegister(reg_addr, (unsigned short)0x0000);
Nurbol 0:69c047b34ca6 53 }
Nurbol 0:69c047b34ca6 54 //
Nurbol 0:69c047b34ca6 55 // Set the shadow registers to power-on state
Nurbol 0:69c047b34ca6 56 //
Nurbol 0:69c047b34ca6 57 shadow_IODIR = 0xFFFF;
Nurbol 0:69c047b34ca6 58 shadow_GPIO = 0;
Nurbol 0:69c047b34ca6 59 shadow_GPPU = 0;
Nurbol 0:69c047b34ca6 60 shadow_IPOL = 0;
Nurbol 0:69c047b34ca6 61 }
Nurbol 0:69c047b34ca6 62
Nurbol 0:69c047b34ca6 63 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 64 * write_bit
Nurbol 0:69c047b34ca6 65 * Write a 1/0 to a single bit of the 16-bit port
Nurbol 0:69c047b34ca6 66 */
Nurbol 0:69c047b34ca6 67 void MCP23017::write_bit(int value, int bit_number) {
Nurbol 0:69c047b34ca6 68 if (value == 0) {
Nurbol 0:69c047b34ca6 69 shadow_GPIO &= ~(1 << bit_number);
Nurbol 0:69c047b34ca6 70 } else {
Nurbol 0:69c047b34ca6 71 shadow_GPIO |= 1 << bit_number;
Nurbol 0:69c047b34ca6 72 }
Nurbol 0:69c047b34ca6 73 writeRegister(GPIO, (unsigned short)shadow_GPIO);
Nurbol 0:69c047b34ca6 74 }
Nurbol 0:69c047b34ca6 75
Nurbol 0:69c047b34ca6 76 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 77 * Write a combination of bits to the 16-bit port
Nurbol 0:69c047b34ca6 78 */
Nurbol 0:69c047b34ca6 79 void MCP23017::write_mask(unsigned short data, unsigned short mask) {
Nurbol 0:69c047b34ca6 80 shadow_GPIO = (shadow_GPIO & ~mask) | data;
Nurbol 0:69c047b34ca6 81 writeRegister(GPIO, (unsigned short)shadow_GPIO);
Nurbol 0:69c047b34ca6 82 }
Nurbol 0:69c047b34ca6 83
Nurbol 0:69c047b34ca6 84 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 85 * read_bit
Nurbol 0:69c047b34ca6 86 * Read a single bit from the 16-bit port
Nurbol 0:69c047b34ca6 87 */
Nurbol 0:69c047b34ca6 88 int MCP23017::read_bit(int bit_number) {
Nurbol 0:69c047b34ca6 89 shadow_GPIO = readRegister(GPIO);
Nurbol 0:69c047b34ca6 90 return ((shadow_GPIO >> bit_number) & 0x0001);
Nurbol 0:69c047b34ca6 91 }
Nurbol 0:69c047b34ca6 92
Nurbol 0:69c047b34ca6 93 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 94 * read_mask
Nurbol 0:69c047b34ca6 95 */
Nurbol 0:69c047b34ca6 96 int MCP23017::read_mask(unsigned short mask) {
Nurbol 0:69c047b34ca6 97 shadow_GPIO = readRegister(GPIO);
Nurbol 0:69c047b34ca6 98 return (shadow_GPIO & mask);
Nurbol 0:69c047b34ca6 99 }
Nurbol 0:69c047b34ca6 100
Nurbol 0:69c047b34ca6 101 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 102 * Config
Nurbol 0:69c047b34ca6 103 * set direction and pull-up registers
Nurbol 0:69c047b34ca6 104 */
Nurbol 0:69c047b34ca6 105 void MCP23017::config(unsigned short dir_config, unsigned short pullup_config, unsigned short polarity_config) {
Nurbol 0:69c047b34ca6 106 shadow_IODIR = dir_config;
Nurbol 0:69c047b34ca6 107 writeRegister(IODIR, (unsigned short)shadow_IODIR);
Nurbol 0:69c047b34ca6 108 shadow_GPPU = pullup_config;
Nurbol 0:69c047b34ca6 109 writeRegister(GPPU, (unsigned short)shadow_GPPU);
Nurbol 0:69c047b34ca6 110 shadow_IPOL = polarity_config;
Nurbol 0:69c047b34ca6 111 writeRegister(IPOL, (unsigned short)shadow_IPOL);
Nurbol 0:69c047b34ca6 112 }
Nurbol 0:69c047b34ca6 113
Nurbol 0:69c047b34ca6 114 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 115 * writeRegister
Nurbol 0:69c047b34ca6 116 * write a byte
Nurbol 0:69c047b34ca6 117 */
Nurbol 0:69c047b34ca6 118 void MCP23017::writeRegister(int regAddress, unsigned char data) {
Nurbol 0:69c047b34ca6 119 char buffer[2];
Nurbol 0:69c047b34ca6 120
Nurbol 0:69c047b34ca6 121 buffer[0] = regAddress;
Nurbol 0:69c047b34ca6 122 buffer[1] = data;
Nurbol 0:69c047b34ca6 123 _i2c.write(MCP23017_i2cAddress, buffer, 2);
Nurbol 0:69c047b34ca6 124 }
Nurbol 0:69c047b34ca6 125
Nurbol 0:69c047b34ca6 126 /*----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 127 * write Register
Nurbol 0:69c047b34ca6 128 * write two bytes
Nurbol 0:69c047b34ca6 129 */
Nurbol 0:69c047b34ca6 130 void MCP23017::writeRegister(int regAddress, unsigned short data) {
Nurbol 0:69c047b34ca6 131 char buffer[3];
Nurbol 0:69c047b34ca6 132
Nurbol 0:69c047b34ca6 133 buffer[0] = regAddress;
Nurbol 0:69c047b34ca6 134 tmp_data.value16 = data;
Nurbol 0:69c047b34ca6 135 buffer[1] = tmp_data.value8[0];
Nurbol 0:69c047b34ca6 136 buffer[2] = tmp_data.value8[1];
Nurbol 0:69c047b34ca6 137
Nurbol 0:69c047b34ca6 138 _i2c.write(MCP23017_i2cAddress, buffer, 3);
Nurbol 0:69c047b34ca6 139 }
Nurbol 0:69c047b34ca6 140
Nurbol 0:69c047b34ca6 141 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 142 * readRegister
Nurbol 0:69c047b34ca6 143 */
Nurbol 0:69c047b34ca6 144 int MCP23017::readRegister(int regAddress) {
Nurbol 0:69c047b34ca6 145 char buffer[2];
Nurbol 0:69c047b34ca6 146
Nurbol 0:69c047b34ca6 147 buffer[0] = regAddress;
Nurbol 0:69c047b34ca6 148 _i2c.write(MCP23017_i2cAddress, buffer, 1);
Nurbol 0:69c047b34ca6 149 _i2c.read(MCP23017_i2cAddress, buffer, 2);
Nurbol 0:69c047b34ca6 150
Nurbol 0:69c047b34ca6 151 return ((int)(buffer[0] + (buffer[1]<<8)));
Nurbol 0:69c047b34ca6 152 }
Nurbol 0:69c047b34ca6 153
Nurbol 0:69c047b34ca6 154 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 155 * pinMode
Nurbol 0:69c047b34ca6 156 */
Nurbol 0:69c047b34ca6 157 void MCP23017::pinMode(int pin, int mode) {
Nurbol 0:69c047b34ca6 158 if (DIR_INPUT) {
Nurbol 0:69c047b34ca6 159 shadow_IODIR |= 1 << pin;
Nurbol 0:69c047b34ca6 160 } else {
Nurbol 0:69c047b34ca6 161 shadow_IODIR &= ~(1 << pin);
Nurbol 0:69c047b34ca6 162 }
Nurbol 0:69c047b34ca6 163 writeRegister(IODIR, (unsigned short)shadow_IODIR);
Nurbol 0:69c047b34ca6 164 }
Nurbol 0:69c047b34ca6 165
Nurbol 0:69c047b34ca6 166 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 167 * digitalRead
Nurbol 0:69c047b34ca6 168 */
Nurbol 0:69c047b34ca6 169 int MCP23017::digitalRead(int pin) {
Nurbol 0:69c047b34ca6 170 shadow_GPIO = readRegister(GPIO);
Nurbol 0:69c047b34ca6 171 if ( shadow_GPIO & (1 << pin)) {
Nurbol 0:69c047b34ca6 172 return 1;
Nurbol 0:69c047b34ca6 173 } else {
Nurbol 0:69c047b34ca6 174 return 0;
Nurbol 0:69c047b34ca6 175 }
Nurbol 0:69c047b34ca6 176 }
Nurbol 0:69c047b34ca6 177
Nurbol 0:69c047b34ca6 178 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 179 * digitalWrite
Nurbol 0:69c047b34ca6 180 */
Nurbol 0:69c047b34ca6 181 void MCP23017::digitalWrite(int pin, int val) {
Nurbol 0:69c047b34ca6 182 //If this pin is an INPUT pin, a write here will
Nurbol 0:69c047b34ca6 183 //enable the internal pullup
Nurbol 0:69c047b34ca6 184 //otherwise, it will set the OUTPUT voltage
Nurbol 0:69c047b34ca6 185 //as appropriate.
Nurbol 0:69c047b34ca6 186 bool isOutput = !(shadow_IODIR & 1<<pin);
Nurbol 0:69c047b34ca6 187
Nurbol 0:69c047b34ca6 188 if (isOutput) {
Nurbol 0:69c047b34ca6 189 //This is an output pin so just write the value
Nurbol 0:69c047b34ca6 190 if (val) shadow_GPIO |= 1 << pin;
Nurbol 0:69c047b34ca6 191 else shadow_GPIO &= ~(1 << pin);
Nurbol 0:69c047b34ca6 192 writeRegister(GPIO, (unsigned short)shadow_GPIO);
Nurbol 0:69c047b34ca6 193 } else {
Nurbol 0:69c047b34ca6 194 //This is an input pin, so we need to enable the pullup
Nurbol 0:69c047b34ca6 195 if (val) {
Nurbol 0:69c047b34ca6 196 shadow_GPPU |= 1 << pin;
Nurbol 0:69c047b34ca6 197 } else {
Nurbol 0:69c047b34ca6 198 shadow_GPPU &= ~(1 << pin);
Nurbol 0:69c047b34ca6 199 }
Nurbol 0:69c047b34ca6 200 writeRegister(GPPU, (unsigned short)shadow_GPPU);
Nurbol 0:69c047b34ca6 201 }
Nurbol 0:69c047b34ca6 202 }
Nurbol 0:69c047b34ca6 203
Nurbol 0:69c047b34ca6 204 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 205 * digitalWordRead
Nurbol 0:69c047b34ca6 206 */
Nurbol 0:69c047b34ca6 207 unsigned short MCP23017::digitalWordRead() {
Nurbol 0:69c047b34ca6 208 shadow_GPIO = readRegister(GPIO);
Nurbol 0:69c047b34ca6 209 return shadow_GPIO;
Nurbol 0:69c047b34ca6 210 }
Nurbol 0:69c047b34ca6 211
Nurbol 0:69c047b34ca6 212 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 213 * digitalWordWrite
Nurbol 0:69c047b34ca6 214 */
Nurbol 0:69c047b34ca6 215 void MCP23017::digitalWordWrite(unsigned short w) {
Nurbol 0:69c047b34ca6 216 shadow_GPIO = w;
Nurbol 0:69c047b34ca6 217 writeRegister(GPIO, (unsigned short)shadow_GPIO);
Nurbol 0:69c047b34ca6 218 }
Nurbol 0:69c047b34ca6 219
Nurbol 0:69c047b34ca6 220 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 221 * inputPolarityMask
Nurbol 0:69c047b34ca6 222 */
Nurbol 0:69c047b34ca6 223 void MCP23017::inputPolarityMask(unsigned short mask) {
Nurbol 0:69c047b34ca6 224 writeRegister(IPOL, mask);
Nurbol 0:69c047b34ca6 225 }
Nurbol 0:69c047b34ca6 226
Nurbol 0:69c047b34ca6 227 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 228 * inputoutputMask
Nurbol 0:69c047b34ca6 229 */
Nurbol 0:69c047b34ca6 230 void MCP23017::inputOutputMask(unsigned short mask) {
Nurbol 0:69c047b34ca6 231 shadow_IODIR = mask;
Nurbol 0:69c047b34ca6 232 writeRegister(IODIR, (unsigned short)shadow_IODIR);
Nurbol 0:69c047b34ca6 233 }
Nurbol 0:69c047b34ca6 234
Nurbol 0:69c047b34ca6 235 /*-----------------------------------------------------------------------------
Nurbol 0:69c047b34ca6 236 * internalPullupMask
Nurbol 0:69c047b34ca6 237 */
Nurbol 0:69c047b34ca6 238 void MCP23017::internalPullupMask(unsigned short mask) {
Nurbol 0:69c047b34ca6 239 shadow_GPPU = mask;
Nurbol 0:69c047b34ca6 240 writeRegister(GPPU, (unsigned short)shadow_GPPU);
Nurbol 0:69c047b34ca6 241 }
Nurbol 0:69c047b34ca6 242