From: pwpiwi <pwpiwi@users.noreply.github.com>
Date: Fri, 6 Mar 2020 16:14:35 +0000 (+0100)
Subject: fixing some fpga and iclass issues
X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/7a53739728caea10b0857596fe3e30606295e8b4

fixing some fpga and iclass issues
* make fpga_version_info.c phony and delete it on 'make clean'
* wait for transfer to complete before returning from FpgaSendCommand()
* log correct tag times in iclass simulation
* shorten pulse from TC1 to TC0 in StartCountSspClk()
* shorten ssp_frame pulse in fpga/hi_reader.v
* some reformatting and whitespace fixes
---

diff --git a/armsrc/Makefile b/armsrc/Makefile
index 7b9e1356..f4ad2ad6 100644
--- a/armsrc/Makefile
+++ b/armsrc/Makefile
@@ -83,8 +83,9 @@ all: $(OBJS)
 
 .DELETE_ON_ERROR:
 
-# version.c should be remade on every compilation
-.PHONY: version.c
+# version.c and fpga_version_info.c to be remade on every compilation
+.PHONY: version.c fpga_version_info.c
+
 version.c: default_version.c
 	perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ 
 
@@ -132,7 +133,7 @@ clean:
 	$(DELETE) $(OBJDIR)$(PATHSEP)*.d
 	$(DELETE) $(OBJDIR)$(PATHSEP)*.z
 	$(DELETE) $(OBJDIR)$(PATHSEP)*.bin
-	$(DELETE) version.c
+	$(DELETE) version.c fpga_version_info.c
 
 .PHONY: all clean help
 help:
diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index 4f0a19b9..56bf67e0 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -1467,13 +1467,13 @@ void  __attribute__((noreturn)) AppMain(void) {
 
 	// Reset SPI
 	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
+	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; // required twice on some AT91SAM Revisions (see Errata in AT91SAM datasheet)
 	// Reset SSC
 	AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
 
-	// Load the FPGA image, which we have stored in our flash.
-	// (the HF version by default)
+	// Load the FPGA image, which we have stored in our flash (HF version by default)
 	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-
+	
 	StartTickCount();
 
 #ifdef WITH_LCD
diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c
index 8693d6b5..61db66d3 100644
--- a/armsrc/fpgaloader.c
+++ b/armsrc/fpgaloader.c
@@ -32,7 +32,7 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end;
 static uint8_t *fpga_image_ptr = NULL;
 static uint32_t uncompressed_bytes_cnt;
 
-#define OUTPUT_BUFFER_LEN 		80
+#define OUTPUT_BUFFER_LEN       80
 
 //-----------------------------------------------------------------------------
 // Set up the Serial Peripheral Interface as master
@@ -49,16 +49,16 @@ void SetupSpi(int mode)
 
 	// Disable PIO control of the following pins, allows use by the SPI peripheral
 	AT91C_BASE_PIOA->PIO_PDR =
-		GPIO_NCS0	|
-		GPIO_NCS2 	|
-		GPIO_MISO	|
-		GPIO_MOSI	|
+		GPIO_NCS0   |
+		GPIO_NCS2   |
+		GPIO_MISO   |
+		GPIO_MOSI   |
 		GPIO_SPCK;
 
 	AT91C_BASE_PIOA->PIO_ASR =
-		GPIO_NCS0	|
-		GPIO_MISO	|
-		GPIO_MOSI	|
+		GPIO_NCS0   |
+		GPIO_MISO   |
+		GPIO_MOSI   |
 		GPIO_SPCK;
 
 	AT91C_BASE_PIOA->PIO_BSR = GPIO_NCS2;
@@ -71,41 +71,41 @@ void SetupSpi(int mode)
 	switch (mode) {
 		case SPI_FPGA_MODE:
 			AT91C_BASE_SPI->SPI_MR =
-				( 0 << 24)	|	// Delay between chip selects (take default: 6 MCK periods)
-				(14 << 16)	|	// Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
-				( 0 << 7)	|	// Local Loopback Disabled
-				( 1 << 4)	|	// Mode Fault Detection disabled
-				( 0 << 2)	|	// Chip selects connected directly to peripheral
-				( 0 << 1) 	|	// Fixed Peripheral Select
-				( 1 << 0);		// Master Mode
+				( 0 << 24)  |   // Delay between chip selects (take default: 6 MCK periods)
+				(14 << 16)  |   // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
+				( 0 << 7)   |   // Local Loopback Disabled
+				( 1 << 4)   |   // Mode Fault Detection disabled
+				( 0 << 2)   |   // Chip selects connected directly to peripheral
+				( 0 << 1)   |   // Fixed Peripheral Select
+				( 1 << 0);      // Master Mode
 			AT91C_BASE_SPI->SPI_CSR[0] =
-				( 1 << 24)	|	// Delay between Consecutive Transfers (32 MCK periods)
-				( 1 << 16)	|	// Delay Before SPCK (1 MCK period)
-				( 6 << 8)	|	// Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
-				( 8 << 4)	|	// Bits per Transfer (16 bits)
-				( 0 << 3)	|	// Chip Select inactive after transfer
-				( 1 << 1)	|	// Clock Phase data captured on leading edge, changes on following edge
-				( 0 << 0);		// Clock Polarity inactive state is logic 0
+				( 1 << 24)  |   // Delay between Consecutive Transfers (32 MCK periods)
+				( 1 << 16)  |   // Delay Before SPCK (1 MCK period)
+				( 6 << 8)   |   // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
+				( 8 << 4)   |   // Bits per Transfer (16 bits)
+				( 0 << 3)   |   // Chip Select inactive after transfer
+				( 1 << 1)   |   // Clock Phase data captured on leading edge, changes on following edge
+				( 0 << 0);      // Clock Polarity inactive state is logic 0
 			break;
 		case SPI_LCD_MODE:
 			AT91C_BASE_SPI->SPI_MR =
-				( 0 << 24)	|	// Delay between chip selects (take default: 6 MCK periods)
-				(11 << 16)	|	// Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
-				( 0 << 7)	|	// Local Loopback Disabled
-				( 1 << 4)	|	// Mode Fault Detection disabled
-				( 0 << 2)	|	// Chip selects connected directly to peripheral
-				( 0 << 1) 	|	// Fixed Peripheral Select
-				( 1 << 0);		// Master Mode
+				( 0 << 24)  |   // Delay between chip selects (take default: 6 MCK periods)
+				(11 << 16)  |   // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
+				( 0 << 7)   |   // Local Loopback Disabled
+				( 1 << 4)   |   // Mode Fault Detection disabled
+				( 0 << 2)   |   // Chip selects connected directly to peripheral
+				( 0 << 1)   |   // Fixed Peripheral Select
+				( 1 << 0);      // Master Mode
 			AT91C_BASE_SPI->SPI_CSR[2] =
-				( 1 << 24)	|	// Delay between Consecutive Transfers (32 MCK periods)
-				( 1 << 16)	|	// Delay Before SPCK (1 MCK period)
-				( 6 << 8)	|	// Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
-				( 1 << 4)	|	// Bits per Transfer (9 bits)
-				( 0 << 3)	|	// Chip Select inactive after transfer
-				( 1 << 1)	|	// Clock Phase data captured on leading edge, changes on following edge
-				( 0 << 0);		// Clock Polarity inactive state is logic 0
+				( 1 << 24)  |   // Delay between Consecutive Transfers (32 MCK periods)
+				( 1 << 16)  |   // Delay Before SPCK (1 MCK period)
+				( 6 << 8)   |   // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
+				( 1 << 4)   |   // Bits per Transfer (9 bits)
+				( 0 << 3)   |   // Chip Select inactive after transfer
+				( 1 << 1)   |   // Clock Phase data captured on leading edge, changes on following edge
+				( 0 << 0);      // Clock Polarity inactive state is logic 0
 			break;
-		default:				// Disable SPI
+		default:                // Disable SPI
 			AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
 			break;
 	}
@@ -118,9 +118,9 @@ void SetupSpi(int mode)
 void FpgaSetupSsc(uint16_t FPGA_mode) {
 	// First configure the GPIOs, and get ourselves a clock.
 	AT91C_BASE_PIOA->PIO_ASR =
-		GPIO_SSC_FRAME	|
-		GPIO_SSC_DIN	|
-		GPIO_SSC_DOUT	|
+		GPIO_SSC_FRAME  |
+		GPIO_SSC_DIN    |
+		GPIO_SSC_DOUT   |
 		GPIO_SSC_CLK;
 	AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
 
@@ -135,14 +135,14 @@ void FpgaSetupSsc(uint16_t FPGA_mode) {
 
 	// 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync
 	// pulse, no output sync
-	if ((FPGA_mode & 0x1c0) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) {
+	if ((FPGA_mode & FPGA_MAJOR_MODE_MASK) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) {
 		AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
 	} else {
 		AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
-	}		
+	}
 
-	// TX clock comes from TK pin, no clock output, outputs change on falling
-	// edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF
+	// TX clock comes from TK pin, no clock output, outputs change on rising edge of TK, 
+	// TF (frame sync) is sampled on falling edge of TK, start TX on rising edge of TF
 	AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
 
 	// tx framing is the same as the rx framing
@@ -157,8 +157,7 @@ void FpgaSetupSsc(uint16_t FPGA_mode) {
 // ourselves, not to another buffer). The stuff to manipulate those buffers
 // is in apps.h, because it should be inlined, for speed.
 //-----------------------------------------------------------------------------
-bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count)
-{
+bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count) {
 	if (buf == NULL) return false;
 
 	AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;        // Disable DMA Transfer
@@ -173,11 +172,11 @@ bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count)
 
 //----------------------------------------------------------------------------
 // Uncompress (inflate) the FPGA data. Returns one decompressed byte with
-// each call. 
+// each call.
 //----------------------------------------------------------------------------
 static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer)
 {
-	if (fpga_image_ptr == compressed_fpga_stream->next_out) {	// need more data
+	if (fpga_image_ptr == compressed_fpga_stream->next_out) {   // need more data
 		compressed_fpga_stream->next_out = output_buffer;
 		compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
 		fpga_image_ptr = output_buffer;
@@ -190,7 +189,7 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
 	}
 
 	uncompressed_bytes_cnt++;
-	
+
 	return *fpga_image_ptr++;
 }
 
@@ -207,7 +206,7 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga
 	}
 
 	return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
-	
+
 }
 
 
@@ -224,14 +223,14 @@ static void fpga_inflate_free(voidpf opaque, voidpf address)
 
 
 //----------------------------------------------------------------------------
-// Initialize decompression of the respective (HF or LF) FPGA stream 
+// Initialize decompression of the respective (HF or LF) FPGA stream
 //----------------------------------------------------------------------------
 static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
 {
 	uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
-	
+
 	uncompressed_bytes_cnt = 0;
-	
+
 	// initialize z_stream structure for inflate:
 	compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
 	compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
@@ -247,7 +246,7 @@ static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_s
 	for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
 		header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
 	}
-	
+
 	// Check for a valid .bit file (starts with bitparse_fixed_header)
 	if(memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) {
 		return true;
@@ -275,25 +274,25 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
 {
 
 	//Dbprintf("DownloadFPGA(len: %d)", FpgaImageLen);
-	
+
 	int i=0;
 
 	AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
 	AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
-	HIGH(GPIO_FPGA_ON);		// ensure everything is powered on
+	HIGH(GPIO_FPGA_ON);     // ensure everything is powered on
 
 	SpinDelay(50);
 
 	LED_D_ON();
 
 	// These pins are inputs
-    AT91C_BASE_PIOA->PIO_ODR =
-    	GPIO_FPGA_NINIT |
-    	GPIO_FPGA_DONE;
+	AT91C_BASE_PIOA->PIO_ODR =
+		GPIO_FPGA_NINIT |
+		GPIO_FPGA_DONE;
 	// PIO controls the following pins
-    AT91C_BASE_PIOA->PIO_PER =
-    	GPIO_FPGA_NINIT |
-    	GPIO_FPGA_DONE;
+	AT91C_BASE_PIOA->PIO_PER =
+		GPIO_FPGA_NINIT |
+		GPIO_FPGA_DONE;
 	// Enable pull-ups
 	AT91C_BASE_PIOA->PIO_PPUER =
 		GPIO_FPGA_NINIT |
@@ -305,8 +304,8 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
 	LOW(GPIO_FPGA_DIN);
 	// These pins are outputs
 	AT91C_BASE_PIOA->PIO_OER =
-		GPIO_FPGA_NPROGRAM	|
-		GPIO_FPGA_CCLK		|
+		GPIO_FPGA_NPROGRAM  |
+		GPIO_FPGA_CCLK      |
 		GPIO_FPGA_DIN;
 
 	// enter FPGA configuration mode
@@ -335,7 +334,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
 		}
 		DownloadFPGA_byte(b);
 	}
-	
+
 	// continue to clock FPGA until ready signal goes high
 	i=100000;
 	while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
@@ -407,14 +406,14 @@ static int bitparse_find_section(int bitstream_version, char section_name, unsig
 
 
 //----------------------------------------------------------------------------
-// Check which FPGA image is currently loaded (if any). If necessary 
+// Check which FPGA image is currently loaded (if any). If necessary
 // decompress and load the correct (HF or LF) image to the FPGA
 //----------------------------------------------------------------------------
 void FpgaDownloadAndGo(int bitstream_version)
 {
 	z_stream compressed_fpga_stream;
 	uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
-	
+
 	// check whether or not the bitstream is already loaded
 	if (downloaded_bitstream == bitstream_version) {
 		FpgaEnableTracing();
@@ -422,8 +421,8 @@ void FpgaDownloadAndGo(int bitstream_version)
 	}
 
 	// make sure that we have enough memory to decompress
-	BigBuf_free(); BigBuf_Clear_ext(false);	
-	
+	BigBuf_free(); BigBuf_Clear_ext(false);
+
 	if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
 		return;
 	}
@@ -435,13 +434,13 @@ void FpgaDownloadAndGo(int bitstream_version)
 	}
 
 	inflateEnd(&compressed_fpga_stream);
-	
+
 	// turn off antenna
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	
+
 	// free eventually allocated BigBuf memory
-	BigBuf_free(); BigBuf_Clear_ext(false);	
-}	
+	BigBuf_free(); BigBuf_Clear_ext(false);
+}
 
 
 //-----------------------------------------------------------------------------
