LTC2942 interface with interrupt and battery register calculations
LTC294X.cpp
- Committer:
- kaushalpkk
- Date:
- 2019-08-08
- Revision:
- 1:547ec53dc37d
- Parent:
- 0:f9e13080204a
File content as of revision 1:547ec53dc37d:
#include "mbed.h"
#include "LTC294X.h"
LTC29421::LTC29421(PinName _a,PinName _b,PinName _c,void (*interruptFunc)()):
_i2c(_a, _b),_alcc(_c){
_i2c.frequency(400000);
_alcc.fall(interruptFunc);
_addr = 0xC8;
_battMax = 0x00;
_presc = 128;
DEBUG("WARNING! use setPrescAndBattCap() to set Battery Capacity\r\n");
}
LTC29421::LTC29421(PinName _a,PinName _b,PinName _c,void (*interruptFunc)(), float battCap):
_i2c(_a, _b),_alcc(_c){
_i2c.frequency(400000);
_alcc.fall(interruptFunc);
_addr = 0xC8;
setPrescAndBattCap(battCap);
}
void LTC29421::setPrescAndBattCap(float battcap){
_battCap = battcap;
float posM = (char)23*_battCap;
for(int i=0; i<8; i++){
if(pow(2,(float)i) >= posM){
_presc = pow(2,(float)i);
setPrescaler((int)_presc);
break;
}
}
DEBUG("Prescaler 'M' set to %d\r\n", (int)_presc);
_battMax = ((_battCap*1000)*128)/(_presc*0.085);
DEBUG("Battery capacity computed as %.2f Ah with bat max 0x%X \r\n", _battCap, (int)_battMax);
}
void LTC29421::setADCMode(int modeSel){
char ans = getControlReg();
switch(modeSel) {
case ADC_AUTO:
sbi(ans, ADC_VOLT_MODE);
sbi(ans, ADC_TEMP_MODE);
break;
case ADC_VOLT:
sbi(ans, ADC_VOLT_MODE);
cbi(ans, ADC_TEMP_MODE);
break;
case ADC_TEMP:
cbi(ans, ADC_VOLT_MODE);
sbi(ans, ADC_TEMP_MODE);
break;
case ADC_SLEEP:
cbi(ans, ADC_VOLT_MODE);
cbi(ans, ADC_TEMP_MODE);
break;
default:
break;
}
setControlReg(ans);
}
void LTC29421::setPrescaler(int val){
if(val <= 7) {
char ans = getControlReg();
if((val & 0x01) != 0) {
sbi(ans, PRESCALER_0);
} else {
cbi(ans, PRESCALER_0);
}
if((val & 0x02) != 0) {
sbi(ans, PRESCALER_1);
} else {
cbi(ans, PRESCALER_1);
}
if((val & 0x04) != 0) {
sbi(ans, PRESCALER_2);
} else {
cbi(ans, PRESCALER_2);
}
setControlReg(ans);
_presc = (float)getPrescaler();
} else {
}
}
int LTC29421::getPrescaler(){
char res = 0x00;
char ans = getControlReg();
if((ans & _BV(PRESCALER_0)) != 0) {
sbi(res, 0x00);
} else {
cbi(res, 0x00);
}
if((ans & _BV(PRESCALER_1)) != 0) {
sbi(res, 0x01);
} else {
cbi(res, 0x01);
}
if((ans & _BV(PRESCALER_2)) != 0) {
sbi(res, 0x02);
} else {
cbi(res, 0x02);
}
ans = getControlReg();
return (int)(pow(2,(float)ans));
}
void LTC29421::configALCC(int modeSel){
char ans = getControlReg();
switch(modeSel) {
case ALCC_ALERT:
sbi(ans, ALCC_ALERT_MODE);
cbi(ans, ALCC_CHRGC_MODE);
break;
case ALCC_CCOMP:
cbi(ans, ALCC_ALERT_MODE);
sbi(ans, ALCC_CHRGC_MODE);
break;
case ALCC_OFF:
cbi(ans, ALCC_ALERT_MODE);
cbi(ans, ALCC_CHRGC_MODE);
break;
default:
break;
}
setControlReg(ans);
}
void LTC29421::shutdown(){
char ans = 0x00;
ans = getControlReg();
sbi(ans,IC_SHUTDOWN);
setControlReg(ans);
}
void LTC29421::wake(){
char ans = 0x00;
ans = getControlReg();
cbi(ans,IC_SHUTDOWN);
setControlReg(ans);
}
int LTC29421::accumulatedChargeReg(){
char inn = ACC_MSB;
char outt[2];
_i2c.write( _addr, &inn, 1 , true);
_i2c.read( _addr, outt, 2 );
int accChg = (int)outt[0];
accChg = (accChg*256)+ outt[1];
return accChg;
}
float LTC29421::accumulatedCharge(){
int reg = accumulatedChargeReg();
float res = ((float)accumulatedChargeReg()/_battMax)*100;
return res;
}
void LTC29421::accumulatedChargeReg(int inp){
shutdown();
char cmd[3];
cmd[0] = ACC_MSB;
cmd[1] = (0xFF00 & inp) >> 8;
cmd[2] = (0x00FF & inp);
_i2c.write(_addr, cmd, 3, true);
wake();
}
void LTC29421::accumulatedCharge(float inp){
inp = (inp/100)*_battMax;
accumulatedChargeReg(inp);
}
void LTC29421::setChargeThresholdLow(float prect){
char cmd[3];
prect = (prect/100)*_battMax;
cmd[0] = CHRG_THL_MSB;
cmd[1] = (0xFF00 & (int)prect) >> 8;
cmd[2] = (0x00FF & (int)prect);
_i2c.write(_addr, cmd, 2, true);
}
void LTC29421::setChargeThresholdHigh(float prect){
char cmd[3];
prect = (prect/100)*_battMax;
cmd[0] = CHRG_THH_MSB;
cmd[1] = (0xFF00 & (int)prect) >> 8;
cmd[2] = (0x00FF & (int)prect);
_i2c.write(_addr, cmd, 2, true);
}
float LTC29421::voltage(){
char inn = VOLT_MSB;
char outt[2];
_i2c.write( _addr, &inn, 1 ,true );
_i2c.read( _addr, outt, 2 );
int vtemp = (int)outt[0];
vtemp = (vtemp*256)+ outt[1];
float vol = 6 * ((float)vtemp / 65535);
return vol;
}
void LTC29421::setVoltageThresholdLow(float inp){
char cmd[2];
int ans = (int)(inp *65535)/6;
ans = ans >> 8;
cmd[0] = VOLT_THL;
cmd[1] = (char)ans;
_i2c.write(_addr, cmd, 2, true);
}
void LTC29421::setVoltageThresholdHigh(float inp){
char cmd[2];
int ans = (int)(inp *65535)/6;
ans = ans >> 8;
cmd[0] = VOLT_THH;
cmd[1] = (char)ans;
_i2c.write(_addr, cmd, 2, true);
}
float LTC29421::temperature(){
char inn = TEMP_MSB;
char outt[2];
_i2c.write( _addr, &inn, 1 ,true );
_i2c.read( _addr, outt, 2 );
int ttemp = (int)outt[0];
ttemp = (ttemp*256)+ outt[1];
float tempp = (600 * ((float)ttemp / 65535)) - 273.15;
return tempp;
}
void LTC29421::setTemperatureThresholdLow(float inp){
int ans = (int)(((inp+273.15)*65535)/600);
ans = ans >> 8;
char cmd[2];
cmd[0] = TEMPERATURE_THL;
cmd[1] = ans;
_i2c.write(_addr, cmd, 2, true);
}
void LTC29421::setTemperatureThresholdHigh(float inp){
int ans = (int)(((inp+273.15)*65535)/600);
ans = ans >> 8;
char cmd[2];
cmd[0] = TEMPERATURE_THH;
cmd[1] = ans;
_i2c.write(_addr, cmd, 2, true);
}
void LTC29421::readAll(){
char cmd[16];
cmd[0] = REG_STATUS;
_i2c.write(_addr, cmd, 1, true);
_i2c.read(_addr, cmd, 16); // read the two-byte echo result
DEBUG("===================================================\r\n");
DEBUG("REG_STATUS [%X] \r\n",cmd[REG_STATUS]);
DEBUG("REG_CONTROL [%X] \r\n",cmd[REG_CONTROL]);
DEBUG("ACC_CHARGE [%X %X] \r\n",cmd[ACC_MSB],cmd[ACC_LSB]);
DEBUG("CHRG_THH [%X %X] \r\n",cmd[CHRG_THH_MSB],cmd[CHRG_THH_LSB]);
DEBUG("CHRG_THL [%X %X] \r\n",cmd[CHRG_THL_MSB],cmd[CHRG_THL_LSB]);
DEBUG("VOLTAGE [%X %X] \r\n",cmd[VOLT_MSB],cmd[VOLT_LSB]);
DEBUG("VOLT_THH [%X] \r\n",cmd[VOLT_THH]);
DEBUG("VOLT_THL [%X] \r\n",cmd[VOLT_THL]);
DEBUG("TEMPERATURE [%X %X] \r\n",cmd[TEMP_MSB],cmd[TEMP_LSB]);
DEBUG("TEMPERATURE_THH [%X] \r\n",cmd[TEMPERATURE_THH]);
DEBUG("TEMPERATURE_THL [%X] \r\n",cmd[TEMPERATURE_THL]);
DEBUG("===================================================\r\n");
DEBUG("\r\n");
}
int LTC29421::alertResponse(){
char reg = getStatusReg();
char ans;
char cmd= 0x19;
_i2c.read(cmd, &ans, 1);
if(ans == 0xC8){
DEBUG("alert = %x, reg = %x\r\n", ans,reg);
return reg;
}else
return -1;
}
char LTC29421::getControlReg()
{
char cmd;
char ans;
cmd= REG_CONTROL;
_i2c.write(_addr, &cmd, 1, true);
_i2c.read(_addr, &ans, 1);
return ans;
}
char LTC29421::getStatusReg()
{
char cmd;
char ans;
cmd= REG_STATUS;
_i2c.write(_addr, &cmd, 1, true);
_i2c.read(_addr, &ans, 1);
return ans;
}
void LTC29421::setControlReg(char inp)
{
char cmd[2];
cmd[0] = REG_CONTROL;
cmd[1] = inp;
_i2c.write(_addr, cmd, 2, true);
}