Device driver for TCA9554A, which is I2C GPIO expander IC.
tca9554a.cpp
- Committer:
- coisme
- Date:
- 2016-05-26
- Revision:
- 2:0d772298e874
- Parent:
- 0:402147fa55f6
File content as of revision 2:0d772298e874:
#include "tca9554a.h" #define LEN_ONE_BYTE 1 #define LEN_TWO_BYTE 2 TCA9554A::TCA9554A(I2C *conn, SlaveAddress addr) { connection = conn; slaveAddress = addr; } TCA9554A::Status TCA9554A::read(RegisterAddress addr, uint8_t *buf) { char regAddr = (char)addr; // Sets the register address to be read. if (connection->write((slaveAddress << 1), ®Addr, LEN_ONE_BYTE) != 0) { return ERROR_I2C_WRITE; } // Reads the register value. char val = 0; if (connection->read(((slaveAddress << 1) | 0x01), &val, LEN_ONE_BYTE) != 0) { return ERROR_I2C_READ; } *buf = (uint8_t)val; return SUCCESS; } TCA9554A::Status TCA9554A::write(RegisterAddress addr, uint8_t val) { char buf[LEN_TWO_BYTE]; buf[0] = (char)addr; buf[1] = (char)val; // Writes to the devices. if (connection->write((slaveAddress << 1), buf, LEN_TWO_BYTE) != 0) { return ERROR_I2C_WRITE; } return SUCCESS; } TCA9554A::Status TCA9554A::configurePort(Port port, Direction dir, PolarityInversion pol) { Status status; uint8_t buf = 0; // Reads the current configuration register value. if ((status=read(REG_ADDR_CONFIG, &buf)) != SUCCESS) { return status; } // Modifies the specified bit. buf = (((~port) & buf) | dir); // Writes back to the configuration register. if ((status=write(REG_ADDR_CONFIG, buf)) != SUCCESS) { return status; } // Reads the current polarity inversion register value. if ((status=read(REG_ADDR_POLARITY, &buf)) != SUCCESS) { return status; } // Modifies the specified bit. buf = (((~port) & buf) | pol); // Writes back to the polarity inversion register. if ((status=write(REG_ADDR_POLARITY, buf)) != SUCCESS) { return status; } return status; } TCA9554A::Status TCA9554A::getPortLevel(LogicLevel *val, Port port) { Status status; uint8_t buf = 0; // Reads the input register if ((status=read(REG_ADDR_INPUT, &buf)) != SUCCESS) { return status; } *val = (((port & buf) > 0) ? HIGH : LOW); return status; } TCA9554A::Status TCA9554A::setPortLevel(Port port, LogicLevel val) { Status status; // Get the current register setting. uint8_t buf = 0; if ((status=read(REG_ADDR_OUTPUT, &buf)) != SUCCESS) { return status; } // Modify the specified bit by port. buf = ((buf & (~port) | (port * val))); // Write back the modified value to the register. if ((status=write(REG_ADDR_OUTPUT, buf)) != SUCCESS) { return status; } return status; } TCA9554A::Status TCA9554A::getPortDirection(Direction *dir, Port port) { Status status; // Get the current register setting. uint8_t buf = 0; if ((status=read(REG_ADDR_OUTPUT, &buf)) != SUCCESS) { return status; } // Gets the value of the specified port. *dir = ((buf & port) > 0) ? DIR_INPUT : DIR_OUTPUT; return status; }