00001
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <inavr.h>
00037
00038
00039 #define MODULE_SMBUS
00040 #include "smbus.h"
00041
00042 #include "timer.h"
00043 #include "pack.h"
00044 #include "analog.h"
00045 #include "calibration.h"
00046
00047 #include <iom406.h>
00048 #include "interpret.h"
00049 #include "main.h"
00050 #include "pwrmgmt.h"
00051
00052
00053
00054 typedef unsigned char (*ptr2funcUC_V)(void);
00055 extern ptr2funcUC_V SMB_ReadCmd[];
00056 extern ptr2funcUC_V SMB_WriteCmd[];
00057
00058
00059 unsigned char FastCRC(unsigned char LastCRC, unsigned char newbyte);
00060
00061
00062
00063
00064 #define HIGHEST_SMB_CMD 0x3F
00065
00066
00067
00068
00069
00070
00071 #define TWS_MASK 0xF8
00072 #define TWS_NSTAT 0xF8
00073
00074
00075 #define TWS_START 0x08
00076 #define TWS_RESTART 0x10
00077 #define TWS_WRITE_ACK 0x18
00078 #define TWS_WRITE_NAK 0x20
00079 #define TWS_TXDATA_ACK 0x28
00080 #define TWS_TXDATA_NAK 0x30
00081 #define TWS_LOST_ARB 0x38
00082
00083 #define TWS_READ_ACK 0x40
00084 #define TWS_READ_NAK 0x48
00085 #define TWS_RXDATA_ACK 0x50
00086 #define TWS_RXDATA_NACK 0x58
00087
00088
00089
00090 #define TWS_SLA_W 0x60
00091 #define TWS_SLA_R 0xA8
00092 #define TWS_RDATA 0x80
00093 #define TWS_RCMD 0x80
00094 #define TWS_RSTOP 0xA0
00095 #define TWS_REPEAT 0xA0
00096 #define TWS_RACK 0xB8
00097 #define TWS_RNAK 0xC0
00098 #define TWS_FINAL 0xC8
00099 #define TWS_BERR 0x00
00100
00101
00102
00103
00104 #define TWC_GO 0x85
00105 #define TWC_READ_NoACK 0x85
00106 #define TWC_START 0xA5
00107 #define TWC_STOP 0x94
00108 #define TWC_RESTART 0xB5
00109
00110
00111
00112
00113 unsigned char TEST50US = 0;
00114 unsigned char SMLOCK = 0;
00115
00116 unsigned char TW_MTxBuf[8];
00117 unsigned char TW_MTxBufCnt = 0;
00118 unsigned char TW_MTxBufIndex = 0;
00119
00120
00121
00122 unsigned char TW_TxBuf[36];
00123 unsigned char TW_TxBufCnt = 0;
00124 unsigned char TW_TxBufIndex = 0;
00125
00126 unsigned char TW_RxBuf[10];
00127 signed char TW_RxBufCnt = 0;
00128 unsigned char TW_RxBufIndex = 0;
00129
00130
00131
00132
00133
00134
00135
00136 unsigned char TWI_CmdFlags;
00137 #define SMB_GenBusTimeout 1
00138 #define SMB_SetUpReply 2
00139 #define SMB_GotCmdData 4
00140
00141 unsigned char CurrentCmd = 0xFF;
00142 unsigned char UsePEC = 0;
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 void InitSMBus(void)
00154 {
00155 SMB_RestoreBus();
00156 TWBCSR = (1<<TWBCIF) | (1<<TWBCIE) | (1<<TWBDT1) | (1<<TWBDT0) | (0<<TWBCIP);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 #pragma vector = TWI_BUS_CD_vect
00172 __interrupt void TWICD_ISR(void)
00173 {
00174
00175 SMBvariables[SMBV_BattMode][hibyte] &= ~(0xE3);
00176
00177 if(TWBCSR & (1<<TWBCIP))
00178 {
00179 TWBCSR &= ~(1<<TWBCIP);
00180 ChangePowerMode(POWERMODE_IDLE,0);
00181 }
00182 else
00183 {
00184 TWBCSR |= (1<<TWBCIP);
00185 ChangePowerMode(POWERMODE_ACTIVE,0);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 #pragma vector = PCINT0_vect
00200 __interrupt void PCINT0_ISR(void)
00201 {
00202 TEST50US = 0;
00203 }
00204
00205
00206
00207
00208 #pragma vector = PCINT1_vect
00209 __interrupt void PCINT1_ISR(void)
00210 {
00211 ;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 unsigned char TXmsg[4][4];
00292 volatile unsigned char TXmsgHead = 0;
00293 volatile unsigned char TXmsgTail = 0;
00294 volatile unsigned char TXmsgQty = 0;
00295
00296 #define TXmsgEmpty (TXmsgQty == 0)
00297 #define TXmsgFull (TXmsgQty == 4)
00298 #define TXmsgDelete {++TXmsgTail; TXmsgTail &= (4-1); TXmsgQty--;}
00299
00300
00301 void MasterInsertMsg(unsigned char addr, unsigned char cmd, unsigned int data)
00302 {
00303
00304
00305
00306
00307 unsigned char * ptr = TXmsg[TXmsgHead];
00308
00309 *ptr++ = addr;
00310 *ptr++ = cmd;
00311 *ptr++ = (unsigned char) data;
00312 *ptr = (unsigned char)(data>>8);
00313
00314 if(TXmsgFull)
00315 return;
00316
00317
00318 ++TXmsgHead;
00319 TXmsgHead &= (4-1);
00320 TXmsgQty++;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 enum {TW_IDLE=0, TW_Wait4Stop, TW_Wait4Cmd, TW_Wait4RW, TW_Wait4Data, TW_ReplyData, TW_MSLA_W, TW_MCMD_W, TW_MDATA_W };
00369
00370 unsigned char TWISR_state = TW_IDLE;
00371
00372
00373 #pragma vector = TWI_vect
00374 __interrupt void TWI_ISR(void)
00375 {
00376 static unsigned char TWISR_CmdFeatures = 0;
00377 unsigned char Status;
00378 unsigned char tmp;
00379
00380 Status = TWSR & 0xF8;
00381
00382 switch(TWISR_state)
00383 {
00384 default:
00385 case TW_IDLE:
00386 if(TWS_SLA_W == Status)
00387 {
00388 if(TWI_CmdFlags == SMB_GotCmdData)
00389 {
00390
00391
00392
00393 TWISR_state = TW_Wait4Stop;
00394 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
00395 return;
00396 }
00397 else
00398 TWISR_state = TW_Wait4Cmd;
00399 }
00400 else
00401 if(TWS_RSTOP == Status)
00402 {
00403 ;
00404 }
00405 else
00406 if(TWS_START == Status)
00407 {
00408 TWDR = TW_MTxBuf[TW_MTxBufIndex++];
00409 TWISR_state = TW_MSLA_W;
00410 }
00411 else
00412 {
00413 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00414 TWI_CmdFlags = SMB_GenBusTimeout;
00415 TWCR = (1<<TWEA) | (1<<TWEN);
00416 TWISR_state = TW_IDLE;
00417 return;
00418 }
00419 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00420 break;
00421
00422 case TW_Wait4Stop:
00423 if(TWS_RSTOP == Status)
00424 {
00425 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00426 TWISR_state = TW_IDLE;
00427 }
00428 else
00429 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
00430 break;
00431
00432
00433
00434
00435 case TW_Wait4Cmd:
00436 if(TWS_RCMD == Status)
00437 {
00438 tmp = TWDR;
00439 if(tmp <= HIGHEST_SMB_CMD)
00440 {
00441 CurrentCmd = tmp;
00442 tmp = SM_Cmd_Table[tmp][0];
00443 if(tmp & SMBslave)
00444 {
00445 TWISR_CmdFeatures = tmp;
00446 TWISR_state = TW_Wait4RW;
00447 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00448 return;
00449 }
00450 }
00451 }
00452
00453 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00454 TWI_CmdFlags = SMB_GenBusTimeout;
00455 TWCR = (1<<TWEA) | (1<<TWEN);
00456 TWISR_state = TW_IDLE;
00457 return;
00458
00459
00460
00461 case TW_Wait4RW:
00462 if(TWS_RDATA == Status)
00463 {
00464
00465 TW_RxBuf[0] = TWAR & 0xFE;
00466 TW_RxBuf[1] = CurrentCmd;
00467 TW_RxBuf[2] = TWDR;
00468 TW_RxBufIndex = 3;
00469 if(TWISR_CmdFeatures & SCWW)
00470 {
00471 TW_RxBufCnt = 1;
00472 }
00473 else
00474 if(TWISR_CmdFeatures & SCWG)
00475 {
00476 tmp = TWDR;
00477 if((tmp >= 1) && (tmp <= 32))
00478 TW_RxBufCnt = TWDR;
00479 else
00480 {
00481 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_BadSize;
00482 TWI_CmdFlags = SMB_GenBusTimeout;
00483 TWCR = (1<<TWEA) | (1<<TWEN);
00484 TWISR_state = TW_IDLE;
00485 return;
00486 }
00487 }
00488 else
00489 {
00490 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_AccessDenied;
00491 TWI_CmdFlags = SMB_GenBusTimeout;
00492 TWCR = (1<<TWEA) | (1<<TWEN);
00493 TWISR_state = TW_IDLE;
00494 return;
00495 }
00496 TWISR_state = TW_Wait4Data;
00497 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00498 }
00499 else
00500 if(TWS_REPEAT == Status)
00501 {
00502 if(TWISR_CmdFeatures & (SCRW | SCRG))
00503 {
00504 TWI_CmdFlags = SMB_SetUpReply;
00505 TWISR_state = TW_ReplyData;
00506 }
00507 else
00508 {
00509 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00510 TWI_CmdFlags = SMB_GenBusTimeout;
00511 TWCR = (1<<TWEA) | (1<<TWEN);
00512 TWISR_state = TW_IDLE;
00513 return;
00514 }
00515 TWCR = (1<<TWEA) | (1<<TWEN);
00516 return;
00517 }
00518 else
00519 {
00520 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00521 TWI_CmdFlags = SMB_GenBusTimeout;
00522 TWCR = (1<<TWEA) | (1<<TWEN);
00523 TWISR_state = TW_IDLE;
00524 return;
00525 }
00526 break;
00527
00528
00529 case TW_Wait4Data:
00530 if(TWS_RDATA == Status)
00531 {
00532 tmp = TWDR;
00533 if(--TW_RxBufCnt < -1)
00534 {
00535 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_BadSize;
00536 TWI_CmdFlags = SMB_GenBusTimeout;
00537 TWCR = (1<<TWEA) | (1<<TWEN);
00538 TWISR_state = TW_IDLE;
00539 return;
00540 }
00541 TW_RxBuf[TW_RxBufIndex++] = TWDR;
00542 }
00543
00544 else
00545 if(TWS_RSTOP == Status)
00546 {
00547
00548 if((TW_RxBufCnt > 0) || (TW_RxBufCnt < -1))
00549 {
00550 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_BadSize;
00551 }
00552 else
00553 {
00554 if(0 == TW_RxBufCnt)
00555 UsePEC = 0;
00556 else
00557 if(-1 == TW_RxBufCnt)
00558 UsePEC = 1;
00559
00560 TW_RxBufCnt = TW_RxBufIndex;
00561 TW_RxBufIndex = 0;
00562 TWI_CmdFlags = SMB_GotCmdData;
00563
00564 }
00565 TWISR_state = TW_IDLE;
00566 }
00567
00568 else
00569 {
00570 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00571 TWI_CmdFlags = SMB_GenBusTimeout;
00572 TWCR = (1<<TWEA) | (1<<TWEN);
00573 TWISR_state = TW_IDLE;
00574 return;
00575 }
00576
00577 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00578 break;
00579
00580
00581 case TW_ReplyData:
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 if((TWS_SLA_R == Status) || (TWS_RACK == Status))
00592 {
00593 TWDR = TW_TxBuf[TW_TxBufIndex++];
00594 if(--TW_TxBufCnt == 0)
00595 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
00596 else
00597 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00598 }
00599 else
00600 if(TWS_RNAK == Status)
00601 {
00602 if(TW_TxBufCnt == 1)
00603 {
00604 TW_TxBufCnt = 0;
00605 UsePEC = 0;
00606 }
00607 else
00608 if(TW_TxBufCnt == 0)
00609 UsePEC = 1;
00610 else
00611 {
00612 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00613 }
00614 TWISR_state = TW_IDLE;
00615 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00616 }
00617 else
00618
00619 {
00620
00621 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_BadSize;
00622 TWISR_state = TW_IDLE;
00623 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00624 }
00625 break;
00626
00627
00628
00629
00630
00631 case TW_MSLA_W:
00632 if(TWS_WRITE_ACK == Status)
00633 {
00634 TWDR = TW_MTxBuf[TW_MTxBufIndex++];
00635 TWISR_state = TW_MCMD_W;
00636 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00637 }
00638 else
00639 {
00640 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWSTO) | (1<<TWEN) | (1<<TWIE);
00641 TWISR_state = TW_IDLE;
00642 TW_MTxBufCnt = 0;
00643 TW_MTxBufIndex = 0;
00644 TXmsgDelete;
00645 SMLOCK = 0;
00646 }
00647 break;
00648
00649 case TW_MCMD_W:
00650 if(TWS_TXDATA_ACK == Status)
00651 {
00652 if(TW_MTxBufCnt > TW_MTxBufIndex)
00653 {
00654 TWDR = TW_MTxBuf[TW_MTxBufIndex++];
00655 TWISR_state = TW_MCMD_W;
00656 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00657 }
00658 else
00659 {
00660 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWSTO) | (1<<TWEN) | (1<<TWIE);
00661 TWISR_state = TW_IDLE;
00662 TW_MTxBufCnt = 0;
00663 TW_MTxBufIndex = 0;
00664 TXmsgDelete;
00665 SMLOCK = 0;
00666 }
00667 }
00668 else
00669 {
00670 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWSTO) | (1<<TWEN) | (1<<TWIE);
00671 TWISR_state = TW_IDLE;
00672 TW_MTxBufCnt = 0;
00673 TW_MTxBufIndex = 0;
00674 TXmsgDelete;
00675 SMLOCK = 0;
00676 }
00677 break;
00678
00679 }
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 void SMB_Master(void)
00695 {
00696 unsigned char * ptr;
00697 unsigned char PEC;
00698
00699 if(!(TW_MTxBufCnt))
00700 {
00701 if(TXmsgEmpty)
00702 return;
00703
00704 ptr = TXmsg[TXmsgTail];
00705 if(UsePEC)
00706 {
00707 PEC = FastCRC( 0, TW_MTxBuf[0] = *ptr++);
00708 PEC = FastCRC(PEC, TW_MTxBuf[1] = *ptr++);
00709 PEC = FastCRC(PEC, TW_MTxBuf[2] = *ptr++);
00710 PEC = FastCRC(PEC, TW_MTxBuf[3] = *ptr);
00711 TW_MTxBuf[4] = PEC;
00712 TW_MTxBufCnt = 5;
00713 }
00714 else
00715 {
00716 TW_MTxBuf[0] = *ptr++;
00717 TW_MTxBuf[1] = *ptr++;
00718 TW_MTxBuf[2] = *ptr++;
00719 TW_MTxBuf[3] = *ptr;
00720 TW_MTxBufCnt = 4;
00721 }
00722
00723 TW_MTxBufIndex = 0;
00724 SMLOCK = 0;
00725 TEST50US = 0;
00726 }
00727
00728 if(SMLOCK)
00729 return;
00730
00731 if(TEST50US)
00732 {
00733 __disable_interrupt();
00734 if((PINA & (1<<6)) && (TWISR_state == TW_IDLE))
00735 {
00736 SMLOCK = 1;
00737 TWBR = 12;
00738 TWCR = ((1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE));
00739 PCICR = 0;
00740 TEST50US = 0;
00741 }
00742 __enable_interrupt();
00743 return;
00744 }
00745
00746 if((PINA & (1<<6)) && (TWISR_state == TW_IDLE))
00747 {
00748 TEST50US = 1;
00749
00750 PCIFR = (1<<PCIF1) | (1<<PCIF0);
00751 PCMSK0 = (1<<6);
00752 PCICR = (1<<PCIE0);
00753 }
00754 }
00755
00756
00757
00758
00759
00760 void Check50uS(void)
00761 {
00762 if(TEST50US)
00763 SMB_Master();
00764 }
00765
00766
00767
00768
00769
00770
00771 void SMB_CmdInterpreter(void)
00772 {
00773 unsigned char temp;
00774
00775 if(SMB_GenBusTimeout == TWI_CmdFlags)
00776 {
00777 TWI_CmdFlags = 0;
00778
00779 SetGenericTimer(SMBfaultTimer, 26);
00780 return;
00781 }
00782 else
00783 if(SMB_SetUpReply == TWI_CmdFlags)
00784 {
00785 TWI_CmdFlags = 0;
00786 TW_TxBufIndex = 0;
00787 TW_TxBufCnt = 0;
00788 if(0 != SMB_ReadCmd[CurrentCmd]())
00789 {
00790 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnsuptdCommand;
00791 SetGenericTimer(SMBfaultTimer, 26);
00792 TW_TxBufIndex = 0;
00793 TW_TxBufCnt = 0;
00794 return;
00795 }
00796 else
00797 {
00798
00799 temp = FastCRC(0, (TWAR & 0xFE));
00800 temp = FastCRC(temp, CurrentCmd);
00801 temp = FastCRC(temp, (TWAR | 1));
00802
00803 do {temp = FastCRC(temp, TW_TxBuf[TW_TxBufIndex++]);}
00804 while(TW_TxBufIndex != TW_TxBufCnt);
00805
00806 TW_TxBuf[TW_TxBufIndex] = temp;
00807 TW_TxBufCnt++;
00808 TW_TxBufIndex = 0;
00809 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
00810 }
00811 return;
00812 }
00813 else
00814 if(SMB_GotCmdData == TWI_CmdFlags)
00815 {
00816
00817
00818
00819
00820
00821
00822 if(UsePEC)
00823 {
00824 temp = 0;
00825
00826 do { temp = FastCRC(temp, TW_RxBuf[TW_RxBufIndex++]); }
00827 while(TW_RxBufCnt != TW_RxBufIndex);
00828
00829 if(temp)
00830 {
00831 SMBvariables[SMBV_BattStatus][lobyte] |= SMBerr_UnknownError;
00832
00833
00834 SetGenericTimer(SMBfaultTimer, 26);
00835 TWI_CmdFlags = 0;
00836 return;
00837 }
00838 }
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 TW_RxBufIndex = 2;
00849
00850
00851 if(0 != SMB_WriteCmd[CurrentCmd]())
00852 {
00853 TW_RxBufIndex = 0;
00854 TW_RxBufCnt = 0;
00855
00856
00857 SetGenericTimer(SMBfaultTimer, 26);
00858 TWI_CmdFlags = 0;
00859 return;
00860 }
00861
00862 TWI_CmdFlags = 0;
00863 return;
00864 }
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874 void SMB_RestoreBus(void)
00875 {
00876 TWCR = 0;
00877 TWISR_state = TW_IDLE;
00878 TWAR = BATTERY_ADDR;
00879 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
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
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 void FillResponseInt(unsigned int info)
00921 {
00922 TW_TxBuf[0] = (unsigned char) info;
00923 TW_TxBuf[1] = (unsigned char) (info >> 8);
00924
00925 TW_TxBufIndex = 0;
00926 TW_TxBufCnt = 2;
00927 }
00928
00929
00930 void FillResponseStr(char __flash * source)
00931 {
00932 unsigned char * dest = TW_TxBuf;
00933 unsigned char ctr = 0;
00934
00935 for(;;)
00936 {
00937 if(*dest++ = *source++)
00938 ctr++;
00939 else
00940 break;
00941 }
00942
00943 TW_TxBufIndex = 0;
00944 TW_TxBufCnt = ctr;
00945 }
00946
00947
00948
00949
00950
00951
00952 unsigned char SMBR_MfrAccess(void)
00953 {
00954 FillResponseInt(SMBvar_int[SMBV_MfrAccess]);
00955 return 0;
00956 }
00957
00958
00959
00960 unsigned char SMBR_RemCapAlm(void)
00961 {
00962 FillResponseInt(SMBvar_int[SMBV_RemCapAlm]);
00963 return 0;
00964 }
00965
00966
00967 unsigned char SMBR_RemTimeAlm(void)
00968 {
00969 FillResponseInt(SMBvar_int[SMBV_RemTimeAlm]);
00970 return 0;
00971 }
00972
00973
00974 unsigned char SMBR_BattMode(void)
00975 {
00976 FillResponseInt(SMBvar_int[SMBV_BattMode]);
00977 return 0;
00978 }
00979
00980
00981 unsigned char SMBR_AtRate(void)
00982 {
00983 FillResponseInt(SMBvar_int[SMBV_AtRate]);
00984 return 0;
00985 }
00986
00987
00988 unsigned char SMBR_AtRateTTF(void)
00989 {
00990 unsigned int temp = AtRateTTF();
00991 SMBvar_int[SMBV_AtRateTTF] = temp;
00992 FillResponseInt(temp);
00993 return 0;
00994 }
00995
00996
00997 unsigned char SMBR_AtRateTTE(void)
00998 {
00999 unsigned int temp = AtRateTTE();
01000 SMBvar_int[SMBV_AtRateTTE] = temp;
01001 FillResponseInt(temp);
01002 return 0;
01003 }
01004
01005
01006 unsigned char SMBR_AtRateOK(void)
01007 {
01008 unsigned int temp = AtRateOK();
01009 SMBvar_int[SMBV_AtRateOK] = temp;
01010 FillResponseInt(temp);
01011 return 0;
01012 }
01013
01014
01015 unsigned char SMBR_Temperature(void)
01016 {
01017 unsigned int temp = GetTemperature();
01018 SMBvar_int[SMBV_Temperature] = temp;
01019 FillResponseInt(temp);
01020 return 0;
01021 }
01022
01023
01024 unsigned char SMBR_Voltage(void)
01025 {
01026 unsigned int volt = GetVoltage();
01027 SMBvar_int[SMBV_Voltage] = volt;
01028 FillResponseInt(volt);
01029 return 0;
01030 }
01031
01032
01033 unsigned char SMBR_Current(void)
01034 {
01035 signed int current = Current1Sec();
01036
01037 SMBvar_int[SMBV_Current] = (unsigned int) current;
01038 FillResponseInt((unsigned int) current);
01039 return 0;
01040 }
01041
01042
01043 unsigned char SMBR_AvgCurrent(void)
01044 {
01045 signed int current = CCarray_Average();
01046
01047 SMBvar_int[SMBV_AvgCurrent] = (unsigned int) current;
01048 FillResponseInt((unsigned int) current);
01049 return 0;
01050 }
01051
01052
01053 unsigned char SMBR_MaxError(void)
01054 {
01055 FillResponseInt(SMBvar_int[SMBV_MaxError] = 0);
01056 return 0;
01057 }
01058
01059
01060 unsigned char SMBR_RelSOC(void)
01061 {
01062 unsigned int temp = RelativeSOC();
01063
01064 SMBvar_int[SMBV_RelSOC] = temp;
01065 FillResponseInt(temp);
01066 return 0;
01067 }
01068
01069
01070 unsigned char SMBR_AbsSOC(void)
01071 {
01072 unsigned int temp = AbsoluteSOC();
01073 SMBvar_int[SMBV_AbsSOC] = temp;
01074 FillResponseInt(temp);
01075 return 0;
01076 }
01077
01078
01079 unsigned char SMBR_RemCap(void)
01080 {
01081 unsigned int cap = RemainingCap();
01082 FillResponseInt(cap);
01083 SMBvar_int[SMBV_RemCap] = cap;
01084 return 0;
01085 }
01086
01087
01088 unsigned char SMBR_FullChgCap(void)
01089 {
01090 unsigned int cap = FullChgCap();
01091 FillResponseInt(cap);
01092 SMBvar_int[SMBV_FullChgCap] = cap;
01093 return 0;
01094 }
01095
01096
01097 unsigned char SMBR_RunTTE(void)
01098 {
01099 unsigned int temp = TimeToEmpty(0);
01100 FillResponseInt(temp);
01101 SMBvar_int[SMBV_RunTTE] = temp;
01102 return 0;
01103 }
01104
01105
01106 unsigned char SMBR_AvgTTE(void)
01107 {
01108 unsigned int temp = TimeToEmpty(1);
01109 FillResponseInt(temp);
01110 SMBvar_int[SMBV_AvgTTE] = temp;
01111 return 0;
01112 }
01113
01114
01115 unsigned char SMBR_AvgTTF(void)
01116 {
01117 unsigned int temp = AvgTimeToFull();
01118 FillResponseInt(temp);
01119 SMBvar_int[SMBV_AvgTTF] = temp;
01120 return 0;
01121 }
01122
01123
01124
01125
01126
01127
01128 unsigned char SMBR_ChgCurrent(void)
01129 {
01130 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01131 FillResponseInt(SMBvar_int[SMBV_ChgCurrent]);
01132 return 0;
01133 }
01134
01135
01136 unsigned char SMBR_ChgVoltage(void)
01137 {
01138 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01139 FillResponseInt(SMBvar_int[SMBV_ChgVoltage]);
01140 return 0;
01141 }
01142
01143
01144
01145
01146
01147 unsigned char SMBR_BattStatus(void)
01148 {
01149 FillResponseInt(SMBvar_int[SMBV_BattStatus]);
01150 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01151 return 0;
01152 }
01153
01154
01155 unsigned char SMBR_CycleCount(void)
01156 {
01157 FillResponseInt(SMBvar_int[SMBV_CycleCount]);
01158 return 0;
01159 }
01160
01161
01162 unsigned char SMBR_DesignCap(void)
01163 {
01164 unsigned long temp;
01165
01166 if(SMBvariables[SMBV_BattMode][hibyte] & CAPACITY_MODE)
01167 temp = PACK_DESIGNCAPMW;
01168 else
01169 temp = PACK_DESIGNCAPC5;
01170
01171 FillResponseInt(temp);
01172 SMBvar_int[SMBV_DesignCap] = (unsigned int)temp;
01173 return 0;
01174 }
01175
01176
01177 unsigned char SMBR_DesignVolt(void)
01178 {
01179 FillResponseInt(PACK_NOMINALV);
01180 SMBvar_int[SMBV_DesignVolt] = PACK_NOMINALV;
01181 return 0;
01182 }
01183
01184
01185 unsigned char SMBR_SpecInfo(void)
01186 {
01187 FillResponseInt(SMBvar_int[SMBV_SpecInfo]);
01188 return 0;
01189 }
01190
01191
01192 unsigned char SMBR_MfrDate(void)
01193 {
01194 FillResponseInt(SMBvar_int[SMBV_MfrDate]);
01195 return 0;
01196 }
01197
01198
01199 unsigned char SMBR_SerialNo(void)
01200 {
01201 FillResponseInt(SMBvar_int[SMBV_SerialNo]);
01202 return 0;
01203
01204 }
01205
01206
01207 unsigned char SMBR_MfrName(void)
01208 {
01209 FillResponseStr(str_MfrName);
01210 return 0;
01211 }
01212
01213
01214
01215 unsigned char SMBR_DeviceName(void)
01216 {
01217 FillResponseStr(str_DeviceName);
01218 return 0;
01219 }
01220
01221
01222 unsigned char SMBR_DeviceChem(void)
01223 {
01224 FillResponseStr(str_DeviceChem);
01225 return 0;
01226 }
01227
01228
01229 unsigned char SMBR_MfrData(void)
01230 {
01231 FillResponseStr(str_MfrData);
01232 return 0;
01233 }
01234
01235
01236 unsigned char SMBR_Opt5(void)
01237 {
01238 FillResponseInt(12345);
01239 return 0;
01240
01241 }
01242
01243
01244 unsigned char SMBR_Opt4(void)
01245 {
01246 FillResponseInt( calibration_state );
01247 return 0;
01248
01249 }
01250
01251
01252 unsigned char SMBR_Opt3(void)
01253 {
01254
01255 return SMBerr_ReservedCommand;
01256 }
01257
01258
01259 unsigned char SMBR_Opt2(void)
01260 {
01261
01262 return SMBerr_ReservedCommand;
01263 }
01264
01265
01266 unsigned char SMBR_Opt1(void)
01267 {
01268
01269 return SMBerr_ReservedCommand;
01270 }
01271
01272
01273 unsigned char SMBR_invalid(void)
01274 {
01275 return SMBerr_UnsuptdCommand;
01276 }
01277
01278
01279
01280
01281
01282
01283 ptr2funcUC_V SMB_ReadCmd[HIGHEST_SMB_CMD+1] =
01284 {
01285 SMBR_MfrAccess,
01286 SMBR_RemCapAlm,
01287 SMBR_RemTimeAlm,
01288 SMBR_BattMode,
01289 SMBR_AtRate,
01290 SMBR_AtRateTTF,
01291 SMBR_AtRateTTE,
01292 SMBR_AtRateOK,
01293 SMBR_Temperature,
01294 SMBR_Voltage,
01295 SMBR_Current,
01296 SMBR_AvgCurrent,
01297 SMBR_MaxError,
01298 SMBR_RelSOC,
01299 SMBR_AbsSOC,
01300 SMBR_RemCap,
01301 SMBR_FullChgCap,
01302 SMBR_RunTTE,
01303 SMBR_AvgTTE,
01304 SMBR_AvgTTF,
01305 SMBR_ChgCurrent,
01306 SMBR_ChgVoltage,
01307 SMBR_BattStatus,
01308 SMBR_CycleCount,
01309 SMBR_DesignCap,
01310 SMBR_DesignVolt,
01311 SMBR_SpecInfo,
01312 SMBR_MfrDate,
01313 SMBR_SerialNo,
01314 SMBR_invalid,
01315 SMBR_invalid,
01316 SMBR_invalid,
01317 SMBR_MfrName,
01318 SMBR_DeviceName,
01319 SMBR_DeviceChem,
01320 SMBR_MfrData,
01321 SMBR_invalid,
01322 SMBR_invalid,
01323 SMBR_invalid,
01324 SMBR_invalid,
01325 SMBR_invalid,
01326 SMBR_invalid,
01327 SMBR_invalid,
01328 SMBR_invalid,
01329 SMBR_invalid,
01330 SMBR_invalid,
01331 SMBR_invalid,
01332 SMBR_Opt5,
01333 SMBR_invalid,
01334 SMBR_invalid,
01335 SMBR_invalid,
01336 SMBR_invalid,
01337 SMBR_invalid,
01338 SMBR_invalid,
01339 SMBR_invalid,
01340 SMBR_invalid,
01341 SMBR_invalid,
01342 SMBR_invalid,
01343 SMBR_invalid,
01344 SMBR_invalid,
01345 SMBR_Opt4,
01346 SMBR_Opt3,
01347 SMBR_Opt2,
01348 SMBR_Opt1
01349 };
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 unsigned char SMBW_MfrAccess(void)
01361 {
01362 unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
01363 SMBvar_int[SMBV_MfrAccess] = temp | (TW_RxBuf[TW_RxBufIndex]<<8);
01364 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01365 return 0;
01366 }
01367
01368
01369 unsigned char SMBW_RemCapAlm(void)
01370 {
01371 unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
01372 SMBvar_int[SMBV_RemCapAlm] = temp | (TW_RxBuf[TW_RxBufIndex]<<8);
01373 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01374 return 0;
01375 }
01376
01377
01378 unsigned char SMBW_RemTimeAlm(void)
01379 {
01380 unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
01381 SMBvar_int[SMBV_RemTimeAlm] = temp | (TW_RxBuf[TW_RxBufIndex]<<8);
01382 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01383 return 0;
01384 }
01385
01386
01387 unsigned char SMBW_BattMode(void)
01388 {
01389 unsigned char tempH = TW_RxBuf[TW_RxBufIndex+1];
01390 unsigned char tempL;
01391
01392 tempL = SMBvariables[SMBV_BattMode][lobyte] & 0xF0;
01393
01394 if(tempH & 0x1C)
01395 return SMBerr_AccessDenied;
01396
01397
01398 if(~(tempL & INTERNAL_CHARGE_CONTROLLER))
01399 {
01400 tempH &= ~CHARGE_CONTROLLER_ENABLED;
01401 }
01402
01403
01404 if(tempH & PRIMARY_BATTERY)
01405 {
01406 ;
01407 }
01408
01409 if(tempH & ALARM_MODE)
01410 SetAlarmMode;
01411
01412
01413 if(tempH & CHARGER_MODE)
01414 {
01415 ;
01416 }
01417
01418
01419 if(tempH & CAPACITY_MODE)
01420 {
01421 ;
01422 }
01423
01424
01425 SMBvar_int[SMBV_BattMode] = tempL | (tempH<<8);
01426
01427 return 0;
01428 }
01429
01430
01431
01432 unsigned char SMBW_AtRate(void)
01433 {
01434 unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
01435 SMBvar_int[SMBV_AtRate] = temp | (TW_RxBuf[TW_RxBufIndex++]<<8);
01436 SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;
01437 return 0;
01438 }
01439
01440 unsigned char SMBW_Opt5(void)
01441 {
01442 __disable_interrupt();
01443 MCUSR = 0x1F;
01444
01445
01446 asm("jmp 0x9000");
01447
01448
01449 return(1);
01450
01451
01452 }
01453
01454 unsigned char SMBW_Opt4(void)
01455 {
01456 calibration_state_req = TW_RxBuf[TW_RxBufIndex++];
01457 calibration_state_req |= (unsigned int)TW_RxBuf[TW_RxBufIndex++] << 8;
01458 SetCalibRequest;
01459 return 0;
01460 }
01461
01462 unsigned char SMBW_Opt3(void)
01463 {
01464 return SMBerr_ReservedCommand;
01465 }
01466
01467 unsigned char SMBW_Opt2(void)
01468 {
01469 return SMBerr_ReservedCommand;
01470 }
01471
01472 unsigned char SMBW_Opt1(void)
01473 {
01474 return SMBerr_ReservedCommand;
01475 }
01476
01477 unsigned char SMBW_Invalid(void)
01478 {
01479 return SMBerr_AccessDenied;
01480 }
01481
01482
01483
01484
01485 ptr2funcUC_V SMB_WriteCmd[HIGHEST_SMB_CMD+1] =
01486 {
01487 SMBW_MfrAccess,
01488 SMBW_RemCapAlm,
01489 SMBW_RemTimeAlm,
01490 SMBW_BattMode,
01491 SMBW_AtRate,
01492 SMBW_Invalid,
01493 SMBW_Invalid,
01494 SMBW_Invalid,
01495 SMBW_Invalid,
01496 SMBW_Invalid,
01497 SMBW_Invalid,
01498 SMBW_Invalid,
01499 SMBW_Invalid,
01500 SMBW_Invalid,
01501 SMBW_Invalid,
01502 SMBW_Invalid,
01503
01504 SMBW_Invalid,
01505 SMBW_Invalid,
01506 SMBW_Invalid,
01507 SMBW_Invalid,
01508 SMBW_Invalid,
01509 SMBW_Invalid,
01510 SMBW_Invalid,
01511 SMBW_Invalid,
01512 SMBW_Invalid,
01513 SMBW_Invalid,
01514 SMBW_Invalid,
01515 SMBW_Invalid,
01516 SMBW_Invalid,
01517 SMBW_Invalid,
01518 SMBW_Invalid,
01519 SMBW_Invalid,
01520
01521 SMBW_Invalid,
01522 SMBW_Invalid,
01523 SMBW_Invalid,
01524 SMBW_Invalid,
01525 SMBW_Invalid,
01526 SMBW_Invalid,
01527 SMBW_Invalid,
01528 SMBW_Invalid,
01529 SMBW_Invalid,
01530 SMBW_Invalid,
01531 SMBW_Invalid,
01532 SMBW_Invalid,
01533 SMBW_Invalid,
01534 SMBW_Invalid,
01535 SMBW_Invalid,
01536 SMBW_Opt5,
01537
01538 SMBW_Invalid,
01539 SMBW_Invalid,
01540 SMBW_Invalid,
01541 SMBW_Invalid,
01542 SMBW_Invalid,
01543 SMBW_Invalid,
01544 SMBW_Invalid,
01545 SMBW_Invalid,
01546 SMBW_Invalid,
01547 SMBW_Invalid,
01548 SMBW_Invalid,
01549 SMBW_Invalid,
01550 SMBW_Opt4,
01551 SMBW_Opt3,
01552 SMBW_Opt2,
01553 SMBW_Opt1
01554 };
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 __flash unsigned char crctable[16] = {0,0x07,0x0E,0x90, 0x1c,0x1b,0x12,0x15, 0x38,0x3F,0x36,0x31, 0x24,0x23,0x2A,0x2D};
01570 __flash unsigned char crctable2[16] = {0,0x70,0xE0,0x90, 0xC1,0xB1,0x21,0x51, 0x83,0xF3,0x63,0x13, 0x42,0x32,0xA2,0xD2};
01571
01572 unsigned char FastCRC(unsigned char LastCRC, unsigned char newbyte)
01573 {
01574 unsigned char index;
01575
01576 index = newbyte;
01577 index ^= LastCRC;
01578 index >>= 4;
01579 LastCRC &= 0x0F;
01580 LastCRC ^= crctable2[index];
01581
01582 index = LastCRC;
01583 index ^= newbyte;
01584 index &= 0x0F;
01585 LastCRC &= 0xF0;
01586 LastCRC ^= crctable[index];
01587
01588 return(LastCRC);
01589 }
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01617
01618 void InitSMBvariables(void)
01619 {
01620 SMBvar_int[SMBV_MfrAccess] = 0x4060;
01621 SMBvar_int[SMBV_RemCapAlm] = (PACK_DESIGNCAPTYP / 10);
01622 SMBvar_int[SMBV_RemTimeAlm] = 0x000A;
01623 SMBvar_int[SMBV_BattMode ] = 0x0000;
01624 SMBvar_int[SMBV_AtRate ] = 0x0000;
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647 SMBvar_int[SMBV_BattStatus] = 0x0080;
01648 SMBvar_int[SMBV_CycleCount] = 0x0000;
01649
01650
01651
01652
01653
01654
01655 SMBvar_int[SMBV_SpecInfo ] = 0x0031;
01656 SMBvar_int[SMBV_MfrDate ] = ((2005-1980)<<9)+(8<<5)+(31);
01657 SMBvar_int[SMBV_SerialNo ] = 12345;
01658
01659
01660
01661
01662 SetMaxTopAcc((long)6600*10727);
01663
01664 }
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724