This library provides simplified I2C access to a Microchip MCP23x17 GPIO expender device, including a general interface for any GPIO expender

Dependents:   MCP23017App

Committer:
Yann
Date:
Fri Jan 09 14:37:42 2015 +0000
Revision:
0:ebd3a7cc9b92
Child:
1:ec9e770173d5
Add support of interruptions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Yann 0:ebd3a7cc9b92 1 /* mbed simplified access to Microchip MCP28x17 GPIO expender devices (I2C)
Yann 0:ebd3a7cc9b92 2 * Copyright (c) 2010-2012 ygarcia, MIT License
Yann 0:ebd3a7cc9b92 3 *
Yann 0:ebd3a7cc9b92 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Yann 0:ebd3a7cc9b92 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
Yann 0:ebd3a7cc9b92 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
Yann 0:ebd3a7cc9b92 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Yann 0:ebd3a7cc9b92 8 * furnished to do so, subject to the following conditions:
Yann 0:ebd3a7cc9b92 9 *
Yann 0:ebd3a7cc9b92 10 * The above copyright notice and this permission notice shall be included in all copies or
Yann 0:ebd3a7cc9b92 11 * substantial pinions of the Software.
Yann 0:ebd3a7cc9b92 12 *
Yann 0:ebd3a7cc9b92 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Yann 0:ebd3a7cc9b92 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Yann 0:ebd3a7cc9b92 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Yann 0:ebd3a7cc9b92 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Yann 0:ebd3a7cc9b92 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Yann 0:ebd3a7cc9b92 18 */
Yann 0:ebd3a7cc9b92 19 #include <iostream>
Yann 0:ebd3a7cc9b92 20 #include <sstream>
Yann 0:ebd3a7cc9b92 21
Yann 0:ebd3a7cc9b92 22 #include "MCP23017_I2C.h"
Yann 0:ebd3a7cc9b92 23
Yann 0:ebd3a7cc9b92 24 #define IODIRA 0x00
Yann 0:ebd3a7cc9b92 25 #define IODIRB 0x01
Yann 0:ebd3a7cc9b92 26 #define IPOLA 0x02
Yann 0:ebd3a7cc9b92 27 #define IPOLB 0x03
Yann 0:ebd3a7cc9b92 28 #define GPINTENA 0x04
Yann 0:ebd3a7cc9b92 29 #define GPINTENB 0x05
Yann 0:ebd3a7cc9b92 30 #define DEFVALA 0x06
Yann 0:ebd3a7cc9b92 31 #define DEFVALB 0x07
Yann 0:ebd3a7cc9b92 32 #define INTCONA 0x08
Yann 0:ebd3a7cc9b92 33 #define INTCONB 0x09
Yann 0:ebd3a7cc9b92 34 #define IOCONA 0x0a
Yann 0:ebd3a7cc9b92 35 #define IOCONB 0x0b
Yann 0:ebd3a7cc9b92 36 #define GPPUA 0x0c
Yann 0:ebd3a7cc9b92 37 #define GPPUB 0x0d
Yann 0:ebd3a7cc9b92 38 #define INTFA 0x0e
Yann 0:ebd3a7cc9b92 39 #define INTFB 0x0f
Yann 0:ebd3a7cc9b92 40 #define INTCAPA 0x10
Yann 0:ebd3a7cc9b92 41 #define INTCAPB 0x11
Yann 0:ebd3a7cc9b92 42 #define GPIOA 0x12
Yann 0:ebd3a7cc9b92 43 #define GPIOB 0x13
Yann 0:ebd3a7cc9b92 44 #define OLATA 0x14
Yann 0:ebd3a7cc9b92 45 #define OLATB 0x15
Yann 0:ebd3a7cc9b92 46
Yann 0:ebd3a7cc9b92 47 namespace MCP23017_I2C {
Yann 0:ebd3a7cc9b92 48
Yann 0:ebd3a7cc9b92 49 unsigned char CMCP23017_I2C::I2CModuleRefCounter = 0;
Yann 0:ebd3a7cc9b92 50
Yann 0:ebd3a7cc9b92 51 CMCP23017_I2C::CMCP23017_I2C(const PinName p_sda, const PinName p_scl, const unsigned char p_address, const PinName p_intA, const PinName p_intB, const PinName p_reset, const bool p_internalPullUp, const unsigned int p_frequency) : _gpioAFlags(0x00), _gpioBFlags(0x00), _buses(), _busesIndex(0x00), _internalId("") {
Yann 0:ebd3a7cc9b92 52 DEBUG_ENTER("CMCP23017_I2C")
Yann 0:ebd3a7cc9b92 53
Yann 0:ebd3a7cc9b92 54 if (CMCP23017_I2C::I2CModuleRefCounter != 0) {
Yann 0:ebd3a7cc9b92 55 error("CMCP23017_I2C: Wrong params");
Yann 0:ebd3a7cc9b92 56 }
Yann 0:ebd3a7cc9b92 57 #ifdef __DEBUG
Yann 0:ebd3a7cc9b92 58 std::ostringstream out(std::ostringstream::out);
Yann 0:ebd3a7cc9b92 59 out << "CMCP23017_I2C #" << CMCP23017_I2C::I2CModuleRefCounter;
Yann 0:ebd3a7cc9b92 60 _internalId.assign(out.str());
Yann 0:ebd3a7cc9b92 61 DEBUG("CMCP23017_I2C: _internalId='%s'", _internalId.c_str())
Yann 0:ebd3a7cc9b92 62 #endif // __DEBUG
Yann 0:ebd3a7cc9b92 63 _i2cInstance = new I2C(p_sda, p_scl);
Yann 0:ebd3a7cc9b92 64 CMCP23017_I2C::I2CModuleRefCounter += 1;
Yann 0:ebd3a7cc9b92 65 DEBUG_ENTER("CMCP23017_I2C: refCounter=%d", CMCP23017_I2C::I2CModuleRefCounter)
Yann 0:ebd3a7cc9b92 66
Yann 0:ebd3a7cc9b92 67 _slaveAddress = (p_address << 1) | 0x40; // Slave address format is: 0 0 1 0 A3 A2 A1 R/W
Yann 0:ebd3a7cc9b92 68 DEBUG("CMCP23017_I2C: I2C slave adress: 0x%02x", _slaveAddress)
Yann 0:ebd3a7cc9b92 69 _i2cInstance->frequency(p_frequency); // Set the frequency of the I2C interface
Yann 0:ebd3a7cc9b92 70
Yann 0:ebd3a7cc9b92 71 if (p_intA != NC) {
Yann 0:ebd3a7cc9b92 72 DEBUG("CMCP23017_I2C: INTA managed");
Yann 0:ebd3a7cc9b92 73 _intA = new InterruptIn(p_intA);
Yann 0:ebd3a7cc9b92 74 if (p_internalPullUp) _intA->mode(PullDown);
Yann 0:ebd3a7cc9b92 75 _intA->enable_irq(); // Enable interrupt
Yann 0:ebd3a7cc9b92 76 } else {
Yann 0:ebd3a7cc9b92 77 DEBUG("CMCP23017_I2C: INTA not managed");
Yann 0:ebd3a7cc9b92 78 _intA = NULL; // Not used
Yann 0:ebd3a7cc9b92 79 }
Yann 0:ebd3a7cc9b92 80 if (p_intB != NC) {
Yann 0:ebd3a7cc9b92 81 DEBUG("CMCP23017_I2C: INTB managed");
Yann 0:ebd3a7cc9b92 82 _intB = new InterruptIn(p_intB);
Yann 0:ebd3a7cc9b92 83 if (p_internalPullUp) _intB->mode(PullDown);
Yann 0:ebd3a7cc9b92 84 _intB->enable_irq(); // Enable interrupt
Yann 0:ebd3a7cc9b92 85 } else {
Yann 0:ebd3a7cc9b92 86 DEBUG("CMCP23017_I2C: INTB not managed");
Yann 0:ebd3a7cc9b92 87 _intB = NULL; // Not used
Yann 0:ebd3a7cc9b92 88 }
Yann 0:ebd3a7cc9b92 89 if (p_reset != NC) {
Yann 0:ebd3a7cc9b92 90 DEBUG("CMCP23017_I2C: RESET managed");
Yann 0:ebd3a7cc9b92 91 _reset = new DigitalOut(p_reset);
Yann 0:ebd3a7cc9b92 92 _reset->write(1); // Disable reset
Yann 0:ebd3a7cc9b92 93 } else {
Yann 0:ebd3a7cc9b92 94 DEBUG("CMCP23017_I2C: RESET not managed");
Yann 0:ebd3a7cc9b92 95 _reset = NULL; // Not used
Yann 0:ebd3a7cc9b92 96 }
Yann 0:ebd3a7cc9b92 97
Yann 0:ebd3a7cc9b92 98 DEBUG_LEAVE("CMCP23017_I2C")
Yann 0:ebd3a7cc9b92 99 }
Yann 0:ebd3a7cc9b92 100
Yann 0:ebd3a7cc9b92 101 CMCP23017_I2C::~CMCP23017_I2C() {
Yann 0:ebd3a7cc9b92 102 DEBUG_ENTER("~CMCP23017_I2C")
Yann 0:ebd3a7cc9b92 103
Yann 0:ebd3a7cc9b92 104 // Release I2C instance
Yann 0:ebd3a7cc9b92 105 DEBUG_ENTER("~CMCP23017_I2C: refCounter=%d", CMCP23017_I2C::I2CModuleRefCounter)
Yann 0:ebd3a7cc9b92 106 CMCP23017_I2C::I2CModuleRefCounter -= 1;
Yann 0:ebd3a7cc9b92 107 if (CMCP23017_I2C::I2CModuleRefCounter == 0) {
Yann 0:ebd3a7cc9b92 108 delete _i2cInstance;
Yann 0:ebd3a7cc9b92 109 _i2cInstance = NULL;
Yann 0:ebd3a7cc9b92 110 }
Yann 0:ebd3a7cc9b92 111 // Release _wp if required
Yann 0:ebd3a7cc9b92 112 if (_intA != NULL) {
Yann 0:ebd3a7cc9b92 113 delete _intA;
Yann 0:ebd3a7cc9b92 114 }
Yann 0:ebd3a7cc9b92 115 if (_intB != NULL) {
Yann 0:ebd3a7cc9b92 116 delete _intB;
Yann 0:ebd3a7cc9b92 117 }
Yann 0:ebd3a7cc9b92 118 if (_reset != NULL) {
Yann 0:ebd3a7cc9b92 119 delete _reset;
Yann 0:ebd3a7cc9b92 120 }
Yann 0:ebd3a7cc9b92 121
Yann 0:ebd3a7cc9b92 122 DEBUG_LEAVE("~CMCP23017_I2C")
Yann 0:ebd3a7cc9b92 123 }
Yann 0:ebd3a7cc9b92 124
Yann 0:ebd3a7cc9b92 125 bool CMCP23017_I2C::Initialize(const unsigned char p_gpioAFlags, const unsigned char p_gpioBFlags) {
Yann 0:ebd3a7cc9b92 126
Yann 0:ebd3a7cc9b92 127 // Configure default behavior
Yann 0:ebd3a7cc9b92 128 _gpioAFlags = p_gpioAFlags;
Yann 0:ebd3a7cc9b92 129 _gpioBFlags = p_gpioBFlags;
Yann 0:ebd3a7cc9b92 130 configure(_gpioAFlags, _gpioBFlags);
Yann 0:ebd3a7cc9b92 131
Yann 0:ebd3a7cc9b92 132 return true;
Yann 0:ebd3a7cc9b92 133 }
Yann 0:ebd3a7cc9b92 134
Yann 0:ebd3a7cc9b92 135 void CMCP23017_I2C::configure(const unsigned char p_gpioAFlags, const unsigned char p_gpioBFlags) { // TODO Optimization with sequential access
Yann 0:ebd3a7cc9b92 136 // DEBUG_ENTER("CMCP23017_I2C::configure: 0x%02x 0x%02x", p_gpioAFlags, p_gpioBFlags)
Yann 0:ebd3a7cc9b92 137
Yann 0:ebd3a7cc9b92 138 // Setup IOCON - See REGISTER 1-6: IOCON – I/O EXPANDER CONFIGURATION REGISTER
Yann 0:ebd3a7cc9b92 139 writeRegister(IOCONA, 0x10); // Sequential operation disabled
Yann 0:ebd3a7cc9b92 140 writeRegister(IOCONB, 0x10); // Sequential operation disabled
Yann 0:ebd3a7cc9b92 141 // Setup IODIR - See REGISTER 1-1: IODIR – I/O DIRECTION REGISTER (ADDR 0x00)
Yann 0:ebd3a7cc9b92 142 writeRegister(IODIRA, p_gpioAFlags);
Yann 0:ebd3a7cc9b92 143 writeRegister(IODIRB, p_gpioBFlags);
Yann 0:ebd3a7cc9b92 144 // Setup IPOL - See REGISTER 1-2: IPOL – INPUT POLARITY PORT REGISTER
Yann 0:ebd3a7cc9b92 145 writeRegister(IPOLA, 0x00); // GPIO register bit will reflect the same logic state of the input pin
Yann 0:ebd3a7cc9b92 146 writeRegister(IPOLB, 0x00);
Yann 0:ebd3a7cc9b92 147 // Setup GPPU - See REGISTER 1-7: GPPU – GPIO PULL-UP RESISTOR REGISTER
Yann 0:ebd3a7cc9b92 148 writeRegister(GPPUA, 0x00);
Yann 0:ebd3a7cc9b92 149 writeRegister(GPPUB, 0x00);
Yann 0:ebd3a7cc9b92 150
Yann 0:ebd3a7cc9b92 151 // Setup interrupt
Yann 0:ebd3a7cc9b92 152 if (_intA != NULL) {
Yann 0:ebd3a7cc9b92 153 DEBUG("CMCP23017_I2C::configure: Setup INTA")
Yann 0:ebd3a7cc9b92 154 // Setup GPINTEN - See GPINTEN – INTERRUPT-ON-CHANGE PINS
Yann 0:ebd3a7cc9b92 155 writeRegister(GPINTENA, 0x00); // Disable GPIO interrupt-on-change events
Yann 0:ebd3a7cc9b92 156 // Setup DEFVAL - See REGISTER 1-4: DEFVAL – DEFAULT VALUE REGISTER
Yann 0:ebd3a7cc9b92 157 writeRegister(DEFVALA, 0x00); // Pin level change from 0 to 1 raises an interrupt
Yann 0:ebd3a7cc9b92 158 // Setup INTCON - REGISTER 1-5: INTCON – INTERRUPT-ON-CHANGE CONTROL REGISTER
Yann 0:ebd3a7cc9b92 159 writeRegister(INTCONA, 0xff); // Pin level change from 0 to 1 raises an interrupt
Yann 0:ebd3a7cc9b92 160 }
Yann 0:ebd3a7cc9b92 161 if (_intB != NULL) {
Yann 0:ebd3a7cc9b92 162 DEBUG("CMCP23017_I2C::configure: Setup INTB")
Yann 0:ebd3a7cc9b92 163 // Setup GPINTEN - See GPINTEN – INTERRUPT-ON-CHANGE PINS
Yann 0:ebd3a7cc9b92 164 writeRegister(GPINTENB, 0x00); // Disable GPIO interrupt-on-change events
Yann 0:ebd3a7cc9b92 165 // Setup DEFVAL - See REGISTER 1-4: DEFVAL – DEFAULT VALUE REGISTER
Yann 0:ebd3a7cc9b92 166 writeRegister(DEFVALB, 0x00); // Pin level change from 0 to 1 raises an interrupt
Yann 0:ebd3a7cc9b92 167 // Setup INTCON - REGISTER 1-5: INTCON – INTERRUPT-ON-CHANGE CONTROL REGISTER
Yann 0:ebd3a7cc9b92 168 writeRegister(INTCONB, 0xff); // Pin level change from 0 to 1 raises an interrupt
Yann 0:ebd3a7cc9b92 169 }
Yann 0:ebd3a7cc9b92 170
Yann 0:ebd3a7cc9b92 171 // DumpRegisters();
Yann 0:ebd3a7cc9b92 172
Yann 0:ebd3a7cc9b92 173 // DEBUG_LEAVE("CMCP23017_I2C::configure")
Yann 0:ebd3a7cc9b92 174 }
Yann 0:ebd3a7cc9b92 175
Yann 0:ebd3a7cc9b92 176 void CMCP23017_I2C::reset() {
Yann 0:ebd3a7cc9b92 177 // DEBUG_ENTER("CMCP23017_I2C::reset")
Yann 0:ebd3a7cc9b92 178 if (_reset != NULL) {
Yann 0:ebd3a7cc9b92 179 _reset->write(0);
Yann 0:ebd3a7cc9b92 180 wait_us(1);
Yann 0:ebd3a7cc9b92 181 _reset->write(1);
Yann 0:ebd3a7cc9b92 182 wait_us(1);
Yann 0:ebd3a7cc9b92 183 if ((_gpioAFlags != 0x00) || (_gpioBFlags != 0x00)) { // Apply configuration
Yann 0:ebd3a7cc9b92 184 configure(_gpioAFlags, _gpioBFlags);
Yann 0:ebd3a7cc9b92 185 } // else, POR reset values, see DS21952B-page 10 Clause 1.6 Configuration and Control Registers
Yann 0:ebd3a7cc9b92 186 }
Yann 0:ebd3a7cc9b92 187 // DEBUG_LEAVE("CMCP23017_I2C::reset")
Yann 0:ebd3a7cc9b92 188 }
Yann 0:ebd3a7cc9b92 189
Yann 0:ebd3a7cc9b92 190 void CMCP23017_I2C::setIntrACallback(void (* p_fptr)(void)) {
Yann 0:ebd3a7cc9b92 191 if (_intA != NULL) {
Yann 0:ebd3a7cc9b92 192 unsigned char vregister;
Yann 0:ebd3a7cc9b92 193 if (!readRegister(IOCONA, &vregister)) {
Yann 0:ebd3a7cc9b92 194 return;
Yann 0:ebd3a7cc9b92 195 }
Yann 0:ebd3a7cc9b92 196 if (isBitSet(vregister, 1)) {
Yann 0:ebd3a7cc9b92 197 _intA->rise(p_fptr);
Yann 0:ebd3a7cc9b92 198 } else {
Yann 0:ebd3a7cc9b92 199 _intA->fall(p_fptr);
Yann 0:ebd3a7cc9b92 200 }
Yann 0:ebd3a7cc9b92 201 }
Yann 0:ebd3a7cc9b92 202 }
Yann 0:ebd3a7cc9b92 203
Yann 0:ebd3a7cc9b92 204 void CMCP23017_I2C::setIntrBCallback(void (* p_fptr)(void)) {
Yann 0:ebd3a7cc9b92 205 if (_intB != NULL) {
Yann 0:ebd3a7cc9b92 206 unsigned char vregister;
Yann 0:ebd3a7cc9b92 207 if (!readRegister(IOCONB, &vregister)) {
Yann 0:ebd3a7cc9b92 208 return;
Yann 0:ebd3a7cc9b92 209 }
Yann 0:ebd3a7cc9b92 210 if (isBitSet(vregister, 1)) {
Yann 0:ebd3a7cc9b92 211 _intB->rise(p_fptr);
Yann 0:ebd3a7cc9b92 212 } else {
Yann 0:ebd3a7cc9b92 213 _intB->fall(p_fptr);
Yann 0:ebd3a7cc9b92 214 }
Yann 0:ebd3a7cc9b92 215 }
Yann 0:ebd3a7cc9b92 216 }
Yann 0:ebd3a7cc9b92 217
Yann 0:ebd3a7cc9b92 218 template<typename T>
Yann 0:ebd3a7cc9b92 219 void CMCP23017_I2C::setIntrACallback (const T * p_tptr, void(T::* p_mptr)(void)) {
Yann 0:ebd3a7cc9b92 220 if (_intA != NULL) {
Yann 0:ebd3a7cc9b92 221 unsigned char vregister;
Yann 0:ebd3a7cc9b92 222 if (!readRegister(IOCONA, &vregister)) {
Yann 0:ebd3a7cc9b92 223 return;
Yann 0:ebd3a7cc9b92 224 }
Yann 0:ebd3a7cc9b92 225 if (isBitSet(vregister, 1)) {
Yann 0:ebd3a7cc9b92 226 _intA->rise(p_tptr, p_mptr);
Yann 0:ebd3a7cc9b92 227 } else {
Yann 0:ebd3a7cc9b92 228 _intA->fall(p_tptr, p_mptr);
Yann 0:ebd3a7cc9b92 229 }
Yann 0:ebd3a7cc9b92 230 }
Yann 0:ebd3a7cc9b92 231 }
Yann 0:ebd3a7cc9b92 232
Yann 0:ebd3a7cc9b92 233 template<typename T>
Yann 0:ebd3a7cc9b92 234 void CMCP23017_I2C::setIntrBCallback (const T * p_tptr, void(T::* p_mptr)(void)) {
Yann 0:ebd3a7cc9b92 235 unsigned char vregister;
Yann 0:ebd3a7cc9b92 236 if (!readRegister(IOCONB, &vregister)) {
Yann 0:ebd3a7cc9b92 237 return;
Yann 0:ebd3a7cc9b92 238 }
Yann 0:ebd3a7cc9b92 239 if (isBitSet(vregister, 1)) {
Yann 0:ebd3a7cc9b92 240 _intB->rise(p_tptr, p_mptr);
Yann 0:ebd3a7cc9b92 241 } else {
Yann 0:ebd3a7cc9b92 242 _intB->fall(p_tptr, p_mptr);
Yann 0:ebd3a7cc9b92 243 }
Yann 0:ebd3a7cc9b92 244 }
Yann 0:ebd3a7cc9b92 245
Yann 0:ebd3a7cc9b92 246 void CMCP23017_I2C::setupInterrupts(const unsigned char p_mirroring, const unsigned char p_openDrain, const unsigned char p_polarity) {
Yann 0:ebd3a7cc9b92 247 DEBUG_ENTER("CMCP23017_I2C::setupInterrupts: %02x, %02x, %02x", p_mirroring, p_openDrain, p_polarity)
Yann 0:ebd3a7cc9b92 248
Yann 0:ebd3a7cc9b92 249 // Setup IOCONA
Yann 0:ebd3a7cc9b92 250 unsigned char vregister;
Yann 0:ebd3a7cc9b92 251 if (!readRegister(INTCONA, &vregister)) {
Yann 0:ebd3a7cc9b92 252 return;
Yann 0:ebd3a7cc9b92 253 }
Yann 0:ebd3a7cc9b92 254 // Setup INTCON - REGISTER 1-5: INTCON – INTERRUPT-ON-CHANGE CONTROL REGISTER
Yann 0:ebd3a7cc9b92 255 vregister = setBit(vregister, 6, p_mirroring);
Yann 0:ebd3a7cc9b92 256 vregister = setBit(vregister, 2, p_openDrain);
Yann 0:ebd3a7cc9b92 257 vregister = setBit(vregister, 1, p_polarity);
Yann 0:ebd3a7cc9b92 258 writeRegister(INTCONA, vregister);
Yann 0:ebd3a7cc9b92 259
Yann 0:ebd3a7cc9b92 260 // Setup IOCONB
Yann 0:ebd3a7cc9b92 261 if (!readRegister(INTCONB, &vregister)) {
Yann 0:ebd3a7cc9b92 262 return;
Yann 0:ebd3a7cc9b92 263 }
Yann 0:ebd3a7cc9b92 264 // Setup INTCON - REGISTER 1-5: INTCON – INTERRUPT-ON-CHANGE CONTROL REGISTER
Yann 0:ebd3a7cc9b92 265 vregister = setBit(vregister, 6, p_mirroring);
Yann 0:ebd3a7cc9b92 266 vregister = setBit(vregister, 2, p_openDrain);
Yann 0:ebd3a7cc9b92 267 vregister = setBit(vregister, 1, p_polarity);
Yann 0:ebd3a7cc9b92 268 writeRegister(INTCONB, vregister);
Yann 0:ebd3a7cc9b92 269
Yann 0:ebd3a7cc9b92 270 }
Yann 0:ebd3a7cc9b92 271
Yann 0:ebd3a7cc9b92 272 int CMCP23017_I2C::setupInterruptPin(const unsigned char p_gpioId, const InterruptModes p_mode) {
Yann 0:ebd3a7cc9b92 273 DEBUG_ENTER("CMCP23017_I2C::setupInterruptPin: %02x, %02x", p_gpioId, p_mode)
Yann 0:ebd3a7cc9b92 274
Yann 0:ebd3a7cc9b92 275 // Retrive the register address
Yann 0:ebd3a7cc9b92 276 unsigned char gpioIntconId, gpioDefvalId, gpioGpintenId;
Yann 0:ebd3a7cc9b92 277 if (!registerIdFromGpioId(p_gpioId, &gpioIntconId)) {
Yann 0:ebd3a7cc9b92 278 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -1")
Yann 0:ebd3a7cc9b92 279 return -1;
Yann 0:ebd3a7cc9b92 280 }
Yann 0:ebd3a7cc9b92 281 if (gpioIntconId == GPIOA) {
Yann 0:ebd3a7cc9b92 282 gpioIntconId = INTCONA;
Yann 0:ebd3a7cc9b92 283 gpioDefvalId = DEFVALA;
Yann 0:ebd3a7cc9b92 284 gpioGpintenId = GPINTENA;
Yann 0:ebd3a7cc9b92 285 } else {
Yann 0:ebd3a7cc9b92 286 gpioIntconId = INTCONB;
Yann 0:ebd3a7cc9b92 287 gpioDefvalId = DEFVALB;
Yann 0:ebd3a7cc9b92 288 gpioGpintenId = GPINTENB;
Yann 0:ebd3a7cc9b92 289 }
Yann 0:ebd3a7cc9b92 290 DEBUG("CMCP23017_I2C::setupInterruptPin: gpioIntconId=%02x gpioDefvalId=%02x gpioGpintenId=%02x", gpioIntconId, gpioDefvalId, gpioGpintenId)
Yann 0:ebd3a7cc9b92 291
Yann 0:ebd3a7cc9b92 292 // Retrive the GPIO pin number
Yann 0:ebd3a7cc9b92 293 unsigned char gpioBit = gpioBitFromGpioId(p_gpioId);
Yann 0:ebd3a7cc9b92 294 DEBUG("CMCP23017_I2C::setupInterruptPin: gpioBit=%02x", gpioBit)
Yann 0:ebd3a7cc9b92 295
Yann 0:ebd3a7cc9b92 296 // Read it
Yann 0:ebd3a7cc9b92 297 unsigned char gpioIntconValue, gpioDefvalValue, gpioGpintenValue;
Yann 0:ebd3a7cc9b92 298 if (!readRegister(gpioIntconId, &gpioIntconValue)) {
Yann 0:ebd3a7cc9b92 299 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -2")
Yann 0:ebd3a7cc9b92 300 return -2;
Yann 0:ebd3a7cc9b92 301 }
Yann 0:ebd3a7cc9b92 302 if (!readRegister(gpioDefvalId, &gpioDefvalValue)) {
Yann 0:ebd3a7cc9b92 303 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -2")
Yann 0:ebd3a7cc9b92 304 return -2;
Yann 0:ebd3a7cc9b92 305 }
Yann 0:ebd3a7cc9b92 306 if (!readRegister(gpioGpintenId, &gpioGpintenValue)) {
Yann 0:ebd3a7cc9b92 307 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -2")
Yann 0:ebd3a7cc9b92 308 return -2;
Yann 0:ebd3a7cc9b92 309 }
Yann 0:ebd3a7cc9b92 310 DEBUG("CMCP23017_I2C::setupInterruptPin: gpioIntconValue=%02x gpioDefvalValue=%02x gpioGpintenValue=%02x", gpioIntconValue, gpioDefvalValue, gpioGpintenValue)
Yann 0:ebd3a7cc9b92 311
Yann 0:ebd3a7cc9b92 312 //
Yann 0:ebd3a7cc9b92 313 switch (static_cast<unsigned char>(p_mode)) {
Yann 0:ebd3a7cc9b92 314 case static_cast<unsigned char>(OnChange):
Yann 0:ebd3a7cc9b92 315 gpioIntconValue = setBit(gpioIntconValue, gpioBit, 0x00);
Yann 0:ebd3a7cc9b92 316 gpioDefvalValue = setBit(gpioDefvalValue, gpioBit, 0x00);
Yann 0:ebd3a7cc9b92 317 break;
Yann 0:ebd3a7cc9b92 318 case static_cast<unsigned char>(OnRising):
Yann 0:ebd3a7cc9b92 319 gpioIntconValue = setBit(gpioIntconValue, gpioBit, 0x01);
Yann 0:ebd3a7cc9b92 320 gpioDefvalValue = setBit(gpioDefvalValue, gpioBit, 0x00);
Yann 0:ebd3a7cc9b92 321 break;
Yann 0:ebd3a7cc9b92 322 case static_cast<unsigned char>(OnFalling):
Yann 0:ebd3a7cc9b92 323 gpioIntconValue = setBit(gpioIntconValue, gpioBit, 0x01);
Yann 0:ebd3a7cc9b92 324 gpioDefvalValue = setBit(gpioDefvalValue, gpioBit, 0x01);
Yann 0:ebd3a7cc9b92 325 break;
Yann 0:ebd3a7cc9b92 326 } // End of 'switch' statement
Yann 0:ebd3a7cc9b92 327
Yann 0:ebd3a7cc9b92 328 // Enable interrupt
Yann 0:ebd3a7cc9b92 329 gpioGpintenValue = setBit(gpioGpintenValue, gpioBit, 0x01);
Yann 0:ebd3a7cc9b92 330
Yann 0:ebd3a7cc9b92 331 // Write register
Yann 0:ebd3a7cc9b92 332 DEBUG("CMCP23017_I2C::setupInterruptPin: gpioIntconValue=%02x gpioDefvalValue=%02x gpioGpintenValue=%02x", gpioIntconValue, gpioDefvalValue, gpioGpintenValue)
Yann 0:ebd3a7cc9b92 333 writeRegister(gpioDefvalId, gpioDefvalValue);
Yann 0:ebd3a7cc9b92 334 writeRegister(gpioIntconId, gpioIntconValue);
Yann 0:ebd3a7cc9b92 335 writeRegister(gpioGpintenId, gpioGpintenValue);
Yann 0:ebd3a7cc9b92 336
Yann 0:ebd3a7cc9b92 337 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: 0")
Yann 0:ebd3a7cc9b92 338 return 0;
Yann 0:ebd3a7cc9b92 339 }
Yann 0:ebd3a7cc9b92 340
Yann 0:ebd3a7cc9b92 341 int CMCP23017_I2C::getLastInterruptPin(unsigned char * p_gpioId, unsigned char * p_value) {
Yann 0:ebd3a7cc9b92 342 DEBUG_ENTER("CMCP23017_I2C::getLastInterruptPin")
Yann 0:ebd3a7cc9b92 343
Yann 0:ebd3a7cc9b92 344 // Read first INTFA if required
Yann 0:ebd3a7cc9b92 345 unsigned char vregister;
Yann 0:ebd3a7cc9b92 346 if (_gpioAFlags != 0x00) {
Yann 0:ebd3a7cc9b92 347 if (!readRegister(INTFA, &vregister)) {
Yann 0:ebd3a7cc9b92 348 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -1")
Yann 0:ebd3a7cc9b92 349 return -1;
Yann 0:ebd3a7cc9b92 350 }
Yann 0:ebd3a7cc9b92 351 vregister &= _gpioAFlags; // Cannot have interrupt on output port
Yann 0:ebd3a7cc9b92 352 for (unsigned char bit = 0; bit < GPIO_SIZE; bit++) {
Yann 0:ebd3a7cc9b92 353 if (isBitSet(vregister, bit)) {
Yann 0:ebd3a7cc9b92 354 *p_gpioId = bit;
Yann 0:ebd3a7cc9b92 355 readRegister(INTCAPA, p_value);
Yann 0:ebd3a7cc9b92 356 *p_value = (*p_value >> bit) & 0x01;
Yann 0:ebd3a7cc9b92 357
Yann 0:ebd3a7cc9b92 358 DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPin (A): %02x %02x", *p_gpioId, *p_value)
Yann 0:ebd3a7cc9b92 359 return 0;
Yann 0:ebd3a7cc9b92 360 }
Yann 0:ebd3a7cc9b92 361 } // End of 'for' statement
Yann 0:ebd3a7cc9b92 362 }
Yann 0:ebd3a7cc9b92 363
Yann 0:ebd3a7cc9b92 364 // If not interrupt on GPIOA, try with GPIOB
Yann 0:ebd3a7cc9b92 365 if (_gpioBFlags != 0x00) {
Yann 0:ebd3a7cc9b92 366 if (!readRegister(INTFB, &vregister)) {
Yann 0:ebd3a7cc9b92 367 DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -2")
Yann 0:ebd3a7cc9b92 368 return -2;
Yann 0:ebd3a7cc9b92 369 }
Yann 0:ebd3a7cc9b92 370 vregister &= _gpioBFlags; // Cannot have interrupt on output port
Yann 0:ebd3a7cc9b92 371 for (unsigned char bit = 0; bit < GPIO_SIZE; bit++) {
Yann 0:ebd3a7cc9b92 372 if (isBitSet(vregister, bit)) {
Yann 0:ebd3a7cc9b92 373 *p_gpioId = bit + GPIO_SIZE;
Yann 0:ebd3a7cc9b92 374 readRegister(INTCAPB, p_value);
Yann 0:ebd3a7cc9b92 375 *p_value = (*p_value >> bit) & 0x01;
Yann 0:ebd3a7cc9b92 376
Yann 0:ebd3a7cc9b92 377 DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPin (B): %02x %02x", *p_gpioId, *p_value)
Yann 0:ebd3a7cc9b92 378 return 0;
Yann 0:ebd3a7cc9b92 379 }
Yann 0:ebd3a7cc9b92 380 } // End of 'for' statement
Yann 0:ebd3a7cc9b92 381 }
Yann 0:ebd3a7cc9b92 382
Yann 0:ebd3a7cc9b92 383 DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPin: 0")
Yann 0:ebd3a7cc9b92 384 return 0;
Yann 0:ebd3a7cc9b92 385 }
Yann 0:ebd3a7cc9b92 386
Yann 0:ebd3a7cc9b92 387 int CMCP23017_I2C::read(const unsigned char p_gpioId, unsigned char * p_value) {
Yann 0:ebd3a7cc9b92 388 DEBUG_ENTER("CMCP23017_I2C::read: 0x%02x", p_gpioId)
Yann 0:ebd3a7cc9b92 389
Yann 0:ebd3a7cc9b92 390 // Retrive the register address
Yann 0:ebd3a7cc9b92 391 unsigned char gpioRegisterId;
Yann 0:ebd3a7cc9b92 392 if (!registerIdFromGpioId(p_gpioId, &gpioRegisterId)) {
Yann 0:ebd3a7cc9b92 393 DEBUG_LEAVE("CMCP23017_I2C::read: -1")
Yann 0:ebd3a7cc9b92 394 return -1;
Yann 0:ebd3a7cc9b92 395 }
Yann 0:ebd3a7cc9b92 396 DEBUG("CMCP23017_I2C::read: gpioRegisterId=%02x", gpioRegisterId)
Yann 0:ebd3a7cc9b92 397 unsigned char gpioBit = gpioBitFromGpioId(p_gpioId);
Yann 0:ebd3a7cc9b92 398 DEBUG("CMCP23017_I2C::read: gpioBit=%02x", gpioBit)
Yann 0:ebd3a7cc9b92 399
Yann 0:ebd3a7cc9b92 400 // Read it
Yann 0:ebd3a7cc9b92 401 unsigned char gpioRegisterValue;
Yann 0:ebd3a7cc9b92 402 if (!readRegister(gpioRegisterId, &gpioRegisterValue)) {
Yann 0:ebd3a7cc9b92 403 DEBUG_LEAVE("CMCP23017_I2C::read: -2")
Yann 0:ebd3a7cc9b92 404 return -2;
Yann 0:ebd3a7cc9b92 405 }
Yann 0:ebd3a7cc9b92 406 DEBUG("CMCP23017_I2C::read: gpioRegisterValue=%02x", gpioRegisterValue)
Yann 0:ebd3a7cc9b92 407
Yann 0:ebd3a7cc9b92 408 DEBUG_LEAVE("CMCP23017_I2C::read: 0")
Yann 0:ebd3a7cc9b92 409 return 0;
Yann 0:ebd3a7cc9b92 410 }
Yann 0:ebd3a7cc9b92 411
Yann 0:ebd3a7cc9b92 412 bool CMCP23017_I2C::registerIdFromGpioId(const unsigned char p_gpioId, unsigned char * p_gpioRegisterId) {
Yann 0:ebd3a7cc9b92 413 DEBUG_ENTER("CMCP23017_I2C::registerIdFromGpioId: 0x%02x", p_gpioId)
Yann 0:ebd3a7cc9b92 414
Yann 0:ebd3a7cc9b92 415 // Sanity check
Yann 0:ebd3a7cc9b92 416 if (p_gpioId > GPIO_MAX) {
Yann 0:ebd3a7cc9b92 417 DEBUG_ENTER("CMCP23017_I2C::registerIdFromGpioId: false")
Yann 0:ebd3a7cc9b92 418 return false;
Yann 0:ebd3a7cc9b92 419 }
Yann 0:ebd3a7cc9b92 420
Yann 0:ebd3a7cc9b92 421 *p_gpioRegisterId = (p_gpioId < GPIO_MED) ? GPIOA : GPIOB;
Yann 0:ebd3a7cc9b92 422
Yann 0:ebd3a7cc9b92 423 DEBUG_ENTER("CMCP23017_I2C::registerIdFromGpioId: true")
Yann 0:ebd3a7cc9b92 424 return true;
Yann 0:ebd3a7cc9b92 425 }
Yann 0:ebd3a7cc9b92 426
Yann 0:ebd3a7cc9b92 427 int CMCP23017_I2C::write(const unsigned char p_gpioId, const unsigned char p_value) {
Yann 0:ebd3a7cc9b92 428 DEBUG_ENTER("CMCP23017_I2C::write: 0x%02x 0x%02x", p_gpioId, p_value)
Yann 0:ebd3a7cc9b92 429
Yann 0:ebd3a7cc9b92 430 // Retrive the register address
Yann 0:ebd3a7cc9b92 431 unsigned char gpioRegisterId;
Yann 0:ebd3a7cc9b92 432 if (!registerIdFromGpioId(p_gpioId, &gpioRegisterId)) {
Yann 0:ebd3a7cc9b92 433 DEBUG_LEAVE("CMCP23017_I2C::write: -1")
Yann 0:ebd3a7cc9b92 434 return -1;
Yann 0:ebd3a7cc9b92 435 }
Yann 0:ebd3a7cc9b92 436 DEBUG("CMCP23017_I2C::write: gpioRegisterId=%02x", gpioRegisterId)
Yann 0:ebd3a7cc9b92 437
Yann 0:ebd3a7cc9b92 438 // Retrive the GPIO pin number
Yann 0:ebd3a7cc9b92 439 unsigned char gpioBit = gpioBitFromGpioId(p_gpioId);
Yann 0:ebd3a7cc9b92 440 DEBUG("CMCP23017_I2C::write: gpioBit=%02x", gpioBit)
Yann 0:ebd3a7cc9b92 441
Yann 0:ebd3a7cc9b92 442 // Read it
Yann 0:ebd3a7cc9b92 443 unsigned char gpioRegisterValue;
Yann 0:ebd3a7cc9b92 444 if (!readRegister(gpioRegisterId, &gpioRegisterValue)) {
Yann 0:ebd3a7cc9b92 445 DEBUG_LEAVE("CMCP23017_I2C::write: -2")
Yann 0:ebd3a7cc9b92 446 return -2;
Yann 0:ebd3a7cc9b92 447 }
Yann 0:ebd3a7cc9b92 448 DEBUG("CMCP23017_I2C::write: gpioRegisterValue=%02x", gpioRegisterValue)
Yann 0:ebd3a7cc9b92 449
Yann 0:ebd3a7cc9b92 450 // Update GPIO bit
Yann 0:ebd3a7cc9b92 451 if (!isBitEqual(gpioRegisterValue, gpioBit, p_value)) {
Yann 0:ebd3a7cc9b92 452 // Write it if required
Yann 0:ebd3a7cc9b92 453 gpioRegisterValue = setBit(gpioRegisterValue, gpioBit, p_value);
Yann 0:ebd3a7cc9b92 454 DEBUG("CMCP23017_I2C::write: New gpioRegisterValue=%02x", gpioRegisterValue)
Yann 0:ebd3a7cc9b92 455 if (!writeRegister(gpioRegisterId, gpioRegisterValue)) {
Yann 0:ebd3a7cc9b92 456 DEBUG_LEAVE("CMCP23017_I2C::write: -3")
Yann 0:ebd3a7cc9b92 457 return -3;
Yann 0:ebd3a7cc9b92 458 }
Yann 0:ebd3a7cc9b92 459 }
Yann 0:ebd3a7cc9b92 460
Yann 0:ebd3a7cc9b92 461 DEBUG_LEAVE("CMCP23017_I2C::write: 0")
Yann 0:ebd3a7cc9b92 462 return 0;
Yann 0:ebd3a7cc9b92 463 }
Yann 0:ebd3a7cc9b92 464
Yann 0:ebd3a7cc9b92 465 unsigned char CMCP23017_I2C::createBus(const std::list<unsigned char> p_lines, const PinMode p_mode) {
Yann 0:ebd3a7cc9b92 466 unsigned char busId = _busesIndex++;
Yann 0:ebd3a7cc9b92 467
Yann 0:ebd3a7cc9b92 468 _buses.insert(_buses.end(), std::pair<unsigned char, std::list<unsigned char> >(busId, p_lines));
Yann 0:ebd3a7cc9b92 469
Yann 0:ebd3a7cc9b92 470 return busId;
Yann 0:ebd3a7cc9b92 471 }
Yann 0:ebd3a7cc9b92 472
Yann 0:ebd3a7cc9b92 473 void CMCP23017_I2C::deleteBus(const unsigned char p_busId) {
Yann 0:ebd3a7cc9b92 474 // Sanity check
Yann 0:ebd3a7cc9b92 475 std::map<unsigned char, std::list<unsigned char> >::iterator result = _buses.find(p_busId);
Yann 0:ebd3a7cc9b92 476 if (result == _buses.end()) { // Invalid bus identifier
Yann 0:ebd3a7cc9b92 477 return;
Yann 0:ebd3a7cc9b92 478 }
Yann 0:ebd3a7cc9b92 479
Yann 0:ebd3a7cc9b92 480 _buses.erase(p_busId);
Yann 0:ebd3a7cc9b92 481 }
Yann 0:ebd3a7cc9b92 482
Yann 0:ebd3a7cc9b92 483 int CMCP23017_I2C::busRead(const unsigned char p_busId) {
Yann 0:ebd3a7cc9b92 484 return -1;
Yann 0:ebd3a7cc9b92 485 }
Yann 0:ebd3a7cc9b92 486
Yann 0:ebd3a7cc9b92 487 int CMCP23017_I2C::busWrite(const unsigned char p_busId, const unsigned char p_value) {
Yann 0:ebd3a7cc9b92 488 return -1;
Yann 0:ebd3a7cc9b92 489 }
Yann 0:ebd3a7cc9b92 490
Yann 0:ebd3a7cc9b92 491 bool CMCP23017_I2C::writeRegister(const unsigned char p_registerId, const unsigned char p_value) {
Yann 0:ebd3a7cc9b92 492 // DEBUG_ENTER("CMCP23017_I2C::writeRegister: Memory address: 0x%02x - 0x%02x", p_registerId, p_value)
Yann 0:ebd3a7cc9b92 493
Yann 0:ebd3a7cc9b92 494 // 1.Prepare buffer
Yann 0:ebd3a7cc9b92 495 char i2cBuffer[2]; // Register address + one byte of data
Yann 0:ebd3a7cc9b92 496 // 1.1. Memory address
Yann 0:ebd3a7cc9b92 497 i2cBuffer[0] = p_registerId;
Yann 0:ebd3a7cc9b92 498 // 1.2. Datas
Yann 0:ebd3a7cc9b92 499 i2cBuffer[1] = p_value;
Yann 0:ebd3a7cc9b92 500 // DEBUG("CMCP23017_I2C::writeRegister: Data=0x%02x 0x%02x", i2cBuffer[0], i2cBuffer[1])
Yann 0:ebd3a7cc9b92 501
Yann 0:ebd3a7cc9b92 502 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
Yann 0:ebd3a7cc9b92 503 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 2);
Yann 0:ebd3a7cc9b92 504 // wait(0.02);
Yann 0:ebd3a7cc9b92 505
Yann 0:ebd3a7cc9b92 506 // DEBUG_LEAVE("CMCP23017_I2C::writeRegister %x", (bool)(result == 0))
Yann 0:ebd3a7cc9b92 507 return (bool)(result == 0);
Yann 0:ebd3a7cc9b92 508 }
Yann 0:ebd3a7cc9b92 509
Yann 0:ebd3a7cc9b92 510 bool CMCP23017_I2C::readRegister(const unsigned char p_registerId, unsigned char * p_value) {
Yann 0:ebd3a7cc9b92 511 // DEBUG_ENTER("CMCP23017_I2C::readRegister: Memory address: 0x%02x", p_registerId)
Yann 0:ebd3a7cc9b92 512
Yann 0:ebd3a7cc9b92 513 // 1.Prepare buffer
Yann 0:ebd3a7cc9b92 514 char i2cBuffer[1]; // Register address + one byte of data
Yann 0:ebd3a7cc9b92 515 // 1.1. Memory address
Yann 0:ebd3a7cc9b92 516 i2cBuffer[0] = p_registerId;
Yann 0:ebd3a7cc9b92 517 // DEBUG("CMCP23017_I2C::readRegister: Data=0x%02x", i2cBuffer[0])
Yann 0:ebd3a7cc9b92 518
Yann 0:ebd3a7cc9b92 519 // 2. Send I2C start + memory address
Yann 0:ebd3a7cc9b92 520 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 1, true) == 0) {
Yann 0:ebd3a7cc9b92 521 // wait(0.02);
Yann 0:ebd3a7cc9b92 522 // DEBUG("CMCP23017_I2C::readRegister: Write memory done")
Yann 0:ebd3a7cc9b92 523 // 2. Read data + I2C stop
Yann 0:ebd3a7cc9b92 524 int result = _i2cInstance->read(_slaveAddress, (char *)p_value, 1);
Yann 0:ebd3a7cc9b92 525 // wait(0.02);
Yann 0:ebd3a7cc9b92 526
Yann 0:ebd3a7cc9b92 527 // DEBUG_LEAVE("C24LCXX_I2C::readRegister (byte): %x", (bool)(result == 0))
Yann 0:ebd3a7cc9b92 528 return (bool)(result == 0);
Yann 0:ebd3a7cc9b92 529 }
Yann 0:ebd3a7cc9b92 530
Yann 0:ebd3a7cc9b92 531 // DEBUG_LEAVE("CMCP23017_I2C::readRegister false")
Yann 0:ebd3a7cc9b92 532 return false;
Yann 0:ebd3a7cc9b92 533 }
Yann 0:ebd3a7cc9b92 534
Yann 0:ebd3a7cc9b92 535 void CMCP23017_I2C::DumpRegisters() {
Yann 0:ebd3a7cc9b92 536
Yann 0:ebd3a7cc9b92 537 unsigned char value;
Yann 0:ebd3a7cc9b92 538 for (unsigned int registerId = 0; registerId < 0x16; registerId++) {
Yann 0:ebd3a7cc9b92 539 readRegister(registerId, &value);
Yann 0:ebd3a7cc9b92 540 DEBUG("CMCP23017_I2C::DumpRegisters: register[%d] = 0x%02x", registerId, value)
Yann 0:ebd3a7cc9b92 541 }
Yann 0:ebd3a7cc9b92 542 }
Yann 0:ebd3a7cc9b92 543
Yann 0:ebd3a7cc9b92 544 void CMCP23017_I2C::DumpRegister(unsigned int p_registerId) {
Yann 0:ebd3a7cc9b92 545
Yann 0:ebd3a7cc9b92 546 unsigned char value;
Yann 0:ebd3a7cc9b92 547 readRegister(p_registerId, &value);
Yann 0:ebd3a7cc9b92 548 DEBUG("CMCP23017_I2C::DumpRegister: register[%d] = 0x%02x", p_registerId, value)
Yann 0:ebd3a7cc9b92 549 }
Yann 0:ebd3a7cc9b92 550
Yann 0:ebd3a7cc9b92 551 } // End of namespace MCP23017_I2C