/* * batterygauge.cpp * Author: Jinsuk Seo * Date: Nov 8, 2012 */ #include #include #include #include #include #include #include #include #include "batterygauge.h" #include using namespace std; #define MAX_BUS 64 #define MODE_CONFIG 0x00 #define OPERATIONAL 0x10 #define STANDBY 0x00 #define CTRL_CONFIG 0x01 #define IO_LOW 0x0C #define IO_HIGH 0x0D #define CHARGE_LSB 0x02 #define CHARGE_MSB 0x03 #define COUNTER_LSB 0x04 #define COUNTER_MSB 0x05 #define CURRENT_LSB 0x06 #define CURRENT_MSB 0x07 #define VOLTAGE_LSB 0x08 #define VOLTAGE_MSB 0x09 #define TEMPERATURE_LSB 0x0A #define TEMPERATURE_MSB 0x0B batterygauge::batterygauge(int bus, int address) { I2CBus = bus; I2CAddress = address; //readFullSensorState(); } int batterygauge::readFullSensorState() { char namebuf[MAX_BUS]; snprintf(namebuf, sizeof(namebuf), "/dev/i2c-%d", I2CBus); int file; if ((file = open(namebuf, O_RDWR)) < 0){ cout << "Failed to open STC3100 on " << namebuf << " I2C Bus" << endl; return(1); } if (ioctl(file, I2C_SLAVE, I2CAddress) < 0){ cout << "I2C_SLAVE address " << I2CAddress << " failed..." << endl; return(2); } int numberBytes = BATTERYGAUGE_I2C_BUFFER; int bytesRead = read(file, this->dataBuffer, numberBytes); if (bytesRead == -1){ cout << "Failure to read Byte Stream in readFullSensorState()" << endl; } close(file); this->charge = convertcharge(CHARGE_MSB, CHARGE_LSB); this->current = convertcurrent(CURRENT_MSB, CURRENT_LSB); this->voltage = convertvoltage(VOLTAGE_MSB, VOLTAGE_LSB); this->temperature = converttemperature(TEMPERATURE_MSB, TEMPERATURE_LSB); return 0; } double batterygauge::convertcharge(int msb_reg_addr, int lsb_reg_addr) { short msb = 0x00 | dataBuffer[msb_reg_addr]; short lsb = 0x00 | dataBuffer[lsb_reg_addr]; short temp = (msb<<8) | lsb; double output = temp; output = 6.70 * output / 50; return output; } double batterygauge::convertcurrent(int msb_reg_addr, int lsb_reg_addr) { short temp = dataBuffer[msb_reg_addr]; temp = (temp<<8) | dataBuffer[lsb_reg_addr]; short signedbit = temp & (1 << 13); if (signedbit == 0) { // Positive temp &= ~(1 << 14); temp &= ~(1 << 15); } else { // Negative temp |= 1 << 14; temp |= 1 << 15; } double output = temp; output = 11.77 * output / 50; return output; } double batterygauge::convertvoltage(int msb_reg_addr, int lsb_reg_addr) { short temp = dataBuffer[msb_reg_addr]; temp = (temp<<8) | dataBuffer[lsb_reg_addr]; short signedbit = temp & (1 << 11); if (signedbit == 0) { // Positive temp &= 0x0FFF; } else { // Negative temp |= 0xF000; } double output = temp; output = 2.44 * output / 1000; return output; } double batterygauge::converttemperature(int msb_reg_addr, int lsb_reg_addr) { short temp = dataBuffer[msb_reg_addr]; temp = (temp<<8) | dataBuffer[lsb_reg_addr]; short signedbit = temp & (1 << 11); if (signedbit == 0) { // Positive temp &= 0x0FFF; } else { // Negative temp |= 0xF000; } double output = temp; output = 0.125 * output; return output; } int batterygauge::writeI2CDeviceByte(char address, char value) { char namebuf[MAX_BUS]; snprintf(namebuf, sizeof(namebuf), "/dev/i2c-%d", I2CBus); int file; if ((file = open(namebuf, O_RDWR)) < 0){ cout << "Failed to open batterygauge on " << namebuf << " I2C Bus" << endl; return(1); } if (ioctl(file, I2C_SLAVE, I2CAddress) < 0){ cout << "I2C_SLAVE address " << I2CAddress << " failed..." << endl; return(2); } char buffer[2]; buffer[0] = address; buffer[1] = value; if ( write(file, buffer, 2) != 2) { cout << "Failure to write values to I2C Device address." << endl; return(3); } close(file); return 0; } int batterygauge::setModeConfig(MODECONFIG mode) { int ret_value = 0; switch(mode) { case STAND_BY: { ret_value = writeI2CDeviceByte(MODE_CONFIG, STANDBY); break; } case OPERATE: { ret_value = writeI2CDeviceByte(MODE_CONFIG, OPERATIONAL); break; } case NOLOAD: { ret_value = writeI2CDeviceByte(CTRL_CONFIG, IO_HIGH); break; } case LOAD: { ret_value = writeI2CDeviceByte(CTRL_CONFIG, IO_LOW); break; } } return ret_value; } MODECONFIG batterygauge::getModeConfig() { this->readFullSensorState(); char temp = dataBuffer[MODE_CONFIG]; short mode = temp & (1 << 4); //cout << "The current mode config is: " << mode << endl; this->modeConfig = (MODECONFIG) mode; return this->modeConfig; }