diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c
index 770c63544..8a0d4934a 100644
--- a/armsrc/hitag2.c
+++ b/armsrc/hitag2.c
@@ -18,7 +18,7 @@
 // Piwi, 2019
 // Iceman, 2019
 // Anon, 2019
-// Doegos, 2020
+// Doegox, 2020
 
 #include "hitag2.h"
 #include "hitag2_crypto.h"
@@ -96,7 +96,6 @@ size_t blocknr;
 size_t flipped_bit = 0;
 uint32_t byte_value = 0;
 
-
 static int hitag2_reset(void) {
     tag.state = TAG_STATE_RESET;
     tag.crypto_active = 0;
@@ -143,6 +142,8 @@ static int hitag2_init(void) {
 #define HITAG_T_TAG_CAPTURE_THREE_HALF  41
 #define HITAG_T_TAG_CAPTURE_FOUR_HALF   57
 
+/*
+// sim
 static void hitag_send_bit(int bit) {
     LED_A_ON();
 
@@ -167,6 +168,7 @@ static void hitag_send_bit(int bit) {
     LED_A_OFF();
 }
 
+// sim
 static void hitag_send_frame(const uint8_t *frame, size_t frame_len) {
     // SOF - send start of frame
     hitag_send_bit(1);
@@ -183,6 +185,7 @@ static void hitag_send_frame(const uint8_t *frame, size_t frame_len) {
     // Drop the modulation
     LOW(GPIO_SSC_DOUT);
 }
+*/
 
 // sim
 static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
@@ -215,42 +218,43 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
 
         // Read/Write command: ..xx x..y  yy with yyy == ~xxx, xxx is sector number
         case 10: {
-            unsigned int sector = (~(((rx[0] << 2) & 0x04) | ((rx[1] >> 6) & 0x03)) & 0x07);
+            uint16_t sector = (~(((rx[0] << 2) & 0x04) | ((rx[1] >> 6) & 0x03)) & 0x07);
+
             // Verify complement of sector index
             if (sector != ((rx[0] >> 3) & 0x07)) {
-                //DbpString("Transmission error (read/write)");
+                DbpString("Transmission error (read/write)");
                 return;
             }
 
             switch (rx[0] & 0xC6) {
                 // Read command: 11xx x00y
-                case 0xC0:
+                case 0xC0: {
                     memcpy(tx, tag.sectors[sector], 4);
                     *txlen = 32;
                     break;
-
+                }
                 // Inverted Read command: 01xx x10y
-                case 0x44:
+                case 0x44: {
                     for (size_t i = 0; i < 4; i++) {
                         tx[i] = tag.sectors[sector][i] ^ 0xff;
                     }
                     *txlen = 32;
                     break;
-
+                }
                 // Write command: 10xx x01y
-                case 0x82:
+                case 0x82: {
                     // Prepare write, acknowledge by repeating command
                     memcpy(tx, rx, nbytes(rxlen));
                     *txlen = rxlen;
                     tag.active_sector = sector;
                     tag.state = TAG_STATE_WRITING;
                     break;
-
+                }
                 // Unknown command
-                default:
+                default: {
                     Dbprintf("Unknown command: %02x %02x", rx[0], rx[1]);
                     return;
-                    break;
+                }
             }
         }
         break;
@@ -284,15 +288,13 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
 
             // Reset the cipher state
             hitag2_cipher_reset(&tag, rx);
+
             // Check if the authentication was correct
             if (!hitag2_cipher_authenticate(&(tag.cs), rx + 4)) {
                 // The reader failed to authenticate, do nothing
                 Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed!", rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]);
                 return;
             }
-            // Succesful, but commented out reporting back to the Host, this may delay to much.
-            // Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x OK!",rx[0],rx[1],rx[2],rx[3],rx[4],rx[5],rx[6],rx[7]);
-
             // Activate encryption algorithm for all further communication
             tag.crypto_active = 1;
 
@@ -303,15 +305,13 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
         break;
     }
 
-    // LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false);
-    // LogTrace(tx, nbytes(txlen), 0, 0, NULL, true);
-
     if (tag.crypto_active) {
         hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8);
     }
 }
 
