Program Listing for File mcp23017.cpp
↰ Return to documentation for file (src/mcp23017.cpp
)
#include <cstdint>
#include "mcp23017/mcp23017.hh"
using iplo::MCP23017;
using iplo::MCP230XXStatus;
MCP23017::MCP23017(I2C& bus, std::uint8_t address) : MCP230XX(bus, address) {}
bool MCP23017::begin() {
_bus.selectDevice(_address);
if (!isConnected()) {
return false;
}
if (!writeRegister(MCP23017Registers::IOCR, 0b00100000)) {
return false;
}
if (!writeRegister(MCP23017Registers::PUR_A, 0xFF)) {
return false;
}
if (!writeRegister(MCP23017Registers::PUR_B, 0xFF)) {
return false;
}
return true;
}
bool MCP23017::isConnected() {
auto res = _bus.readByte();
if (res < 0) {
_error = I2C_ERROR;
return false;
}
_error = OK;
return true;
}
bool MCP23017::pinMode(std::uint8_t pin, PinMode mode) {
if (pin > 15) {
_error = PIN_ERROR;
return false;
}
if ((mode != PinMode::INPUT) && (mode != PinMode::INPUT_PULLUP) && (mode != PinMode::OUTPUT)) {
_error = VALUE_ERROR;
return false;
}
auto dataDirectionRegister = MCP23017Registers::DDR_A;
if (pin > 7) {
dataDirectionRegister = MCP23017Registers::DDR_B;
pin -= 8;
}
auto registerValue = readRegister(dataDirectionRegister);
if (_error != OK) {
return false;
}
if ((mode == PinMode::INPUT) || (mode == PinMode::INPUT_PULLUP)) {
registerValue |= 1 << pin;
} else {
registerValue &= ~(1 << pin);
}
writeRegister(dataDirectionRegister, registerValue);
if (_error != OK) {
return false;
}
return true;
}
bool MCP23017::digitalWrite(std::uint8_t pin, std::uint8_t value) {
if (pin > 15) {
_error = PIN_ERROR;
return false;
}
auto gpioRegister = MCP23017Registers::GPIO_A;
if (pin > 7) {
gpioRegister = MCP23017Registers::GPIO_B;
pin -= 8;
}
auto registerValue = readRegister(gpioRegister);
if (_error != OK) {
return false;
}
value ? registerValue |= 1 << pin : registerValue &= ~(1 << pin);
writeRegister(gpioRegister, registerValue);
if (_error != OK) {
return false;
}
return true;
}
std::uint8_t MCP23017::digitalRead(std::uint8_t pin) {
if (pin > 15) {
_error = PIN_ERROR;
return INVALID_READ;
}
auto gpioRegister = MCP23017Registers::GPIO_A;
if (pin > 7) {
gpioRegister = MCP23017Registers::GPIO_B;
pin -= 8;
}
auto registerValue = readRegister(gpioRegister);
if (_error != OK) {
return INVALID_READ;
}
return registerValue & 1 << pin ? 1 : 0;
}
bool MCP23017::setPolarity(std::uint8_t pin, bool reversed) {
if (pin > 15) {
_error = PIN_ERROR;
return false;
}
auto polarityRegister = MCP23017Registers::POL_A;
if (pin > 7) {
polarityRegister = MCP23017Registers::POL_B;
pin -= 8;
}
auto registerValue = readRegister(polarityRegister);
if (_error != OK) {
return false;
}
reversed ? registerValue |= 1 << pin : registerValue &= ~(1 << pin);
writeRegister(polarityRegister, registerValue);
if (_error != OK) {
return false;
}
return true;
}
bool MCP23017::getPolarity(std::uint8_t pin, bool& reversed) {
if (pin > 15) {
_error = PIN_ERROR;
return false;
}
auto polarityRegister = MCP23017Registers::POL_A;
if (pin > 7) {
polarityRegister = MCP23017Registers::POL_B;
pin -= 8;
}
const auto registerValue = readRegister(polarityRegister);
if (_error != OK) {
return false;
}
reversed = (registerValue & 1 << pin) > 0;
return true;
}
bool MCP23017::setPullUp(std::uint8_t pin, bool pullUp) {
if (pin > 15) {
_error = PIN_ERROR;
return false;
}
auto pullUpRegister = MCP23017Registers::PUR_A;
if (pin > 7) {
pullUpRegister = MCP23017Registers::PUR_B;
pin -= 8;
}
auto registerValue = readRegister(pullUpRegister);
if (_error != OK) {
return false;
}
pullUp ? registerValue |= 1 << pin : registerValue &= ~(1 << pin);
writeRegister(pullUpRegister, registerValue);
if (_error != OK) {
return false;
}
return true;
}
bool MCP23017::getPullUp(std::uint8_t pin, bool& pullUp) {
if (pin > 15) {
_error = PIN_ERROR;
return false;
}
auto pullUpRegister = MCP23017Registers::PUR_A;
if (pin > 7) {
pullUpRegister = MCP23017Registers::PUR_B;
pin -= 8;
}
const auto val = readRegister(pullUpRegister);
if (_error != OK) {
return false;
}
pullUp = (val & 1 << pin) > 0;
return true;
}
bool MCP23017::pinMode8(MCP23017Port port, std::uint8_t value) {
if (port == MCP23017Port::DDRA) {
return writeRegister(MCP23017Registers::DDR_A, value);
}
return writeRegister(MCP23017Registers::DDR_B, value);
}
bool MCP23017::digitalWrite8(MCP23017Port port, std::uint8_t value) {
if (port == MCP23017Port::DDRA) {
return writeRegister(MCP23017Registers::GPIO_A, value);
}
return writeRegister(MCP23017Registers::GPIO_B, value);
}
std::uint8_t MCP23017::digitalRead8(MCP23017Port port) {
if (port == MCP23017Port::DDRA) {
return readRegister(MCP23017Registers::GPIO_A);
}
return readRegister(MCP23017Registers::GPIO_B);
}
bool MCP23017::setPolarity8(MCP23017Port port, std::uint8_t mask) {
if (port == MCP23017Port::DDRA) {
return writeRegister(MCP23017Registers::POL_A, mask);
}
return writeRegister(MCP23017Registers::POL_B, mask);
}
bool MCP23017::getPolarity8(MCP23017Port port, std::uint8_t& mask) {
if (port == MCP23017Port::DDRA) {
mask = readRegister(MCP23017Registers::POL_A);
} else {
mask = readRegister(MCP23017Registers::POL_B);
}
return _error == OK;
}
bool MCP23017::setPullUp8(MCP23017Port port, std::uint8_t mask) {
if (port == MCP23017Port::DDRA) {
return writeRegister(MCP23017Registers::PUR_A, mask);
}
return writeRegister(MCP23017Registers::PUR_B, mask);
}
bool MCP23017::getPullUp8(MCP23017Port port, std::uint8_t& mask) {
if (port == MCP23017Port::DDRA) {
mask = readRegister(MCP23017Registers::PUR_A);
} else {
mask = readRegister(MCP23017Registers::PUR_B);
}
return _error == OK;
}
bool MCP23017::pinMode16(std::uint16_t value) {
if (!writeRegister(MCP23017Registers::DDR_A, value >> 8)) {
return false;
}
return writeRegister(MCP23017Registers::DDR_B, value & 0xFF);
}
bool MCP23017::digitalWrite16(std::uint16_t value) {
if (!writeRegister(MCP23017Registers::GPIO_A, value >> 8)) {
return false;
}
return writeRegister(MCP23017Registers::GPIO_B, value & 0xFF);
}
std::uint16_t MCP23017::digitalRead16() {
std::uint16_t value = readRegister(MCP23017Registers::GPIO_A);
value <<= 8;
value += readRegister(MCP23017Registers::GPIO_B);
return value;
}
bool MCP23017::setPolarity16(std::uint16_t mask) {
if (!writeRegister(MCP23017Registers::POL_A, mask >> 8)) {
return false;
}
return writeRegister(MCP23017Registers::POL_B, mask & 0xFF);
}
bool MCP23017::getPolarity16(std::uint16_t& mask) {
mask = readRegister(MCP23017Registers::POL_A);
mask <<= 8;
mask += readRegister(MCP23017Registers::POL_B);
return _error == OK;
}
bool MCP23017::setPullUp16(std::uint16_t mask) {
if (!writeRegister(MCP23017Registers::PUR_A, mask >> 8)) {
return false;
}
return writeRegister(MCP23017Registers::PUR_B, mask & 0xFF);
}
bool MCP23017::getPullUp16(std::uint16_t& mask) {
mask = readRegister(MCP23017Registers::PUR_A);
mask <<= 8;
mask += readRegister(MCP23017Registers::PUR_B);
return _error == OK;
}
std::uint16_t MCP23017::readAll() {
return digitalRead16();
}
std::uint8_t MCP23017::extractPinValue(std::uint16_t registerValue, std::uint8_t pin) {
return registerValue & 1 << pin ? 1 : 0;
}