+ LED_B_OFF();
+ LED_C_OFF();
+ DbpString("write successful");
+}
+
+int timestamp;
+
+/* Handle (whether to respond) a frame in tag mode */
+static void frame_handle_tag(struct legic_frame const * const f)
+{
+ uint8_t *BigBuf = BigBuf_get_addr();
+
+ /* 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 = BigBuf[addr];
+ int hash = LegicCRC(addr, data, 11) << 8;
+ 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, BigBuf[OFFSET_LOG+i]);
+ }
+
+ for(i = -1; i<legic_read_count; i++) {
+ uint32_t t;
+ t = BigBuf[OFFSET_LOG+256+i*4];
+ t |= BigBuf[OFFSET_LOG+256+i*4+1] << 8;
+ t |= BigBuf[OFFSET_LOG+256+i*4+2] <<16;
+ t |= BigBuf[OFFSET_LOG+256+i*4+3] <<24;
+
+ Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
+ BigBuf[OFFSET_LOG+128+i],
+ BigBuf[OFFSET_LOG+384+i],
+ t);
+ }
+ }
+ legic_state = STATE_DISCON;
+ legic_read_count = 0;
+ SpinDelay(10);
+ LED_C_OFF();
+ return;
+}
+
+/* Read bit by bit untill full frame is received
+ * Call to process frame end answer
+ */
+static void emit(int bit)
+{
+ if(bit == -1) {
+ if(current_frame.bits <= 4) {
+ frame_clean(¤t_frame);
+ } else {
+ frame_handle_tag(¤t_frame);
+ frame_clean(¤t_frame);
+ }
+ WDT_HIT();
+ } else if(bit == 0) {
+ frame_append_bit(¤t_frame, 0);
+ } else if(bit == 1) {
+ frame_append_bit(¤t_frame, 1);
+ }