-// sim
+// reader/writer
+// returns how long it took
 static uint32_t hitag_reader_send_bit(int bit) {
     uint32_t wait = 0;
     LED_A_ON();
@@ -330,36 +330,41 @@ static uint32_t hitag_reader_send_bit(int bit) {
 
     if (bit == 0) {
         // Zero bit: |_-|
-        lf_wait_periods(HITAG_T_0-HITAG_T_LOW); // wait for 18-22 times the carrier period
-        wait += HITAG_T_0-HITAG_T_LOW;
+        lf_wait_periods(HITAG_T_0 - HITAG_T_LOW); // wait for 18-22 times the carrier period
+        wait += HITAG_T_0 - HITAG_T_LOW;
     } else {
         // One bit: |_--|
-        lf_wait_periods(HITAG_T_1-HITAG_T_LOW); // wait for 26-32 times the carrier period
-        wait += HITAG_T_1-HITAG_T_LOW;
+        lf_wait_periods(HITAG_T_1 - HITAG_T_LOW); // wait for 26-32 times the carrier period
+        wait += HITAG_T_1 - HITAG_T_LOW;
     }
     /*lf_wait_periods(10);*/
     LED_A_OFF();
     return wait;
 }
 
-// sim
+// reader/writer
 static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) {
+
     uint32_t wait = 0;
     // Send the content of the frame
     for (size_t i = 0; i < frame_len; i++) {
         wait += hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1);
     }
+
     // Enable modulation, which means, drop the field
     lf_modulation(true);
+
     // Wait for 4-10 times the carrier period
     lf_wait_periods(HITAG_T_LOW);
     wait += HITAG_T_LOW;
+
     // Disable modulation, just activates the field again
     lf_modulation(false);
 
     // t_stop, high field for stop condition (> 36)
     lf_wait_periods(HITAG_T_STOP);
     wait += HITAG_T_STOP;
+
     return wait;
 }
 
@@ -688,10 +693,10 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
                     }
 
                     if (blocknr > 7) {
-                        DbpString("Read successful!");
                         bSuccessful = true;
                         return false;
                     }
+
                     *txlen = 10;
                     tx[0] = 0xC0 | (blocknr << 3) | ((blocknr ^ 7) >> 2);
                     tx[1] = ((blocknr ^ 7) << 6);
@@ -951,7 +956,6 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
                 Dbhexdump(4, rx, false);
             }
             if (blocknr > 0) {
-                DbpString("Read successful!");
                 bSuccessful = true;
                 return false;
             }
