00001
00029 #include <avr/interrupt.h>
00030 #include <avr/io.h>
00031 #include <util/delay.h>
00032
00033 #include "halSCD.h"
00034 #include "utils.h"
00035
00036 #define simulation 0 // Set this to 1 for simulation, 0 otherwise
00037 #define DEBUG 1 // Set this to 1 to enable debug code
00038 #define F_CPU 16000000UL // Change this to the correct frequency
00039 #define ETU_TERMINAL 372
00040 #define ETU_ICC 1488 // 372 * 4 because F_T1 = 4 * F_T0
00041 #define ETU_HALF(X) ((unsigned int) ((X)/2))
00042 #define ETU_LESS_THAN_HALF(X) ((unsigned int) ((X)*0.46))
00043 #define ETU_EXTENDED(X) ((unsigned int) ((X)*1.075))
00044 #define ICC_VCC_DELAY_US 50
00045 #define PULL_UP_HIZ_ICC 1 // Set to 1 to enable pull-ups when setting
00046
00047
00048
00049
00050
00051
00057 uint16_t GetTerminalFreq()
00058 {
00059 uint8_t sreg;
00060 uint16_t time, result;
00061
00062 sreg = SREG;
00063 cli();
00064 TCNT3 = 1;
00065 asm volatile("nop\n\t"
00066 "nop\n\t"
00067 "nop\n\t"
00068 "nop\n\t"
00069 "nop\n\t"
00070 "nop\n\t"
00071 "nop\n\t"
00072 "nop\n\t"
00073 "nop\n\t"
00074 "nop\n\t"
00075 "nop\n\t"
00076 "nop\n\t"
00077 "nop\n\t"
00078 "nop\n\t"
00079 "nop\n\t"
00080 "nop\n\t"
00081 "nop\n\t"
00082 "nop\n\t"
00083 "nop\n\t"
00084 "nop\n\t"
00085 "nop\n\t"
00086 "nop\n\t"
00087 "nop\n\t"
00088 "nop\n\t"
00089 "nop\n\t"
00090 "nop\n\t"
00091 "nop\n\t"
00092 "nop\n\t"
00093 "nop\n\t"
00094 "nop\n\t"
00095 "nop\n\t"
00096 "nop\n\t"
00097 "nop\n\t"
00098 "nop\n\t"
00099 "nop\n\t"
00100 "nop\n\t"
00101 "nop\n\t"
00102 "nop\n\t"
00103 "nop\n\t"
00104 "nop\n\t"
00105 "nop\n\t"
00106 "nop\n\t"
00107 "nop\n\t"
00108 "nop\n\t"
00109 "nop\n\t"
00110 "nop\n\t"
00111 "nop\n\t"
00112 "nop\n\t"
00113 "nop\n\t"
00114 ::);
00115 time = TCNT3;
00116
00117 if(time == 1)
00118 result = 0;
00119 else
00120 result = (uint16_t)(((F_CPU/1000) * time) / 50);
00121
00122 SREG = sreg;
00123
00124 return result;
00125 }
00126
00130 uint16_t ReadCounterTerminal()
00131 {
00132 uint16_t i;
00133 uint8_t sreg;
00134
00135
00136 sreg = SREG;
00137 cli();
00138 i = TCNT3;
00139 SREG = sreg;
00140
00141 return i;
00142
00143
00144 }
00145
00146
00154 void StartCounterTerminal()
00155 {
00156
00157 TCCR3A = 0x0C;
00158
00159
00160
00161
00162 Write16bitRegister(&OCR3A, ETU_TERMINAL);
00163 #if simulation
00164 TCCR3B = 0x0A;
00165 #else
00166 TCCR3B = 0x0F;
00167 #endif
00168 }
00169
00173 void StopCounterTerminal()
00174 {
00175 TCCR3B = 0;
00176 Write16bitRegister(&TCNT3, 0);
00177 }
00178
00182 void PauseCounterTerminal()
00183 {
00184 TCCR3B = 0;
00185 }
00186
00192 uint8_t GetResetStateTerminal()
00193 {
00194 return bit_is_set(PIND, PD0);
00195 }
00196
00204 void LoopTerminalETU(uint8_t nEtus)
00205 {
00206 uint8_t i;
00207
00208 Write16bitRegister(&OCR3A, ETU_TERMINAL);
00209 TCCR3A = 0x0C;
00210 Write16bitRegister(&TCNT3, 1);
00211 TIFR3 |= _BV(OCF3A);
00212
00213 for(i = 0; i < nEtus; i++)
00214 {
00215 while(bit_is_clear(TIFR3, OCF3A));
00216 TIFR3 |= _BV(OCF3A);
00217 }
00218 }
00219
00220
00230 void SendByteTerminalNoParity(uint8_t byte, uint8_t inverse_convention)
00231 {
00232 uint8_t bitval, i, parity;
00233 volatile uint8_t tmp;
00234
00235
00236
00237 if(!GetTerminalFreq())
00238 return;
00239
00240
00241
00242 TCCR3A = 0x0C;
00243
00244 PORTC |= _BV(PC4);
00245 DDRC |= _BV(PC4);
00246 Write16bitRegister(&OCR3A, ETU_TERMINAL);
00247 Write16bitRegister(&TCNT3, 1);
00248 TIFR3 |= _BV(OCF3A);
00249
00250
00251
00252
00253
00254 TCCR3A = 0x08;
00255
00256
00257
00258 if(inverse_convention)
00259 {
00260 tmp = ~byte;
00261 byte = 0;
00262 for(i = 0; i < 8; i++)
00263 {
00264 bitval = tmp & _BV((7-i));
00265 if(bitval) byte = byte | _BV(i);
00266 }
00267 }
00268
00269
00270 while(bit_is_clear(TIFR3, OCF3A));
00271 TIFR3 |= _BV(OCF3A);
00272
00273
00274 parity = 0;
00275 for(i = 0; i < 8; i++)
00276 {
00277 bitval = (uint8_t) (byte & (uint8_t)(1 << i));
00278
00279 if(bitval != 0)
00280 {
00281 TCCR3A = 0x0C;
00282 if(!inverse_convention) parity = parity ^ 1;
00283 }
00284 else
00285 {
00286 TCCR3A = 0x08;
00287 if(inverse_convention) parity = parity ^ 1;
00288 }
00289
00290 while(bit_is_clear(TIFR3, OCF3A));
00291 TIFR3 |= _BV(OCF3A);
00292 }
00293
00294
00295 if((!inverse_convention && parity != 0) ||
00296 (inverse_convention && parity == 0))
00297 TCCR3A = 0x0C;
00298 else
00299 TCCR3A = 0x08;
00300
00301
00302
00303 while(bit_is_clear(TIFR3, OCF3A));
00304 TIFR3 |= _BV(OCF3A);
00305 while(bit_is_clear(TIFR3, OCF3A));
00306 TIFR3 |= _BV(OCF3A);
00307
00308
00309 TCCR3A = 0x0C;
00310 DDRC &= ~(_BV(PC4));
00311 PORTC |= _BV(PC4);
00312 }
00313
00324 uint8_t SendByteTerminalParity(uint8_t byte, uint8_t inverse_convention)
00325 {
00326 uint8_t i;
00327 volatile uint8_t tmp;
00328
00329 SendByteTerminalNoParity(byte, inverse_convention);
00330
00331
00332 LoopTerminalETU(1);
00333
00334
00335 if(bit_is_clear(PINC, PC4))
00336 {
00337 Write16bitRegister(&OCR3A, ETU_TERMINAL);
00338 Write16bitRegister(&TCNT3, 1);
00339 TIFR3 |= _BV(OCF3A);
00340 TCCR3A = 0x0C;
00341 i = 0;
00342
00343 do{
00344 i++;
00345
00346
00347 LoopTerminalETU(2);
00348
00349 SendByteTerminalNoParity(byte, inverse_convention);
00350
00351
00352 LoopTerminalETU(1);
00353 tmp = bit_is_clear(PINC, PC4);
00354 }while(i<4 && tmp != 0);
00355
00356 if(tmp != 0)
00357 return 1;
00358 }
00359
00360 return 0;
00361 }
00362
00369 uint8_t WaitForTerminalData(uint16_t max_cycles)
00370 {
00371 uint8_t result = 0;
00372 uint16_t c = 0;
00373 volatile uint8_t bit;
00374
00375 do{
00376 bit = bit_is_set(PINC, PC4);
00377 c = c + 1;
00378
00379 if(max_cycles != 0 && c == max_cycles) break;
00380 }while(bit != 0);
00381
00382
00383 if(bit != 0) result = 1;
00384
00385 return result;
00386 }
00387
00388
00399 uint8_t GetByteTerminalNoParity(uint8_t inverse_convention, uint8_t *r_byte)
00400 {
00401 volatile uint8_t bit;
00402 uint8_t i, byte, parity;
00403
00404 TCCR3A = 0x0C;
00405 DDRC &= ~(_BV(PC4));
00406 PORTC |= _BV(PC4);
00407
00408
00409
00410 while(bit_is_set(PINC, PC4));
00411
00412 Write16bitRegister(&TCNT3, 1);
00413
00414 Write16bitRegister(&OCR3A, ETU_HALF(ETU_TERMINAL));
00415 TIFR3 |= _BV(OCF3A);
00416
00417 while(bit_is_clear(TIFR3, OCF3A));
00418 TIFR3 |= _BV(OCF3A);
00419
00420
00421 bit = bit_is_set(PINC, PC4);
00422 Write16bitRegister(&OCR3A, ETU_TERMINAL);
00423 *r_byte = 0;
00424 byte = 0;
00425 parity = 0;
00426 if(bit) return 1;
00427
00428
00429 for(i = 0; i < 8; i++)
00430 {
00431 while(bit_is_clear(TIFR3, OCF3A));
00432 TIFR3 |= _BV(OCF3A);
00433 bit = bit_is_set(PINC, PC4);
00434
00435 if(inverse_convention && bit == 0)
00436 {
00437 byte = byte | _BV(7-i);
00438 parity = parity ^ 1;
00439 }
00440 else if(inverse_convention == 0 && bit != 0)
00441 {
00442 byte = byte | _BV(i);
00443 parity = parity ^ 1;
00444 }
00445 }
00446
00447 *r_byte = byte;
00448
00449
00450 while(bit_is_clear(TIFR3, OCF3A));
00451 TIFR3 |= _BV(OCF3A);
00452 bit = bit_is_set(PINC, PC4);
00453
00454
00455
00456 Write16bitRegister(&OCR3A, ETU_HALF(ETU_TERMINAL));
00457 while(bit_is_clear(TIFR3, OCF3A));
00458 TIFR3 |= _BV(OCF3A);
00459
00460 if(inverse_convention)
00461 {
00462 if(parity && bit) return 1;
00463 if(!parity && !bit) return 1;
00464 }
00465 else
00466 {
00467 if(parity && !bit) return 1;
00468 if(!parity && bit) return 1;
00469 }
00470
00471 return 0;
00472 }
00473
00484 uint8_t GetByteTerminalParity(uint8_t inverse_convention, uint8_t *r_byte)
00485 {
00486 uint8_t result;
00487
00488 result = GetByteTerminalNoParity(inverse_convention, r_byte);
00489 if(result != 0)
00490 {
00491
00492 if(!GetTerminalFreq())
00493 return result;
00494
00495
00496 TCCR3A = 0x0C;
00497 DDRC |= _BV(PC4);
00498
00499 Write16bitRegister(&OCR3A,
00500 ETU_LESS_THAN_HALF(ETU_TERMINAL));
00501 Write16bitRegister(&TCNT3, 1);
00502 TIFR3 |= _BV(OCF3A);
00503
00504 TCCR3A = 0x08;
00505
00506 while(bit_is_clear(TIFR3, OCF3A));
00507 TIFR3 |= _BV(OCF3A);
00508
00509 Write16bitRegister(&OCR3A,
00510 ETU_EXTENDED(ETU_TERMINAL));
00511 while(bit_is_clear(TIFR3, OCF3A));
00512 TIFR3 |= _BV(OCF3A);
00513
00514
00515 TCCR3A = 0x0C;
00516 DDRC &= ~(_BV(PC4));
00517 PORTC |= _BV(PC4);
00518
00519
00520
00521 Write16bitRegister(&OCR3A, ETU_LESS_THAN_HALF(ETU_TERMINAL));
00522 while(bit_is_clear(TIFR3, OCF3A));
00523 TIFR3 |= _BV(OCF3A);
00524 }
00525
00526 return result;
00527 }
00528
00539 void SendT0ATRTerminal(uint8_t inverse_convention, uint8_t TC1)
00540 {
00541 if(inverse_convention)
00542 SendByteTerminalNoParity(0x3F, inverse_convention);
00543 else
00544 SendByteTerminalNoParity(0x3B, inverse_convention);
00545
00546 LoopTerminalETU(250);
00547 SendByteTerminalNoParity(0x60, inverse_convention);
00548 LoopTerminalETU(2);
00549 SendByteTerminalNoParity(0x00, inverse_convention);
00550 LoopTerminalETU(2);
00551 SendByteTerminalNoParity(TC1, inverse_convention);
00552 LoopTerminalETU(2);
00553 }
00554
00555
00556
00557
00561 uint8_t IsICCInserted()
00562 {
00563 return bit_is_set(PIND, PD1);
00564 }
00565
00566
00570 uint8_t IsICCPowered()
00571 {
00572 return bit_is_clear(PIND, PD7);
00573 }
00574
00580 uint8_t PowerUpICC()
00581 {
00582 if(bit_is_clear(PIND, PD1))
00583 return 1;
00584
00585 PORTD &= ~(_BV(PD7));
00586 DDRD |= _BV(PD7);
00587
00588 return 0;
00589 }
00590
00594 void PowerDownICC()
00595 {
00596 DDRD |= _BV(PD7);
00597 PORTD |= _BV(PD7);
00598 }
00599
00600
00608 void LoopICCETU(uint8_t nEtus)
00609 {
00610 uint8_t i;
00611
00612 Write16bitRegister(&OCR1A, ETU_ICC);
00613 TCCR1A = 0x30;
00614 Write16bitRegister(&TCNT1, 1);
00615 TIFR1 |= _BV(OCF1A);
00616
00617 for(i = 0; i < nEtus; i++)
00618 {
00619 while(bit_is_clear(TIFR1, OCF1A));
00620 TIFR1 |= _BV(OCF1A);
00621 }
00622 }
00623
00631 uint8_t WaitForICCData(uint16_t max_cycles)
00632 {
00633 uint8_t result = 0;
00634 uint16_t c = 0;
00635 volatile uint8_t bit;
00636
00637 do{
00638 bit = bit_is_set(PINB, PB6);
00639 c = c + 1;
00640
00641 if(max_cycles != 0 && c == max_cycles) break;
00642 }while(bit != 0);
00643
00644
00645 if(bit != 0) result = 1;
00646
00647 return result;
00648 }
00649
00660 uint8_t GetByteICCNoParity(uint8_t inverse_convention, uint8_t *r_byte)
00661 {
00662 volatile uint8_t bit;
00663 uint8_t i, byte, parity;
00664
00665 TCCR1A = 0x30;
00666 DDRB &= ~(_BV(PB6));
00667
00668 #if PULL_UP_HIZ_ICC
00669 PORTB |= _BV(PB6);
00670 #else
00671 PORTB &= ~(_BV(PB6));
00672 #endif
00673
00674
00675 while(bit_is_set(PINB, PB6));
00676
00677 Write16bitRegister(&TCNT1, 1);
00678 Write16bitRegister(&OCR1A, ETU_HALF(ETU_ICC));
00679 TIFR1 |= _BV(OCF1A);
00680
00681 while(bit_is_clear(TIFR1, OCF1A));
00682 TIFR1 |= _BV(OCF1A);
00683
00684
00685 bit = bit_is_set(PINB, PB6);
00686 Write16bitRegister(&OCR1A, ETU_ICC);
00687 *r_byte = 0;
00688 byte = 0;
00689 parity = 0;
00690 if(bit) return 1;
00691
00692
00693 for(i = 0; i < 8; i++)
00694 {
00695 while(bit_is_clear(TIFR1, OCF1A));
00696 TIFR1 |= _BV(OCF1A);
00697 bit = bit_is_set(PINB, PB6);
00698
00699 if(inverse_convention && bit == 0)
00700 {
00701 byte = byte | _BV(7-i);
00702 parity = parity ^ 1;
00703 }
00704 else if(inverse_convention == 0 && bit != 0)
00705 {
00706 byte = byte | _BV(i);
00707 parity = parity ^ 1;
00708 }
00709 }
00710
00711 *r_byte = byte;
00712
00713
00714 while(bit_is_clear(TIFR1, OCF1A));
00715 TIFR1 |= _BV(OCF1A);
00716 bit = bit_is_set(PINB, PB6);
00717
00718
00719 Write16bitRegister(&OCR1A, ETU_HALF(ETU_ICC));
00720 while(bit_is_clear(TIFR1, OCF1A));
00721 TIFR1 |= _BV(OCF1A);
00722
00723 if(inverse_convention)
00724 {
00725 if(parity && bit) return 1;
00726 if(!parity && !bit) return 1;
00727 }
00728 else
00729 {
00730 if(parity && !bit) return 1;
00731 if(!parity && bit) return 1;
00732 }
00733
00734 return 0;
00735 }
00736
00737
00748 uint8_t GetByteICCParity(uint8_t inverse_convention, uint8_t *r_byte)
00749 {
00750 uint8_t result;
00751
00752 result = GetByteICCNoParity(inverse_convention, r_byte);
00753 if(result != 0)
00754 {
00755
00756 if(!IsICCInserted())
00757 return result;
00758
00759
00760 TCCR1A = 0x30;
00761 DDRB |= _BV(PB6);
00762 Write16bitRegister(&OCR1A,
00763 ETU_LESS_THAN_HALF(ETU_ICC));
00764 Write16bitRegister(&TCNT1, 1);
00765 TIFR1 |= _BV(OCF1A);
00766 TCCR1A = 0x20;
00767
00768 while(bit_is_clear(TIFR1, OCF1A));
00769 TIFR1 |= _BV(OCF1A);
00770 Write16bitRegister(&OCR1A,
00771 ETU_EXTENDED(ETU_ICC));
00772 while(bit_is_clear(TIFR1, OCF1A));
00773 TIFR1 |= _BV(OCF1A);
00774
00775
00776 TCCR1A = 0x30;
00777 DDRB &= ~(_BV(PB6));
00778 PORTB |= _BV(PB6);
00779
00780
00781 Write16bitRegister(&OCR1A, ETU_LESS_THAN_HALF(ETU_ICC));
00782 while(bit_is_clear(TIFR1, OCF1A));
00783 TIFR1 |= _BV(OCF1A);
00784 }
00785
00786 return result;
00787 }
00788
00797 void SendByteICCNoParity(uint8_t byte, uint8_t inverse_convention)
00798 {
00799 uint8_t bitval, i, parity;
00800 volatile uint8_t tmp;
00801
00802 if(!IsICCInserted())
00803 return;
00804
00805
00806
00807 TCCR1A = 0x30;
00808 PORTB |= _BV(PB6);
00809 DDRB |= _BV(PB6);
00810 Write16bitRegister(&OCR1A, ETU_ICC);
00811 Write16bitRegister(&TCNT1, 1);
00812 TIFR1 |= _BV(OCF1A);
00813
00814
00815
00816
00817
00818 TCCR1A = 0x20;
00819
00820
00821
00822 if(inverse_convention)
00823 {
00824 tmp = ~byte;
00825 byte = 0;
00826 for(i = 0; i < 8; i++)
00827 {
00828 bitval = tmp & _BV((7-i));
00829 if(bitval) byte = byte | _BV(i);
00830 }
00831 }
00832
00833
00834 while(bit_is_clear(TIFR1, OCF1A));
00835 TIFR1 |= _BV(OCF1A);
00836
00837
00838 parity = 0;
00839 for(i = 0; i < 8; i++)
00840 {
00841 bitval = (uint8_t) (byte & (uint8_t)(1 << i));
00842
00843 if(bitval != 0)
00844 {
00845 TCCR1A = 0x30;
00846 if(!inverse_convention) parity = parity ^ 1;
00847 }
00848 else
00849 {
00850 TCCR1A = 0x20;
00851 if(inverse_convention) parity = parity ^ 1;
00852 }
00853
00854 while(bit_is_clear(TIFR1, OCF1A));
00855 TIFR1 |= _BV(OCF1A);
00856 }
00857
00858
00859 if((!inverse_convention && parity != 0) ||
00860 (inverse_convention && parity == 0))
00861 TCCR1A = 0x30;
00862 else
00863 TCCR1A = 0x20;
00864
00865
00866
00867 while(bit_is_clear(TIFR1, OCF1A));
00868 TIFR1 |= _BV(OCF1A);
00869 while(bit_is_clear(TIFR1, OCF1A));
00870 TIFR1 |= _BV(OCF1A);
00871
00872
00873 TCCR1A = 0x30;
00874 DDRB &= ~(_BV(PB6));
00875 PORTB |= _BV(PB6);
00876 }
00877
00888 uint8_t SendByteICCParity(uint8_t byte, uint8_t inverse_convention)
00889 {
00890 uint8_t i;
00891 volatile uint8_t tmp;
00892
00893 SendByteICCNoParity(byte, inverse_convention);
00894
00895
00896 LoopICCETU(1);
00897
00898
00899 if(bit_is_clear(PINB, PB6))
00900 {
00901 Write16bitRegister(&OCR1A, ETU_ICC);
00902 Write16bitRegister(&TCNT1, 1);
00903 TIFR1 |= _BV(OCF1A);
00904 TCCR1A = 0x30;
00905 i = 0;
00906
00907 do{
00908 i++;
00909
00910
00911 LoopICCETU(2);
00912
00913 SendByteICCNoParity(byte, inverse_convention);
00914
00915
00916 LoopICCETU(1);
00917 tmp = bit_is_clear(PINB, PB6);
00918 }while(i<4 && tmp != 0);
00919
00920 if(tmp != 0)
00921 return 1;
00922 }
00923
00924 return 0;
00925 }
00926
00927
00928
00942 uint8_t GetATRICC(uint8_t *inverse_convention, uint8_t *proto,
00943 uint8_t *TC1, uint8_t *TA3, uint8_t *TB3)
00944 {
00945 uint8_t history, i, tmp, ta, tb, tc, td, nb;
00946 uint8_t check = 0;
00947
00948
00949 GetByteICCNoParity(0, &tmp);
00950 if(tmp == 0x3B) *inverse_convention = 0;
00951 else if(tmp == 0x03) *inverse_convention = 1;
00952 else return 1;
00953
00954
00955 GetByteICCNoParity(*inverse_convention, &tmp);
00956 check ^= tmp;
00957 history = tmp & 0x0F;
00958 ta = tmp & 0x10;
00959 tb = tmp & 0x20;
00960 tc = tmp & 0x40;
00961 td = tmp & 0x80;
00962
00963 if(ta){
00964
00965 GetByteICCNoParity(*inverse_convention, &tmp);
00966 check ^= tmp;
00967 if(tmp != 0x11) return 1;
00968 }
00969
00970
00971 if(tb == 0) return 1;
00972 GetByteICCNoParity(*inverse_convention, &tmp);
00973 check ^= tmp;
00974 if(tmp != 0) return 1;
00975
00976
00977 if(tc)
00978 {
00979 GetByteICCNoParity(*inverse_convention, TC1);
00980 check ^= tmp;
00981 }
00982 else
00983 *TC1 = 0;
00984
00985 if(td){
00986
00987 GetByteICCNoParity(*inverse_convention, &tmp);
00988 check ^= tmp;
00989 nb = tmp & 0x0F;
00990 ta = tmp & 0x10;
00991 tb = tmp & 0x20;
00992 tc = tmp & 0x40;
00993 td = tmp & 0x80;
00994 if(nb == 0x01) *proto = 1;
00995 else if(nb == 0x00) *proto = 0;
00996 else return 1;
00997
00998 if(ta) return 1;
00999 if(tb) return 1;
01000 if(tc){
01001
01002 GetByteICCNoParity(*inverse_convention, &tmp);
01003 check ^= tmp;
01004 if(tmp != 0x0A) return 1;
01005 }
01006 if(td){
01007
01008 GetByteICCNoParity(*inverse_convention, &tmp);
01009 check ^= tmp;
01010 nb = tmp & 0x0F;
01011 ta = tmp & 0x10;
01012 tb = tmp & 0x20;
01013 tc = tmp & 0x40;
01014 td = tmp & 0x80;
01015 if(*proto == 0 && nb != 0x0E) return 1;
01016 if(*proto == 1 && nb != 0x01) return 1;
01017
01018 if(ta)
01019 {
01020
01021 GetByteICCNoParity(*inverse_convention, &tmp);
01022 check ^= tmp;
01023 if(tmp < 0x0F || tmp == 0xFF) return 1;
01024 *TA3 = tmp;
01025 }
01026 else
01027 *TA3 = 0x20;
01028
01029 if(*proto == 1 && tb == 0) return 1;
01030 if(tb)
01031 {
01032
01033 GetByteICCNoParity(*inverse_convention, &tmp);
01034 check ^= tmp;
01035 nb = tmp & 0x0F;
01036 if(nb > 5) return 1;
01037 nb = tmp & 0xF0;
01038 if(nb > 64) return 1;
01039 *TB3 = tmp;
01040 }
01041
01042 if(*proto == 0 && tc != 0) return 1;
01043 if(tc)
01044 {
01045
01046 GetByteICCNoParity(*inverse_convention, &tmp);
01047 check ^= tmp;
01048 if(tmp != 0) return 1;
01049 }
01050 }
01051 }
01052 else
01053 *proto = 0;
01054
01055
01056 for(i = 0; i < history; i++)
01057 {
01058 GetByteICCNoParity(0, &tmp);
01059 check ^= tmp;
01060 }
01061
01062
01063 if(*proto == 1)
01064 {
01065 GetByteICCNoParity(*inverse_convention, &tmp);
01066 check ^= tmp;
01067 if(check != 0) return 1;
01068 }
01069
01070 return 0;
01071 }
01072
01085 uint8_t ResetICC(uint8_t warm, uint8_t *inverse_convention, uint8_t *proto,
01086 uint8_t *TC1, uint8_t *TA3, uint8_t *TB3)
01087 {
01088
01089 if(ActivateICC(warm)) return 1;
01090
01091
01092 LoopICCETU(112);
01093
01094
01095 PORTD |= _BV(PD4);
01096
01097
01098
01099 if(WaitForICCData(50000))
01100 {
01101 if(warm == 0)
01102 return ResetICC(1, inverse_convention, proto, TC1, TA3, TB3);
01103
01104 DeactivateICC();
01105 return 1;
01106 }
01107
01108
01109 if(GetATRICC(inverse_convention, proto, TC1, TA3, TB3))
01110 {
01111 if(warm == 0)
01112 return ResetICC(1, inverse_convention, proto, TC1, TA3, TB3);
01113
01114 DeactivateICC();
01115 return 1;
01116 }
01117
01118 return 0;
01119 }
01120
01128 uint8_t ActivateICC(uint8_t warm)
01129 {
01130 if(warm)
01131 {
01132
01133 PORTD &= ~(_BV(PD4));
01134 DDRD |= _BV(PD4);
01135 }
01136 else{
01137
01138 PORTB &= ~(_BV(PB6));
01139 DDRB |= _BV(PB6);
01140 PORTB &= ~(_BV(PB7));
01141 DDRB |= _BV(PB7);
01142 PORTD &= ~(_BV(PD4));
01143 DDRD |= _BV(PD4);
01144 _delay_us(ICC_VCC_DELAY_US);
01145 if(PowerUpICC())
01146 {
01147 DeactivateICC();
01148 return 1;
01149 }
01150 _delay_us(ICC_VCC_DELAY_US);
01151 }
01152
01153
01154 DDRB &= ~(_BV(PB6));
01155 #if PULL_UP_HIZ_ICC
01156 PORTB |= _BV(PB6);
01157 #else
01158 PORTB &= ~(_BV(PB6));
01159 #endif
01160
01161 if(warm == 0)
01162 {
01163
01164
01165
01166 TCCR0A = 0x42;
01167
01168 OCR0A = 1;
01169
01170
01171 TCNT0 = 0;
01172 TCCR0B = 0x01;
01173 TCCR1A = 0x30;
01174 Write16bitRegister(&OCR1A, ETU_ICC);
01175
01176
01177 TCCR1B = 0x09;
01178 TCCR1C = 0x40;
01179
01180 }
01181
01182 return 0;
01183 }
01184
01188 void DeactivateICC()
01189 {
01190
01191 PORTD &= ~(_BV(PD4));
01192 DDRD |= _BV(PD4);
01193
01194
01195 TCCR0A = 0;
01196 TCCR0B = 0;
01197 TCCR1A = 0;
01198 TCCR1B = 0;
01199
01200
01201 PORTB &= ~(_BV(PB7));
01202 DDRB |= _BV(PB7);
01203
01204
01205 PORTB &= ~(_BV(PB6));
01206 DDRB |= _BV(PB6);
01207
01208
01209 PORTD |= _BV(PD7);
01210 DDRD |= _BV(PD7);
01211 }
01212