@@ -451,8 +450,8 @@ void FpgaDownloadAndGo(int bitstream_version)
 //-----------------------------------------------------------------------------
 void FpgaSendCommand(uint16_t cmd, uint16_t v) {
 	SetupSpi(SPI_FPGA_MODE);
-	while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);	// wait for the transfer to complete
-	AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v;		// send the data
+	AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v;     // write the data to be sent
+	while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);  // wait for the transfer to complete
 }
 
 //-----------------------------------------------------------------------------
diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h
index 9746638d..57e9c28a 100644
--- a/armsrc/fpgaloader.h
+++ b/armsrc/fpgaloader.h
@@ -35,16 +35,17 @@ void SetAdcMuxFor(uint32_t whichGpio);
 #define FPGA_BITSTREAM_HF 2
 
 // Definitions for the FPGA commands.
+#define FPGA_CMD_MASK                               0xF000
 // BOTH
-#define FPGA_CMD_SET_CONFREG                        (1<<12)
+#define FPGA_CMD_SET_CONFREG                       (1<<12)
 // LF
-#define FPGA_CMD_SET_DIVISOR                        (2<<12)
-#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD          (3<<12)
-
+#define FPGA_CMD_SET_DIVISOR                       (2<<12)
+#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD         (3<<12)
 // HF
