diff --git a/src/MCP23017.cpp b/src/MCP23017.cpp index edd69cd..bb7d56a 100644 --- a/src/MCP23017.cpp +++ b/src/MCP23017.cpp @@ -12,7 +12,7 @@ MCP23017::MCP23017(TwoWire& bus) { MCP23017::~MCP23017() {} -void MCP23017::init() +bool MCP23017::init() { //BANK = 0 : sequential register addresses //MIRROR = 0 : use configureInterrupt @@ -24,31 +24,34 @@ void MCP23017::init() //INTPOL = 0 : interrupt active low //UNIMPLMENTED 0 : unimplemented: Read as ‘0’ - writeRegister(MCP23017Register::IOCON, 0b00100000); + bool retval = writeRegister(MCP23017Register::IOCON, 0b00100000); //enable all pull up resistors (will be effective for input pins only) - writeRegister(MCP23017Register::GPPU_A, 0xFF, 0xFF); + retval &= writeRegister(MCP23017Register::GPPU_A, 0xFF, 0xFF); + + return retval; } -void MCP23017::begin() +bool MCP23017::begin() { - init(); + return init(); } -void MCP23017::begin(uint8_t address) +bool MCP23017::begin(uint8_t address) { _deviceAddr = address; - begin(); + return begin(); } -void MCP23017::portMode(MCP23017Port port, uint8_t directions, uint8_t pullups, uint8_t inverted) +bool MCP23017::portMode(MCP23017Port port, uint8_t directions, uint8_t pullups, uint8_t inverted) { - writeRegister(MCP23017Register::IODIR_A + port, directions); - writeRegister(MCP23017Register::GPPU_A + port, pullups); - writeRegister(MCP23017Register::IPOL_A + port, inverted); + bool retVal = writeRegister(MCP23017Register::IODIR_A + port, directions); + retVal &= writeRegister(MCP23017Register::GPPU_A + port, pullups); + retVal &= writeRegister(MCP23017Register::IPOL_A + port, inverted); + return retVal; } -void MCP23017::pinMode(uint8_t pin, uint8_t mode, bool inverted) +bool MCP23017::pinMode(uint8_t pin, uint8_t mode, bool inverted) { MCP23017Register iodirreg = MCP23017Register::IODIR_A; MCP23017Register pullupreg = MCP23017Register::GPPU_A; @@ -75,12 +78,13 @@ void MCP23017::pinMode(uint8_t pin, uint8_t mode, bool inverted) if(inverted) bitSet(pol, pin); else bitClear(pol, pin); - writeRegister(iodirreg, iodir); - writeRegister(pullupreg, pull); - writeRegister(polreg, pol); + bool retVal = writeRegister(iodirreg, iodir); + retVal &= writeRegister(pullupreg, pull); + retVal &= writeRegister(polreg, pol); + return retVal; } -void MCP23017::digitalWrite(uint8_t pin, uint8_t state) +bool MCP23017::digitalWrite(uint8_t pin, uint8_t state) { MCP23017Register gpioreg = MCP23017Register::GPIO_A; uint8_t gpio; @@ -94,7 +98,7 @@ void MCP23017::digitalWrite(uint8_t pin, uint8_t state) if(state == HIGH) bitSet(gpio, pin); else bitClear(gpio, pin); - writeRegister(gpioreg, gpio); + return writeRegister(gpioreg, gpio); } uint8_t MCP23017::digitalRead(uint8_t pin) @@ -112,14 +116,14 @@ uint8_t MCP23017::digitalRead(uint8_t pin) return LOW; } -void MCP23017::writePort(MCP23017Port port, uint8_t value) +bool MCP23017::writePort(MCP23017Port port, uint8_t value) { - writeRegister(MCP23017Register::GPIO_A + port, value); + return writeRegister(MCP23017Register::GPIO_A + port, value); } -void MCP23017::write(uint16_t value) +bool MCP23017::write(uint16_t value) { - writeRegister(MCP23017Register::GPIO_A, lowByte(value), highByte(value)); + return writeRegister(MCP23017Register::GPIO_A, lowByte(value), highByte(value)); } uint8_t MCP23017::readPort(MCP23017Port port) @@ -135,21 +139,23 @@ uint16_t MCP23017::read() return a | b << 8; } -void MCP23017::writeRegister(MCP23017Register reg, uint8_t value) +bool MCP23017::writeRegister(MCP23017Register reg, uint8_t value) { _bus->beginTransmission(_deviceAddr); _bus->write(static_cast(reg)); _bus->write(value); - _bus->endTransmission(); + uint8_t retval = _bus->endTransmission(); + return !retval; } -void MCP23017::writeRegister(MCP23017Register reg, uint8_t portA, uint8_t portB) +bool MCP23017::writeRegister(MCP23017Register reg, uint8_t portA, uint8_t portB) { _bus->beginTransmission(_deviceAddr); _bus->write(static_cast(reg)); _bus->write(portA); _bus->write(portB); - _bus->endTransmission(); + uint8_t retval = _bus->endTransmission(); + return !retval; } @@ -157,77 +163,79 @@ uint8_t MCP23017::readRegister(MCP23017Register reg) { _bus->beginTransmission(_deviceAddr); _bus->write(static_cast(reg)); - _bus->endTransmission(); - _bus->requestFrom(_deviceAddr, (uint8_t)1); + uint8_t retval = _bus->endTransmission(); + retval &= _bus->requestFrom(_deviceAddr, (uint8_t)1); return _bus->read(); } -void MCP23017::readRegister(MCP23017Register reg, uint8_t& portA, uint8_t& portB) +bool MCP23017::readRegister(MCP23017Register reg, uint8_t& portA, uint8_t& portB) { _bus->beginTransmission(_deviceAddr); _bus->write(static_cast(reg)); - _bus->endTransmission(); - _bus->requestFrom(_deviceAddr, (uint8_t)2); + uint8_t retval = _bus->endTransmission(); + retval &= _bus->requestFrom(_deviceAddr, (uint8_t)2); portA = _bus->read(); portB = _bus->read(); + return !retval; } #ifdef _MCP23017_INTERRUPT_SUPPORT_ -void MCP23017::interruptMode(MCP23017InterruptMode intMode) +bool MCP23017::interruptMode(MCP23017InterruptMode intMode) { uint8_t iocon = readRegister(MCP23017Register::IOCON); if(intMode == MCP23017InterruptMode::Or) iocon |= static_cast(MCP23017InterruptMode::Or); else iocon &= ~(static_cast(MCP23017InterruptMode::Or)); - writeRegister(MCP23017Register::IOCON, iocon); + return writeRegister(MCP23017Register::IOCON, iocon); } -void MCP23017::interrupt(MCP23017Port port, uint8_t mode) +bool MCP23017::interrupt(MCP23017Port port, uint8_t mode) { MCP23017Register defvalreg = MCP23017Register::DEFVAL_A + port; MCP23017Register intconreg = MCP23017Register::INTCON_A + port; //enable interrupt for port - writeRegister(MCP23017Register::GPINTEN_A + port, 0xFF); + bool retVal = writeRegister(MCP23017Register::GPINTEN_A + port, 0xFF); switch(mode) { case CHANGE: //interrupt on change - writeRegister(intconreg, 0); + retVal &= writeRegister(intconreg, 0); break; case FALLING: //interrupt falling : compared against defval, 0xff - writeRegister(intconreg, 0xFF); - writeRegister(defvalreg, 0xFF); + retVal &= writeRegister(intconreg, 0xFF); + retVal &= writeRegister(defvalreg, 0xFF); break; case RISING: //interrupt rising : compared against defval, 0x00 - writeRegister(intconreg, 0xFF); - writeRegister(defvalreg, 0x00); + retVal &= writeRegister(intconreg, 0xFF); + retVal &= writeRegister(defvalreg, 0x00); break; } + return retVal; } -void MCP23017::interruptedBy(uint8_t& portA, uint8_t& portB) +bool MCP23017::interruptedBy(uint8_t& portA, uint8_t& portB) { - readRegister(MCP23017Register::INTF_A, portA, portB); + return readRegister(MCP23017Register::INTF_A, portA, portB); } -void MCP23017::disableInterrupt(MCP23017Port port) +bool MCP23017::disableInterrupt(MCP23017Port port) { - writeRegister(MCP23017Register::GPINTEN_A + port, 0x00); + return writeRegister(MCP23017Register::GPINTEN_A + port, 0x00); } -void MCP23017::clearInterrupts() +bool MCP23017::clearInterrupts() { uint8_t a, b; - clearInterrupts(a, b); + return clearInterrupts(a, b); } -void MCP23017::clearInterrupts(uint8_t& portA, uint8_t& portB) +bool MCP23017::clearInterrupts(uint8_t& portA, uint8_t& portB) { - readRegister(MCP23017Register::INTCAP_A, portA, portB); + return readRegister(MCP23017Register::INTCAP_A, portA, portB); } #endif diff --git a/src/MCP23017.h b/src/MCP23017.h index b66df22..443f6fb 100644 --- a/src/MCP23017.h +++ b/src/MCP23017.h @@ -100,12 +100,12 @@ class MCP23017 /** * Uses the I2C address set during construction. Implicitly calls init(). */ - void begin(); + bool begin(); /** * Overrides the I2C address set by the constructor. Implicitly calls begin(). */ - void begin(uint8_t address); + bool begin(uint8_t address); /** * Initializes the chip with the default configuration. * Enables Byte mode (IOCON.BANK = 0 and IOCON.SEQOP = 1). @@ -113,7 +113,7 @@ class MCP23017 * * See "3.2.1 Byte mode and Sequential mode". */ - void init(); + bool init(); /** * Controls the pins direction on a whole port at once. * @@ -122,7 +122,7 @@ class MCP23017 * * See "3.5.1 I/O Direction register". */ - void portMode(MCP23017Port port, uint8_t directions, uint8_t pullups = 0xFF, uint8_t inverted = 0x00); + bool portMode(MCP23017Port port, uint8_t directions, uint8_t pullups = 0xFF, uint8_t inverted = 0x00); /** * Controls a single pin direction. * Pin 0-7 for port A, 8-15 fo port B. @@ -138,7 +138,7 @@ class MCP23017 * This library pinMode function behaves like Arduino's standard pinMode for consistency. * [ OUTPUT | INPUT | INPUT_PULLUP ] */ - void pinMode(uint8_t pin, uint8_t mode, bool inverted = false); + bool pinMode(uint8_t pin, uint8_t mode, bool inverted = false); /** * Writes a single pin state. @@ -149,7 +149,7 @@ class MCP23017 * * See "3.5.10 Port register". */ - void digitalWrite(uint8_t pin, uint8_t state); + bool digitalWrite(uint8_t pin, uint8_t state); /** * Reads a single pin state. * Pin 0-7 for port A, 8-15 for port B. @@ -169,7 +169,7 @@ class MCP23017 * * See "3.5.10 Port register". */ - void writePort(MCP23017Port port, uint8_t value); + bool writePort(MCP23017Port port, uint8_t value); /** * Writes pins state to both ports. * @@ -178,7 +178,7 @@ class MCP23017 * * See "3.5.10 Port register". */ - void write(uint16_t value); + bool write(uint16_t value); /** * Reads pins state for a whole port. @@ -202,7 +202,7 @@ class MCP23017 /** * Writes a single register value. */ - void writeRegister(MCP23017Register reg, uint8_t value); + bool writeRegister(MCP23017Register reg, uint8_t value); /** * Writes values to a register pair. * @@ -210,7 +210,7 @@ class MCP23017 * you have to supply a portA register address to reg. Otherwise, values * will be reversed due to the way the MCP23017 works in Byte mode. */ - void writeRegister(MCP23017Register reg, uint8_t portA, uint8_t portB); + bool writeRegister(MCP23017Register reg, uint8_t portA, uint8_t portB); /** * Reads a single register value. */ @@ -222,7 +222,7 @@ class MCP23017 * you have to supply a portA register address to reg. Otherwise, values * will be reversed due to the way the MCP23017 works in Byte mode. */ - void readRegister(MCP23017Register reg, uint8_t& portA, uint8_t& portB); + bool readRegister(MCP23017Register reg, uint8_t& portA, uint8_t& portB); #ifdef _MCP23017_INTERRUPT_SUPPORT_ @@ -234,28 +234,28 @@ class MCP23017 * Controls the IOCON.MIRROR bit. * See "3.5.6 Configuration register". */ - void interruptMode(MCP23017InterruptMode intMode); + bool interruptMode(MCP23017InterruptMode intMode); /** * Configures interrupt registers using an Arduino-like API. * mode can be one of CHANGE, FALLING or RISING. */ - void interrupt(MCP23017Port port, uint8_t mode); + bool interrupt(MCP23017Port port, uint8_t mode); /** * Disable interrupts for the specified port. */ - void disableInterrupt(MCP23017Port port); + bool disableInterrupt(MCP23017Port port); /** * Reads which pin caused the interrupt. */ - void interruptedBy(uint8_t& portA, uint8_t& portB); + bool interruptedBy(uint8_t& portA, uint8_t& portB); /** * Clears interrupts on both ports. */ - void clearInterrupts(); + bool clearInterrupts(); /** * Clear interrupts on both ports. Returns port values at the time the interrupt occured. */ - void clearInterrupts(uint8_t& portA, uint8_t& portB); + bool clearInterrupts(uint8_t& portA, uint8_t& portB); #endif };