Advertisement
Guest User

Untitled

a guest
Nov 24th, 2014
590
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.64 KB | None | 0 0
  1.  
  2.  
  3. int sc_switch = 2;
  4. int sc_clk = 11; // OC2A!
  5. int sc_rst = 3;
  6. int sc_rxtx = 4;
  7.  
  8. void setup() {
  9.   Serial.begin(9600);
  10.   pinMode(sc_switch, INPUT_PULLUP);
  11.   digitalWrite(sc_clk, LOW);
  12.   pinMode(sc_clk, OUTPUT);
  13.   digitalWrite(sc_rst, LOW);
  14.   pinMode(sc_rst, OUTPUT); // RST = true
  15.   digitalWrite(sc_rxtx, LOW);
  16.   pinMode(sc_rxtx, INPUT); // HiZ
  17.  
  18.   // 16bit speed counter
  19.   TCCR1A = 0; // normal mode
  20.   TCCR1B = _BV(CS10); // 16MHz
  21.   TIMSK1 = _BV(TOIE1); // OVF int
  22. }
  23.  
  24. volatile word timer_ovf_count;
  25.  
  26. ISR(TIMER1_OVF_vect) {
  27.   timer_ovf_count++;
  28. }
  29.  
  30. void wait_card()
  31. {
  32.  while (digitalRead(sc_switch) == HIGH) {
  33.    delay(10);
  34.    if (digitalRead(sc_switch) == HIGH) continue;
  35.    delay(10);
  36.    if (digitalRead(sc_switch) == HIGH) continue;
  37.    delay(10);
  38.    if (digitalRead(sc_switch) == HIGH) continue;
  39.    break;
  40.  }
  41. }
  42.  
  43. int check_card()
  44. {
  45.  if (digitalRead(sc_switch) == HIGH) {
  46.    delay(10);
  47.   if (digitalRead(sc_switch) != HIGH) return true;
  48.    delay(10);
  49.   if (digitalRead(sc_switch) != HIGH) return true;
  50.    delay(10);
  51.   if (digitalRead(sc_switch) != HIGH) return true;
  52.   return false;  
  53.  }
  54.  return true;
  55. }
  56.  
  57. inline void tunedDelay(uint16_t delay) {
  58.   uint8_t tmp=0;
  59.  
  60.   asm volatile("sbiw    %0, 0x01 \n\t"
  61.     "ldi %1, 0xFF \n\t"
  62.     "cpi %A0, 0xFF \n\t"
  63.     "cpc %B0, %1 \n\t"
  64.     "brne .-10 \n\t"
  65.     : "+r" (delay), "+a" (tmp)
  66.     : "0" (delay)
  67.     );
  68. }
  69.  
  70. int rx_bits;
  71. word rx_delay1;
  72. word rx_delay2;
  73. word tx_delay;
  74.  
  75. void set_baudrate_low()
  76. {
  77.   // etu^-1 = 4MHz / 372 = 10752 bps
  78.   rx_bits = 8 + 1 + 2; // 8 + parity + stop
  79.   rx_delay1 = 110;
  80.   rx_delay2 = 200;
  81.   tx_delay = 200;
  82. }
  83.  
  84. void set_baudrate_high()
  85. {
  86.   // etu^-1 = 4MHz * 2 / 372 = 21504 bps
  87.   rx_bits = 8 + 1 + 1; // 8 + parity + stop
  88.   rx_delay1 = 50;
  89.   rx_delay2 = 90;
  90.   tx_delay = 90;
  91. }
  92.  
  93. int rx_pos;
  94. int rx_buf[256]; // 10 or 11 bit
  95. word rx_timestamp[256];
  96. unsigned long last_rx_timestamp;
  97.  
  98. void rx_byte()
  99. {
  100.   int v = 0, d = 1, i;
  101.   word t = TCNT1;
  102.  
  103.   tunedDelay(rx_delay1);
  104.   for (i = 0; i < rx_bits; i++) {
  105.      int b;
  106.      tunedDelay(rx_delay2);
  107.      b = digitalRead(sc_rxtx) == HIGH ? d : 0;
  108.      v |= b;
  109.      d <<= 1;
  110.   }
  111.  
  112.   if (rx_pos < 256) {
  113.     rx_buf[rx_pos] = v;
  114.     rx_timestamp[rx_pos] = t;
  115.     rx_pos++;
  116.   }
  117. }
  118.  
  119. unsigned long last_tx_timestamp;
  120.  
  121. byte tx_byte(byte x)
  122. {
  123.   int v = x, p, i;
  124.  
  125.   p = x;
  126.   p = p ^ (p >> 4);
  127.   p = p ^ (p >> 2);
  128.   p = p ^ (p >> 1);
  129.   if (p & 1) v |= 0x100; // parity
  130.  
  131.   v |= 0xFE00; // stop bit
  132.  
  133.   cli();
  134.   word t = TCNT1;
  135.   word th = timer_ovf_count;
  136.   if ((TIFR1 & _BV(TOV1)) && t < 0x1000) {
  137.      th++;
  138.   }
  139.   last_tx_timestamp = (((unsigned long)th) << 16) + t;
  140.   sei();
  141.  
  142.   pinMode(sc_rxtx, OUTPUT); // Lo, start
  143.   tunedDelay(tx_delay);
  144.  
  145.   for (i = 0; i < rx_bits; i++) {
  146.     if (v & 1) {
  147.       pinMode(sc_rxtx, INPUT); // HiZ
  148.     } else {
  149.       pinMode(sc_rxtx, OUTPUT); // Lo
  150.     }
  151.     tunedDelay(tx_delay);
  152.     v >>= 1;
  153.   }
  154.  
  155.   pinMode(sc_rxtx, INPUT); // HiZ, nen no tame
  156.   //delay(10); // yukkuri
  157.  
  158.   return x;
  159. }
  160.  
  161. void rx_bytes(long first_byte_timeout, long rest_bytes_timeout)
  162. {
  163.   rx_pos = 0;
  164.  
  165.   long timeout = first_byte_timeout;
  166.  
  167.   while (timeout > 0) {
  168.     timeout--;
  169.     if (digitalRead(sc_rxtx) == LOW) {
  170.       cli();
  171.       word t = TCNT1;
  172.       word th = timer_ovf_count;
  173.       if ((TIFR1 & _BV(TOV1)) && t < 0x1000) {
  174.          th++;
  175.       }
  176.       last_rx_timestamp = (((unsigned long)th) << 16) + t;
  177.       sei();
  178.       if (digitalRead(sc_rxtx) == HIGH) continue;
  179.       if (digitalRead(sc_rxtx) == HIGH) continue;
  180.       if (digitalRead(sc_rxtx) == HIGH) continue;
  181.       if (digitalRead(sc_rxtx) == HIGH) continue;
  182.       rx_byte();
  183.       timeout = rest_bytes_timeout;
  184.     }
  185.   }
  186. }
  187.  
  188. void dump_rx_buffer()
  189. {
  190.   for (int i = 0; i < rx_pos; i++) {
  191.     Serial.print("+");
  192.     Serial.print(rx_buf[i], HEX);
  193.     Serial.print(" ");
  194.     Serial.println(rx_timestamp[i], HEX);
  195.   }
  196. }
  197.  
  198. void pre_connection()
  199. {
  200.   digitalWrite(sc_rst, LOW); // RST = true
  201.   pinMode(sc_rxtx, INPUT); // HiZ
  202.   TCCR2A = 0; // disconnect CLK
  203. }
  204.  
  205. byte i_counter = 0x00;
  206.  
  207. void reset_card()
  208. {
  209.   OCR2A = 1; // 16MHz / 4
  210.   TCCR2A = _BV(COM2A0) | _BV(WGM21); // toggle A, CTC
  211.   TCCR2B = _BV(CS20); // 16MHz
  212.  
  213.   // wait 400 clk = 100ms (+alpha) < 40k clk
  214.   delay(100 + 100);
  215.  
  216.   // IO must be HIGH
  217.   if (digitalRead(sc_rxtx) != HIGH) {
  218.     Serial.println("!!! sc_rxtx != HIGH @ RST");
  219.   }
  220.  
  221.   digitalWrite(sc_rst, HIGH); // RST = false
  222.  
  223.   set_baudrate_low();
  224.   // wait ATR
  225.   Serial.println("### Wait ATR");
  226.   rx_bytes(400000L, 100000L);
  227.   if (rx_pos > 0) {
  228.     Serial.println("### Get ATR: ");
  229.     dump_rx_buffer();
  230.   } else {
  231.     Serial.println("!!! No ATR");    
  232.   }
  233.   set_baudrate_high();
  234.   {
  235.     Serial.println("### IFS");
  236.     byte lrc = 0;
  237.     lrc ^= tx_byte(0x00); // NAD
  238.     lrc ^= tx_byte(0xC1); // PCB, S(IFS, REQ)
  239.     lrc ^= tx_byte(1);    // LEN
  240.     lrc ^= tx_byte(254);  // IFS max
  241.     tx_byte(lrc);
  242.    
  243.     rx_bytes(400000L, 100000L);
  244.     dump_rx_buffer();
  245.   }
  246.  
  247.   i_counter = 0;
  248. }
  249.  
  250.  
  251. void command()
  252. {
  253.   Serial.println("### run command");
  254.  
  255.   Serial.println("### INI");
  256.   byte lrc = 0;
  257.   lrc ^= tx_byte(0x00); // NAD
  258.   lrc ^= tx_byte(i_counter); // PCB
  259.   lrc ^= tx_byte(5); // LEN
  260.   // INF
  261.   lrc ^= tx_byte(0x90); // CLA
  262.   lrc ^= tx_byte(0x30); // INS
  263.   lrc ^= tx_byte(0x00); // P1
  264.   lrc ^= tx_byte(0x00); // P2
  265.   lrc ^= tx_byte(0x00); // Le
  266.   // LRC
  267.   tx_byte(lrc);
  268.  
  269.   rx_bytes(400000L, 100000L);
  270.   dump_rx_buffer();
  271.  
  272.   i_counter ^= 0x40;
  273.  
  274.   byte cardId[6];
  275.   cardId[0] = rx_buf[11];
  276.   cardId[1] = rx_buf[12];
  277.   cardId[2] = rx_buf[13];
  278.   cardId[3] = rx_buf[14];
  279.   cardId[4] = rx_buf[15];
  280.   cardId[5] = rx_buf[16];
  281.  
  282.   Serial.println("### EMM benchmark");
  283.   Serial.flush();
  284.   unsigned long R = 1UL;
  285.   for (int rshift = 0; rshift < 32; rshift++, R <<= 1) {
  286.     unsigned long total = 0;
  287.    
  288.     for (int L = 0; L < 128 * 13; L += 13) {
  289.       lrc = 0;
  290.       lrc ^= tx_byte(0x00); // NAD
  291.       lrc ^= tx_byte(i_counter); // PCB
  292.       lrc ^= tx_byte(14 + 8 * 13); // LEN
  293.       // INF
  294.       lrc ^= tx_byte(0x90); // CLA
  295.       lrc ^= tx_byte(0x36); // INS
  296.       lrc ^= tx_byte(0x00); // P1
  297.       lrc ^= tx_byte(0x00); // P2
  298.       lrc ^= tx_byte(8 + 8 * 13);
  299.       lrc ^= tx_byte(cardId[0]);
  300.       lrc ^= tx_byte(cardId[1]);
  301.       lrc ^= tx_byte(cardId[2]);
  302.       lrc ^= tx_byte(cardId[3]);
  303.       lrc ^= tx_byte(cardId[4]);
  304.       lrc ^= tx_byte(cardId[5]);
  305.       lrc ^= tx_byte(8 + 8 * 13 -  7); // EMM len
  306.       lrc ^= tx_byte(0x00); // protocol
  307.    
  308.       for (int i = 0; i < 13; i++) {  
  309.         lrc ^= tx_byte(((L + i) >> 0) & 0xFF);
  310.         lrc ^= tx_byte(((L + i) >> 8) & 0xFF);
  311.         lrc ^= tx_byte(0x00);
  312.         lrc ^= tx_byte(0x00);
  313.         lrc ^= tx_byte((R >> 0) & 0xFF);
  314.         lrc ^= tx_byte((R >> 8) & 0xFF);
  315.         lrc ^= tx_byte((R >> 16) & 0xFF);
  316.         lrc ^= tx_byte((R >> 24) & 0xFF);
  317.       }
  318.       lrc ^= tx_byte(0x00); // Le
  319.       // LRC
  320.       tx_byte(lrc);
  321.      
  322.       rx_bytes(4000000L, 100000L);
  323.       //dump_rx_buffer();
  324.    
  325.       i_counter ^= 0x40;
  326.      
  327.       total += last_rx_timestamp - last_tx_timestamp;
  328.     }
  329.     Serial.print("R,");
  330.     Serial.print(R);
  331.     Serial.print(",");
  332.     Serial.println(total);
  333.     Serial.flush();
  334.   }
  335. }
  336.  
  337. void loop()
  338. {
  339.   pre_connection();
  340.   wait_card();
  341.   Serial.println("### card connected");
  342.   reset_card();
  343.   Serial.println("### card ready");
  344.   while (true) {
  345.     Serial.println(">");
  346.     while (Serial.available() == 0) {
  347.       if (!check_card()) {
  348.         Serial.println("### card removed");
  349.         return;
  350.       }
  351.     }
  352.     if (Serial.read() == '\n') {
  353.       command();
  354.     }
  355.   }
  356. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement