Knud Dalgaard / 310-TMC3-TestHW

Dependencies:   mbed

Committer:
knuderich
Date:
Fri May 09 11:30:55 2014 +0000
Revision:
0:c92ca0229c9a
P029 P030 gpio

Who changed what in which revision?

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