00001
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include <iom406.h>
00057 #include <inavr.h>
00058
00059 #include "main.h"
00060 #include "pack.h"
00061
00062 #define MODULE_ANALOG
00063 #include "analog.h"
00064
00065 #define MODULE_CALIBRATION
00066 #include "calibration.h"
00067
00068
00069 #include "smbus.h"
00070 #include "timer.h"
00071 #include "pwrmgmt.h"
00072 #include "ee.h"
00073
00074
00075
00076 void CCarray_Init(void);
00077
00078
00079
00080
00081
00082
00083
00084 signed long MaxTopAcc = 0;
00085 signed long MaxBottomAcc = 0;
00086
00087 unsigned char CC_delay_acc = 0;
00088 unsigned char CC_delay_inst = 0;
00089
00090
00091 unsigned int CellV[4] = {0};
00092 unsigned int OnChipTemp = 0;
00093
00094
00095 unsigned int Thermistor[4] = {0};
00096 unsigned int VPA4 = 0;
00097
00098
00099
00100
00101
00102
00103 signed int CCarray[64];
00104 char CCindex = 0;
00105 char CCvalidsamples = 0;
00106
00107
00108
00109
00110
00111 unsigned int ADCbuffer[10];
00112 unsigned int ADCgain[4];
00113 unsigned int VTgain;
00114 unsigned char ADCchannel;
00115
00116
00117 #define FixedThermistorPullup 1000
00118
00119
00120
00121
00122
00123
00124
00125
00126 void SetMaxTopAcc(long value)
00127 {
00128 MaxTopAcc = value;
00129 }
00130
00131 void FullChargeReached(void)
00132 {
00133 signed long temp;
00134
00135 temp = RunningAcc - MaxBottomAcc;
00136 RunningAcc = MaxTopAcc = temp;
00137 MaxBottomAcc = 0;
00138 SMBvariables[SMBV_BattStatus][lobyte] &= ~FULLY_DISCHARGED;
00139 SMBvariables[SMBV_BattStatus][lobyte] |= FULLY_CHARGED;
00140 }
00141
00142
00143
00144 void FullDischargeReached(void)
00145 {
00146 MaxTopAcc -= RunningAcc;
00147 RunningAcc = MaxBottomAcc = 0;
00148 SMBvariables[SMBV_BattStatus][lobyte] |= FULLY_DISCHARGED;
00149 SMBvariables[SMBV_BattStatus][lobyte] &= ~FULLY_CHARGED;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 unsigned int GetVoltage(void)
00161 {
00162 unsigned int volt;
00163
00164 volt = ReadCell(1);
00165 volt += ReadCell(2);
00166 if(PACKSTACK > 2)
00167 volt += ReadCell(3);
00168 if(PACKSTACK > 3)
00169 volt += ReadCell(4);
00170 return volt;
00171 }
00172
00173
00174 long GetCharge(void)
00175 {
00176 unsigned long calc = (RunningAcc / 10727);
00177 return calc;
00178 }
00179
00180
00181 long GetCharge_mAmins(void)
00182 {
00183 unsigned long calc = (RunningAcc / 179);
00184 return calc;
00185 }
00186
00187
00188 long GetChgUntilFull_mAmins(void)
00189 {
00190 unsigned long calc = (MaxTopAcc - RunningAcc);
00191 return (calc / 179);
00192 }
00193
00194
00195 unsigned int GetMaxChg(void)
00196
00197 {
00198 unsigned long calc = MaxTopAcc / 10727;
00199 return (unsigned int) calc;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 unsigned int AtRateTTF(void)
00227 {
00228 signed long calc;
00229 unsigned int temp = (unsigned int)SMBvar_int[SMBV_AtRate];
00230
00231 if((signed int) temp > 0)
00232 {
00233 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00234 {
00235 temp = 65535;
00236 }
00237 else
00238 {
00239 calc = PACK_DESIGNCAPTYP;
00240 calc = calc * 60;
00241 calc -= GetCharge_mAmins();
00242 temp = calc / temp;
00243 }
00244 }
00245 else
00246 temp = 65535;
00247
00248 return temp;
00249 }
00250
00251
00252 unsigned int AtRateTTE(void)
00253 {
00254 signed long calc;
00255 unsigned int temp = (unsigned int)SMBvar_int[SMBV_AtRate];
00256
00257 if((signed int) temp < 0)
00258 {
00259 temp = -((signed int) temp);
00260
00261 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00262 {
00263 calc = GetCharge_mAmins() * PACK_MINV;
00264 calc = calc / 10000;
00265 temp = calc / temp;
00266 }
00267 else
00268 {
00269 calc = GetCharge_mAmins();
00270 temp = calc / temp;
00271 }
00272 }
00273 else
00274 temp = 65535;
00275
00276 return temp;
00277 }
00278
00279
00280 unsigned int AtRateOK(void)
00281 {
00282 unsigned long calc;
00283 unsigned int temp = (unsigned int)SMBvar_int[SMBV_AtRate];
00284
00285 if((signed int) temp < 0)
00286 {
00287 temp = -((signed int) temp);
00288
00289 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00290 {
00291 calc = Current1Sec() * GetVoltage();
00292 calc = calc / 10000;
00293 temp += calc;
00294
00295 calc = GetCharge_mAmins();
00296 calc = calc * PACK_MINV;
00297 calc = calc * 6;
00298 calc = calc / 10;
00299 }
00300 else
00301 {
00302 temp += Current1Sec();
00303 calc = GetCharge_mAmins() * 6;
00304 }
00305
00306 if(calc > temp)
00307 temp = 65535;
00308 else
00309 temp = 0;
00310 }
00311 else
00312 temp = 65535;
00313
00314 return temp;
00315 }
00316
00317
00318 unsigned int GetTemperature(void)
00319 {
00320 return ReadTemperature(0);
00321 }
00322
00323
00324
00325 unsigned char RelativeSOC(void)
00326 {
00327 unsigned long charge = (RunningAcc * 100) / MaxTopAcc;
00328
00329 return (unsigned char) charge;
00330 }
00331
00332
00333 unsigned int AbsoluteSOC(void)
00334 {
00335 unsigned long charge = (GetCharge() * 100);
00336 charge = charge / PACK_DESIGNCAPTYP;
00337 return (unsigned int) charge;
00338 }
00339
00340
00341 unsigned int RemainingCap(void)
00342 {
00343 unsigned long calc;
00344 unsigned int charge = GetCharge();
00345
00346 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00347 {
00348 calc = charge * GetVoltage();
00349 charge = calc / 10000;
00350 }
00351
00352 return charge;
00353 }
00354
00355
00356
00357 unsigned int FullChgCap(void)
00358 {
00359 unsigned long calc = GetMaxChg();
00360
00361 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00362 {
00363 calc = calc * PACK_NOMINALV;
00364 calc = calc / 10000;
00365 }
00366
00367 return (unsigned int) calc;
00368 }
00369
00370
00371
00372 unsigned int TimeToEmpty(unsigned char avgd)
00373 {
00374 signed int rate;
00375 unsigned long presentrate;
00376 unsigned long cap;
00377
00378 if(0 == avgd)
00379 rate = Current1Sec();
00380 else
00381 rate = CCarray_Average();
00382
00383 if(rate >= 0)
00384 return 65535;
00385
00386 rate = -rate;
00387
00388 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00389 {
00390
00391 presentrate = rate * GetVoltage();
00392
00393
00394 cap = GetCharge_mAmins() * PACK_MINV;
00395
00396
00397 cap = cap / presentrate;
00398 }
00399 else
00400 {
00401 cap = GetCharge_mAmins() / rate;
00402 }
00403
00404 return (unsigned int) cap;
00405 }
00406
00407
00408
00409
00410 unsigned int AvgTimeToFull(void)
00411 {
00412 signed int rate;
00413 unsigned long presentrate;
00414 unsigned long cap;
00415
00416 rate = Current1Sec();
00417 if(rate <= 0)
00418 return 65535;
00419
00420
00421 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
00422 {
00423
00424 presentrate = rate * GetVoltage();
00425
00426
00427 cap = GetChgUntilFull_mAmins() * PACK_MINV;
00428
00429
00430 cap = cap / presentrate;
00431 }
00432 else
00433 {
00434 cap = GetChgUntilFull_mAmins() / rate;
00435 }
00436
00437 return (unsigned int) cap;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00456 #define FAST_RC_CAL (sig_array[0x01])
00457 #define SLOW_RC_LO_CAL (sig_array[0x06])
00458 #define SLOW_RC_HI_CAL (sig_array[0x07])
00459 #define BG_C_CAL (sig_array[0x09])
00460 #define CELL1_LO_CAL (sig_array[0x10])
00461 #define CELL1_HI_CAL (sig_array[0x11])
00462 #define CELL2_LO_CAL (sig_array[0x12])
00463 #define CELL2_HI_CAL (sig_array[0x13])
00464 #define CELL3_LO_CAL (sig_array[0x14])
00465 #define CELL3_HI_CAL (sig_array[0x15])
00466 #define CELL4_LO_CAL (sig_array[0x16])
00467 #define CELL4_HI_CAL (sig_array[0x17])
00468 #define ADC0_LO_CAL (sig_array[0x18]) // currently not used
00469 #define ADC0_HI_CAL (sig_array[0x19]) // currently not used
00470 #define VPTAT_LO_CAL (sig_array[0x1A])
00471 #define VPTAT_HI_CAL (sig_array[0x1B])
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 void ReadFactoryCalibration(void)
00489 {
00490 unsigned char __flash * ptr = 0;
00491 char i;
00492 char flags = SREG;
00493 char temp;
00494 unsigned char sig_array[0x1C];
00495
00496
00497 __disable_interrupt();
00498 for(i=0; i< 0x1C; i++)
00499 {
00500 SPMCSR = (1<<SIGRD) | (1<<SPMEN);
00501 temp = *ptr++;
00502 sig_array[i] = temp;
00503 }
00504
00505 if(flags & 0x80)
00506 __enable_interrupt();
00507
00508
00509
00510
00511 SlowRCCal = (SLOW_RC_HI_CAL << 8)|(SLOW_RC_LO_CAL);
00512 FastRCCal = FAST_RC_CAL;
00513
00514
00515 BGCCRCal = BG_C_CAL| 0x80;
00516 if (ReadVrefCalibration()) {
00517 calibration_state &= ~CAL_VREF_MASK;
00518 calibration_state |= CAL_VREF_OK;
00519 } else {
00520 calibration_state &= ~CAL_VREF_MASK;
00521 }
00522
00523
00524 ADCgain[0] = (CELL1_HI_CAL << 8)|(CELL1_LO_CAL);
00525 ADCgain[1] = (CELL2_HI_CAL << 8)|(CELL2_LO_CAL);
00526 ADCgain[2] = (CELL3_HI_CAL << 8)|(CELL3_LO_CAL);
00527 ADCgain[3] = (CELL4_HI_CAL << 8)|(CELL4_LO_CAL);
00528
00529
00530 VTgain = (VPTAT_HI_CAL<<8) | VPTAT_LO_CAL;
00531
00532
00533 if (ReadCCOffsetCalibration()) {
00534 calibration_state &= ~CAL_CC_MASK;
00535 calibration_state |= CAL_CC_OK;
00536 } else {
00537 calibration_state &= ~CAL_CC_MASK;
00538 }
00539 }
00540
00541
00542
00543 unsigned char ReadVrefCalibration(void)
00544 {
00545 unsigned char temp;
00546
00547 while(EECR & (1<<EEPE));
00548 EEAR = EESTORAGE_BGCCR;
00549 EECR = (1<<EERE);
00550 temp = EEDR;
00551 if (temp != 0xFF) {
00552 BGCCR = temp;
00553 while(EECR & (1<<EEPE));
00554 EEAR = EESTORAGE_BGCRR;
00555 EECR = (1<<EERE);
00556 BGCRR = EEDR;
00557 return(1);
00558 } else {
00559 BGCRR = 0x0F;
00560 BGCCR = BGCCRCal;
00561 return(0);
00562 }
00563 }
00564
00565
00566 unsigned char ReadCCOffsetCalibration(void)
00567 {
00568 signed char temp;
00569
00570 while(EECR & (1<<EEPE));
00571 EEAR = EESTORAGE_CC_valid;
00572 EECR = (1<<EERE);
00573 temp = EEDR;
00574 if (temp != -1) {
00575 do {} while(EECR & (1<<EEPE));
00576 EEAR = EESTORAGE_CCoffset;
00577 EECR = (1<<EERE);
00578 temp = EEDR;
00579 CCoffset = (signed int)temp;
00580 do {} while(EECR & (1<<EEPE));
00581 EEAR = EESTORAGE_CCIoffset;
00582 EECR = (1<<EERE);
00583 temp=EEDR;
00584 CCIoffset = (signed long)temp;
00585 return(1);
00586 } else {
00587 CCIoffset = 0;
00588 CCoffset = 0;
00589 return(0);
00590 }
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 unsigned char CalibrateVREF(void)
00604 {
00605 long int V_error;
00606 long int old_V_error;
00607 unsigned char ratio_counter;
00608 unsigned char loopcount;
00609 volatile unsigned int vui_temp;
00610
00611 BGCRR = 0x0f;
00612 BGCCR = BGCCRCal;
00613 VADMUX = CAL_CHANNEL;
00614 VADCSR = (1 << VADEN);
00615 vui_temp = VADC;
00616 loopcount = CAL_WAIT;
00617 while (loopcount--) {
00618 VADCSR |= (1 << VADSC) | (1 << VADCCIF);
00619 do {} while(!(VADCSR & (1 << VADCCIF)));
00620 vui_temp = VADC;
00621 }
00622 VADCSR |= (1 << VADSC) | (1 << VADCCIF);
00623 do {} while(!(VADCSR & (1 << VADCCIF)));
00624 V_error = VADC;
00625 V_error = V_error * CAL_GAIN;
00626 V_error = V_error - Vcalibration_value;
00627 loopcount = 8;
00628 while (V_error < vcalibration_level[loopcount]) {
00629 loopcount--;
00630 if (!loopcount) {
00631 break;
00632 }
00633 }
00634 BGCRR = tempcal[loopcount];
00635
00636 V_error = vcalibration_level[7];
00637 ratio_counter = (1 << BGEN) - 1;
00638 do
00639 {
00640 ratio_counter++;
00641 BGCCR = ratio_counter;
00642 old_V_error = V_error;
00643 if(ratio_counter & 0x40)
00644 {
00645 BGCRR = 0x0f;
00646 BGCCR = BGCCRCal;
00647 return 0;
00648 }
00649 vui_temp = VADC;
00650 VADCSR |= (1 << VADSC) | (1 << VADCCIF);
00651 do {} while(!(VADCSR & (1 << VADCCIF)));
00652 V_error = VADC;
00653 V_error = V_error * CAL_GAIN;
00654 V_error = V_error - Vcalibration_value;
00655 } while(V_error > 0);
00656 if(old_V_error < (-V_error)) {
00657 ratio_counter--;
00658 }
00659 BGCCR = ratio_counter;
00660
00661 do {} while(EECR & (1<<EEPE));
00662 do {} while(SPMCSR & (1<<SPMEN));
00663 EEAR = EESTORAGE_BGCRR;
00664 EEDR = tempcal[loopcount];
00665 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (0<<EEPE) | (0<<EERE);
00666 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (1<<EEPE) | (0<<EERE);
00667
00668 do {} while(EECR & (1<<EEPE));
00669 EEAR = EESTORAGE_BGCCR;
00670 EEDR = ratio_counter;
00671 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (0<<EEPE) | (0<<EERE);
00672 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (1<<EEPE) | (0<<EERE);
00673
00674 return 1;
00675 }
00676
00677
00678
00679 unsigned char CalibrateCCoffset(void)
00680 {
00681 unsigned char index = CCindex;
00682 volatile signed long cc_temp;
00683
00684 index--;
00685 index &= 63;
00686 CCIoffset = CCarray[index];
00687
00688 ChangePowerMode(POWERMODE_ACTIVE,0);
00689 while (CC_delay_acc--) {
00690 do {} while (!(CADCSRB & (1<<CADACIF)));
00691 cc_temp = CADAC;
00692 CADCSRB = (1<<CADACIE) | (1<<CADICIE) | (1<<CADACIF) | (1<<CADRCIF) | (1<<CADICIF);
00693 }
00694 CCoffset = CADAC;
00695
00696 if ((CCoffset > CCoffset_limit) || (CCIoffset > CCIoffset_limit) ||
00697 (CCoffset < -CCoffset_limit) || (CCIoffset < -CCIoffset_limit)) {
00698 CCoffset = 0;
00699 CCIoffset = 0;
00700 return(0);
00701
00702 } else {
00703 do {} while(EECR & (1<<EEPE));
00704 do {} while(SPMCSR & (1<<SPMEN));
00705 EEAR = EESTORAGE_CC_valid;
00706 EEDR = 0x00;
00707 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (0<<EEPE) | (0<<EERE);
00708 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (1<<EEPE) | (0<<EERE);
00709
00710 do {} while(EECR & (1<<EEPE));
00711 EEAR = EESTORAGE_CCIoffset;
00712 EEDR = (unsigned char)CCIoffset;
00713 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (0<<EEPE) | (0<<EERE);
00714 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (1<<EEPE) | (0<<EERE);
00715
00716 do {} while(EECR & (1<<EEPE));
00717 EEAR = EESTORAGE_CCoffset;
00718 EEDR = (unsigned char)CCoffset;
00719 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (0<<EEPE) | (0<<EERE);
00720 EECR = (0<<EEPM1) | (0<<EEPM0) | (0<<EERIE) | (1<<EEMPE) | (1<<EEPE) | (0<<EERE);
00721 return(1);
00722 }
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 void CCmode(unsigned char mode)
00743 {
00744 switch (mode)
00745 {
00746 default:
00747 case CC_DISABLED:
00748 CCSR = 0;
00749 CCarray_Init();
00750 CADCSRA = 0;
00751 break;
00752
00753 case CC_ACCUMULATE:
00754 if(CCSR != ((1<<XOE)|(1<<ACS)))
00755 {
00756 Timer32KHz = 9;
00757 CCSR = (1<<XOE);
00758 }
00759 BGCCR |= (1<<BGEN);
00760 CADCSRB = (1<<CADACIE) | (1<<CADICIE) | (1<<CADACIF) | (1<<CADRCIF) | (1<<CADICIF);
00761 while ( CADCSRA & (1<<CADUB) );
00762 CADCSRA = (1<<CADEN) | ACCUM_CONV_TIME;
00763 CC_delay_acc = 4;
00764 CC_delay_inst = 4;
00765 CCarray_Init();
00766 break;
00767
00768 case CC_REGULAR:
00769 if(CCSR != ((1<<XOE)|(1<<ACS)))
00770 {
00771 Timer32KHz = 9;
00772 CCSR = (1<<XOE);
00773 }
00774 CCarray_Init();
00775 BGCCR |= (1<<BGEN);
00776 CADRDC = -(ACTIVE_CURRENT_THRESHOLD + (CCIoffset>>4));
00777 CADCSRB = (1<<CADRCIE) | (1<<CADACIF) | (1<<CADRCIF) | (1<<CADICIF);
00778 while ( CADCSRA & (1<<CADUB) );
00779 CADCSRA = (1<<CADSE) | REG_CONV_TIME;
00780 break;
00781 }
00782 }
00783
00784
00785 void CCinit(void)
00786 {
00787 CCmode(CC_DISABLED);
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 void CCarray_Init(void)
00802 {
00803 CCvalidsamples = 0;
00804 CCindex = 0;
00805 }
00806
00807
00808
00809 void CCarray_AddSample(signed int newsample)
00810 {
00811 if(CC_delay_inst)
00812 {
00813 CC_delay_inst--;
00814 return;
00815 }
00816
00817 CCarray[CCindex++] = newsample;
00818 CCindex &= 63;
00819
00820 if(CCvalidsamples < 64)
00821 CCvalidsamples++;
00822 }
00823
00824
00825
00826 signed int Current1Sec(void)
00827 {
00828 unsigned char temp = CCindex;
00829
00830 temp--;
00831 temp &= 63;
00832 return CCarray[temp];
00833 }
00834
00835
00836
00837
00838
00839
00840
00841 signed int CCarray_Average(void)
00842 {
00843 signed long avg = 0;
00844 unsigned char ctr = CCvalidsamples;
00845 unsigned char temp;
00846 signed int * ptr = CCarray;
00847
00848 if(0 == ctr)
00849 return 0;
00850
00851 temp = ctr;
00852 while(temp--)
00853 avg += *ptr++;
00854
00855 if(64 == ctr)
00856 return (signed int) (avg >> 6);
00857 else
00858 if(1 == ctr)
00859 return (signed int) (avg);
00860 else
00861 return (signed int) (avg / ctr );
00862 }
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 #define CCI_CAL 172
00907
00908 #pragma vector = CCADC_vect
00909 __interrupt void CC_Instantaneous_ISR(void)
00910 {
00911 static unsigned char timer = 0;
00912 static signed long sl = 0;
00913 static unsigned char mod_remainder;
00914 signed int temp,temp2;
00915
00916
00917
00918 if(PowerMode == POWERMODE_IDLE)
00919 {
00920 temp = CADIC;
00921 temp <<= 3;
00922 RunningAcc += (signed long) temp;
00923 RunningAcc += (signed long) temp;
00924 RunningAcc += (signed long) temp;
00925 RunningAcc += (signed long) temp;
00926
00927
00928 temp2 = CADIC;
00929 temp = temp2;
00930 temp += temp2;
00931 temp += temp2/2;
00932 temp -= CCIoffset;
00933 CCarray_AddSample(temp);
00934 return;
00935 }
00936
00937
00938 if(0 == ++timer)
00939 {
00940 sl /= 16;
00941 sl -= CCIoffset;
00942 CCarray_AddSample((signed int) sl);
00943 sl = 0;
00944 }
00945
00946
00947
00948
00949 temp = mod_remainder;
00950 temp += CCI_CAL;
00951 mod_remainder = (unsigned char) temp;
00952
00953 if(temp>>8)
00954 {
00955 temp = CADIC;
00956
00957 LatestCCI = temp;
00958 sl += temp;
00959 }
00960 else
00961 LatestCCI = CADIC;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 #pragma vector = CCADC_REG_CUR_vect
00987 __interrupt void CC_RegularCurrent_ISR(void)
00988 {
00989 ChangePowerMode(POWERMODE_ACTIVE,0);
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 #pragma vector = CCADC_ACC_vect
01019 __interrupt void CC_Accumulator_ISR(void)
01020 {
01021 union {signed long acc; unsigned char byte[4];} lastCCreading;
01022
01024
01025
01026
01027
01028
01029
01030 lastCCreading.acc = CADAC;
01031
01032 lastCCreading.acc -= (signed long) CCoffset;
01033
01034
01035 if(CC_delay_acc)
01036 {
01037 CC_delay_acc--;
01038 return;
01039 }
01040
01041 RunningAcc += lastCCreading.acc;
01042
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 void ADCinit(void)
01089 {
01090
01091
01092 ReadFactoryCalibration();
01093
01094
01095
01096 }
01097
01098
01099
01100
01101
01102
01103 void StartAdc(unsigned char select)
01104 {
01105 unsigned char temp = (1<<select);
01106
01107
01109 DIDR0 = 0x0F;
01110
01111 PORTA &= 0xE0;
01112 PORTA |= (1<<4);
01113 DDRA &= 0xE0;
01114 DDRA |= (1<<4) | temp;
01115
01116 VADMUX = 5;
01117 VADCSR = (1<<VADEN) | (1<<VADCCIF);
01118 VADCSR = (1<<VADEN) | (1<<VADSC) | (1<<VADCCIE);
01119 }
01120
01121
01122
01123
01124
01125 #pragma vector = VADC_vect
01126 __interrupt void ADC_INT(void)
01127 {
01128 unsigned char temp;
01129 static char counter;
01130
01131 temp = VADMUX;
01132
01133 ADCbuffer[temp-1] = VADC;
01134
01135 if((temp <= 4) && (temp >= 1))
01136 cell_current[temp-1] = LatestCCI;
01137
01138 if(temp == 5) {
01139 counter = VPTAT_READINGS;
01140 temp++;
01141 }
01142
01143 if((temp == 6)||(temp == 7)) {
01144 if(--counter == 0) {
01145 temp++;
01146 counter = ADC0_READINGS;
01147 }
01148 } else {
01149 temp++;
01150 if(10 == temp) {
01151 DisableCellBalancing();
01152 } else {
01153 if(10 < temp) {
01154 temp = 1;
01155 } else {
01156 if(5 == temp) {
01157 SetADCScanDone;
01158 EnableCellBalancing();
01159 VADCSR = 0;
01160 return;
01161 }
01162 }
01163 }
01164 }
01165
01166 VADMUX = temp;
01167 VADCSR |= (1<<VADSC);
01168 }
01169
01170
01171
01172
01173
01174
01175
01176 void CalculateADCresults(void)
01177 {
01178 unsigned long calc;
01179 unsigned char index;
01180
01181 unsigned int thermV;
01182
01183
01184 for(index = 0; index < PACKSTACK; index++)
01185 {
01186 calc = ADCbuffer[index]<<2;
01187 calc = calc * ADCgain[index];
01188 calc >>= 16;
01189 CellV[index] = (unsigned int)(calc);
01190 if((unsigned int)calc < CELL_TOOLITTLEV)
01191 DoShutdown(SHUTDOWN_REASON_UNDERVOLTAGE);
01192 if((unsigned int)calc > CELL_TOOMUCHV)
01193 DoShutdown(SHUTDOWN_REASON_OVERVOLTAGE);
01194 }
01195
01198
01199
01200 calc = ADCbuffer[4];
01201 calc = calc * 344;
01202 VPA4 = (unsigned int) (calc >> 8);
01203
01204
01205
01206
01207
01208
01209
01210 calc = ADCbuffer[5];
01211 calc = calc * VTgain;
01212 OnChipTemp = (unsigned int) (calc / 1638);
01213
01214
01215
01216 index = ThermistorSelect;
01217 index++;
01218 index &= 0x03;
01219 thermV = ADCbuffer[index+7];
01220 Thermistor[ThermistorSelect] = thermV;
01221 }
01222
01223
01224
01225
01226
01227
01228
01229 unsigned int ReadTemperature(unsigned char channel)
01230 {
01231
01232 if(0 == channel)
01233 return OnChipTemp;
01234
01235
01236
01237
01238
01239
01240
01241 if(channel > 5)
01242 return 0;
01243
01245 return Thermistor[channel-1];
01246
01247 }
01248
01249
01250
01251
01252 unsigned int ReadCell(char cell)
01253 {
01254 if((cell == 0) || (cell > 4))
01255 return 0;
01256
01257 return CellV[cell-1];
01258 }
01259
01260
01261 void DisableCellBalancing(void)
01262 {
01263 CBCR = 0;
01264 }
01265
01266
01267 void EnableCellBalancing(void)
01268 {
01269 if(CellToBalance)
01270 {
01271 CBCR = (1<<(CellToBalance-1));
01272 }
01273 else
01274 CBCR = 0;
01275 }
01276
01277
01278
01279