-#define FPGA_CMD_TRACE_ENABLE                       (2<<12)
+#define FPGA_CMD_TRACE_ENABLE                      (2<<12)
 
 // Definitions for the FPGA configuration word.
+#define FPGA_MAJOR_MODE_MASK                        0x01C0
 // LF
 #define FPGA_MAJOR_MODE_LF_ADC                      (0<<6)
 #define FPGA_MAJOR_MODE_LF_EDGE_DETECT              (1<<6)
@@ -58,6 +59,7 @@ void SetAdcMuxFor(uint32_t whichGpio);
 // BOTH
 #define FPGA_MAJOR_MODE_OFF                         (7<<6)
 
+#define FPGA_MINOR_MODE_MASK                        0x003F
 // Options for LF_ADC
 #define FPGA_LF_ADC_READER_FIELD                    (1<<0)
 
diff --git a/armsrc/iclass.c b/armsrc/iclass.c
index afe1a607..3f89ae85 100644
--- a/armsrc/iclass.c
+++ b/armsrc/iclass.c
@@ -538,7 +538,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
 		if (modulated_response_size > 0) {
 			uint32_t response_time = reader_eof_time + DELAY_ICLASS_VCD_TO_VICC_SIM;
 			TransmitTo15693Reader(modulated_response, modulated_response_size, &response_time, 0, false);
-			LogTrace_ISO15693(trace_data, trace_data_size, response_time*32, response_time*32 + modulated_response_size/2, NULL, false);
+			LogTrace_ISO15693(trace_data, trace_data_size, response_time*32, response_time*32 + modulated_response_size*32*64, NULL, false);
 		}
 
 	}
