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); }