Mingcheng Lin / Mbed 2 deprecated TEST

Dependencies:   mbed

Committer:
mrweilun
Date:
Wed May 08 03:37:43 2019 +0000
Revision:
0:3d3331775af2
jjj

Who changed what in which revision?

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