@@ -566,17 +566,11 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
 
 	LED_A_ON();
 
+	Iso15693InitTag();
+	
 	uint32_t simType = arg0;
 	uint32_t numberOfCSNS = arg1;
 
-	// setup hardware for simulation:
-	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
-	LED_D_OFF();
-	FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
-	StartCountSspClk();
-
 	// Enable and clear the trace
 	set_tracing(true);
 	clear_trace();
@@ -589,9 +583,8 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
 		doIClassSimulation(ICLASS_SIM_MODE_CSN, NULL);
 	} else if (simType == ICLASS_SIM_MODE_CSN_DEFAULT) {
 		//Default CSN
-		uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
-		// Use the CSN from commandline
-		memcpy(emulator, csn_crc, 8);
+		uint8_t csn[] = {0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0};
+		memcpy(emulator, csn, 8);
 		doIClassSimulation(ICLASS_SIM_MODE_CSN, NULL);
 	} else if (simType == ICLASS_SIM_MODE_READER_ATTACK) {
 		uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
@@ -636,9 +629,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
 static void ReaderTransmitIClass(uint8_t *frame, int len, uint32_t *start_time) {
 
 	CodeIso15693AsReader(frame, len);
-
 	TransmitTo15693Tag(ToSend, ToSendMax, start_time);
-
 	uint32_t end_time = *start_time + 32*(8*ToSendMax-4); // substract the 4 padding bits after EOF
 	LogTrace_ISO15693(frame, len, *start_time*4, end_time*4, NULL, true);
 }
diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c
index 9f6516aa..5672e66d 100644
--- a/armsrc/iso15693.c
+++ b/armsrc/iso15693.c
@@ -291,7 +291,6 @@ void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) {
 			AT91C_BASE_SSC->SSC_THR = send_word;
 			while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
 			AT91C_BASE_SSC->SSC_THR = send_word;
-
 			data <<= 1;
 		}
 		WDT_HIT();
@@ -299,7 +298,6 @@ void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) {
 	LED_B_OFF();
 
 	*start_time = *start_time + DELAY_ARM_TO_TAG;
-
 }
 
 
