00001
00040
00041
00042
00043
00044 #include <inavr.h>
00045
00046 #define MODULE_BOOTLDR
00047 #include "bootldr.h"
00048
00049 #include "iom406.h"
00050 #include "flash.h"
00051
00052
00053 void TWI_handler(void);
00054 void SMB_RestoreBus(void);
00055 unsigned char FastCRC(unsigned char LastCRC, unsigned char newbyte);
00056 void SMB_BusTimeout(void);
00057 void SMB_Reply(void);
00058 void SMB_CmdInterpreter(void);
00059 void LoopMemory(void);
00060
00061
00062
00063
00064
00065 #define HIGHEST_SMB_CMD 0x3F
00066
00067
00068
00069
00070
00071
00072 #define TWS_MASK 0xF8
00073 #define TWS_NSTAT 0xF8
00074
00075
00076 #define TWS_START 0x08
00077 #define TWS_RESTART 0x10
00078 #define TWS_WRITE_ACK 0x18
00079 #define TWS_WRITE_NAK 0x20
00080 #define TWS_TXDATA_ACK 0x28
00081 #define TWS_TXDATA_NAK 0x30
00082 #define TWS_LOST_ARB 0x38
00083
00084 #define TWS_READ_ACK 0x40
00085 #define TWS_READ_NAK 0x48
00086 #define TWS_RXDATA_ACK 0x50
00087 #define TWS_RXDATA_NACK 0x58
00088
00089
00090
00091 #define TWS_SLA_W 0x60
00092 #define TWS_SLA_R 0xA8
00093 #define TWS_RDATA 0x80
00094 #define TWS_RCMD 0x80
00095 #define TWS_RSTOP 0xA0
00096 #define TWS_REPEAT 0xA0
00097 #define TWS_RACK 0xB8
00098 #define TWS_RNAK 0xC0
00099 #define TWS_FINAL 0xC8
00100 #define TWS_BERR 0x00
00101
00102
00103
00104
00105 #define TWC_GO 0x85
00106 #define TWC_READ_NoACK 0x85
00107 #define TWC_START 0xA5
00108 #define TWC_STOP 0x94
00109 #define TWC_RESTART 0xB5
00110
00111
00112
00113
00114
00115 unsigned char TW_TxBuf[36];
00116 unsigned char TW_TxBufCnt;
00117 unsigned char TW_TxBufIndex;
00118
00119 unsigned char TW_RxBuf[36];
00120 unsigned char TW_RxBufCnt;
00121 unsigned char TW_RxBufIndex;
00122
00123 unsigned char TW_state;
00124 unsigned char UsePEC;
00125
00126 unsigned char LoopFlag;
00127 unsigned char BigData;
00128 unsigned char src_i;
00129 unsigned char dest_i;
00130 unsigned char ctr;
00131 unsigned char lomemptr;
00132 unsigned char himemptr;
00133 unsigned char __flash *fptr;
00134 unsigned int eptr;
00135
00136 unsigned char SRAMbuffer[128];
00137
00138
00139
00140
00141
00142
00143 unsigned char TWI_CmdFlags;
00144 #define SMB_GenBusTimeout 1
00145 #define SMB_SetUpReply 2
00146 #define SMB_GotCmdData 4
00147
00148
00149 unsigned char Status;
00150 #define SUCCESS 0
00151 #define BUSY 1
00152 #define BADPARAM 2
00153 #define CRCERROR 3
00154 #define FAILURE 0xFF
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00173
00174 void __low_level_init(void)
00175 {
00176 unsigned char __flash * ptr = 0;
00177
00178 if(!(MCUSR))
00179 return;
00180
00181
00182
00183 if(MCUSR & (1<<WDRF))
00184 {
00186 }
00187
00188
00189
00190 if((*ptr++ != 0xFF) || (*ptr != 0xFF))
00191 {
00192 MCUCR &= (1<<IVSEL);
00193 asm("jmp 0");
00194 }
00195
00196
00197 }
00198
00199
00200
00201
00202 void init_boot(void)
00203 {
00204 __disable_interrupt();
00205 TW_TxBufCnt = 0;
00206 TW_TxBufIndex = 0;
00207 TW_RxBufCnt = 0;
00208 TW_RxBufIndex = 0;
00209 TW_state = 0;
00210 UsePEC = 0;
00211 Status = SUCCESS;
00212 LoopFlag = 0;
00213 BigData = 0;
00214
00215 SMB_RestoreBus();
00216 TWBCSR = (1<<TWBCIF) | (1<<TWBDT1) | (1<<TWBDT0) | (0<<TWBCIP);
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 #ifdef ENABLE_TESTCODE
00228
00229 void BOOT_TEST_EF(void)
00230 {
00231
00232 TWI_CmdFlags = SMB_GotCmdData;
00233 TW_RxBuf[TWRX_CMD] = 'E';
00234 TW_RxBuf[TWRX_MEM] = 'F';
00235 TW_RxBuf[TWRX_LOADDR] = 0x80;
00236 TW_RxBuf[TWRX_HIADDR] = 0;
00237 UsePEC = 0;
00238 }
00239
00240 void BOOT_TEST_EE(void)
00241 {
00242
00243 TWI_CmdFlags = SMB_GotCmdData;
00244 TW_RxBuf[TWRX_CMD] = 'E';
00245 TW_RxBuf[TWRX_MEM] = 'E';
00246 TW_RxBuf[TWRX_LOADDR] = 0xF0;
00247 TW_RxBuf[TWRX_HIADDR] = 0x01;
00248 TW_RxBuf[TWRX_SIZE] = 0x0a;
00249 UsePEC = 0;
00250 }
00251
00252 void BOOT_TEST_I(void)
00253 {
00254 unsigned char i;
00255 TWI_CmdFlags = SMB_GotCmdData;
00256 TW_RxBuf[TWRX_CMD] = 'I';
00257 TW_RxBuf[TWRX_LOADDR] = 0;
00258 TW_RxBuf[TWRX_HIADDR] = 0;
00259 for(i=0; i<16; i++)
00260 TW_RxBuf[TWRX_DATA+i]=i+33;
00261 TW_RxBuf[TWRX_OFFSET] = 0x33;
00262 TW_RxBuf[TWRX_SIZE] = 16;
00263 UsePEC = 0;
00264 }
00265
00266 void BOOT_TEST_WF(void)
00267 {
00268 unsigned char i;
00269
00270
00271 for(i=0; i<128; i++)
00272 SRAMbuffer[i]=i+33;
00273 TWI_CmdFlags = SMB_GotCmdData;
00274 TW_RxBuf[TWRX_CMD] = 'W';
00275 TW_RxBuf[TWRX_MEM] = 'F';
00276 TW_RxBuf[TWRX_LOADDR] = 0x80;
00277 TW_RxBuf[TWRX_HIADDR] = 0;
00278 UsePEC = 0;
00279 }
00280
00281 void BOOT_TEST_WE(void)
00282 {
00283 unsigned char i;
00284
00285 for(i=0; i<128; i++)
00286 SRAMbuffer[i]=i+33;
00287 TWI_CmdFlags = SMB_GotCmdData;
00288 TW_RxBuf[TWRX_CMD] = 'W';
00289 TW_RxBuf[TWRX_MEM] = 'E';
00290 TW_RxBuf[TWRX_LOADDR] = 0xF0;
00291 TW_RxBuf[TWRX_HIADDR] = 0x01;
00292 TW_RxBuf[TWRX_OFFSET] = 0x33;
00293 TW_RxBuf[TWRX_SIZE] = 0x0c;
00294 UsePEC = 0;
00295 }
00296
00297 void BOOT_TEST_PF(void)
00298 {
00299 unsigned char i;
00300
00301
00302 for(i=0; i<128; i++)
00303 SRAMbuffer[i] = 0;
00304
00305 TWI_CmdFlags = SMB_GotCmdData;
00306 TW_RxBuf[TWRX_CMD] = 'P';
00307 TW_RxBuf[TWRX_MEM] = 'F';
00308 TW_RxBuf[TWRX_LOADDR] = 0x80;
00309 TW_RxBuf[TWRX_HIADDR] = 0x00;
00310 UsePEC = 0;
00311 }
00312
00313 void BOOT_TEST_PE(void)
00314 {
00315 unsigned char i;
00316
00317
00318 for(i=0; i<128; i++)
00319 SRAMbuffer[i] = 0;
00320
00321 TWI_CmdFlags = SMB_GotCmdData;
00322 TW_RxBuf[TWRX_CMD] = 'P';
00323 TW_RxBuf[TWRX_MEM] = 'E';
00324 TW_RxBuf[TWRX_LOADDR] = 0xE0;
00325 TW_RxBuf[TWRX_HIADDR] = 0x01;
00326 TW_RxBuf[TWRX_OFFSET] = 0x00;
00327 TW_RxBuf[TWRX_SIZE] = 0x20;
00328 UsePEC = 0;
00329 }
00330
00331 unsigned char bigI;
00332
00333 void BOOT_TEST_bigI(void)
00334 {
00335 unsigned char i;
00336 TW_RxBuf[TWRX_BLKCNT] = 32;
00337 TWI_CmdFlags = SMB_GotCmdData;
00338 TW_RxBuf[TWRX_CMD] = 'I';
00339 for(i=0; i<26; i++)
00340 TW_RxBuf[TWRX_DATA+i]=i+1;
00341 bigI = i+1;
00342 TW_RxBuf[TWRX_OFFSET] = 0;
00343 TW_RxBuf[TWRX_SIZE] = 128;
00344 UsePEC = 0;
00345 }
00346
00347 void BOOT_TEST_bigI32(void)
00348 {
00349 unsigned char i;
00350 TW_RxBuf[TWRX_BLKCNT] = 32;
00351 TWI_CmdFlags = SMB_GotCmdData;
00352 for(i=0; i<32; i++)
00353 TW_RxBuf[3+i]=i+bigI;
00354 bigI += i;
00355 }
00356
00357 void BOOT_TEST_bigI8(void)
00358 {
00359 unsigned char i;
00360 TW_RxBuf[TWRX_BLKCNT] = 6;
00361 TWI_CmdFlags = SMB_GotCmdData;
00362 for(i=0; i<6; i++)
00363 TW_RxBuf[3+i]=i+bigI;
00364 }
00365
00366
00367
00368
00369
00370 void TestManager(void)
00371 {
00372 static unsigned char testctr = 0;
00373
00374 switch(testctr)
00375 {
00376 case 0:
00377 BOOT_TEST_I();
00378 testctr++;
00379 break;
00380
00381 case 1:
00382 BOOT_TEST_WF();
00383 testctr++;
00384 break;
00385
00386 case 2:
00387 BOOT_TEST_PF();
00388 testctr++;
00389 break;
00390
00391 case 3:
00392 BOOT_TEST_EF();
00393 testctr++;
00394 break;
00395
00396 case 4:
00397 if(!LoopFlag)
00398 {
00399 BOOT_TEST_WE();
00400 testctr++;
00401 }
00402 break;
00403
00404 case 5:
00405 if(!LoopFlag)
00406 {
00407 BOOT_TEST_EE();
00408 testctr++;
00409 }
00410 break;
00411
00412 case 6:
00413 if(!LoopFlag)
00414 {
00415 BOOT_TEST_PE();
00416 testctr++;
00417 }
00418 break;
00419
00420 case 7:
00421 BOOT_TEST_bigI();
00422 testctr++;
00423 break;
00424
00425 case 8:
00426 BOOT_TEST_bigI32();
00427 testctr++;
00428 break;
00429
00430 case 9:
00431 BOOT_TEST_bigI32();
00432 testctr++;
00433 break;
00434
00435 case 10:
00436 BOOT_TEST_bigI32();
00437 testctr++;
00438 break;
00439
00440 case 11:
00441 BOOT_TEST_bigI8();
00442 testctr++;
00443 break;
00444
00445 case 12:
00446 break;
00447
00448 }
00449 }
00450
00451 #endif
00452
00453
00454
00455
00456
00457
00458 void main(void)
00459 {
00460 init_boot();
00461
00462 for(;;)
00463 {
00464
00465 #ifdef ENABLE_TESTCODE
00466 TestManager();
00467 #endif
00468
00469 if(TWCR & (1<<TWINT))
00470 TWI_handler();
00471
00472 if(TWI_CmdFlags)
00473 {
00474 if(TWI_CmdFlags == SMB_SetUpReply)
00475 {
00476 TWI_CmdFlags = 0;
00477 SMB_Reply();
00478 }
00479 else
00480 if(TWI_CmdFlags == SMB_GotCmdData)
00481 {
00482 TWI_CmdFlags = 0;
00483 SMB_CmdInterpreter();
00484 }
00485 else
00486 if(TWI_CmdFlags == SMB_GenBusTimeout)
00487 {
00488 TWI_CmdFlags = 0;
00489 SMB_BusTimeout();
00490 }
00491 }
00492
00493 if(LoopFlag)
00494 LoopMemory();
00495 }
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 enum {TW_IDLE=0, TW_Wait4Cmd, TW_Wait4RW, TW_Wait4Data, TW_ReplyData, TW_MSLA_W, TW_MCMD_W, TW_MDATA_W };
00517
00518 void TWI_handler(void)
00519 {
00520 unsigned char Status;
00521
00522 Status = TWSR & 0xF8;
00523
00524 switch(TW_state)
00525 {
00526 default:
00527 case TW_IDLE:
00528 if(TWS_SLA_W == Status)
00529 {
00530 TW_state = TW_Wait4Cmd;
00531 }
00532 else
00533 if(TWS_RSTOP == Status)
00534 {
00535 ;
00536 }
00537 else
00538 {
00539 TWI_CmdFlags = SMB_GenBusTimeout;
00540 TWCR = (1<<TWEA) | (1<<TWEN);
00541 return;
00542 }
00543 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00544 break;
00545
00546
00547
00548
00549 case TW_Wait4Cmd:
00550 if(TWS_RCMD == Status)
00551 {
00552 if(SMBV_Opt5 == TWDR)
00553 {
00554 TW_state = TW_Wait4RW;
00555 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00556 return;
00557 }
00558 }
00559
00560 TWI_CmdFlags = SMB_GenBusTimeout;
00561 TWCR = (1<<TWEA) | (1<<TWEN);
00562 TW_state = TW_IDLE;
00563 break;
00564
00565
00566 case TW_Wait4RW:
00567 if(TWS_RDATA == Status)
00568 {
00569
00570 TW_RxBuf[0] = TWAR & 0xFE;
00571 TW_RxBuf[1] = SMBV_Opt5;
00572 TW_RxBuf[2] = TWDR;
00573 TW_RxBufCnt = TWDR;
00574 TW_RxBufIndex = 3;
00575 TW_state = TW_Wait4Data;
00576 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00577 }
00578 else
00579 if(TWS_REPEAT == Status)
00580 {
00581 TWI_CmdFlags = SMB_SetUpReply;
00582 TW_state = TW_ReplyData;
00583 TWCR = (1<<TWEA) | (1<<TWEN);
00584 return;
00585 }
00586 else
00587 {
00588 TWI_CmdFlags = SMB_GenBusTimeout;
00589 TWCR = (1<<TWEA) | (1<<TWEN);
00590 TW_state = TW_IDLE;
00591 }
00592 break;
00593
00594
00595 case TW_Wait4Data:
00596 if(TWS_RDATA == Status)
00597 {
00598 TW_RxBuf[TW_RxBufIndex++] = TWDR;
00599 if(0 == --TW_RxBufCnt)
00600 {
00601 TW_RxBufCnt = TW_RxBufIndex;
00602 TW_RxBufIndex = 0;
00603 TWI_CmdFlags = SMB_GotCmdData;
00604
00605
00606
00607
00608 TWCR = (1<<TWEA) | (1<<TWEN);
00609 TW_state = TW_IDLE;
00610 return;
00611 }
00612 }
00613 else
00614 if(TWS_RSTOP == Status)
00615 {
00616
00617 TW_state = TW_IDLE;
00618 }
00619 else
00620 {
00621 TWI_CmdFlags = SMB_GenBusTimeout;
00622 TWCR = (1<<TWEA) | (1<<TWEN);
00623 TW_state = TW_IDLE;
00624 return;
00625 }
00626 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00627 break;
00628
00629
00630 case TW_ReplyData:
00631
00632
00633
00634
00635
00636
00637
00638
00639 if((TWS_SLA_R == Status) || (TWS_RACK == Status))
00640 {
00641 TWDR = TW_TxBuf[TW_TxBufIndex++];
00642 if(--TW_TxBufCnt == 0)
00643 TWCR = (1<<TWINT) | (1<<TWEN);
00644 else
00645 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00646 }
00647 else
00648 if(TWS_RNAK == Status)
00649 {
00650 if(TW_TxBufCnt == 1)
00651 {
00652 TW_TxBufCnt = 0;
00653 UsePEC = 0;
00654 }
00655 else
00656 if(TW_TxBufCnt == 0)
00657 UsePEC = 1;
00658 else
00659 {
00660 ;
00661 }
00662 TW_state = TW_IDLE;
00663 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00664 }
00665 else
00666
00667 {
00668 TW_state = TW_IDLE;
00669 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00670 }
00671 break;
00672
00673 }
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 void SMB_BusTimeout(void)
00693 {
00694 int i;
00695
00696 for(i=7000; i!=0; i--);
00697
00698 SMB_RestoreBus();
00699 }
00700
00701
00702
00703 void SMB_Reply(void)
00704 {
00705 unsigned char temp;
00706
00707 TWI_CmdFlags = 0;
00708 TW_TxBufIndex = 0;
00709 TW_TxBufCnt = 0;
00710
00711
00712 TW_TxBuf[0] = 1;
00713 TW_TxBuf[1] = Status;
00714 TW_TxBufIndex = 0;
00715 TW_TxBufCnt = 2;
00716
00717
00718 temp = FastCRC(0, (TWAR & 0xFE));
00719 temp = FastCRC(temp, SMBV_Opt5);
00720 temp = FastCRC(temp, (TWAR | 1));
00721
00722 do {temp = FastCRC(temp, TW_TxBuf[TW_TxBufIndex++]);}
00723 while(TW_TxBufIndex != TW_TxBufCnt);
00724
00725 TW_TxBuf[TW_TxBufIndex] = temp;
00726 TW_TxBufCnt++;
00727 TW_TxBufIndex = 0;
00728 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00729 }
00730
00731
00732
00733
00734
00735 unsigned char EEbusy(void)
00736 {
00737 return (EECR & (1<<EEPE));
00738 }
00739
00740
00741
00742 unsigned char EEget(unsigned int address)
00743 {
00744 while(EECR & (1<<EEPE));
00745 EEAR = address;
00746 EECR |= (1<<EERE);
00747 return EEDR;
00748 }
00749
00750 void EEerase(unsigned int address)
00751 {
00752 while(EECR & (1<<EEPE));
00753 EEAR = address;
00754 EECR = (1<<EEPM0) | (1<<EEMPE);
00755 EECR = (1<<EEPM0) | (1<<EEMPE) | (1<<EEPE);
00756 }
00757
00758 void EEwrite(unsigned int address, unsigned char data)
00759 {
00760 while(EECR & (1<<EEPE));
00761 EEAR = address;
00762 EEDR = data;
00763 EECR = (1<<EEMPE);
00764 EECR = (1<<EEMPE) | (1<<EEPE);
00765 }
00766
00767
00768
00769
00770
00771
00772 void LoopMemory(void)
00773 {
00774 if(LoopFlag == 'E')
00775 {
00776 if(EEbusy())
00777 return;
00778 EEwrite(eptr++, SRAMbuffer[dest_i++]);
00779 if(--ctr)
00780 return;
00781 Status = SUCCESS;
00782 LoopFlag = 0;
00783 return;
00784 }
00785 else
00786 if(LoopFlag == 'e')
00787 {
00788 if(EEbusy())
00789 return;
00790 EEerase(eptr++);
00791 if(--ctr)
00792 return;
00793 Status = SUCCESS;
00794 LoopFlag = 0;
00795 return;
00796 }
00797 }
00798
00799
00800
00801
00802
00803
00804 void SMB_CmdInterpreter(void)
00805 {
00806 unsigned char temp;
00807
00808 if(UsePEC)
00809 {
00810 temp = 0;
00811
00812 do { temp = FastCRC(temp, TW_RxBuf[TW_RxBufIndex++]); }
00813 while(TW_RxBufCnt != TW_RxBufIndex);
00814
00815 if(temp)
00816 {
00817 Status = CRCERROR;
00818 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
00819 return;
00820 }
00821 }
00822
00823 Status = BUSY;
00824
00825
00826 if(!BigData)
00827 {
00828
00829 lomemptr = TW_RxBuf[TWRX_LOADDR];
00830 himemptr = TW_RxBuf[TWRX_HIADDR];
00831 src_i = TWRX_DATA;
00832 dest_i = TW_RxBuf[TWRX_OFFSET];
00833 ctr = TW_RxBuf[TWRX_SIZE];
00834
00835 temp = TW_RxBuf[TWRX_CMD];
00836 }
00837 else
00838 {
00839 temp = 'I';
00840 src_i = 3;
00841
00842 }
00843
00844
00845 if(temp == 'W')
00846 {
00847 if(TW_RxBuf[TWRX_MEM] == 'F')
00848 {
00849 src_i = 0;
00850 lomemptr &= 0x80;
00851 dest_i = lomemptr;
00852 do
00853 {
00854 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00855 _FILL_TEMP_WORD(((himemptr<<8)|dest_i), (SRAMbuffer[src_i]|(SRAMbuffer[src_i+1]<<8)));
00856 #pragma diag_default=Pe1053 // Back to default.
00857 src_i += 2;
00858 dest_i += 2;
00859 }
00860 while(src_i < 0x80);
00861
00862 _PAGE_WRITE((himemptr<<8)|lomemptr);
00863 _WAIT_FOR_SPM();
00864 _ENABLE_RWW_SECTION();
00865
00866 Status = SUCCESS;
00867 }
00868 else
00869 if(TW_RxBuf[TWRX_MEM] == 'E')
00870 {
00871 eptr = (himemptr<<8) | lomemptr;
00872 if((eptr + ctr) > 512)
00873 Status = BADPARAM;
00874 else
00875 {
00876 LoopFlag = 'E';
00877 }
00878 }
00879 else
00880 Status = BADPARAM;
00881 }
00882
00883 else
00884 if(temp == 'V')
00885 {
00886 if(TW_RxBuf[TWRX_MEM] == 'F')
00887 {
00888 src_i = SUCCESS;
00889 dest_i = 0;
00890 fptr = (unsigned char __flash *)(lomemptr | (himemptr<<8));
00891 do { if(SRAMbuffer[dest_i++] != *fptr++) src_i=FAILURE; }
00892 while (dest_i < 128);
00893 Status = src_i;
00894 }
00895 else
00896 if(TW_RxBuf[TWRX_MEM] == 'E')
00897 {
00898 eptr = (himemptr<<8) | lomemptr;
00899 if((eptr + ctr) > 512)
00900 Status = BADPARAM;
00901 else
00902 {
00903 src_i = SUCCESS;
00904 do { if(SRAMbuffer[dest_i++] != EEget(eptr++)) src_i=FAILURE; }
00905 while (--ctr);
00906 Status = src_i;
00907 }
00908 }
00909 else
00910 Status = BADPARAM;
00911 }
00912
00913 else
00914 if(temp == 'E')
00915 {
00916 if(TW_RxBuf[TWRX_MEM] == 'F')
00917 {
00918 _WAIT_FOR_SPM();
00919 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00920 _PAGE_ERASE( (himemptr<<8) | (lomemptr & 0x80) );
00921 #pragma diag_default=Pe1053 // Back to default.
00922
00923 Status = SUCCESS;
00924 }
00925 else
00926 if(TW_RxBuf[TWRX_MEM] == 'E')
00927 {
00928 eptr = (himemptr<<8) | lomemptr;
00929 if((eptr + ctr) > 512)
00930 Status = BADPARAM;
00931 else
00932 {
00933 LoopFlag = 'e';
00934 }
00935 }
00936 else
00937 Status = BADPARAM;
00938 }
00939
00940 else
00941 if(temp == 'P')
00942 {
00943 if(TW_RxBuf[TWRX_MEM] == 'F')
00944 {
00945 if(lomemptr & 0x7F)
00946 Status = BADPARAM;
00947 else
00948 {
00949 dest_i = 0;
00950 fptr = (unsigned char __flash *)(lomemptr | (himemptr<<8));
00951 do {SRAMbuffer[dest_i++] = *fptr++; }
00952 while (dest_i < 128);
00953 Status = SUCCESS;
00954 }
00955 }
00956 else
00957 if(TW_RxBuf[TWRX_MEM] == 'E')
00958 {
00959 eptr = (himemptr<<8) | lomemptr;
00960 if((eptr + ctr) > 512)
00961 Status = BADPARAM;
00962 else
00963 {
00964 do { SRAMbuffer[dest_i++] = EEget(eptr++); }
00965 while (--ctr);
00966 Status = SUCCESS;
00967 }
00968 }
00969 else
00970 Status = BADPARAM;
00971 }
00972
00973 else
00974 if(temp == 'A')
00975 {
00976 Status = SUCCESS;
00977 }
00978
00979 else
00980 if(temp == 'I')
00981 {
00982 if((ctr+dest_i) > 128)
00983 Status = BADPARAM;
00984 else
00985 {
00986 if(!BigData)
00987 {
00988 if(ctr > 26)
00989 {
00990 BigData = 1;
00991 temp = TW_RxBuf[TWRX_BLKCNT] - 6;
00992 }
00993 else
00994 temp = ctr;
00995 }
00996 else
00997 {
00998 if(ctr <= TW_RxBuf[TWRX_BLKCNT])
00999 BigData = 0;
01000 temp = TW_RxBuf[TWRX_BLKCNT];
01001 }
01002
01003
01004 do
01005 {
01006 SRAMbuffer[dest_i++] = TW_RxBuf[src_i++];
01007 ctr--;
01008 }
01009 while (--temp);
01010 Status = SUCCESS;
01011 }
01012 }
01013
01014 else
01015 if(temp == 'w')
01016 {
01017 ;
01018 }
01019
01020 else
01021 if(temp == 'v')
01022 {
01023 ;
01024 }
01025
01026 else
01027 if(temp == 'X')
01028 {
01029 asm("jmp 0");
01030 }
01031
01032 else
01033 {
01034 SMB_BusTimeout();
01035 TW_RxBufIndex = 0;
01036 TW_RxBufCnt = 0;
01037 return;
01038 }
01039
01040 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
01041 return;
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051 void SMB_RestoreBus(void)
01052 {
01053 TWCR = 0;
01054 TW_state = TW_IDLE;
01055 TWAR = 0x16;
01056 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
01057
01058
01059
01060
01061
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 __flash unsigned char crctable[16] = {0,0x07,0x0E,0x90, 0x1c,0x1b,0x12,0x15, 0x38,0x3F,0x36,0x31, 0x24,0x23,0x2A,0x2D};
01079 __flash unsigned char crctable2[16] = {0,0x70,0xE0,0x90, 0xC1,0xB1,0x21,0x51, 0x83,0xF3,0x63,0x13, 0x42,0x32,0xA2,0xD2};
01080
01081 unsigned char FastCRC(unsigned char LastCRC, unsigned char newbyte)
01082 {
01083 unsigned char index;
01084
01085 index = newbyte;
01086 index ^= LastCRC;
01087 index >>= 4;
01088 LastCRC &= 0x0F;
01089 LastCRC ^= crctable2[index];
01090
01091 index = LastCRC;
01092 index ^= newbyte;
01093 index &= 0x0F;
01094 LastCRC &= 0xF0;
01095 LastCRC ^= crctable[index];
01096
01097 return(LastCRC);
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132