LTC2942 interface with interrupt and battery register calculations
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Sat Jul 16 2022 08:04:36 by 1.7.2