This library provides simplified I2C access to a Microchip MCP23x17 GPIO expender device, including a general interface for any GPIO expender
Diff: MCP23017_I2C.cpp
- Revision:
- 2:3bea48e1505c
- Parent:
- 1:ec9e770173d5
- Child:
- 3:b902729a1675
--- a/MCP23017_I2C.cpp Fri Jan 09 15:35:40 2015 +0000
+++ b/MCP23017_I2C.cpp Tue Jan 13 10:09:01 2015 +0000
@@ -71,7 +71,7 @@
if (p_intA != NC) {
DEBUG("CMCP23017_I2C: INTA managed");
_intA = new InterruptIn(p_intA);
- if (p_internalPullUp) _intA->mode(PullDown);
+ if (p_internalPullUp) _intA->mode(::PullDown);
_intA->enable_irq(); // Enable interrupt
} else {
DEBUG("CMCP23017_I2C: INTA not managed");
@@ -80,7 +80,7 @@
if (p_intB != NC) {
DEBUG("CMCP23017_I2C: INTB managed");
_intB = new InterruptIn(p_intB);
- if (p_internalPullUp) _intB->mode(PullDown);
+ if (p_internalPullUp) _intB->mode(::PullDown);
_intB->enable_irq(); // Enable interrupt
} else {
DEBUG("CMCP23017_I2C: INTB not managed");
@@ -272,27 +272,33 @@
int CMCP23017_I2C::setupInterruptPin(const unsigned char p_gpioId, const InterruptModes p_mode) {
DEBUG_ENTER("CMCP23017_I2C::setupInterruptPin: %02x, %02x", p_gpioId, p_mode)
- // Retrive the register address
+ // Retrieve the register address
unsigned char gpioIntconId, gpioDefvalId, gpioGpintenId;
if (!registerIdFromGpioId(p_gpioId, &gpioIntconId)) {
DEBUG_LEAVE("CMCP23017_I2C::setupInterruptPin: -1")
return -1;
}
+ unsigned char gpioFlags;
if (gpioIntconId == GPIOA) {
gpioIntconId = INTCONA;
gpioDefvalId = DEFVALA;
gpioGpintenId = GPINTENA;
+ gpioFlags = _gpioAFlags;
} else {
gpioIntconId = INTCONB;
gpioDefvalId = DEFVALB;
gpioGpintenId = GPINTENB;
+ gpioFlags = _gpioBFlags;
}
- DEBUG("CMCP23017_I2C::setupInterruptPin: gpioIntconId=%02x gpioDefvalId=%02x gpioGpintenId=%02x", gpioIntconId, gpioDefvalId, gpioGpintenId)
+ DEBUG("CMCP23017_I2C::setupInterruptPin: gpioIntconId=%02x gpioDefvalId=%02x gpioGpintenId=%02x gpioFlags=%02x", gpioIntconId, gpioDefvalId, gpioGpintenId, gpioFlags)
- // Retrive the GPIO pin number
+ // Retrieve the GPIO pin number
unsigned char gpioBit = gpioBitFromGpioId(p_gpioId);
DEBUG("CMCP23017_I2C::setupInterruptPin: gpioBit=%02x", gpioBit)
-
+ if (!isBitEqual(gpioFlags, gpioBit, 0x01)) { // Port pin is not configure as input
+ DEBUG_LEAVE("CMCP23017_I2C::setupPullPin: -1")
+ return -1;
+ }
// Read it
unsigned char gpioIntconValue, gpioDefvalValue, gpioGpintenValue;
if (!readRegister(gpioIntconId, &gpioIntconValue)) {
@@ -338,8 +344,65 @@
return 0;
}
- int CMCP23017_I2C::getLastInterruptPin(unsigned char * p_gpioId, unsigned char * p_value) {
- DEBUG_ENTER("CMCP23017_I2C::getLastInterruptPin")
+ int CMCP23017_I2C::setupPullPin(const unsigned char p_gpioId, const PullModes p_mode) {
+ DEBUG_ENTER("CMCP23017_I2C::setupPullPin: %02x, %02x", p_gpioId, p_mode)
+
+ // Retrieve the register address
+ unsigned char gpioGppuId;
+ if (!registerIdFromGpioId(p_gpioId, &gpioGppuId)) {
+ DEBUG_LEAVE("CMCP23017_I2C::setupPullPin: -1")
+ return -1;
+ }
+ unsigned char gpioFlags;
+ if (gpioGppuId == GPIOA) {
+ gpioGppuId = GPPUA;
+ gpioFlags = _gpioAFlags;
+ } else {
+ gpioGppuId = GPPUB;
+ gpioFlags = _gpioBFlags;
+ }
+ DEBUG("CMCP23017_I2C::setupPullPin: gpioGppuId=%02x gpioFlags=%02x", gpioGppuId, gpioFlags)
+
+ // Retrieve the GPIO pin number
+ unsigned char gpioBit = gpioBitFromGpioId(p_gpioId);
+ DEBUG("CMCP23017_I2C::setupPullPin: gpioBit=%02x", gpioBit)
+ if (!isBitEqual(gpioFlags, gpioBit, 0x01)) { // Port pin is not configure as input
+ DEBUG_LEAVE("CMCP23017_I2C::setupPullPin: -1")
+ return -1;
+ }
+
+ // Read it
+ unsigned char gpioGppuValue;
+ if (!readRegister(gpioGppuId, &gpioGppuValue)) {
+ DEBUG_LEAVE("CMCP23017_I2C::setupPullPin: -2")
+ return -2;
+ }
+ DEBUG("CMCP23017_I2C::setupPullPin: gpioGppuId=%02x", gpioGppuId)
+
+ //
+ switch (static_cast<unsigned char>(p_mode)) {
+ case static_cast<unsigned char>(AbstractGpioExpender::PullOff):
+ gpioGppuValue = setBit(gpioGppuValue, gpioBit, 0x00);
+ break;
+ case static_cast<unsigned char>(AbstractGpioExpender::PullUp):
+ gpioGppuValue = setBit(gpioGppuValue, gpioBit, 0x01);
+ break;
+ case static_cast<unsigned char>(AbstractGpioExpender::PullDown):
+ // Not supporte, nothing to do
+ break;
+ } // End of 'switch' statement
+
+ // Write register
+ DEBUG("CMCP23017_I2C::setupPullPin: gpioGppuValue=%02x", gpioGppuValue)
+ writeRegister(gpioGppuId, gpioGppuValue);
+
+
+ DEBUG_LEAVE("CMCP23017_I2C::setupPullPin: 0")
+ return 0;
+ }
+
+ int CMCP23017_I2C::getLastInterruptPinAndValue(unsigned char * p_gpioId, unsigned char * p_value) {
+ DEBUG_ENTER("CMCP23017_I2C::getLastInterruptPinAndValue")
// Read first INTFA if required
unsigned char vregister;
@@ -355,7 +418,7 @@
readRegister(INTCAPA, p_value);
*p_value = (*p_value >> bit) & 0x01;
- DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPin (A): %02x %02x", *p_gpioId, *p_value)
+ DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPinAndValue (A): %02x %02x", *p_gpioId, *p_value)
return 0;
}
} // End of 'for' statement
@@ -374,20 +437,20 @@
readRegister(INTCAPB, p_value);
*p_value = (*p_value >> bit) & 0x01;
- DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPin (B): %02x %02x", *p_gpioId, *p_value)
+ DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPinAndValue (B): %02x %02x", *p_gpioId, *p_value)
return 0;
}
} // End of 'for' statement
}
- DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPin: 0")
+ DEBUG_LEAVE("CMCP23017_I2C::getLastInterruptPinAndValue: 0")
return 0;
}
int CMCP23017_I2C::read(const unsigned char p_gpioId, unsigned char * p_value) {
DEBUG_ENTER("CMCP23017_I2C::read: 0x%02x", p_gpioId)
- // Retrive the register address
+ // Retrieve the register address
unsigned char gpioRegisterId;
if (!registerIdFromGpioId(p_gpioId, &gpioRegisterId)) {
DEBUG_LEAVE("CMCP23017_I2C::read: -1")
@@ -430,7 +493,7 @@
int CMCP23017_I2C::write(const unsigned char p_gpioId, const unsigned char p_value) {
DEBUG_ENTER("CMCP23017_I2C::write: 0x%02x 0x%02x", p_gpioId, p_value)
- // Retrive the register address
+ // Retrieve the register address
unsigned char gpioRegisterId;
if (!registerIdFromGpioId(p_gpioId, &gpioRegisterId)) {
DEBUG_LEAVE("CMCP23017_I2C::write: -1")
@@ -438,7 +501,7 @@
}
DEBUG("CMCP23017_I2C::write: gpioRegisterId=%02x", gpioRegisterId)
- // Retrive the GPIO pin number
+ // Retrieve the GPIO pin number
unsigned char gpioBit = gpioBitFromGpioId(p_gpioId);
DEBUG("CMCP23017_I2C::write: gpioBit=%02x", gpioBit)
@@ -484,12 +547,16 @@
}
int CMCP23017_I2C::busRead(const unsigned char p_busId, unsigned short * p_value) {
+// DEBUG_ENTER("CMCP23017_I2C::busRead: 0x%02x", p_busId)
+
// Sanity checks
if (_buses.size() == 0) {
+ DEBUG_LEAVE("CMCP23017_I2C::busRead: -1")
return -1;
}
std::map<unsigned char, std::list<unsigned char> >::iterator result = _buses.find(p_busId);
if (result == _buses.end()) { // Invalid bus identifier
+ DEBUG_LEAVE("CMCP23017_I2C::busRead: -1")
return -1;
}
@@ -503,16 +570,20 @@
}
} // End of 'for' statement
+// DEBUG_LEAVE("CMCP23017_I2C::busRead: 0")
return 0;
}
int CMCP23017_I2C::busWrite(const unsigned char p_busId, const unsigned short p_value) {
+// DEBUG_ENTER("CMCP23017_I2C::busWrite: 0x%02x - 0x%02x", p_busId, p_value)
+
// Sanity checks
if (_buses.size() == 0) {
return -1;
}
std::map<unsigned char, std::list<unsigned char> >::iterator result = _buses.find(p_busId);
if (result == _buses.end()) { // Invalid bus identifier
+ DEBUG_LEAVE("CMCP23017_I2C::busWrite: -1")
return -1;
}
@@ -523,6 +594,7 @@
value >>= 1;
} // End of 'for' statement
+// DEBUG_LEAVE("CMCP23017_I2C::busWrite: 0")
return 0;
}
Yann Garcia