00001
00031 #include <ioavr.h>
00032 #include <inavr.h>
00033
00034 #include "structs.h"
00035 #include "enums.h"
00036
00037 #include "ADC.h"
00038 #include "battery.h"
00039 #include "main.h"
00040 #include "OWI.h"
00041 #include "time.h"
00042
00043 #ifdef NIMH
00044 #include "NIMHspecs.h"
00045 #endif // NIMH
00046
00047 #ifdef LIION
00048 #include "LIIONspecs.h"
00049 #endif // LIION
00050
00051
00052
00053
00054
00055
00056
00060 __eeprom Battery_t BattControl[2] = {{TRUE, TRUE, FALSE},
00061 {TRUE, TRUE, FALSE}};
00062
00063
00064 Batteries_t BattData;
00065
00066
00067
00071 __eeprom unsigned char BattEEPROM[4][32];
00072
00073
00075 unsigned char BattActive;
00076
00077
00084 const RID_Lookup_t RID[RID_TABLE_SIZE] = {
00085 {558, 659, 3900, 550, 260, 300, 10},
00086 {744, 843, 6800, 750, 360, 300, 14},
00087 {869, 958, 10000, 1000, 475, 300, 19},
00088 {1097, 1153, 24000, 2000, 475, 420, 38}
00089 };
00090
00091
00105
00106 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {
00107 {1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27},
00108 {742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24},
00109 {494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17},
00110 {310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10}
00111 };
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00136 unsigned char BatteryCheck(void)
00137 {
00138 unsigned char success = TRUE;
00139 unsigned int oldCapacity;
00140
00141
00142 oldCapacity = BattData.Capacity;
00143
00144 if (!BatteryStatusRefresh()) {
00145 success = FALSE;
00146 }
00147
00148 if (oldCapacity != BattData.Capacity) {
00149 success = FALSE;
00150 }
00151
00152 return(success);
00153 }
00154
00155
00169 unsigned char BatteryStatusRefresh(void)
00170 {
00171
00172 unsigned char success = FALSE;
00173
00174 BattData.Present = FALSE;
00175 BattData.Charged = FALSE;
00176 BattData.Low = TRUE;
00177 BattData.Circuit = OW_NONE;
00178 BattData.Temperature = 0;
00179 BattData.Capacity = 0;
00180 BattData.MaxCurrent = 0;
00181 BattData.MaxTime = 0;
00182 BattData.MinCurrent = 0;
00183
00184 NTCLookUp();
00185 BattData.HasRID = RIDLookUp();
00186
00187
00188 if (ADCS.VBAT >= BAT_VOLTAGE_MIN) {
00189 BattData.Low = FALSE;
00190 }
00191
00192
00193 if (ADCS.VBAT >= BAT_VOLTAGE_LOW) {
00194 BattData.Charged = TRUE;
00195 }
00196
00197
00198
00199
00205 if (((OCR1B == 0) && (!BattData.Low)) ||
00206 ((OCR1B != 0) && (ADCS.avgIBAT > 0))) {
00207 BattData.Present = TRUE;
00208 success = TRUE;
00209 } else {
00210 BattData.Low = FALSE;
00211 success = FALSE;
00212 }
00213
00214 #ifndef ALLOW_NO_RID
00215
00216 if(!BattData.HasRID) {
00217 success = FALSE;
00218 }
00219 #endif
00220
00221 return(success);
00222 }
00223
00224
00236 unsigned char BatteryDataRefresh(void)
00237 {
00238 unsigned char offset;
00239 unsigned char i, crc, family, temp, page;
00240 unsigned char success;
00241
00242
00243 for (page = 0; page < 4; page++) {
00244 success = FALSE;
00245
00246 if (OWI_DetectPresence(OWIBUS) == OWIBUS) {
00247
00248
00249 OWI_SendByte(OWI_ROM_READ, OWIBUS);
00250 family = OWI_ReceiveByte(OWIBUS);
00251 crc = OWI_ComputeCRC8(family,0);
00252
00253 for (i = 0; i < 6; i++) {
00254 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc);
00255 }
00256
00257
00258 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
00259 BattData.Circuit = family;
00260
00261
00262 if (BattData.Circuit == OW_DS2505) {
00263 offset = page*32;
00264 OWI_SendByte(DS2505_DATA_READ, OWIBUS);
00265 OWI_SendByte(offset, OWIBUS);
00266 OWI_SendByte(0, OWIBUS);
00267
00268
00269 crc = OWI_ComputeCRC8(DS2505_DATA_READ,0);
00270 crc = OWI_ComputeCRC8(offset,crc);
00271 crc = OWI_ComputeCRC8(0,crc);
00272
00273
00274
00275 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
00276 crc = 0;
00277
00278
00279 for (i=0; i<32; i++) {
00280 temp = OWI_ReceiveByte(OWIBUS);
00281 crc = OWI_ComputeCRC8(temp, crc);
00282 BattEEPROM[page][i] = temp;
00283 }
00284
00285 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
00286 success = TRUE;
00287 }
00288 } else {
00289 }
00290 } else {
00291 }
00292 } else {
00293 }
00294 } else {
00295 }
00296
00297
00298 if (!success) {
00299 for (i=0; i<32; i++) {
00300 BattEEPROM[page][i] = 0;
00301 }
00302 }
00303 }
00304
00305 return(success);
00306 }
00307
00308
00317 void EnableBattery(unsigned char bat)
00318 {
00319
00320 Time_Set(TIMER_GEN,0,0,100);
00321
00322
00323 BattActive = bat;
00324
00325
00326 PORTB |= (1 << (PB4+bat));
00327
00328
00329 PORTB &= ~(1<<(PB5-bat));
00330
00331 do {
00332 } while (Time_Left(TIMER_GEN));
00333 }
00334
00335
00340 void DisableBatteries(void)
00341 {
00342
00343 PORTB &= ~((1<<PB4)|(1<<PB5));
00344 }
00345
00346
00356 unsigned char RIDLookUp (void)
00357 {
00358 unsigned char i, found = FALSE;
00359
00360
00361
00362 for (i = 0 ; i < RID_TABLE_SIZE; i++) {
00363 if (ADCS.rawRID >= RID[i].Low) {
00364 if (ADCS.rawRID <= RID[i].High) {
00365 BattData.Capacity = RID[i].Capacity;
00366 BattData.MaxCurrent = RID[i].Icharge;
00367 BattData.MaxTime = RID[i].tCutOff;
00368 BattData.MinCurrent = RID[i].ICutOff;
00369
00370 found = TRUE;
00371 }
00372 }
00373 }
00374
00375
00376 if (!found) {
00377 BattData.Capacity = DEF_BAT_CAPACITY;
00378 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX;
00379 BattData.MaxTime = DEF_BAT_TIME_MAX;
00380 BattData.MinCurrent = DEF_BAT_CURRENT_MIN;
00381 }
00382
00383 return(found);
00384 }
00385
00386
00398 void NTCLookUp (void)
00399 {
00400 unsigned char i;
00401 unsigned char found = FALSE;
00402
00403
00404
00405
00406 for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++) {
00407 if (ADCS.rawNTC >= NTC[i].ADC) {
00408 BattData.Temperature = (i<<2) ;
00409 BattData.ADCSteps = NTC[i].ADCsteps;
00410 BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps;
00411
00412 found = TRUE;
00413 }
00414 }
00415
00416
00417 if (!found) {
00418 BattData.Temperature = 80;
00419 }
00420 }