cycyy

Dependencies:   MCP23017 WattBob_TextLCD

Committer:
mihaidd
Date:
Wed May 08 03:58:47 2019 +0000
Revision:
0:a9b4ee4ed395
ccc

Who changed what in which revision?

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