@@ -1357,20 +1355,23 @@ void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) {
 
 
 // Initialize the proxmark as iso15k reader
-void Iso15693InitReader() {
+void Iso15693InitReader(void) {
 	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
-	// Start from off (no field generated)
-	LED_D_OFF();
+	// switch field off and wait until tag resets
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+	LED_D_OFF();
 	SpinDelay(10);
 
-	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+	// switch field on
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
+	LED_D_ON();
+	
+	// initialize SSC and select proper AD input
 	FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
+	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
-	// Give the tags time to energize
-	LED_D_ON();
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
+	// give tags some time to energize
 	SpinDelay(250);
 }
 
@@ -1570,29 +1571,14 @@ void ReaderIso15693(uint32_t parameter) {
 
 	LED_A_ON();
 
+	Iso15693InitReader();
+
+	StartCountSspClk();
 	set_tracing(true);
 
 	uint8_t TagUID[8] = {0x00};
-
-	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-
 	uint8_t answer[ISO15693_MAX_RESPONSE_LENGTH];
 
-	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-	// Setup SSC
-	FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
-
-	// Start from off (no field generated)
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	SpinDelay(200);
-
-	// Give the tags time to energize
-	LED_D_ON();
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
-	SpinDelay(200);
-	StartCountSspClk();
-
-
 	// FIRST WE RUN AN INVENTORY TO GET THE TAG UID
 	// THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
 
@@ -1650,6 +1636,17 @@ void ReaderIso15693(uint32_t parameter) {
 }
 
 
+// Initialize the proxmark as iso15k tag
+void Iso15693InitTag(void) {
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
+	LED_D_OFF();
+	FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
+	StartCountSspClk();
+}
+
+
 // Simulate an ISO15693 TAG.
 // For Inventory command: print command and send Inventory Response with given UID
 // TODO: interpret other reader commands and send appropriate response
@@ -1657,20 +1654,14 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
 
 	LED_A_ON();
 
-	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
-	FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
-
-	StartCountSspClk();
-
-	uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
+	Iso15693InitTag();
 
 	// Build a suitable response to the reader INVENTORY command
 	BuildInventoryResponse(uid);
 
 	// Listen to reader
 	while (!BUTTON_PRESS()) {
+		uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
 		uint32_t eof_time = 0, start_time = 0;
 		int cmd_len = GetIso15693CommandFromReader(cmd, sizeof(cmd), &eof_time);
 
diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h
index e48e4d4a..15dfe763 100644
--- a/armsrc/iso15693.h
+++ b/armsrc/iso15693.h
@@ -22,21 +22,22 @@
 #define DELAY_ISO15693_VCD_TO_VICC_READER 1056 // 1056/3,39MHz = 311.5us from end of command EOF to start of tag response
 #define DELAY_ISO15693_VICC_TO_VCD_READER 1024 // 1024/3.39MHz = 302.1us between end of tag response and next reader command
 
-void Iso15693InitReader();
-void CodeIso15693AsReader(uint8_t *cmd, int n);
-void CodeIso15693AsTag(uint8_t *cmd, size_t len);
-void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow);
-int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time);
-void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time);
-int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time);
-void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string);
-void AcquireRawAdcSamplesIso15693(void);
-void ReaderIso15693(uint32_t parameter);
-void SimTagIso15693(uint32_t parameter, uint8_t *uid);
-void BruteforceIso15693Afi(uint32_t speed);
-void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]);
-void SetTag15693Uid(uint8_t *uid);
-void SetDebugIso15693(uint32_t flag);
-bool LogTrace_ISO15693(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
+extern void Iso15693InitReader(void);
+extern void Iso15693InitTag(void);
+extern void CodeIso15693AsReader(uint8_t *cmd, int n);
+extern void CodeIso15693AsTag(uint8_t *cmd, size_t len);
+extern void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow);
+extern int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time);
+extern void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time);
+extern int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time);
+extern void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string);
+extern void AcquireRawAdcSamplesIso15693(void);
+extern void ReaderIso15693(uint32_t parameter);
+extern void SimTagIso15693(uint32_t parameter, uint8_t *uid);
+extern void BruteforceIso15693Afi(uint32_t speed);
+extern void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]);
+extern void SetTag15693Uid(uint8_t *uid);
+extern void SetDebugIso15693(uint32_t flag);
+extern bool LogTrace_ISO15693(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
 
 #endif
diff --git a/armsrc/util.c b/armsrc/util.c
index 4bff3a26..b0cd1818 100644
--- a/armsrc/util.c
+++ b/armsrc/util.c
@@ -137,8 +137,7 @@ void LED(int led, int ms)
 // not clicked, or held down (for ms || 1sec)
 // In general, don't use this function unless you expect a
 // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
-int BUTTON_CLICKED(int ms)
-{
+int BUTTON_CLICKED(int ms) {
 	// Up to 500ms in between clicks to mean a double click
 	int ticks = (48000 * (ms ? ms : 1000)) >> 10;
 
@@ -200,8 +199,7 @@ int BUTTON_CLICKED(int ms)
 }
 
 // Determine if a button is held down
-int BUTTON_HELD(int ms)
-{
+int BUTTON_HELD(int ms) {
 	// If button is held for one second
 	int ticks = (48000 * (ms ? ms : 1000)) >> 10;
 
@@ -218,8 +216,7 @@ int BUTTON_HELD(int ms)
 
 	uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
 
-	for(;;)
-	{
+	for(;;) {
 		uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
 
 		// As soon as our button let go, we didn't hold long enough
@@ -227,8 +224,7 @@ int BUTTON_HELD(int ms)
 			return BUTTON_SINGLE_CLICK;
 
 		// Have we waited the full second?
-		else
-			if (now == (uint16_t)(start + ticks))
+		else if (now == (uint16_t)(start + ticks))
 				return BUTTON_HOLD;
 
 		WDT_HIT();
@@ -240,8 +236,7 @@ int BUTTON_HELD(int ms)
 
 // attempt at high resolution microsecond timer
 // beware: timer counts in 21.3uS increments (1024/48Mhz)
-void SpinDelayUs(int us)
-{
+void SpinDelayUs(int us) {
 	int ticks = (48*us) >> 10;
 
 	// Borrow a PWM unit for my real-time clock
@@ -262,8 +257,7 @@ void SpinDelayUs(int us)
 	}
 }
 
-void SpinDelay(int ms)
-{
+void SpinDelay(int ms) {
   // convert to uS and call microsecond delay function
 	SpinDelayUs(ms*1000);
 }
@@ -314,8 +308,7 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers
 //  ti = GetTickCount() - ti;
 //  Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
 
-void StartTickCount()
-{
+void StartTickCount() {
 	// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
 	// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
 	uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff;     // = 16 * main clock frequency (16MHz) / slow clock frequency
@@ -328,7 +321,7 @@ void StartTickCount()
 /*
 * Get the current count.
 */
-uint32_t RAMFUNC GetTickCount(){
+uint32_t RAMFUNC GetTickCount(void) {
 	return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
 }
 
@@ -336,8 +329,7 @@ uint32_t RAMFUNC GetTickCount(){
 //  -------------------------------------------------------------------------
 //  microseconds timer
 //  -------------------------------------------------------------------------
-void StartCountUS()
-{
+void StartCountUS(void) {
 	AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
 //  AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC1XC1S_TIOA0;
 	AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
@@ -359,14 +351,14 @@ void StartCountUS()
 	}
 
 
-uint32_t RAMFUNC GetCountUS(){
+uint32_t RAMFUNC GetCountUS(void) {
 	return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV * 2) / 3); //was  /15) * 10);
 }
 
 
 static uint32_t GlobalUsCounter = 0;
 
-uint32_t RAMFUNC GetDeltaCountUS(){
+uint32_t RAMFUNC GetDeltaCountUS(void) {
 	uint32_t g_cnt = GetCountUS();
 	uint32_t g_res = g_cnt - GlobalUsCounter;
 	GlobalUsCounter = g_cnt;
@@ -377,8 +369,7 @@ uint32_t RAMFUNC GetDeltaCountUS(){
 //  -------------------------------------------------------------------------
 //  Timer for iso14443 commands. Uses ssp_clk from FPGA
 //  -------------------------------------------------------------------------
-void StartCountSspClk()
-{
+void StartCountSspClk(void) {
 	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2);  // Enable Clock to all timers
 	AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1       // XC0 Clock = TIOA1
 							| AT91C_TCB_TC1XC1S_NONE        // XC1 Clock = none
@@ -395,7 +386,7 @@ void StartCountSspClk()
 							| AT91C_TC_WAVE                 // Waveform Mode
 							| AT91C_TC_AEEVT_SET            // Set TIOA1 on external event
 							| AT91C_TC_ACPC_CLEAR;          // Clear TIOA1 on RC Compare
-	AT91C_BASE_TC1->TC_RC = 0x02;                           // RC Compare value = 0x02
+	AT91C_BASE_TC1->TC_RC = 1;                              // RC Compare value = 1; pulse width to TC0
 
 	// use TC0 to count TIOA1 pulses
 	AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;               // disable TC0
@@ -425,7 +416,7 @@ void StartCountSspClk()
 	while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK));     // wait for ssp_clk to go high; 1st ssp_clk after start of frame
 	while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK);        // wait for ssp_clk to go low;
 	while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK));     // wait for ssp_clk to go high; 2nd ssp_clk after start of frame
-	if ((AT91C_BASE_SSC->SSC_RFMR & SSC_FRAME_MODE_BITS_IN_WORD(32)) == SSC_FRAME_MODE_BITS_IN_WORD(16)) {
+	if ((AT91C_BASE_SSC->SSC_RFMR & SSC_FRAME_MODE_BITS_IN_WORD(32)) == SSC_FRAME_MODE_BITS_IN_WORD(16)) { // 16bit frame
 		while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK);    // wait for ssp_clk to go low;
 		while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high; 3rd ssp_clk after start of frame
 		while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK);    // wait for ssp_clk to go low;
@@ -439,8 +430,8 @@ void StartCountSspClk()
 	AT91C_BASE_TCB->TCB_BCR = 1;                            // assert Sync (set all timers to 0 on next active clock edge)
 	// at the next (3rd/7th) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0)
 	// at the next (4th/8th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on,
-	// whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer.
-	// (just started with the transfer of the 3rd Bit).
+	// whenever the last three/four bits of our counter go 0, we can be sure to be in the middle of a frame transfer.
+
 	// The high word of the counter (TC2) will not reset until the low word (TC0) overflows. Therefore need to wait quite some time before
 	// we can use the counter.
 	while (AT91C_BASE_TC0->TC_CV < 0xFFFF);
diff --git a/common/Makefile_Enabled_Options.common b/common/Makefile_Enabled_Options.common
index d9f6d3b9..edc86b85 100644
--- a/common/Makefile_Enabled_Options.common
+++ b/common/Makefile_Enabled_Options.common
@@ -4,7 +4,7 @@
 #  
 #BEGIN
 APP_CFLAGS += -DWITH_ISO14443a_StandAlone \
-        -DWITH_LF\
+        -DWITH_LF \
         -DWITH_ISO15693 \
         -DWITH_ISO14443a \
         -DWITH_ISO14443b \
diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit
index ea7c7ebf..c5beb0b9 100644
Binary files a/fpga/fpga_hf.bit and b/fpga/fpga_hf.bit differ
diff --git a/fpga/hi_reader.v b/fpga/hi_reader.v
index fe5ae4e5..edb9a8a6 100644
--- a/fpga/hi_reader.v
+++ b/fpga/hi_reader.v
@@ -30,16 +30,16 @@ reg after_hysteresis, after_hysteresis_prev, after_hysteresis_prev_prev;
 reg [11:0] has_been_low_for;
 always @(negedge adc_clk)
 begin
-    if(& adc_d[7:0]) after_hysteresis <= 1'b1;
-    else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0;
+    if (& adc_d[7:0]) after_hysteresis <= 1'b1;
+    else if (~(| adc_d[7:0])) after_hysteresis <= 1'b0;
 
-    if(after_hysteresis)
+    if (after_hysteresis)
     begin
-        has_been_low_for <= 7'b0;
+        has_been_low_for <= 12'd0;
     end
     else
     begin
-        if(has_been_low_for == 12'd4095)
+        if (has_been_low_for == 12'd4095)
         begin
             has_been_low_for <= 12'd0;
             after_hysteresis <= 1'b1;
@@ -235,6 +235,16 @@ end
 
 
 // ssp clock and frame signal for communication to and from ARM
+//                _____       _____       _____       _
+// ssp_clk       |     |_____|     |_____|     |_____|
+//                   _____
+// ssp_frame     ___|     |____________________________
+//                ___________ ___________ ___________ _
+// ssp_d_in      X___________X___________X___________X_
+//
+// corr_i_cnt    0  1  2  3  4  5  6  7  8  9 10 11 12 ...
+//
+
 reg ssp_clk;
 reg ssp_frame;
 
@@ -249,7 +259,7 @@ begin
 	// (send one frame with 16 Bits)
     if (corr_i_cnt == 6'd1)
         ssp_frame <= 1'b1;
-    if (corr_i_cnt == 6'd5)
+    if (corr_i_cnt == 6'd3)
         ssp_frame <= 1'b0;
 end