- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- FpgaSetupSsc();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
-
- /* Bitbang the transmitter */
- AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
- AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
- AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
-
- setup_timer();
-
- while(!BUTTON_PRESS()) {
- /* Switch on carrier and let the tag charge for 1ms */
- AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT;
- SpinDelay(1);
-
- LED_A_ON();
- frame_send_rwd(queries[0].data, queries[0].bits);
- LED_A_OFF();
-
- frame_clean(¤t_frame);
- LED_B_ON();
- frame_receive_rwd(¤t_frame, responses[0].bits);
- LED_B_OFF();
-
- /* Switch off carrier, make sure tag is reset */
- AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
- SpinDelay(10);
-
- WDT_HIT();
- }
-
+ /* First Part of Handshake (IV) */
+ if(f->bits == 7) {
+ if(f->data == SESSION_IV) {
+ LED_C_ON();
+ prng_timer->TC_CCR = AT91C_TC_SWTRG;
+ legic_prng_init(f->data);
+ frame_send_tag(0x3d, 6, 1); /* 0x3d^0x26 = 0x1b */
+ legic_state = STATE_IV;
+ legic_read_count = 0;
+ legic_prng_bc = 0;
+ legic_prng_iv = f->data;
+
+ /* TIMEOUT */
+ timer->TC_CCR = AT91C_TC_SWTRG;
+ while(timer->TC_CV > 1);
+ while(timer->TC_CV < 280);
+ return;
+ } else if((prng_timer->TC_CV % 50) > 40) {
+ legic_prng_init(f->data);
+ frame_send_tag(0x3d, 6, 1);
+ SpinDelay(20);
+ return;
+ }
+ }
+
+ /* 0x19==??? */
+ if(legic_state == STATE_IV) {
+ if((f->bits == 6) && (f->data == (0x19 ^ get_key_stream(1, 6)))) {
+ legic_state = STATE_CON;
+
+ /* TIMEOUT */
+ timer->TC_CCR = AT91C_TC_SWTRG;
+ while(timer->TC_CV > 1);
+ while(timer->TC_CV < 200);
+ return;
+ } else {
+ legic_state = STATE_DISCON;
+ LED_C_OFF();
+ Dbprintf("0x19 - Frame: %03.3x", f->data);
+ return;
+ }
+ }
+
+ /* Read */
+ if(f->bits == 11) {
+ if(legic_state == STATE_CON) {
+ int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
+ int addr = f->data ^ key; addr = addr >> 1;
+ int data = ((uint8_t*)BigBuf)[addr];
+ int hash = LegicCRC(addr, data, 11) << 8;
+ ((uint8_t*)BigBuf)[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
+ legic_read_count++;
+
+ //Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c);
+ legic_prng_forward(legic_reqresp_drift);
+
+ frame_send_tag(hash | data, 12, 1);
+
+ /* SHORT TIMEOUT */
+ timer->TC_CCR = AT91C_TC_SWTRG;
+ while(timer->TC_CV > 1);
+ legic_prng_forward(legic_frame_drift);
+ while(timer->TC_CV < 180);
+ return;
+ }
+ }
+
+ /* Write */
+ if(f->bits == 23) {
+ int key = get_key_stream(-1, 23); //legic_frame_drift, 23);
+ int addr = f->data ^ key; addr = addr >> 1; addr = addr & 0x3ff;
+ int data = f->data ^ key; data = data >> 11; data = data & 0xff;
+
+ /* write command */
+ legic_state = STATE_DISCON;
+ LED_C_OFF();
+ Dbprintf("write - addr: %x, data: %x", addr, data);
+ return;
+ }
+
+ if(legic_state != STATE_DISCON) {
+ Dbprintf("Unexpected: sz:%u, Data:%03.3x, State:%u, Count:%u", f->bits, f->data, legic_state, legic_read_count);
+ int i;
+ Dbprintf("IV: %03.3x", legic_prng_iv);
+ for(i = 0; i<legic_read_count; i++) {
+ Dbprintf("Read Nb: %u, Addr: %u", i, ((uint8_t*)BigBuf)[OFFSET_LOG+i]);
+ }
+
+ for(i = -1; i<legic_read_count; i++) {
+ uint32_t t;
+ t = ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4];
+ t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] << 8;
+ t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+2] <<16;
+ t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+3] <<24;
+
+ Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
+ ((uint8_t*)BigBuf)[OFFSET_LOG+128+i],
+ ((uint8_t*)BigBuf)[OFFSET_LOG+384+i],
+ t);
+ }
+ }
+ legic_state = STATE_DISCON;
+ legic_read_count = 0;
+ SpinDelay(10);
+ LED_C_OFF();
+ return;