Program Listing for File mcp23008.cpp

Return to documentation for file (src/mcp23008.cpp)

#include <cstdint>

#include "mcp23008/mcp23008.hh"

using iplo::MCP23008;
using iplo::MCP230XXStatus;

MCP23008::MCP23008(I2C& bus, std::uint8_t address) : MCP230XX(bus, address) {}

bool MCP23008::begin() {
    _bus.selectDevice(_address);

    if (!isConnected()) {
        return false;
    }
    if (!writeRegister(MCP23008Registers::IOCR, 0b00100000)) {
        return false;
    }
    if (!writeRegister(MCP23008Registers::PUR_A, 0xFF)) {
        return false;
    }

    return true;
}

bool MCP23008::isConnected() {
    auto res = _bus.readByte();
    if (res < 0) {
        _error = I2C_ERROR;
        return false;
    }

    _error = OK;
    return true;
}

bool MCP23008::pinMode(std::uint8_t pin, PinMode mode) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return false;
    }

    if ((mode != PinMode::INPUT) && (mode != PinMode::INPUT_PULLUP) && (mode != PinMode::OUTPUT)) {
        _error = VALUE_ERROR;
        return false;
    }

    auto registerValue = readRegister(MCP23008Registers::DDR_A);
    if (_error != OK) {
        return false;
    }

    if (mode == PinMode::INPUT || mode == PinMode::INPUT_PULLUP) {
        registerValue |= 1 << pin;
    } else {
        registerValue &= ~(1 << pin);
    }

    writeRegister(MCP23008Registers::DDR_A, registerValue);
    if (_error != OK) {
        return false;
    }

    return true;
}

bool MCP23008::digitalWrite(std::uint8_t pin, std::uint8_t value) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return false;
    }

    auto registerValue = readRegister(MCP23008Registers::GPIO_A);
    if (_error != OK) {
        return false;
    }

    value ? registerValue |= 1 << pin : registerValue &= ~(1 << pin);

    writeRegister(MCP23008Registers::GPIO_A, registerValue);
    if (_error != OK) {
        return false;
    }

    return true;
}

std::uint8_t MCP23008::digitalRead(std::uint8_t pin) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return INVALID_READ;
    }

    const auto registerValue = readRegister(MCP23008Registers::GPIO_A);
    if (_error != OK) {
        return INVALID_READ;
    }

    return registerValue & 1 << pin ? 1 : 0;
}

bool MCP23008::setPolarity(std::uint8_t pin, bool reversed) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return false;
    }

    auto registerValue = readRegister(MCP23008Registers::POL_A);
    if (_error != OK) {
        return false;
    }

    reversed ? registerValue |= 1 << pin : registerValue &= ~(1 << pin);

    writeRegister(MCP23008Registers::POL_A, registerValue);
    if (_error != OK) {
        return false;
    }

    return true;
}

bool MCP23008::getPolarity(std::uint8_t pin, bool& reversed) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return false;
    }

    const auto registerValue = readRegister(MCP23008Registers::POL_A);
    if (_error != OK) {
        return false;
    }

    reversed = (registerValue & 1 << pin) > 0;
    return true;
}

bool MCP23008::setPullUp(std::uint8_t pin, bool pullUp) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return false;
    }

    auto registerValue = readRegister(MCP23008Registers::PUR_A);
    if (_error != OK) {
        return false;
    }

    pullUp ? registerValue |= 1 << pin : registerValue &= ~(1 << pin);

    writeRegister(MCP23008Registers::PUR_A, registerValue);
    if (_error != OK) {
        return false;
    }

    return true;
}

bool MCP23008::getPullUp(std::uint8_t pin, bool& pullUp) {
    if (pin > 7) {
        _error = PIN_ERROR;
        return false;
    }

    const auto registerValue = readRegister(MCP23008Registers::PUR_A);
    if (_error != OK) {
        return false;
    }

    pullUp = (registerValue & 1 << pin) > 0;
    return true;
}

bool MCP23008::pinMode8(std::uint8_t value) {
    return writeRegister(MCP23008Registers::DDR_A, value);
}

bool MCP23008::digitalWrite8(std::uint8_t value) {
    return writeRegister(MCP23008Registers::GPIO_A, value);
}

std::uint8_t MCP23008::digitalRead8() {
    return readRegister(MCP23008Registers::GPIO_A);
}

bool MCP23008::setPolarity8(std::uint8_t mask) {
    return writeRegister(MCP23008Registers::POL_A, mask);
}

bool MCP23008::getPolarity8(std::uint8_t& mask) {
    mask = readRegister(MCP23008Registers::POL_A);
    return _error == OK;
}

bool MCP23008::setPullUp8(std::uint8_t mask) {
    return writeRegister(MCP23008Registers::PUR_A, mask);
}

bool MCP23008::getPullUp8(uint8_t& mask) {
    mask = readRegister(MCP23008Registers::PUR_A);
    return _error == OK;
}

std::uint16_t MCP23008::readAll() {
    return digitalRead8();
}

std::uint8_t MCP23008::extractPinValue(std::uint8_t registerValue, std::uint8_t pin) {
    return registerValue & 1 << pin ? 1 : 0;
}