LTC2942 interface with interrupt and battery register calculations

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LTC294X.cpp Source File

LTC294X.cpp

00001 #include "mbed.h"
00002 #include "LTC294X.h"
00003 
00004 LTC29421::LTC29421(PinName _a,PinName _b,PinName _c,void (*interruptFunc)()):
00005     _i2c(_a, _b),_alcc(_c){
00006 
00007     _i2c.frequency(400000);
00008     _alcc.fall(interruptFunc);
00009     _addr = 0xC8;
00010     _battMax = 0x00;
00011     _presc = 128;
00012     DEBUG("WARNING! use setPrescAndBattCap() to set Battery Capacity\r\n");
00013 
00014 }
00015 
00016 LTC29421::LTC29421(PinName _a,PinName _b,PinName _c,void (*interruptFunc)(), float battCap):
00017     _i2c(_a, _b),_alcc(_c){
00018 
00019     _i2c.frequency(400000);
00020     _alcc.fall(interruptFunc);
00021     _addr = 0xC8;
00022     
00023     setPrescAndBattCap(battCap);
00024 }
00025 
00026 void LTC29421::setPrescAndBattCap(float battcap){
00027     _battCap = battcap;
00028     float posM = (char)23*_battCap;
00029     for(int i=0; i<8; i++){
00030         if(pow(2,(float)i) >= posM){
00031             _presc = pow(2,(float)i);
00032             setPrescaler((int)_presc);
00033             break;
00034         }
00035     } 
00036     DEBUG("Prescaler 'M' set to %d\r\n", (int)_presc);
00037     _battMax = ((_battCap*1000)*128)/(_presc*0.085);
00038     DEBUG("Battery capacity computed as %.2f Ah with bat max 0x%X  \r\n", _battCap, (int)_battMax);    
00039 }
00040 
00041 
00042 void LTC29421::setADCMode(int modeSel){
00043     char ans = getControlReg();
00044 
00045     switch(modeSel) {
00046         case ADC_AUTO:
00047             sbi(ans, ADC_VOLT_MODE);
00048             sbi(ans, ADC_TEMP_MODE);
00049             break;
00050         case ADC_VOLT:
00051             sbi(ans, ADC_VOLT_MODE);
00052             cbi(ans, ADC_TEMP_MODE);
00053             break;
00054         case ADC_TEMP:
00055             cbi(ans, ADC_VOLT_MODE);
00056             sbi(ans, ADC_TEMP_MODE);
00057             break;
00058         case ADC_SLEEP:
00059             cbi(ans, ADC_VOLT_MODE);
00060             cbi(ans, ADC_TEMP_MODE);
00061             break;
00062         default:
00063 
00064             break;
00065     }
00066     setControlReg(ans);
00067 }
00068 
00069 void LTC29421::setPrescaler(int val){
00070     if(val <= 7) {
00071         char ans = getControlReg();
00072 
00073         if((val & 0x01) != 0) {
00074             sbi(ans, PRESCALER_0);
00075         } else {
00076             cbi(ans, PRESCALER_0);
00077         }
00078         if((val & 0x02) != 0) {
00079             sbi(ans, PRESCALER_1);
00080         } else {
00081             cbi(ans, PRESCALER_1);
00082         }
00083         if((val & 0x04) != 0) {
00084             sbi(ans, PRESCALER_2);
00085         } else {
00086             cbi(ans, PRESCALER_2);
00087         }
00088         setControlReg(ans);
00089 
00090         _presc = (float)getPrescaler();
00091 
00092     } else {
00093 
00094     }
00095 }
00096 
00097 int LTC29421::getPrescaler(){
00098     char res = 0x00;
00099     char ans = getControlReg();
00100 
00101     if((ans & _BV(PRESCALER_0)) != 0) {
00102         sbi(res, 0x00);
00103     } else {
00104         cbi(res, 0x00);
00105     }
00106     if((ans & _BV(PRESCALER_1)) != 0) {
00107         sbi(res, 0x01);
00108     } else {
00109         cbi(res, 0x01);
00110     }
00111     if((ans & _BV(PRESCALER_2)) != 0) {
00112         sbi(res, 0x02);
00113     } else {
00114         cbi(res, 0x02);
00115     }
00116     ans = getControlReg();
00117     return (int)(pow(2,(float)ans));
00118 
00119 }
00120 
00121 void LTC29421::configALCC(int modeSel){
00122     char ans = getControlReg();
00123 
00124     switch(modeSel) {
00125         case ALCC_ALERT:
00126             sbi(ans, ALCC_ALERT_MODE);
00127             cbi(ans, ALCC_CHRGC_MODE);
00128             break;
00129         case ALCC_CCOMP:
00130             cbi(ans, ALCC_ALERT_MODE);
00131             sbi(ans, ALCC_CHRGC_MODE);
00132             break;
00133         case ALCC_OFF:
00134             cbi(ans, ALCC_ALERT_MODE);
00135             cbi(ans, ALCC_CHRGC_MODE);
00136             break;
00137         default:
00138 
00139             break;
00140     }
00141     setControlReg(ans);
00142 }
00143 
00144 void LTC29421::shutdown(){
00145     char ans = 0x00;
00146     ans = getControlReg();
00147     sbi(ans,IC_SHUTDOWN);
00148     setControlReg(ans);
00149 }
00150 
00151 void LTC29421::wake(){
00152     char ans = 0x00;
00153     ans = getControlReg();
00154     cbi(ans,IC_SHUTDOWN);
00155     setControlReg(ans);
00156 }
00157 
00158 int LTC29421::accumulatedChargeReg(){
00159     char inn = ACC_MSB;
00160     char outt[2];
00161     _i2c.write( _addr, &inn, 1 , true);
00162     _i2c.read( _addr, outt, 2 );
00163     int accChg = (int)outt[0];
00164     accChg = (accChg*256)+ outt[1];
00165     return accChg;
00166 }
00167 
00168 float LTC29421::accumulatedCharge(){
00169     int reg = accumulatedChargeReg();
00170     float res = ((float)accumulatedChargeReg()/_battMax)*100;
00171     return res;
00172 }
00173 
00174 void LTC29421::accumulatedChargeReg(int inp){
00175     shutdown();
00176     char cmd[3];
00177         
00178     cmd[0] = ACC_MSB;
00179     cmd[1] = (0xFF00 & inp) >> 8;
00180     cmd[2] = (0x00FF & inp);
00181     _i2c.write(_addr, cmd, 3, true);
00182     wake();
00183 }
00184 
00185 void LTC29421::accumulatedCharge(float inp){
00186     inp = (inp/100)*_battMax;
00187     accumulatedChargeReg(inp);
00188 }
00189 
00190 void LTC29421::setChargeThresholdLow(float prect){
00191     char cmd[3];
00192     prect = (prect/100)*_battMax;
00193  
00194     cmd[0] = CHRG_THL_MSB;
00195     cmd[1] = (0xFF00 & (int)prect) >> 8;
00196     cmd[2] = (0x00FF & (int)prect);
00197     _i2c.write(_addr, cmd, 2, true);        
00198 }
00199 
00200 void LTC29421::setChargeThresholdHigh(float prect){
00201     char cmd[3];
00202     prect = (prect/100)*_battMax;
00203  
00204     cmd[0] = CHRG_THH_MSB;
00205     cmd[1] = (0xFF00 & (int)prect) >> 8;
00206     cmd[2] = (0x00FF & (int)prect);
00207     _i2c.write(_addr, cmd, 2, true);            
00208 }
00209 
00210 float LTC29421::voltage(){
00211     char inn = VOLT_MSB;
00212     char outt[2];
00213     _i2c.write( _addr, &inn, 1 ,true );
00214     _i2c.read( _addr, outt, 2 );
00215     int vtemp = (int)outt[0];
00216     vtemp = (vtemp*256)+ outt[1];
00217     float vol = 6 * ((float)vtemp / 65535);
00218     return vol;
00219 }
00220 
00221 void LTC29421::setVoltageThresholdLow(float inp){
00222     char cmd[2];
00223     int ans = (int)(inp *65535)/6;
00224     ans = ans >> 8;
00225     cmd[0] = VOLT_THL;
00226     cmd[1] = (char)ans;
00227     _i2c.write(_addr, cmd, 2, true);            
00228 }
00229 
00230 void LTC29421::setVoltageThresholdHigh(float inp){
00231     char cmd[2];
00232     int ans = (int)(inp *65535)/6;
00233     ans = ans >> 8;
00234     cmd[0] = VOLT_THH;
00235     cmd[1] = (char)ans;
00236     _i2c.write(_addr, cmd, 2, true);            
00237 }
00238 
00239 
00240 float LTC29421::temperature(){
00241     char inn = TEMP_MSB;
00242     char outt[2];
00243     _i2c.write( _addr, &inn, 1 ,true );
00244     _i2c.read( _addr, outt, 2 );
00245     int ttemp = (int)outt[0];
00246     ttemp = (ttemp*256)+ outt[1];
00247     float tempp = (600 * ((float)ttemp / 65535)) - 273.15;
00248     return tempp;
00249 }
00250 
00251 void LTC29421::setTemperatureThresholdLow(float inp){
00252     int ans = (int)(((inp+273.15)*65535)/600);
00253     ans = ans >> 8;
00254     char cmd[2];
00255     cmd[0] = TEMPERATURE_THL;
00256     cmd[1] = ans;
00257     _i2c.write(_addr, cmd, 2, true);
00258 }
00259 
00260 void LTC29421::setTemperatureThresholdHigh(float inp){
00261     int ans = (int)(((inp+273.15)*65535)/600);
00262     ans = ans >> 8;
00263     char cmd[2];
00264     cmd[0] = TEMPERATURE_THH;
00265     cmd[1] = ans;
00266     _i2c.write(_addr, cmd, 2, true);   
00267 }
00268 
00269 void LTC29421::readAll(){
00270     char cmd[16];
00271     cmd[0] = REG_STATUS;
00272     _i2c.write(_addr, cmd, 1, true);
00273     _i2c.read(_addr, cmd, 16); // read the two-byte echo result
00274     DEBUG("===================================================\r\n");
00275     DEBUG("REG_STATUS          [%X] \r\n",cmd[REG_STATUS]);    
00276     DEBUG("REG_CONTROL         [%X] \r\n",cmd[REG_CONTROL]);    
00277     DEBUG("ACC_CHARGE          [%X %X] \r\n",cmd[ACC_MSB],cmd[ACC_LSB]);
00278     DEBUG("CHRG_THH            [%X %X] \r\n",cmd[CHRG_THH_MSB],cmd[CHRG_THH_LSB]);
00279     DEBUG("CHRG_THL            [%X %X] \r\n",cmd[CHRG_THL_MSB],cmd[CHRG_THL_LSB]);
00280     DEBUG("VOLTAGE             [%X %X] \r\n",cmd[VOLT_MSB],cmd[VOLT_LSB]);
00281     DEBUG("VOLT_THH            [%X] \r\n",cmd[VOLT_THH]);    
00282     DEBUG("VOLT_THL            [%X] \r\n",cmd[VOLT_THL]);    
00283     DEBUG("TEMPERATURE         [%X %X] \r\n",cmd[TEMP_MSB],cmd[TEMP_LSB]);
00284     DEBUG("TEMPERATURE_THH     [%X] \r\n",cmd[TEMPERATURE_THH]);    
00285     DEBUG("TEMPERATURE_THL     [%X] \r\n",cmd[TEMPERATURE_THL]);    
00286     DEBUG("===================================================\r\n");
00287     DEBUG("\r\n");
00288 }
00289 
00290 int LTC29421::alertResponse(){
00291     char reg = getStatusReg();
00292     char ans;
00293     char cmd= 0x19;
00294     _i2c.read(cmd, &ans, 1);
00295     if(ans == 0xC8){
00296         DEBUG("alert = %x, reg = %x\r\n", ans,reg);
00297         return reg;
00298     }else
00299         return -1;
00300 }
00301 
00302 char LTC29421::getControlReg()
00303 {
00304     char cmd;
00305     char ans;
00306     cmd= REG_CONTROL;
00307     _i2c.write(_addr, &cmd, 1, true);
00308     _i2c.read(_addr, &ans, 1);
00309 
00310     return ans;
00311 }
00312 
00313 char LTC29421::getStatusReg()
00314 {
00315     char cmd;
00316     char ans;
00317     cmd= REG_STATUS;
00318     _i2c.write(_addr, &cmd, 1, true);
00319     _i2c.read(_addr, &ans, 1);
00320 
00321     return ans;
00322 }
00323 
00324 void LTC29421::setControlReg(char inp)
00325 {
00326     char cmd[2];
00327     cmd[0] = REG_CONTROL;
00328     cmd[1] = inp;
00329     _i2c.write(_addr, cmd, 2, true);
00330 }