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 __eeprom 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
00103
00104 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {
00105 {1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27},
00106 {742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24},
00107 {494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17},
00108 {310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10}
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00134 unsigned char BatteryCheck(void)
00135 {
00136 unsigned char success = TRUE;
00137 unsigned int oldCapacity;
00138
00139
00140 oldCapacity = BattData.Capacity;
00141
00142 if (!BatteryStatusRefresh()) {
00143 success = FALSE;
00144 }
00145
00146 if (oldCapacity != BattData.Capacity) {
00147 success = FALSE;
00148 }
00149
00150 return(success);
00151 }
00152
00153
00167 unsigned char BatteryStatusRefresh(void)
00168 {
00169
00170 unsigned char success = FALSE;
00171
00172 BattData.Present = FALSE;
00173 BattData.Charged = FALSE;
00174 BattData.Low = TRUE;
00175 BattData.Circuit = OW_NONE;
00176 BattData.Temperature = 0;
00177 BattData.Capacity = 0;
00178 BattData.MaxCurrent = 0;
00179 BattData.MaxTime = 0;
00180 BattData.MinCurrent = 0;
00181
00182 NTCLookUp();
00183 BattData.HasRID = RIDLookUp();
00184
00185
00186 if (ADCS.VBAT >= BAT_VOLTAGE_MIN) {
00187 BattData.Low = FALSE;
00188 }
00189
00190
00191 if (ADCS.VBAT >= BAT_VOLTAGE_LOW) {
00192 BattData.Charged = TRUE;
00193 }
00194
00195
00196
00197
00203 if (((OCR1B == 0) && (!BattData.Low)) ||
00204 ((OCR1B != 0) && (ADCS.avgIBAT > 0))) {
00205 BattData.Present = TRUE;
00206 success = TRUE;
00207 } else {
00208 BattData.Low = FALSE;
00209 success = FALSE;
00210 }
00211
00212 #ifndef ALLOW_NO_RID
00213
00214 if(!BattData.HasRID) {
00215 success = FALSE;
00216 }
00217 #endif
00218
00219 return(success);
00220 }
00221
00222
00234 unsigned char BatteryDataRefresh(void)
00235 {
00236 unsigned char offset;
00237 unsigned char i, crc, family, temp, page;
00238 unsigned char success;
00239
00240
00241 for (page = 0; page < 4; page++) {
00242 success = FALSE;
00243
00244 if (OWI_DetectPresence(OWIBUS) == OWIBUS) {
00245
00246
00247 OWI_SendByte(OWI_ROM_READ, OWIBUS);
00248 family = OWI_ReceiveByte(OWIBUS);
00249 crc = OWI_ComputeCRC8(family,0);
00250
00251 for (i = 0; i < 6; i++) {
00252 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc);
00253 }
00254
00255
00256 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
00257 BattData.Circuit = family;
00258
00259
00260 if (BattData.Circuit == OW_DS2505) {
00261 offset = page*32;
00262 OWI_SendByte(DS2505_DATA_READ, OWIBUS);
00263 OWI_SendByte(offset, OWIBUS);
00264 OWI_SendByte(0, OWIBUS);
00265
00266
00267 crc = OWI_ComputeCRC8(DS2505_DATA_READ,0);
00268 crc = OWI_ComputeCRC8(offset,crc);
00269 crc = OWI_ComputeCRC8(0,crc);
00270
00271
00272
00273 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
00274 crc = 0;
00275
00276
00277 for (i=0; i<32; i++) {
00278 temp = OWI_ReceiveByte(OWIBUS);
00279 crc = OWI_ComputeCRC8(temp, crc);
00280 BattEEPROM[page][i] = temp;
00281 }
00282
00283 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
00284 success = TRUE;
00285 }
00286 } else {
00287 }
00288 } else {
00289 }
00290 } else {
00291 }
00292 } else {
00293 }
00294
00295
00296 if (!success) {
00297 for (i=0; i<32; i++) {
00298 BattEEPROM[page][i] = 0;
00299 }
00300 }
00301 }
00302
00303 return(success);
00304 }
00305
00306
00315 void EnableBattery(unsigned char bat)
00316 {
00317
00318 Time_Set(TIMER_GEN,0,0,100);
00319
00320
00321 BattActive = bat;
00322
00323
00324 PORTB |= (1 << (PB4+bat));
00325
00326
00327 PORTB &= ~(1<<(PB5-bat));
00328
00329 do {
00330 } while (Time_Left(TIMER_GEN));
00331 }
00332
00333
00338 void DisableBatteries(void)
00339 {
00340
00341 PORTB &= ~((1<<PB4)|(1<<PB5));
00342 }
00343
00344
00354 unsigned char RIDLookUp (void)
00355 {
00356 unsigned char i, found = FALSE;
00357
00358
00359
00360 for (i = 0 ; i < RID_TABLE_SIZE; i++) {
00361 if (ADCS.rawRID >= RID[i].Low) {
00362 if (ADCS.rawRID <= RID[i].High) {
00363 BattData.Capacity = RID[i].Capacity;
00364 BattData.MaxCurrent = RID[i].Icharge;
00365 BattData.MaxTime = RID[i].tCutOff;
00366 BattData.MinCurrent = RID[i].ICutOff;
00367
00368 found = TRUE;
00369 }
00370 }
00371 }
00372
00373
00374 if (!found) {
00375 BattData.Capacity = DEF_BAT_CAPACITY;
00376 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX;
00377 BattData.MaxTime = DEF_BAT_TIME_MAX;
00378 BattData.MinCurrent = DEF_BAT_CURRENT_MIN;
00379 }
00380
00381 return(found);
00382 }
00383
00384
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
00411
00412
00413 BattData.Temperature -= ( ( (signed int)ADCS.rawNTC
00414 - (signed int)NTC[i].ADC ) << 1
00415 ) / (signed int)BattData.ADCSteps;
00416
00417 found = TRUE;
00418 }
00419 }
00420
00421
00422
00423 if (!found) {
00424 BattData.Temperature = NTC_MAX_TEMPERATURE;
00425 }
00426 }