@@ -970,10 +974,6 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
 // Hitag2 Sniffing
 void SniffHitag2(void) {
 
-    LEDsoff();
-    StopTicks();
-
-    FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
     BigBuf_free();
     BigBuf_Clear_ext(false);
     clear_trace();
@@ -988,19 +988,34 @@ void SniffHitag2(void) {
     DbpString("Starting Hitag2 sniffing");
     LED_D_ON();
 
-    lf_init(false);
+    lf_init(false, false);
+
     logging = false;
 
     size_t periods = 0;
     uint8_t periods_bytes[4];
 
+    int16_t checked = 0;
+
     /*bool waiting_for_first_edge = true;*/
     LED_C_ON();
 
-    while (!BUTTON_PRESS() && !data_available()) {
+    while (!BUTTON_PRESS()) {
 
         WDT_HIT();
 
+        // only every 1000th times, in order to save time when collecting samples.
+        if (checked == 1000) {
+            if (data_available()) {
+                checked = -1;
+                break;
+            } else {
+                checked = 0;
+            }
+        }
+        ++checked;
+
+
         // Receive frame, watch for at most T0*EOF periods
         lf_reset_counter();
 
@@ -1021,69 +1036,57 @@ void SniffHitag2(void) {
             LogTrace(periods_bytes, 4, 0, 0, NULL, true);
         }
 
-
-        /*
-                // Check if frame was captured
-                if (rxlen > 0) {
-                    // frame_count++;
-                    LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame);
-
-                    // Check if we recognize a valid authentication attempt
-                    if (nbytes(rxlen) == 8) {
-                        // Store the authentication attempt
-                        if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) {
-                            memcpy(auth_table + auth_table_len, rx, 8);
-                            auth_table_len += 8;
-                        }
-                    }
-        */
     }
 
     lf_finalize();
 
-    StartTicks();
-
     DbpString("Hitag2 sniffing finish. Use `lf hitag list` for annotations");
 }
 
 // Hitag2 simulation
 void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
 
-    StopTicks();
-
-    // int frame_count = 0;
-    int response = 0, overflow = 0;
-    uint8_t rx[HITAG_FRAME_LEN];
-    size_t rxlen = 0;
-    uint8_t tx[HITAG_FRAME_LEN];
-    size_t txlen = 0;
-
-    FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
     BigBuf_free();
     BigBuf_Clear_ext(false);
     clear_trace();
     set_tracing(true);
 
+    // empties bigbuff etc
+    lf_init(false, true);
+
+    int response = 0;
+    uint8_t rx[HITAG_FRAME_LEN];
+    size_t rxlen = 0;
+    uint8_t tx[HITAG_FRAME_LEN];
+    size_t txlen = 0;
+
     auth_table_len = 0;
     auth_table_pos = 0;
-    auth_table = BigBuf_malloc(AUTH_TABLE_LENGTH);
-    memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
+//    auth_table = BigBuf_malloc(AUTH_TABLE_LENGTH);
+//    memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
 
     // Reset the received frame, frame count and timing info
-    memset(rx, 0x00, sizeof(rx));
+//    memset(rx, 0x00, sizeof(rx));
+//    memset(tx, 0x00, sizeof(tx));
 
     DbpString("Starting Hitag2 simulation");
 
     LED_D_ON();
+
+    // hitag2 state machine?
     hitag2_init();
 
+    // copy user supplied emulation data
     if (tag_mem_supplied) {
         DbpString("Loading hitag2 memory...");
         memcpy((uint8_t *)tag.sectors, data, 48);
     }
 
+    // printing
     uint32_t block = 0;
     for (size_t i = 0; i < 12; i++) {
+
+       // num2bytes?
         for (size_t j = 0; j < 4; j++) {
             block <<= 8;
             block |= tag.sectors[i][j];
@@ -1091,89 +1094,137 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
         Dbprintf("| %d | %08x |", i, block);
     }
 
-    // Set up simulator mode, frequency divisor which will drive the FPGA
-    // and analog mux selection.
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
-    SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+    uint8_t tag_modulation;
+    size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5;
+    uint8_t nrz_samples[max_nrzs];
+    size_t nrzs = 0, periods = 0;
 
-    // Configure output pin that is connected to the FPGA (for modulating)
-    AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT;
-    AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT;
+//    uint32_t command_start = 0, command_duration = 0;
 
-    // Disable modulation at default, which means release resistance
-    LOW(GPIO_SSC_DOUT);
+    int16_t checked = 0;
 
-    // Enable Peripheral Clock for
-    //   TIMER_CLOCK0, used to measure exact timing before answering
-    //   TIMER_CLOCK1, used to capture edges of the tag frames
-    AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
+    while (!BUTTON_PRESS()) {
 
-    AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
-
-    // Disable timer during configuration
-    AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
-    AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
-
-    // TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
-    AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
-
-    // TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
-    // external trigger rising edge, load RA on rising edge of TIOA.
-    AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING;
-
-    // Enable and reset counter
-    AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
-    AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
-
-    // synchronized startup procedure
-    while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC0 returned to zero
-
-    while (!BUTTON_PRESS() && !data_available()) {
-        // Watchdog hit
+loop1:
+        LED_A_OFF();
         WDT_HIT();
 
-        // Receive frame, watch for at most T0*EOF periods
-        while (AT91C_BASE_TC1->TC_CV < HITAG_T0 * HITAG_T_EOF) {
-            // Check if rising edge in modulation is detected
-            if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
-                // Retrieve the new timing values
-                int ra = (AT91C_BASE_TC1->TC_RA / HITAG_T0) + overflow;
-                overflow = 0;
+        // only every 1000th times, in order to save time when collecting samples.
+        if (checked == 100) {
+            if (data_available()) {
+                checked = -1;
+                break;
+            } else {
+                checked = 0;
+            }
+        }
+        ++checked;
 
-                // Reset timer every frame, we have to capture the last edge for timing
-                AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
+        rxlen = 0;
 
-                LED_B_ON();
+        // Keep administration of the first edge detection
+        bool waiting_for_first_edge = true;
 
-                // Capture reader frame
-                if (ra >= HITAG_T_STOP) {
-                    if (rxlen != 0) {
-                        //DbpString("wierd0?");
-                    }
-                    // Capture the T0 periods that have passed since last communication or field drop (reset)
-                    response = (ra - HITAG_T_LOW);
-                } else if (ra >= HITAG_T_1_MIN) {
-                    // '1' bit
-                    rx[rxlen / 8] |= 1 << (7 - (rxlen % 8));
-                    rxlen++;
-                } else if (ra >= HITAG_T_0_MIN) {
-                    // '0' bit
-                    rx[rxlen / 8] |= 0 << (7 - (rxlen % 8));
-                    rxlen++;
-                } else {
-                    // Ignore wierd value, is to small to mean anything
+        // Did we detected any modulaiton at all
+        bool detected_tag_modulation = false;
+
+        // Use the current modulation state as starting point
+        tag_modulation = lf_get_tag_modulation();
+
+        // Receive frame, watch for at most max_nrzs periods
+        // Reset the number of NRZ samples and use edge detection to detect them
+        nrzs = 0;
+        while (nrzs < max_nrzs) {
+            // Get the timing of the next edge in number of wave periods
+            periods = lf_count_edge_periods(128);
+
+            // Just break out of loop after an initial time-out (tag is probably not available)
+            // The function lf_count_edge_periods() returns 0 when a time-out occurs
+            if (periods == 0) {
+                goto loop1;  //break;
+            }
+
+            LED_A_ON();
+
+            // Are we dealing with the first incoming edge
+            if (waiting_for_first_edge) {
+
+                // Register the number of periods that have passed
+                response = periods;
+
+                // Indicate that we have dealt with the first edge
+                waiting_for_first_edge = false;
+
+                // The first edge is always a single NRZ bit, force periods on 16
+                periods = 16;
+
+                // We have received more than 0 periods, so we have detected a tag response
+                detected_tag_modulation = true;
+            }
+
+            // Evaluate the number of periods before the next edge
+            if (periods > 24 && periods <= 64) {
+                // Detected two sequential equal bits and a modulation switch
+                // NRZ modulation: (11 => --|) or (11 __|)
+                nrz_samples[nrzs++] = tag_modulation;
+                nrz_samples[nrzs++] = tag_modulation;
+                // Invert tag modulation state
+                tag_modulation ^= 1;
+            } else if (periods > 0 && periods <= 24) {
+                // Detected one bit and a modulation switch
+                // NRZ modulation: (1 => -|) or (0 _|)
+                nrz_samples[nrzs++] = tag_modulation;
+                tag_modulation ^= 1;
+            } else {
+                tag_modulation ^= 1;
+                // The function lf_count_edge_periods() returns > 64 periods, this is not a valid number periods
+                Dbprintf("Detected unexpected period count: %d", periods);
+                break;
+            }
+        }
+
+        // If there is no response, just repeat the loop
+        if (!detected_tag_modulation) continue;
+
+        // Make sure we always have an even number of samples. This fixes the problem
+        // of ending the manchester decoding with a zero. See the example below where
+        // the '|' character is end of modulation
+        //  One at the end: ..._-|_____...
+        // Zero at the end: ...-_|_____...
+        // The last modulation change of a zero is not detected, but we should take
+        // the half period in account, otherwise the demodulator will fail.
+        if ((nrzs % 2) != 0) {
+            nrz_samples[nrzs++] = tag_modulation;
+        }
+
+        LED_B_ON();
+
+        // decode bitstream
+        manrawdecode((uint8_t *)nrz_samples, &nrzs, true, 0);
+
+        // Verify if the header consists of five consecutive ones
+        if (nrzs < 5) {
+            Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs);
+            continue;
+       } else {
+            for (size_t i = 0; i < 5; i++){
+                if (nrz_samples[i] != 1) {
+                    Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one", i);
                 }
             }
         }
 
+        // Pack the response into a byte array
+        for (size_t i = 5; i < 37; i++){
+            uint8_t bit = nrz_samples[i];
+            rx[rxlen / 8] |= bit << (7 - (rxlen % 8));
+            rxlen++;
+        }
+
         // Check if frame was captured
         if (rxlen > 4) {
-            // frame_count++;
-            LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
 
-            // Disable timer 1 with external trigger to avoid triggers during our own modulation
-            AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
+            LogTrace(rx, nbytes(rxlen), response, 0, NULL, true);
 
             // Process the incoming frame (rx) and prepare the outgoing frame (tx)
             hitag2_handle_reader_command(rx, rxlen, tx, &txlen);
@@ -1183,11 +1234,15 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
             // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low)
             // periods. The gap time T_Low varies (4..10). All timer values are in
             // terms of T0 units
-            while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * (HITAG_T_WAIT_1_MIN - HITAG_T_LOW));
+            lf_wait_periods(200);
 
             // Send and store the tag answer (if there is any)
             if (txlen) {
-                hitag_send_frame(tx, txlen);
+                // Transmit the tag frame
+                //hitag_send_frame(tx, txlen);
+                lf_manchester_send_bytes(tx, txlen);
+
+                // Store the frame in the trace
                 LogTrace(tx, nbytes(txlen), 0, 0, NULL, false);
             }
 
@@ -1195,37 +1250,22 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
             memset(rx, 0x00, sizeof(rx));
             response = 0;
 
-            // Enable and reset external trigger in timer for capturing future frames
-            AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
             LED_B_OFF();
         }
-        // Reset the frame length
-        rxlen = 0;
-        // Save the timer overflow, will be 0 when frame was received
-        overflow += (AT91C_BASE_TC1->TC_CV / HITAG_T0);
-        // Reset the timer to restart while-loop that receives frames
-        AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
     }
 
-    LEDsoff();
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-    set_tracing(false);
-    AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
-    AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
+    lf_finalize();
 
     // release allocated memory from BigBuff.
     BigBuf_free();
 
-    StartTicks();
+    DbpString("Sim stopped");
 
-    DbpString("Sim Stopped");
+//    reply_ng(CMD_LF_HITAG_SIMULATE, (checked == -1) ? PM3_EOPABORTED : PM3_SUCCESS, (uint8_t *)tag.sectors, tag_size);
 }
 
 void ReaderHitag(hitag_function htf, hitag_data *htd) {
 
-    StopTicks();
-
-    int frame_count = 0;
     uint32_t command_start = 0;
     uint32_t command_duration = 0;
     uint32_t response_start = 0;
@@ -1261,9 +1301,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
             // this part will be unreadable
             memset(tag.sectors + 2, 0x0, 30);
             blocknr = 0;
+            break;
         }
-        break;
-
         case RHT1F_AUTHENTICATE: {
             Dbprintf("Read all blocks in authed mode");
             memcpy(nonce, htd->ht1auth.nonce, 4);
@@ -1284,8 +1323,8 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
             DbpString("Logdata_1:");
             Dbhexdump(4, logdata_1, false);
             blocknr = 0;
+            break;
         }
-        break;
         case RHT2F_PASSWORD: {
             Dbprintf("List identifier in password mode");
             if (memcmp(htd->pwd.password, "\x00\x00\x00\x00", 4) == 0)
@@ -1334,17 +1373,17 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
         default: {
             Dbprintf("Error, unknown function: %d", htf);
             set_tracing(false);
-            StartTicks();
             return;
         }
     }
 
     LED_D_ON();
 
+    // hitag2 state machine?
     hitag2_init();
 
     // init as reader
-    lf_init(true);
+    lf_init(true, false);
 
     uint8_t attempt_count = 0;
 
@@ -1379,24 +1418,34 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
     size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit
     uint8_t nrz_samples[max_nrzs];
     size_t nrzs = 0;
+    int16_t checked = 0;
 
-    while (!bStop && !BUTTON_PRESS() && !data_available()) {
+    while (!bStop) {
 
         WDT_HIT();
 
+        // only every 1000th times, in order to save time when collecting samples.
+        if (checked == 1000) {
+            if (BUTTON_PRESS() || data_available()) {
+                checked = -1;
+                break;
+            } else {
+                checked = 0;
+            }
+        }
+        ++checked;
+
         // By default reset the transmission buffer
         tx = txbuf;
         switch (htf) {
             case RHT1F_PLAIN: {
                 bStop = !hitag_plain(rx, rxlen, tx, &txlen, false);
+                break;
             }
-            break;
-
             case RHT1F_AUTHENTICATE: {
                 bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen);
+                break;
             }
-            break;
-
             case RHT2F_PASSWORD: {
                 bStop = !hitag2_password(rx, rxlen, tx, &txlen, false);
                 break;
@@ -1512,7 +1561,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
         // and to be able to overwrite the first samples with the trace (since they currently
         // still use the same memory space)
         if (txlen > 0) {
-            frame_count++;
             LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true);
         }
 
@@ -1543,7 +1591,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
 
         // Verify if the header consists of five consecutive ones
         if (nrzs < 5) {
-            //Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs);
+            Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs);
             break;
         } else {
             size_t i;
@@ -1560,51 +1608,43 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
         for (size_t i = 5; i < nrzs; i++) {
             uint8_t bit = nrz_samples[i];
             if (bit > 1) { // When Manchester detects impossible symbol it writes "7"
-                //Dbprintf("Error in Manchester decoding, abort");
+                Dbprintf("Error in Manchester decoding, abort");
                 break;
             }
             rx[rxlen / 8] |= bit << (7 - (rxlen % 8));
             rxlen++;
         }
+
         if (rxlen % 8 == 1) // skip spurious bit
             rxlen--;
 
         // Check if frame was captured and store it
         if (rxlen > 0) {
-            frame_count++;
-//            if (bCollision){
-//                // AC decoding hack
-//                fix_ac_decoding(rx, 64);
-//                rxlen = 32;
-//            }
 
             LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false);
+
 // TODO when using cumulative time for command_start, pm3 doesn't reply anymore, e.g. on lf hitag read 23 4F4E4D494B52
-            command_start = response_start + response_duration;
-//            command_start = 0;
-            // Dbhexdump(nbytes(rxlen), rx, false);
+// Use delta time?
+//            command_start = response_start + response_duration;
+            command_start = 0;
+            nrzs = 0;
         }
     }
 
 out:
     lf_finalize();
-    Dbprintf("TX/RX frames recorded: %u", frame_count);
 
     // release allocated memory from BigBuff.
     BigBuf_free();
-    StartTicks();
 
     if (bSuccessful)
-        reply_old(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size);
+        reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size);
     else
         reply_mix(CMD_ACK, bSuccessful, 0, 0, 0, 0);
 }
 
 void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
 
-    StopTicks();
-
-    int frame_count = 0;
     uint32_t command_start = 0;
     uint32_t command_duration = 0;
     uint32_t response_start = 0;
@@ -1659,7 +1699,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
         break;
         default: {
             Dbprintf("Error, unknown function: %d", htf);
-            StartTicks();
             return;
         }
         break;
@@ -1670,7 +1709,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
     hitag2_init();
 
     // init as reader
-    lf_init(true);
+    lf_init(true, false);
     
     // Tag specific configuration settings (sof, timings, etc.)
     if (htf < 10) {
@@ -1704,7 +1743,19 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
     uint8_t nrz_samples[max_nrzs];
     size_t nrzs = 0;
 
-    while (!bStop && !BUTTON_PRESS() && !data_available()) {
+    int16_t checked = 0;
+    while (!bStop) {
+
+        // only every 1000th times, in order to save time when collecting samples.
+        if (checked == 1000) {
+            if (BUTTON_PRESS() || data_available()) {
+                checked = -1;
+                break;
+            } else {
+                checked = 0;
+            }
+        }
+        ++checked;
 
         WDT_HIT();
 
@@ -1731,7 +1782,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
 
         // Transmit the reader frame
         command_duration = hitag_reader_send_frame(tx, txlen);
-        
+
         response_start = command_start + command_duration;
 
         // Let the antenna and ADC values settle
@@ -1814,7 +1865,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
         // and to be able to overwrite the first samples with the trace (since they currently
         // still use the same memory space)
         if (txlen > 0) {
-            frame_count++;
             LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true);
         }
 
@@ -1872,8 +1922,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
 
         // Check if frame was captured and store it
         if (rxlen > 0) {
-            frame_count++;
-
             LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false);
             command_start = 0;
         }
@@ -1882,11 +1930,9 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
 
 out:
     lf_finalize();
-    Dbprintf("TX/RX frames recorded: %u", frame_count);
 
     // release allocated memory from BigBuff.
     BigBuf_free();
-    StartTicks();
-    
+
     reply_mix(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, tag_size);
 }