00001
00030 #include <ioavr.h>
00031
00032 #include "enums.h"
00033 #include "structs.h"
00034
00035 #include "ADC.h"
00036 #include "battery.h"
00037 #include "chargefunc.h"
00038 #include "main.h"
00039 #include "menu.h"
00040 #include "PWM.h"
00041 #include "statefunc.h"
00042 #include "time.h"
00043
00044 #ifdef NIMH
00045 #include "NIMHspecs.h"
00046 #endif // NIMH
00047
00048 #ifdef LIION
00049 #include "LIIONspecs.h"
00050 #endif // LIION
00051
00052
00053
00054
00055
00057 ChargeParameters_t ChargeParameters;
00058
00060 HaltParameters_t HaltParameters;
00061
00062
00063
00064
00065
00080 unsigned char ConstantCurrent(void)
00081 {
00082 unsigned char error = FALSE,
00083 wasStopped = FALSE;
00084
00085 do {
00086
00087 ADC_Wait();
00088
00089
00090
00091 if (BattControl[BattActive].ChargeInhibit) {
00092 wasStopped = TRUE;
00093 Time_Stop();
00094 OCR1B = 0;
00095 } else {
00096
00097 if (wasStopped) {
00098 wasStopped = FALSE;
00099
00100
00101 Time_Start();
00102 }
00103
00104
00105
00106 if ((ADCS.avgIBAT < 0) ||
00107 (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) {
00108
00109 if(!PWM_IncrementDutyCycle()) {
00110 #ifdef ABORT_IF_PWM_MAX
00111
00112
00113 SetErrorFlag(ERR_PWM_CONTROL);
00114 ChargeParameters.NextState = ST_ERROR;
00115 error = TRUE;
00116 #endif
00117 }
00118 } else if ((ADCS.avgIBAT >= 0) &&
00119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) {
00120
00121 if(!PWM_DecrementDutyCycle()) {
00122 #ifdef ABORT_IF_PWM_MIN
00123
00124
00125 SetErrorFlag(ERR_PWM_CONTROL);
00126 ChargeParameters.NextState = ST_ERROR;
00127 error = TRUE;
00128 #endif
00129 }
00130 }
00131 }
00132 } while (!HaltNow() && !error);
00133
00134
00135
00136 return(ChargeParameters.NextState);
00137 }
00138
00139
00154 unsigned char ConstantVoltage(void)
00155 {
00156 unsigned char error = FALSE,
00157 wasStopped = FALSE;
00158
00159 do{
00160
00161
00162 ADC_Wait();
00163
00164
00165
00166 if (BattControl[BattActive].ChargeInhibit) {
00167 wasStopped = TRUE;
00168 Time_Stop();
00169 OCR1B = 0;
00170 }
00171
00172 else {
00173
00174 if (wasStopped) {
00175 wasStopped = FALSE;
00176
00177
00178 Time_Start();
00179 }
00180
00181
00182
00183 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) {
00184
00185 if(!PWM_IncrementDutyCycle()) {
00186 #ifdef ABORT_IF_PWM_MAX
00187
00188
00189 SetErrorFlag(ERR_PWM_CONTROL);
00190 ChargeParameters.NextState = ST_ERROR;
00191 error = TRUE;
00192 #endif
00193 }
00194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) {
00195
00196 if(!PWM_DecrementDutyCycle()) {
00197 #ifdef ABORT_IF_PWM_MIN
00198
00199
00200 SetErrorFlag(ERR_PWM_CONTROL);
00201 ChargeParameters.NextState = ST_ERROR;
00202 error = TRUE;
00203 #endif
00204 }
00205 }
00206 }
00207
00208 } while (!HaltNow() && !error);
00209
00210
00211
00212 return(ChargeParameters.NextState);
00213 }
00214
00215
00257 unsigned char MaxVoltageAndCurrent (void)
00258 {
00259 unsigned char error = FALSE,
00260 wasStopped = FALSE,
00261 tempRangeChange;
00262
00263 signed char lastTempRange = -1;
00264
00265
00266 do {
00267
00268 ADC_Wait();
00269 NTCLookUp();
00270
00271
00272
00273 if (BattControl[BattActive].ChargeInhibit) {
00274 wasStopped = TRUE;
00275 Time_Stop();
00276 OCR1B = 0;
00277 }
00278 else {
00279
00280 if (wasStopped) {
00281 wasStopped = FALSE;
00282
00283
00284 Time_Start();
00285 }
00286
00287
00288
00289
00290
00291 tempRangeChange = FALSE;
00292
00293
00294 switch (lastTempRange) {
00295 case T0 :
00296 if ((BattData.Temperature - T0) > TEMP_HYST) {
00297 tempRangeChange = TRUE;
00298 }
00299 else {
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 if (ADCS.VBAT <= BAT_VOLTAGE_MAX_T0) {
00312 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T0;
00313 ChargeParameters.Current = BattData.MaxCurrent;
00314 }
00315 else {
00316 ChargeParameters.Voltage = BAT_VOLTAGE_MAX;
00317 ChargeParameters.Current = BattData.MaxCurrent/2;
00318 }
00319 }
00320 break;
00321
00322
00323 case T1 :
00324 if ((BattData.Temperature - T1) > TEMP_HYST
00325 || (T0 - BattData.Temperature) > TEMP_HYST) {
00326 tempRangeChange = TRUE;
00327 }
00328 break;
00329
00330
00331 case T2 :
00332 if ((BattData.Temperature - T2) > TEMP_HYST
00333 || (T1 - BattData.Temperature) >= TEMP_HYST) {
00334 tempRangeChange = TRUE;
00335 }
00336 break;
00337
00338
00339 case T3 :
00340 if ((T2 - BattData.Temperature) > TEMP_HYST) {
00341 tempRangeChange = TRUE;
00342 }
00343 break;
00344
00345
00346
00347 default : tempRangeChange = TRUE;
00348 }
00349
00350
00351 if (tempRangeChange) {
00352
00353
00354 if (BattData.Temperature <= T0) {
00355 if (ADCS.VBAT <= BAT_VOLTAGE_MAX_T0) {
00356 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T0;
00357 ChargeParameters.Current = BattData.MaxCurrent;
00358 }
00359 else {
00360 ChargeParameters.Voltage = BAT_VOLTAGE_MAX;
00361 ChargeParameters.Current = BattData.MaxCurrent/2;
00362 }
00363 lastTempRange = T0;
00364 }
00365
00366 else {
00367
00368
00369 ChargeParameters.Current = BattData.MaxCurrent;
00370
00371 if (BattData.Temperature <= T1) {
00372 ChargeParameters.Voltage = BAT_VOLTAGE_MAX;
00373 lastTempRange = T1;
00374 }
00375 else if (BattData.Temperature <= T2) {
00376 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T2;
00377 lastTempRange = T2;
00378 }
00379 else {
00380 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T3;
00381 lastTempRange = T3;
00382 }
00383 }
00384 }
00385
00386
00387
00388 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST) &&
00389 ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST)) {
00390
00391 if(!PWM_IncrementDutyCycle()) {
00392 #ifdef ABORT_IF_PWM_MAX
00393
00394
00395 SetErrorFlag(ERR_PWM_CONTROL);
00396 ChargeParameters.NextState = ST_ERROR;
00397 error = TRUE;
00398 #endif
00399 }
00400
00401 }
00402 if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST) ||
00403 ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST)) {
00404 if(!PWM_DecrementDutyCycle()) {
00405 #ifdef ABORT_IF_PWM_MIN
00406
00407
00408 SetErrorFlag(ERR_PWM_CONTROL);
00409 ChargeParameters.NextState = ST_ERROR;
00410 error = TRUE;
00411 #endif
00412 }
00413 }
00414 }
00415 } while (!HaltNow() && !error);
00416
00417
00418
00419 return(ChargeParameters.NextState);
00420 }
00421
00422
00445 unsigned char HaltNow(void)
00446 {
00447 unsigned char i, halt = FALSE;
00448
00449
00450 ADC_Wait();
00451 NTCLookUp();
00452
00453
00454
00455
00456 for (i = 0x01; i != 0; i <<= 1) {
00457 if (HaltParameters.HaltFlags & i) {
00458 switch (i) {
00459
00460 case HALT_VOLTAGE_DROP:
00461
00462
00463
00464 if (ADCS.VBAT > HaltParameters.VBATMax ||
00465 BattControl[BattActive].ChargeInhibit) {
00466 HaltParameters.VBATMax = ADCS.VBAT;
00467 } else if((HaltParameters.VBATMax - ADCS.VBAT) >=
00468 HaltParameters.VoltageDrop) {
00469 halt = TRUE;
00470 }
00471 break;
00472
00473
00474
00475 case HALT_VOLTAGE_MAX:
00476
00477 if (ADCS.VBAT >= HaltParameters.VoltageMax) {
00478 halt = TRUE;
00479 }
00480 break;
00481
00482
00483
00484 case HALT_CURRENT_MIN:
00485
00486
00487
00488 if (ADCS.avgIBAT <= HaltParameters.CurrentMin &&
00489 !BattControl[BattActive].ChargeInhibit) {
00490 halt = TRUE;
00491 }
00492 break;
00493
00494
00495
00496 case HALT_TEMPERATURE_RISE:
00497
00498
00499
00500
00501 if (ADCS.rawNTC > HaltParameters.LastNTC) {
00502 HaltParameters.LastNTC = ADCS.rawNTC;
00503 Time_Set(TIMER_TEMP,0,30,0);
00504
00505
00506 } else if ((HaltParameters.LastNTC - ADCS.rawNTC) >=
00507 (BattData.ADCSteps * HaltParameters.TemperatureRise)) {
00508
00509
00510
00511
00512 if (Time_Left(TIMER_TEMP)) {
00513 halt = TRUE;
00514 } else {
00515 HaltParameters.LastNTC = ADCS.rawNTC;
00516 Time_Set(TIMER_TEMP,0,30,0);
00517 }
00518 }
00519 break;
00520
00521
00522
00523 case HALT_TIME:
00524
00525 if (!Time_Left(TIMER_CHG)) {
00526 halt = TRUE;
00527
00528
00529
00530 if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) {
00531 PWM_Stop();
00532 BattControl[BattActive].Enabled = FALSE;
00533 BattData.Exhausted = TRUE;
00534 SetErrorFlag(ERR_BATTERY_EXHAUSTED);
00535 ChargeParameters.NextState = ST_ERROR;
00536 }
00537 }
00538 break;
00539
00540
00541 default:
00542 break;
00543 }
00544 }
00545 }
00546
00547
00548
00549
00550 if ((BattData.Temperature < HaltParameters.TemperatureMin) ||
00551 (BattData.Temperature > HaltParameters.TemperatureMax)) {
00552
00553 PWM_Stop();
00554 SetErrorFlag(ERR_BATTERY_TEMPERATURE);
00555 ChargeParameters.NextState = ST_ERROR;
00556 halt = TRUE;
00557 }
00558
00559
00560 if (!BatteryCheck()) {
00561 PWM_Stop();
00562 ChargeParameters.NextState = ST_INIT;
00563 halt = TRUE;
00564 }
00565
00566
00567 if (!ADCS.Mains) {
00568 PWM_Stop();
00569 ChargeParameters.NextState = ST_SLEEP;
00570 halt = TRUE;
00571 }
00572
00573 return(halt);
00574 }