From 7cc204bff881ce1d1833d8e93469f6bbba80c70e Mon Sep 17 00:00:00 2001
From: iZsh <izsh@fail0verflow.com>
Date: Fri, 20 Jun 2014 01:02:59 +0200
Subject: [PATCH] THIS REQUIRES A BOOTROM UPDATE!! To save FPGA area, split the
 LF and HF bitstreams and load them on-demand.

---
 .gitignore             |   6 +-
 armsrc/Makefile        |   9 +-
 armsrc/appmain.c       |   9 +-
 armsrc/apps.h          |  28 ++-
 armsrc/fpgaloader.c    |  45 +++-
 armsrc/hitag2.c        |   3 +
 armsrc/iclass.c        |   6 +
 armsrc/iso14443.c      |   4 +
 armsrc/iso14443a.c     |   1 +
 armsrc/iso15693.c      |   5 +
 armsrc/ldscript        |   3 +-
 armsrc/legicrf.c       |   2 +
 armsrc/lfops.c         |  12 +
 armsrc/mifarecmd.c     | 506 ++++++++++++++++++++---------------------
 client/Makefile        |   6 +-
 common/ldscript.common |   4 +-
 fpga/Makefile          |  40 ++--
 fpga/clk_divider.v     |  25 ++
 fpga/fpga.bit          | Bin 42172 -> 0 bytes
 fpga/fpga.v            | 220 ------------------
 fpga/fpga_hf.bit       | Bin 0 -> 42175 bytes
 fpga/fpga_hf.v         | 150 ++++++++++++
 fpga/fpga_lf.bit       | Bin 0 -> 42175 bytes
 fpga/fpga_lf.v         | 125 ++++++++++
 fpga/go.bat            |  52 ++++-
 fpga/lo_edge_detect.v  |  53 +----
 fpga/lo_passthru.v     |  44 +---
 fpga/lo_read.v         |  67 ++----
 fpga/xst.scr           |   1 -
 fpga/xst_hf.scr        |   1 +
 fpga/xst_lf.scr        |   1 +
 include/proxmark3.h    |   4 +
 32 files changed, 771 insertions(+), 661 deletions(-)
 create mode 100644 fpga/clk_divider.v
 delete mode 100644 fpga/fpga.bit
 delete mode 100644 fpga/fpga.v
 create mode 100644 fpga/fpga_hf.bit
 create mode 100644 fpga/fpga_hf.v
 create mode 100644 fpga/fpga_lf.bit
 create mode 100644 fpga/fpga_lf.v
 delete mode 100644 fpga/xst.scr
 create mode 100644 fpga/xst_hf.scr
 create mode 100644 fpga/xst_lf.scr

diff --git a/.gitignore b/.gitignore
index 3f6347a0..3b258b3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,11 +19,13 @@ lua
 luac
 
 fpga/*
-!fpga/fpga.bit
+!fpga/fpga_lf.bit
+!fpga/fpga_hf.bit
 !fpga/*.v
 !fpga/Makefile
 !fpga/fpga.ucf
-!fpga/xst.scr
+!fpga/xst_lf.scr
+!fpga/xst_hf.scr
 !fpga/go.bat
 !fpga/sim.tcl
 
diff --git a/armsrc/Makefile b/armsrc/Makefile
index 2e5350bb..e10c1001 100644
--- a/armsrc/Makefile
+++ b/armsrc/Makefile
@@ -52,10 +52,13 @@ OBJS = $(OBJDIR)/osimage.s19 $(OBJDIR)/fpgaimage.s19
 
 all: $(OBJS)
 
-$(OBJDIR)/fpga.o: fpga.bit
-	$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_bit_start=_binary_fpga_bit_start --redefine-sym _binary____fpga_fpga_bit_end=_binary_fpga_bit_end --prefix-sections=fpga_bit  $^ $@
+$(OBJDIR)/fpga_lf.o: fpga_lf.bit
+	$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_lf_bit_start=_binary_fpga_lf_bit_start --redefine-sym _binary____fpga_fpga_lf_bit_end=_binary_fpga_lf_bit_end --prefix-sections=fpga_lf_bit  $^ $@
 
-$(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga.o $(THUMBOBJ) $(ARMOBJ)
+$(OBJDIR)/fpga_hf.o: fpga_hf.bit
+	$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_hf_bit_start=_binary_fpga_hf_bit_start --redefine-sym _binary____fpga_fpga_hf_bit_end=_binary_fpga_hf_bit_end --prefix-sections=fpga_hf_bit  $^ $@
+
+$(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_lf.o $(OBJDIR)/fpga_hf.o $(THUMBOBJ) $(ARMOBJ)
 	$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
 
 $(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf
diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index b6c32200..b7bc87e7 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -214,6 +214,7 @@ void MeasureAntennaTuning(void)
  * ( hopefully around 95 if it is tuned to 125kHz!)
  */
   
+  	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 	for (i=255; i>19; i--) {
     WDT_HIT();
@@ -236,6 +237,7 @@ void MeasureAntennaTuning(void)
 
   LED_A_ON();
 	// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
+  	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 	SpinDelay(20);
 	// Vref = 3300mV, and an 10:1 voltage divider on the input
@@ -264,6 +266,7 @@ void MeasureAntennaTuningHf(void)
 
 	for (;;) {
 		// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
+		FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 		FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 		SpinDelay(20);
 		// Vref = 3300mV, and an 10:1 voltage divider on the input
@@ -286,6 +289,7 @@ void SimulateTagHfListen(void)
 
 	// We're using this mode just so that I can test it out; the simulated
 	// tag mode would work just as well and be simpler.
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
 
 	// We need to listen to the high-frequency, peak-detected path.
@@ -365,6 +369,7 @@ void SendVersion(void)
 void SamyRun()
 {
 	DbpString("Stand-alone mode! No PC necessary.");
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 
 	// 3 possible options? no just 2 for now
 #define OPTS 2
@@ -923,6 +928,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			break;
 
 		case CMD_SET_LF_DIVISOR:
+		  	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 			FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
 			break;
 
@@ -1017,7 +1023,8 @@ void  __attribute__((noreturn)) AppMain(void)
 	AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
 
 	// Load the FPGA image, which we have stored in our flash.
-	FpgaDownloadAndGo();
+	// (the HF version by default)
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
 	StartTickCount();
   	
diff --git a/armsrc/apps.h b/armsrc/apps.h
index 92228b8d..76d1247a 100644
--- a/armsrc/apps.h
+++ b/armsrc/apps.h
@@ -67,7 +67,8 @@ extern uint32_t BigBuf[];
 /// fpga.h
 void FpgaSendCommand(uint16_t cmd, uint16_t v);
 void FpgaWriteConfWord(uint8_t v);
-void FpgaDownloadAndGo(void);
+void FpgaDownloadAndGo(int bitstream_version);
+int FpgaGatherBitstreamVersion();
 void FpgaGatherVersion(char *dst, int len);
 void FpgaSetupSsc(void);
 void SetupSpi(int mode);
@@ -77,17 +78,20 @@ bool FpgaSetupSscDma(uint8_t *buf, int len);
 void SetAdcMuxFor(uint32_t whichGpio);
 
 // Definitions for the FPGA commands.
-#define FPGA_CMD_SET_CONFREG						(1<<12)
-#define FPGA_CMD_SET_DIVISOR						(2<<12)
+#define FPGA_CMD_SET_CONFREG					(1<<12)
+#define FPGA_CMD_SET_DIVISOR					(2<<12)
 // Definitions for the FPGA configuration word.
-#define FPGA_MAJOR_MODE_LF_READER					(0<<5)
+// LF
+#define FPGA_MAJOR_MODE_LF_READER				(0<<5)
 #define FPGA_MAJOR_MODE_LF_EDGE_DETECT				(1<<5)
-#define FPGA_MAJOR_MODE_HF_READER_TX				(2<<5)
-#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR			(3<<5)
-#define FPGA_MAJOR_MODE_HF_SIMULATOR				(4<<5)
-#define FPGA_MAJOR_MODE_HF_ISO14443A				(5<<5)
-#define FPGA_MAJOR_MODE_LF_PASSTHRU					(6<<5)
-#define FPGA_MAJOR_MODE_OFF							(7<<5)
+#define FPGA_MAJOR_MODE_LF_PASSTHRU				(2<<5)
+// HF
+#define FPGA_MAJOR_MODE_HF_READER_TX				(0<<5)
+#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR			(1<<5)
+#define FPGA_MAJOR_MODE_HF_SIMULATOR				(2<<5)
+#define FPGA_MAJOR_MODE_HF_ISO14443A				(3<<5)
+// BOTH
+#define FPGA_MAJOR_MODE_OFF					(7<<5)
 // Options for LF_EDGE_DETECT
 #define FPGA_LF_EDGE_DETECT_READER_FIELD 			(1<<0)
 // Options for the HF reader, tx to tag
@@ -95,14 +99,14 @@ void SetAdcMuxFor(uint32_t whichGpio);
 // Options for the HF reader, correlating against rx from tag
 #define FPGA_HF_READER_RX_XCORR_848_KHZ				(1<<0)
 #define FPGA_HF_READER_RX_XCORR_SNOOP				(1<<1)
-#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ		(1<<2)
+#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ			(1<<2)
 // Options for the HF simulated tag, how to modulate
 #define FPGA_HF_SIMULATOR_NO_MODULATION				(0<<0)
 #define FPGA_HF_SIMULATOR_MODULATE_BPSK				(1<<0)
 #define FPGA_HF_SIMULATOR_MODULATE_212K				(2<<0)
 #define FPGA_HF_SIMULATOR_MODULATE_424K				(4<<0)
 // Options for ISO14443A
-#define FPGA_HF_ISO14443A_SNIFFER					(0<<0)
+#define FPGA_HF_ISO14443A_SNIFFER				(0<<0)
 #define FPGA_HF_ISO14443A_TAGSIM_LISTEN				(1<<0)
 #define FPGA_HF_ISO14443A_TAGSIM_MOD				(2<<0)
 #define FPGA_HF_ISO14443A_READER_LISTEN				(3<<0)
diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c
index d63310a3..2f996bc5 100644
--- a/armsrc/fpgaloader.c
+++ b/armsrc/fpgaloader.c
@@ -252,7 +252,7 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
 
 static char *bitparse_headers_start;
 static char *bitparse_bitstream_end;
-static int bitparse_initialized;
+static int bitparse_initialized = 0;
 /* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
  * 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
  * After that the format is 1 byte section type (ASCII character), 2 byte length
@@ -322,12 +322,28 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
 // Find out which FPGA image format is stored in flash, then call DownloadFPGA
 // with the right parameters to download the image
 //-----------------------------------------------------------------------------
-extern char _binary_fpga_bit_start, _binary_fpga_bit_end;
-void FpgaDownloadAndGo(void)
+extern char _binary_fpga_lf_bit_start, _binary_fpga_lf_bit_end;
+extern char _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
+void FpgaDownloadAndGo(int bitstream_version)
 {
+	void *bit_start;
+	void *bit_end;
+
+	// check whether or not the bitstream is already loaded
+	if (FpgaGatherBitstreamVersion() == bitstream_version)
+		return;
+
+	if (bitstream_version == FPGA_BITSTREAM_LF) {
+		bit_start = &_binary_fpga_lf_bit_start;
+		bit_end = &_binary_fpga_lf_bit_end;
+	} else if (bitstream_version == FPGA_BITSTREAM_HF) {
+		bit_start = &_binary_fpga_hf_bit_start;
+		bit_end = &_binary_fpga_hf_bit_end;
+	} else
+		return;
 	/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
 	 */
-	if(bitparse_init(&_binary_fpga_bit_start, &_binary_fpga_bit_end)) {
+	if(bitparse_init(bit_start, bit_end)) {
 		/* Successfully initialized the .bit parser. Find the 'e' section and
 		 * send its contents to the FPGA.
 		 */
@@ -351,6 +367,17 @@ void FpgaDownloadAndGo(void)
 		DownloadFPGA((char*)0x102000, 10524*4, 1);
 }
 
+int FpgaGatherBitstreamVersion()
+{
+	char temp[256];
+	FpgaGatherVersion(temp, sizeof (temp));
+	if (!memcmp("LF", temp, 2))
+		return FPGA_BITSTREAM_LF;
+	else if (!memcmp("HF", temp, 2))
+		return FPGA_BITSTREAM_HF;
+	return FPGA_BITSTREAM_ERR;
+}
+
 void FpgaGatherVersion(char *dst, int len)
 {
 	char *fpga_info;
@@ -359,13 +386,15 @@ void FpgaGatherVersion(char *dst, int len)
 	if(!bitparse_find_section('e', &fpga_info, &fpga_info_len)) {
 		strncat(dst, "FPGA image: legacy image without version information", len-1);
 	} else {
-		strncat(dst, "FPGA image built", len-1);
 		/* USB packets only have 48 bytes data payload, so be terse */
-#if 0
 		if(bitparse_find_section('a', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
-			strncat(dst, " from ", len-1);
-			strncat(dst, fpga_info, len-1);
+			if (!memcmp("fpga_lf", fpga_info, 7))
+				strncat(dst, "LF ", len-1);
+			else if (!memcmp("fpga_hf", fpga_info, 7))
+				strncat(dst, "HF ", len-1);
 		}
+		strncat(dst, "FPGA image built", len-1);
+#if 0
 		if(bitparse_find_section('b', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
 			strncat(dst, " for ", len-1);
 			strncat(dst, fpga_info, len-1);
diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c
index 1a0e9b56..9181a62e 100644
--- a/armsrc/hitag2.c
+++ b/armsrc/hitag2.c
@@ -743,6 +743,7 @@ void SnoopHitag(uint32_t type) {
 	
 	// Set up eavesdropping mode, frequency divisor which will drive the FPGA
 	// and analog mux selection.
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -966,6 +967,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
 	
 	// Set up simulator mode, frequency divisor which will drive the FPGA
 	// and analog mux selection.
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -1124,6 +1126,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
 	bool bStop;
 	bool bQuitTraceFull = false;
   
+  FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
   // Reset the return status
   bSuccessful = false;
   
diff --git a/armsrc/iclass.c b/armsrc/iclass.c
index 8d65b523..9c5e8b2b 100644
--- a/armsrc/iclass.c
+++ b/armsrc/iclass.c
@@ -689,6 +689,8 @@ void RAMFUNC SnoopIClass(void)
     // into trace, along with its length and other annotations.
     //uint8_t *trace = (uint8_t *)BigBuf;
     
+    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ 
     // reset traceLen to 0
     iso14a_set_tracing(TRUE);
     iso14a_clear_trace();
@@ -995,6 +997,8 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
 {
 	uint8_t simType = arg0;
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+
   // Enable and clear the trace
 	tracing = TRUE;
 	traceLen = 0;
@@ -1426,6 +1430,8 @@ void ReaderIClass(uint8_t arg0) {
 
 	uint8_t* resp = (((uint8_t *)BigBuf) + 3560);	// was 3560 - tied to other size changes
 
+    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+
 	// Reset trace buffer
     	memset(trace, 0x44, RECV_CMD_OFFSET);
 	traceLen = 0;
diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c
index 5e8eddd2..7a445bcb 100644
--- a/armsrc/iso14443.c
+++ b/armsrc/iso14443.c
@@ -350,6 +350,7 @@ void SimulateIso14443Tag(void)
 
     int cmdsRecvd = 0;
 
+    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
     memset(receivedCmd, 0x44, 400);
 
     CodeIso14443bAsTag(response1, sizeof(response1));
@@ -867,6 +868,7 @@ void ReadSTMemoryIso14443(uint32_t dwLast)
 {
     uint8_t i = 0x00;
 
+    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
     // Make sure that we start from off, since the tags are stateful;
     // confusing things will happen if we don't reset them between reads.
     LED_D_OFF();
@@ -1011,6 +1013,7 @@ void RAMFUNC SnoopIso14443(void)
     // response from the tag.
     int triggered = TRUE;
 
+    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
     // The command (reader -> tag) that we're working on receiving.
     uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE;
     // The response (tag -> reader) that we're working on receiving.
@@ -1196,6 +1199,7 @@ done:
 
 void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[])
 {
+    FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
     if(!powerfield)
     {
         // Make sure that we start from off, since the tags are stateful;
diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c
index 9afe0788..099e1d68 100644
--- a/armsrc/iso14443a.c
+++ b/armsrc/iso14443a.c
@@ -1763,6 +1763,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
 }
 
 void iso14443a_setup(uint8_t fpga_minor_mode) {
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	// Set up the synchronous serial port
 	FpgaSetupSsc();
 	// connect Demodulated Signal to ADC:
diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c
index 63e72c14..ed7beb6f 100644
--- a/armsrc/iso15693.c
+++ b/armsrc/iso15693.c
@@ -606,6 +606,7 @@ void AcquireRawAdcSamplesIso15693(void)
 
 	int8_t prev = 0;
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	BuildIdentifyRequest();
 
 	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
@@ -687,6 +688,7 @@ void RecordRawAdcSamplesIso15693(void)
 
 	int8_t prev = 0;
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	// Setup SSC
 	FpgaSetupSsc();
 
@@ -753,6 +755,7 @@ void Iso15693InitReader() {
 	LED_C_OFF();
 	LED_D_OFF();
 	
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	// Setup SSC
 	// FpgaSetupSsc();
 
@@ -1015,6 +1018,7 @@ void ReaderIso15693(uint32_t parameter)
 	// Blank arrays
 	memset(BigBuf + 3660, 0, 300);
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	// Setup SSC
 	FpgaSetupSsc();
 
@@ -1165,6 +1169,7 @@ void SimTagIso15693(uint32_t parameter)
 	// Blank arrays
 	memset(answer1, 0, 100);
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	// Setup SSC
 	FpgaSetupSsc();
 
diff --git a/armsrc/ldscript b/armsrc/ldscript
index dcb04bf0..d0be3b6a 100644
--- a/armsrc/ldscript
+++ b/armsrc/ldscript
@@ -21,7 +21,8 @@ ENTRY(Vector)
 SECTIONS
 {
 	.fpgaimage : {
-		*(fpga_bit.data)
+		*(fpga_lf_bit.data)
+		*(fpga_hf_bit.data)
 	} >fpgaimage :fpgaimage
 
 	.start : {
diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c
index f2eb680b..3fbdf5cb 100644
--- a/armsrc/legicrf.c
+++ b/armsrc/legicrf.c
@@ -310,6 +310,7 @@ static uint32_t perform_setup_phase_rwd(int iv)
 }
 
 static void LegicCommonInit(void) {
+	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 	FpgaSetupSsc();
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
@@ -687,6 +688,7 @@ void LegicRfSimulate(int phase, int frame, int reqresp)
    legic_frame_drift = frame;
    legic_reqresp_drift = reqresp;
 
+   FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
    SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
    FpgaSetupSsc();
    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K);
diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index 76c4b44e..a0fa870b 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -17,6 +17,7 @@
 
 void AcquireRawAdcSamples125k(int divisor)
 {
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
 		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
 	else if (divisor == 0)
@@ -69,6 +70,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
 	int at134khz;
 
 	/* Make sure the tag is reset */
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	SpinDelay(2500);
 
@@ -158,6 +160,7 @@ void ReadTItag(void)
 	uint32_t threshold = (sampleslo - sampleshi + 1)>>1;
 
 	// TI tags charge at 134.2Khz
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
 
 	// Place FPGA in passthrough mode, in this mode the CROSS_LO line
@@ -365,6 +368,7 @@ void AcquireTiType(void)
 // if not provided a valid crc will be computed from the data and written.
 void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
 {
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);	
 	if(crc == 0) {
 	 	crc = update_crc16(crc, (idlo)&0xff);
 		crc = update_crc16(crc, (idlo>>8)&0xff);
@@ -436,6 +440,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 	int i;
 	uint8_t *tab = (uint8_t *)BigBuf;
     
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
     
 	AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
@@ -602,6 +607,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 	int m=0, n=0, i=0, idx=0, found=0, lastval=0;
   uint32_t hi2=0, hi=0, lo=0;
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 
@@ -815,6 +821,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
 	uint32_t code=0, code2=0;
 	//uint32_t hi2=0, hi=0, lo=0;
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 
@@ -1132,6 +1139,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
 // Write one bit to card
 void T55xxWriteBit(int bit)
 {
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 	if (bit == 0)
@@ -1147,6 +1155,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
 {
 	unsigned int i;
 
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 
@@ -1191,6 +1200,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 	uint8_t *dest = (uint8_t *)BigBuf;
 	int m=0, i=0;
   
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	m = sizeof(BigBuf);
   // Clear destination buffer before sending the command
 	memset(dest, 128, m);
@@ -1255,6 +1265,7 @@ void T55xxReadTrace(void){
 	uint8_t *dest = (uint8_t *)BigBuf;
 	int m=0, i=0;
   
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	m = sizeof(BigBuf);
   // Clear destination buffer before sending the command
 	memset(dest, 128, m);
@@ -1970,6 +1981,7 @@ void SendForward(uint8_t fwd_bit_count) {
   LED_D_ON();
   
   //Field on
+  FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
   FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
   FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
   
diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index c934a280..6a491b53 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -91,66 +91,66 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
 //  iso14a_set_tracing(TRUE);
-
-}
-
-void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
-{
-    // params
-	uint8_t blockNo = arg0;
-	
-	// variables
-	byte_t isOK = 0;
-	byte_t dataoutbuf[16];
-	uint8_t uid[10];
-	uint32_t cuid;
-    
-	// clear trace
-	iso14a_clear_trace();
+
+}
+
+void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
+{
+    // params
+	uint8_t blockNo = arg0;
+	
+	// variables
+	byte_t isOK = 0;
+	byte_t dataoutbuf[16];
+	uint8_t uid[10];
+	uint32_t cuid;
+    
+	// clear trace
+	iso14a_clear_trace();
 	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-    
-	LED_A_ON();
-	LED_B_OFF();
-	LED_C_OFF();
-    
-	while (true) {
-		if(!iso14443a_select_card(uid, NULL, &cuid)) {
-            if (MF_DBGLEVEL >= 1)	Dbprintf("Can't select card");
-			break;
-		};
-        
-		if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
-            if (MF_DBGLEVEL >= 1)	Dbprintf("Read block error");
-			break;
-		};
-        
-		if(mifare_ultra_halt(cuid)) {
-            if (MF_DBGLEVEL >= 1)	Dbprintf("Halt error");
-			break;
-		};
-		
-		isOK = 1;
-		break;
-	}
-	
-	if (MF_DBGLEVEL >= 2)	DbpString("READ BLOCK FINISHED");
-    
-	// add trace trailer
-	memset(uid, 0x44, 4);
-	LogTrace(uid, 4, 0, 0, TRUE);
-	LED_B_ON();
-        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
-	LED_B_OFF();
-    
-    
-    // Thats it...
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	LEDsoff();
-}
-
-//-----------------------------------------------------------------------------
-// Select, Authenticaate, Read an MIFARE tag. 
-// read sector (data = 4 x 16 bytes = 64 bytes)
+    
+	LED_A_ON();
+	LED_B_OFF();
+	LED_C_OFF();
+    
+	while (true) {
+		if(!iso14443a_select_card(uid, NULL, &cuid)) {
+            if (MF_DBGLEVEL >= 1)	Dbprintf("Can't select card");
+			break;
+		};
+        
+		if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
+            if (MF_DBGLEVEL >= 1)	Dbprintf("Read block error");
+			break;
+		};
+        
+		if(mifare_ultra_halt(cuid)) {
+            if (MF_DBGLEVEL >= 1)	Dbprintf("Halt error");
+			break;
+		};
+		
+		isOK = 1;
+		break;
+	}
+	
+	if (MF_DBGLEVEL >= 2)	DbpString("READ BLOCK FINISHED");
+    
+	// add trace trailer
+	memset(uid, 0x44, 4);
+	LogTrace(uid, 4, 0, 0, TRUE);
+	LED_B_ON();
+        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
+	LED_B_OFF();
+    
+    
+    // Thats it...
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+	LEDsoff();
+}
+
+//-----------------------------------------------------------------------------
+// Select, Authenticaate, Read an MIFARE tag. 
+// read sector (data = 4 x 16 bytes = 64 bytes)
 //-----------------------------------------------------------------------------
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 {
@@ -242,72 +242,72 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
 //  iso14a_set_tracing(TRUE);
-
-}
-
-void MifareUReadCard(uint8_t arg0, uint8_t *datain)
-{
-  // params
-        uint8_t sectorNo = arg0;
-        
-        // variables
-        byte_t isOK = 0;
-        byte_t dataoutbuf[16 * 4];
-        uint8_t uid[10];
-        uint32_t cuid;
-
-        // clear trace
-        iso14a_clear_trace();
-//      iso14a_set_tracing(false);
-
+
+}
+
+void MifareUReadCard(uint8_t arg0, uint8_t *datain)
+{
+  // params
+        uint8_t sectorNo = arg0;
+        
+        // variables
+        byte_t isOK = 0;
+        byte_t dataoutbuf[16 * 4];
+        uint8_t uid[10];
+        uint32_t cuid;
+
+        // clear trace
+        iso14a_clear_trace();
+//      iso14a_set_tracing(false);
+
 		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
-        LED_A_ON();
-        LED_B_OFF();
-        LED_C_OFF();
-
-        while (true) {
-                if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                        break;
-                };
-		for(int sec=0;sec<16;sec++){
-                    if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
-                    if (MF_DBGLEVEL >= 1)   Dbprintf("Read block %d error",sec);
-                        break;
-                    };
-                }
-                if(mifare_ultra_halt(cuid)) {
-                if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
-                        break;
-                };
-
-                isOK = 1;
-                break;
-        }
-        
-        if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
-
-        // add trace trailer
-        memset(uid, 0x44, 4);
-        LogTrace(uid, 4, 0, 0, TRUE);
-        
-        LED_B_ON();
-		cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
-  //cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
-        LED_B_OFF();
-
-        // Thats it...
-        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-        LEDsoff();
-//  iso14a_set_tracing(TRUE);
-
-}
-
-
-//-----------------------------------------------------------------------------
-// Select, Authenticaate, Read an MIFARE tag. 
-// read block
+
+        LED_A_ON();
+        LED_B_OFF();
+        LED_C_OFF();
+
+        while (true) {
+                if(!iso14443a_select_card(uid, NULL, &cuid)) {
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
+                        break;
+                };
+		for(int sec=0;sec<16;sec++){
+                    if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
+                    if (MF_DBGLEVEL >= 1)   Dbprintf("Read block %d error",sec);
+                        break;
+                    };
+                }
+                if(mifare_ultra_halt(cuid)) {
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
+                        break;
+                };
+
+                isOK = 1;
+                break;
+        }
+        
+        if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
+
+        // add trace trailer
+        memset(uid, 0x44, 4);
+        LogTrace(uid, 4, 0, 0, TRUE);
+        
+        LED_B_ON();
+		cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
+  //cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
+        LED_B_OFF();
+
+        // Thats it...
+        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+        LEDsoff();
+//  iso14a_set_tracing(TRUE);
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Select, Authenticaate, Read an MIFARE tag. 
+// read block
 //-----------------------------------------------------------------------------
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 {
@@ -384,137 +384,137 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LEDsoff();
 //  iso14a_set_tracing(TRUE);
-
-}
-
-void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
-{
-        // params
-        uint8_t blockNo = arg0;
-        byte_t blockdata[16];
-
-        memset(blockdata,'\0',16);
-        memcpy(blockdata, datain,16);
-        
-        // variables
-        byte_t isOK = 0;
-        uint8_t uid[10];
-        uint32_t cuid;
-
-        // clear trace
-        iso14a_clear_trace();
-	//  iso14a_set_tracing(false);
-
+
+}
+
+void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
+{
+        // params
+        uint8_t blockNo = arg0;
+        byte_t blockdata[16];
+
+        memset(blockdata,'\0',16);
+        memcpy(blockdata, datain,16);
+        
+        // variables
+        byte_t isOK = 0;
+        uint8_t uid[10];
+        uint32_t cuid;
+
+        // clear trace
+        iso14a_clear_trace();
+	//  iso14a_set_tracing(false);
+
 		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
-        LED_A_ON();
-        LED_B_OFF();
-        LED_C_OFF();
-
-        while (true) {
-                if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                        break;
-                };
-
-                if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
-                        break;
-                };
-
-                if(mifare_ultra_halt(cuid)) {
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
-                        break;
-                };
-                
-                isOK = 1;
-                break;
-        }
-        
-        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
-
-        // add trace trailer
-        memset(uid, 0x44, 4);
-        LogTrace(uid, 4, 0, 0, TRUE);
-
-        LED_B_ON();
-  	cmd_send(CMD_ACK,isOK,0,0,0,0);
-//      UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-        LED_B_OFF();
-
-
-        // Thats it...
-        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-        LEDsoff();
-//  iso14a_set_tracing(TRUE);
-
-}
-
-void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
-{
-        // params
-        uint8_t blockNo = arg0;
-        byte_t blockdata[4];
-        
-	memcpy(blockdata, datain,4);
-
-        // variables
-        byte_t isOK = 0;
-        uint8_t uid[10];
-        uint32_t cuid;
-
-        // clear trace
-        iso14a_clear_trace();
-        //  iso14a_set_tracing(false);
-
+
+        LED_A_ON();
+        LED_B_OFF();
+        LED_C_OFF();
+
+        while (true) {
+                if(!iso14443a_select_card(uid, NULL, &cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
+                        break;
+                };
+
+                if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
+                        break;
+                };
+
+                if(mifare_ultra_halt(cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
+                        break;
+                };
+                
+                isOK = 1;
+                break;
+        }
+        
+        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
+
+        // add trace trailer
+        memset(uid, 0x44, 4);
+        LogTrace(uid, 4, 0, 0, TRUE);
+
+        LED_B_ON();
+  	cmd_send(CMD_ACK,isOK,0,0,0,0);
+//      UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+        LED_B_OFF();
+
+
+        // Thats it...
+        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+        LEDsoff();
+//  iso14a_set_tracing(TRUE);
+
+}
+
+void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
+{
+        // params
+        uint8_t blockNo = arg0;
+        byte_t blockdata[4];
+        
+	memcpy(blockdata, datain,4);
+
+        // variables
+        byte_t isOK = 0;
+        uint8_t uid[10];
+        uint32_t cuid;
+
+        // clear trace
+        iso14a_clear_trace();
+        //  iso14a_set_tracing(false);
+
 		iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
-
-        LED_A_ON();
-        LED_B_OFF();
-        LED_C_OFF();
-
-        while (true) {
-                        if(!iso14443a_select_card(uid, NULL, &cuid)) {
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
-                        break;
-                };
-
-                if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
-                        break;
-                };
-
-                if(mifare_ultra_halt(cuid)) {
-                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
-                        break;
-                };
-
-                isOK = 1;
-                break;
-        }
-
-        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
-
-        // add trace trailer
-	memset(uid, 0x44, 4);
-        LogTrace(uid, 4, 0, 0, TRUE);
-
-       LED_B_ON();
-        cmd_send(CMD_ACK,isOK,0,0,0,0);
-//      UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
-        LED_B_OFF();
-
-
-        // Thats it...
-        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-        LEDsoff();
-//  iso14a_set_tracing(TRUE);
-
-}
-
-// Return 1 if the nonce is invalid else return 0
-int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
-	return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
+
+        LED_A_ON();
+        LED_B_OFF();
+        LED_C_OFF();
+
+        while (true) {
+                        if(!iso14443a_select_card(uid, NULL, &cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
+                        break;
+                };
+
+                if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
+                        break;
+                };
+
+                if(mifare_ultra_halt(cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
+                        break;
+                };
+
+                isOK = 1;
+                break;
+        }
+
+        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
+
+        // add trace trailer
+	memset(uid, 0x44, 4);
+        LogTrace(uid, 4, 0, 0, TRUE);
+
+       LED_B_ON();
+        cmd_send(CMD_ACK,isOK,0,0,0,0);
+//      UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+        LED_B_OFF();
+
+
+        // Thats it...
+        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+        LEDsoff();
+//  iso14a_set_tracing(TRUE);
+
+}
+
+// Return 1 if the nonce is invalid else return 0
+int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
+	return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
 	(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
 	(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
 }
diff --git a/client/Makefile b/client/Makefile
index 6d75b4bb..e4a3580b 100644
--- a/client/Makefile
+++ b/client/Makefile
@@ -24,8 +24,10 @@ QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
 MOC = $(QTDIR)/bin/moc
 LUAPLATFORM = mingw
 else ifeq ($(platform),Darwin)
-CXXFLAGS = -I/Library/Frameworks/QtGui.framework/Versions/Current/Headers -I/Library/Frameworks/QtCore.framework/Versions/Current/Headers
-QTLDLIBS = -framework QtGui -framework QtCore
+#CXXFLAGS = -I/Library/Frameworks/QtGui.framework/Versions/Current/Headers -I/Library/Frameworks/QtCore.framework/Versions/Current/Headers
+#QTLDLIBS = -framework QtGui -framework QtCore
+CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
+QTLDLIBS = -F/opt/local/Library/Frameworks -framework QtGui -framework QtCore
 MOC = moc 
 LUAPLATFORM = macosx
 else
diff --git a/common/ldscript.common b/common/ldscript.common
index 7cde5891..f1b63550 100644
--- a/common/ldscript.common
+++ b/common/ldscript.common
@@ -13,8 +13,8 @@ MEMORY
 {
 	bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200             /* Phase 1 bootloader: Copies real bootloader to RAM */
 	bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200    /* Main bootloader code, stored in Flash, executed from RAM */
-	fpgaimage  : ORIGIN = 0x00102000, LENGTH = 64k - 0x2000      /* Place where the FPGA image will end up */
-	osimage    : ORIGIN = 0x00110000, LENGTH = 256K - 64k        /* Place where the main OS will end up */
+	fpgaimage  : ORIGIN = 0x00102000, LENGTH = 96k - 0x2000      /* Place where the FPGA image will end up */
+	osimage    : ORIGIN = 0x00118000, LENGTH = 256K - 96k        /* Place where the main OS will end up */
 	ram        : ORIGIN = 0x00200000, LENGTH = 64K - 0x20        /* RAM, minus small common area */
 	commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
 }
diff --git a/fpga/Makefile b/fpga/Makefile
index 12aeaaae..1aaa9f76 100644
--- a/fpga/Makefile
+++ b/fpga/Makefile
@@ -1,31 +1,33 @@
 include ../common/Makefile.common
 
-all: fpga.ngc fpga.ngd fpga.ncd fpga-placed.ncd fpga.bit
+all: fpga_lf.bit fpga_hf.bit
 clean:
-	$(DELETE) fpga.bgn  fpga.drc  fpga.ncd           fpga.ngd            fpga_par.xrpt    fpga-placed.pad      fpga-placed.par       fpga-placed.xpi   fpga_usage.xml  xlnx_auto_0.ise  xst.srp
-	$(DELETE) fpga.map  fpga.ngc           fpga_ngdbuild.xrpt  fpga.pcf         fpga-placed_pad.csv  fpga-placed.ptwx      fpga.rbt          xlnx_auto_0_xdb
-	$(DELETE) fpga.bld  fpga.mrp  fpga.ngc_xst.xrpt  fpga.ngm            fpga-placed.ncd  fpga-placed_pad.txt  fpga-placed.unroutes  fpga_summary.xml  netlist.lst     xst
+	$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp
+	$(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst
 
-fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_edge_detect.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
-	$(DELETE) fpga.ngc
-	$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
+fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
+	$(DELETE) $@
+	$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr
 
-fpga.ngd: fpga.ngc
-	$(DELETE) fpga.ngd
-	$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf fpga.ngc fpga.ngd
+fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v
+	$(DELETE) $@
+	$(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr
 
-fpga.ncd: fpga.ngd
-	$(DELETE) fpga.ncd
-	$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 fpga.ngd
+%.ngd: %.ngc
+	$(DELETE) $@
+	$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf $< $@
 
-fpga-placed.ncd: fpga.ncd
-	$(DELETE) fpga-placed.ncd
-	$(XILINX_TOOLS_PREFIX)par fpga.ncd fpga-placed.ncd
+%.ncd: %.ngd
+	$(DELETE) $@
+	$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 $<
 
-fpga.bit: fpga-placed.ncd
-	$(DELETE) fpga.bit fpga.drc fpga.rbt
-	$(XILINX_TOOLS_PREFIX)bitgen fpga-placed.ncd fpga.bit
+%-placed.ncd: %.ncd
+	$(DELETE) $@
+	$(XILINX_TOOLS_PREFIX)par $< $@
 
+%.bit: %-placed.ncd
+	$(DELETE) $@ $*.drc $*.rbt
+	$(XILINX_TOOLS_PREFIX)bitgen $< $@
 
 .PHONY: all clean help
 help:
diff --git a/fpga/clk_divider.v b/fpga/clk_divider.v
new file mode 100644
index 00000000..882af5cc
--- /dev/null
+++ b/fpga/clk_divider.v
@@ -0,0 +1,25 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2014 iZsh <izsh at fail0verflow.com>
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+module clk_divider(input clk, input [7:0] divisor, output [7:0] div_cnt, output div_clk);
+
+	reg [7:0] div_cnt_ = 0;
+	reg div_clk_;
+	assign div_cnt = div_cnt_;
+	assign div_clk = div_clk_;
+
+	always @(posedge clk)
+	begin
+		if(div_cnt == divisor) begin
+			div_cnt_ <= 8'd0;
+			div_clk_ = !div_clk_;
+		end else
+			div_cnt_ <= div_cnt_ + 1;
+	end
+
+endmodule
+
diff --git a/fpga/fpga.bit b/fpga/fpga.bit
deleted file mode 100644
index e5ea4fcd33b41a65cf776e06d388ebfcad02bff9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 42172
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
ChxqLP

diff --git a/fpga/fpga.v b/fpga/fpga.v
deleted file mode 100644
index a083ae5c..00000000
--- a/fpga/fpga.v
+++ /dev/null
@@ -1,220 +0,0 @@
-//-----------------------------------------------------------------------------
-// The FPGA is responsible for interfacing between the A/D, the coil drivers,
-// and the ARM. In the low-frequency modes it passes the data straight
-// through, so that the ARM gets raw A/D samples over the SSP. In the high-
-// frequency modes, the FPGA might perform some demodulation first, to
-// reduce the amount of data that we must send to the ARM.
-//
-// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
-// could be improved.
-//
-// Jonathan Westhues, March 2006
-// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
-//-----------------------------------------------------------------------------
-
-`include "lo_read.v"
-`include "lo_passthru.v"
-`include "lo_edge_detect.v"
-`include "hi_read_tx.v"
-`include "hi_read_rx_xcorr.v"
-`include "hi_simulate.v"
-`include "hi_iso14443a.v"
-`include "util.v"
-
-module fpga(
-	spck, miso, mosi, ncs,
-	pck0, ck_1356meg, ck_1356megb,
-	pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
-	adc_d, adc_clk, adc_noe,
-	ssp_frame, ssp_din, ssp_dout, ssp_clk,
-	cross_hi, cross_lo,
-	dbg
-);
-	input spck, mosi, ncs;
-	output miso;
-	input pck0, ck_1356meg, ck_1356megb;
-	output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
-	input [7:0] adc_d;
-	output adc_clk, adc_noe;
-	input ssp_dout;
-	output ssp_frame, ssp_din, ssp_clk;
-	input cross_hi, cross_lo;
-	output dbg;
-
-//assign pck0 = pck0i;
-//	IBUFG #(.IOSTANDARD("DEFAULT") ) pck0b(
-//		.O(pck0),
-//		.I(pck0i)
-//	);
-//assign spck = spcki;
-// IBUFG #(.IOSTANDARD("DEFAULT") ) spckb(
-	// .O(spck),
-	// .I(spcki)
-// );
-
-
-//-----------------------------------------------------------------------------
-// The SPI receiver. This sets up the configuration word, which the rest of
-// the logic looks at to determine how to connect the A/D and the coil
-// drivers (i.e., which section gets it). Also assign some symbolic names
-// to the configuration bits, for use below.
-//-----------------------------------------------------------------------------
-
-reg [15:0] shift_reg;
-reg [7:0] divisor;
-reg [7:0] conf_word;
-
-// We switch modes between transmitting to the 13.56 MHz tag and receiving
-// from it, which means that we must make sure that we can do so without
-// glitching, or else we will glitch the transmitted carrier.
-always @(posedge ncs)
-begin
-	case(shift_reg[15:12])
-		4'b0001: conf_word <= shift_reg[7:0];		// FPGA_CMD_SET_CONFREG
-		4'b0010: divisor <= shift_reg[7:0];			// FPGA_CMD_SET_DIVISOR
-	endcase
-end
-
-always @(posedge spck)
-begin
-	if(~ncs)
-	begin
-		shift_reg[15:1] <= shift_reg[14:0];
-		shift_reg[0] <= mosi;
-	end
-end
-
-wire [2:0] major_mode;
-assign major_mode = conf_word[7:5];
-
-// For the low-frequency configuration:
-wire lo_is_125khz;
-assign lo_is_125khz = conf_word[3];
-
-// For the high-frequency transmit configuration: modulation depth, either
-// 100% (just quite driving antenna, steady LOW), or shallower (tri-state
-// some fraction of the buffers)
-wire hi_read_tx_shallow_modulation;
-assign hi_read_tx_shallow_modulation = conf_word[0];
-
-// For the high-frequency receive correlator: frequency against which to
-// correlate.
-wire hi_read_rx_xcorr_848;
-assign hi_read_rx_xcorr_848 = conf_word[0];
-// and whether to drive the coil (reader) or just short it (snooper)
-wire hi_read_rx_xcorr_snoop;
-assign hi_read_rx_xcorr_snoop = conf_word[1];
-
-// Divide the expected subcarrier frequency for hi_read_rx_xcorr by 4
-wire hi_read_rx_xcorr_quarter;
-assign hi_read_rx_xcorr_quarter = conf_word[2];
-
-// For the high-frequency simulated tag: what kind of modulation to use.
-wire [2:0] hi_simulate_mod_type;
-assign hi_simulate_mod_type = conf_word[2:0];
-
-// For the high-frequency simulated tag: what kind of modulation to use.
-wire lf_field;
-assign lf_field = conf_word[0];
-
-//-----------------------------------------------------------------------------
-// And then we instantiate the modules corresponding to each of the FPGA's
-// major modes, and use muxes to connect the outputs of the active mode to
-// the output pins.
-//-----------------------------------------------------------------------------
-
-lo_read lr(
-	pck0, ck_1356meg, ck_1356megb,
-	lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4,
-	adc_d, lr_adc_clk,
-	lr_ssp_frame, lr_ssp_din, ssp_dout, lr_ssp_clk,
-	cross_hi, cross_lo,
-	lr_dbg,
-	lo_is_125khz, divisor
-);
-
-lo_passthru lp(
-	pck0, ck_1356meg, ck_1356megb,
-	lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4,
-	adc_d, lp_adc_clk,
-	lp_ssp_frame, lp_ssp_din, ssp_dout, lp_ssp_clk,
-	cross_hi, cross_lo,
-	lp_dbg, divisor
-);
-
-lo_edge_detect ls(
-	pck0, ck_1356meg, ck_1356megb,
-	ls_pwr_lo, ls_pwr_hi, ls_pwr_oe1, ls_pwr_oe2, ls_pwr_oe3, ls_pwr_oe4,
-	adc_d, ls_adc_clk,
-	ls_ssp_frame, ls_ssp_din, ssp_dout, ls_ssp_clk,
-	cross_hi, cross_lo,
-	ls_dbg, divisor,
-	lf_field
-);
-
-hi_read_tx ht(
-	pck0, ck_1356meg, ck_1356megb,
-	ht_pwr_lo, ht_pwr_hi, ht_pwr_oe1, ht_pwr_oe2, ht_pwr_oe3, ht_pwr_oe4,
-	adc_d, ht_adc_clk,
-	ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk,
-	cross_hi, cross_lo,
-	ht_dbg,
-	hi_read_tx_shallow_modulation
-);
-
-hi_read_rx_xcorr hrxc(
-	pck0, ck_1356meg, ck_1356megb,
-	hrxc_pwr_lo, hrxc_pwr_hi, hrxc_pwr_oe1, hrxc_pwr_oe2, hrxc_pwr_oe3,	hrxc_pwr_oe4,
-	adc_d, hrxc_adc_clk,
-	hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
-	cross_hi, cross_lo,
-	hrxc_dbg,
-	hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
-);
-
-hi_simulate hs(
-	pck0, ck_1356meg, ck_1356megb,
-	hs_pwr_lo, hs_pwr_hi, hs_pwr_oe1, hs_pwr_oe2, hs_pwr_oe3, hs_pwr_oe4,
-	adc_d, hs_adc_clk,
-	hs_ssp_frame, hs_ssp_din, ssp_dout, hs_ssp_clk,
-	cross_hi, cross_lo,
-	hs_dbg,
-	hi_simulate_mod_type
-);
-
-hi_iso14443a hisn(
-	pck0, ck_1356meg, ck_1356megb,
-	hisn_pwr_lo, hisn_pwr_hi, hisn_pwr_oe1, hisn_pwr_oe2, hisn_pwr_oe3,	hisn_pwr_oe4,
-	adc_d, hisn_adc_clk,
-	hisn_ssp_frame, hisn_ssp_din, ssp_dout, hisn_ssp_clk,
-	cross_hi, cross_lo,
-	hisn_dbg,
-	hi_simulate_mod_type
-);
-
-// Major modes:
-//   000 --  LF reader (generic)
-//   001 --  LF simulated tag (generic)
-//   010 --  HF reader, transmitting to tag; modulation depth selectable
-//   011 --  HF reader, receiving from tag, correlating as it goes; frequency selectable
-//   100 --  HF simulated tag
-//   101 --  HF ISO14443-A
-//   110 --  LF passthrough
-//   111 --  everything off
-
-mux8 mux_ssp_clk		(major_mode, ssp_clk,   lr_ssp_clk,   ls_ssp_clk,   ht_ssp_clk,   hrxc_ssp_clk,   hs_ssp_clk,   hisn_ssp_clk,   lp_ssp_clk,   1'b0);
-mux8 mux_ssp_din		(major_mode, ssp_din,   lr_ssp_din,   ls_ssp_din,   ht_ssp_din,   hrxc_ssp_din,   hs_ssp_din,   hisn_ssp_din,   lp_ssp_din,   1'b0);
-mux8 mux_ssp_frame		(major_mode, ssp_frame, lr_ssp_frame, ls_ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, lp_ssp_frame, 1'b0);
-mux8 mux_pwr_oe1		(major_mode, pwr_oe1,   lr_pwr_oe1,   ls_pwr_oe1,   ht_pwr_oe1,   hrxc_pwr_oe1,   hs_pwr_oe1,   hisn_pwr_oe1,   lp_pwr_oe1,   1'b0);
-mux8 mux_pwr_oe2		(major_mode, pwr_oe2,   lr_pwr_oe2,   ls_pwr_oe2,   ht_pwr_oe2,   hrxc_pwr_oe2,   hs_pwr_oe2,   hisn_pwr_oe2,   lp_pwr_oe2,   1'b0);
-mux8 mux_pwr_oe3		(major_mode, pwr_oe3,   lr_pwr_oe3,   ls_pwr_oe3,   ht_pwr_oe3,   hrxc_pwr_oe3,   hs_pwr_oe3,   hisn_pwr_oe3,   lp_pwr_oe3,   1'b0);
-mux8 mux_pwr_oe4		(major_mode, pwr_oe4,   lr_pwr_oe4,   ls_pwr_oe4,   ht_pwr_oe4,   hrxc_pwr_oe4,   hs_pwr_oe4,   hisn_pwr_oe4,   lp_pwr_oe4,   1'b0);
-mux8 mux_pwr_lo			(major_mode, pwr_lo,    lr_pwr_lo,    ls_pwr_lo,    ht_pwr_lo,    hrxc_pwr_lo,    hs_pwr_lo,    hisn_pwr_lo,    lp_pwr_lo,    1'b0);
-mux8 mux_pwr_hi			(major_mode, pwr_hi,    lr_pwr_hi,    ls_pwr_hi,    ht_pwr_hi,    hrxc_pwr_hi,    hs_pwr_hi,    hisn_pwr_hi,    lp_pwr_hi,    1'b0);
-mux8 mux_adc_clk		(major_mode, adc_clk,   lr_adc_clk,   ls_adc_clk,   ht_adc_clk,   hrxc_adc_clk,   hs_adc_clk,   hisn_adc_clk,   lp_adc_clk,   1'b0);
-mux8 mux_dbg			(major_mode, dbg,       lr_dbg,       ls_dbg,       ht_dbg,       hrxc_dbg,       hs_dbg,       hisn_dbg,       lp_dbg,       1'b0);
-
-// In all modes, let the ADC's outputs be enabled.
-assign adc_noe = 1'b0;
-
-endmodule
diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit
new file mode 100644
index 0000000000000000000000000000000000000000..5389428c5539eb60eee9f27b6956ca950aa79b15
GIT binary patch
literal 42175
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

literal 0
HcmV?d00001

diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v
new file mode 100644
index 00000000..ff7c904a
--- /dev/null
+++ b/fpga/fpga_hf.v
@@ -0,0 +1,150 @@
+//-----------------------------------------------------------------------------
+// The FPGA is responsible for interfacing between the A/D, the coil drivers,
+// and the ARM. In the low-frequency modes it passes the data straight
+// through, so that the ARM gets raw A/D samples over the SSP. In the high-
+// frequency modes, the FPGA might perform some demodulation first, to
+// reduce the amount of data that we must send to the ARM.
+//
+// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
+// could be improved.
+//
+// Jonathan Westhues, March 2006
+// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
+//-----------------------------------------------------------------------------
+
+`include "hi_read_tx.v"
+`include "hi_read_rx_xcorr.v"
+`include "hi_simulate.v"
+`include "hi_iso14443a.v"
+`include "util.v"
+
+module fpga_hf(
+	input spck, output miso, input mosi, input ncs,
+	input pck0, input ck_1356meg, input ck_1356megb,
+	output pwr_lo, output pwr_hi,
+	output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
+	input [7:0] adc_d, output adc_clk, output adc_noe,
+	output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk,
+	input cross_hi, input cross_lo,
+	output dbg
+);
+
+//-----------------------------------------------------------------------------
+// The SPI receiver. This sets up the configuration word, which the rest of
+// the logic looks at to determine how to connect the A/D and the coil
+// drivers (i.e., which section gets it). Also assign some symbolic names
+// to the configuration bits, for use below.
+//-----------------------------------------------------------------------------
+
+reg [15:0] shift_reg;
+reg [7:0] conf_word;
+
+// We switch modes between transmitting to the 13.56 MHz tag and receiving
+// from it, which means that we must make sure that we can do so without
+// glitching, or else we will glitch the transmitted carrier.
+always @(posedge ncs)
+begin
+	case(shift_reg[15:12])
+		4'b0001: conf_word <= shift_reg[7:0];		// FPGA_CMD_SET_CONFREG
+	endcase
+end
+
+always @(posedge spck)
+begin
+	if(~ncs)
+	begin
+		shift_reg[15:1] <= shift_reg[14:0];
+		shift_reg[0] <= mosi;
+	end
+end
+
+wire [2:0] major_mode;
+assign major_mode = conf_word[7:5];
+
+// For the high-frequency transmit configuration: modulation depth, either
+// 100% (just quite driving antenna, steady LOW), or shallower (tri-state
+// some fraction of the buffers)
+wire hi_read_tx_shallow_modulation = conf_word[0];
+
+// For the high-frequency receive correlator: frequency against which to
+// correlate.
+wire hi_read_rx_xcorr_848 = conf_word[0];
+// and whether to drive the coil (reader) or just short it (snooper)
+wire hi_read_rx_xcorr_snoop = conf_word[1];
+
+// Divide the expected subcarrier frequency for hi_read_rx_xcorr by 4
+wire hi_read_rx_xcorr_quarter = conf_word[2];
+
+// For the high-frequency simulated tag: what kind of modulation to use.
+wire [2:0] hi_simulate_mod_type = conf_word[2:0];
+
+//-----------------------------------------------------------------------------
+// And then we instantiate the modules corresponding to each of the FPGA's
+// major modes, and use muxes to connect the outputs of the active mode to
+// the output pins.
+//-----------------------------------------------------------------------------
+
+hi_read_tx ht(
+	pck0, ck_1356meg, ck_1356megb,
+	ht_pwr_lo, ht_pwr_hi, ht_pwr_oe1, ht_pwr_oe2, ht_pwr_oe3, ht_pwr_oe4,
+	adc_d, ht_adc_clk,
+	ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk,
+	cross_hi, cross_lo,
+	ht_dbg,
+	hi_read_tx_shallow_modulation
+);
+
+hi_read_rx_xcorr hrxc(
+	pck0, ck_1356meg, ck_1356megb,
+	hrxc_pwr_lo, hrxc_pwr_hi, hrxc_pwr_oe1, hrxc_pwr_oe2, hrxc_pwr_oe3,	hrxc_pwr_oe4,
+	adc_d, hrxc_adc_clk,
+	hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
+	cross_hi, cross_lo,
+	hrxc_dbg,
+	hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
+);
+
+hi_simulate hs(
+	pck0, ck_1356meg, ck_1356megb,
+	hs_pwr_lo, hs_pwr_hi, hs_pwr_oe1, hs_pwr_oe2, hs_pwr_oe3, hs_pwr_oe4,
+	adc_d, hs_adc_clk,
+	hs_ssp_frame, hs_ssp_din, ssp_dout, hs_ssp_clk,
+	cross_hi, cross_lo,
+	hs_dbg,
+	hi_simulate_mod_type
+);
+
+hi_iso14443a hisn(
+	pck0, ck_1356meg, ck_1356megb,
+	hisn_pwr_lo, hisn_pwr_hi, hisn_pwr_oe1, hisn_pwr_oe2, hisn_pwr_oe3,	hisn_pwr_oe4,
+	adc_d, hisn_adc_clk,
+	hisn_ssp_frame, hisn_ssp_din, ssp_dout, hisn_ssp_clk,
+	cross_hi, cross_lo,
+	hisn_dbg,
+	hi_simulate_mod_type
+);
+
+// Major modes:
+
+//   000 --  HF reader, transmitting to tag; modulation depth selectable
+//   001 --  HF reader, receiving from tag, correlating as it goes; frequency selectable
+//   010 --  HF simulated tag
+//   011 --  HF ISO14443-A
+//   111 --  everything off
+
+mux8 mux_ssp_clk		(major_mode, ssp_clk,   ht_ssp_clk,   hrxc_ssp_clk,   hs_ssp_clk,   hisn_ssp_clk,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_ssp_din		(major_mode, ssp_din,   ht_ssp_din,   hrxc_ssp_din,   hs_ssp_din,   hisn_ssp_din,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_ssp_frame		(major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe1		(major_mode, pwr_oe1,   ht_pwr_oe1,   hrxc_pwr_oe1,   hs_pwr_oe1,   hisn_pwr_oe1,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe2		(major_mode, pwr_oe2,   ht_pwr_oe2,   hrxc_pwr_oe2,   hs_pwr_oe2,   hisn_pwr_oe2,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe3		(major_mode, pwr_oe3,   ht_pwr_oe3,   hrxc_pwr_oe3,   hs_pwr_oe3,   hisn_pwr_oe3,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe4		(major_mode, pwr_oe4,   ht_pwr_oe4,   hrxc_pwr_oe4,   hs_pwr_oe4,   hisn_pwr_oe4,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_lo			(major_mode, pwr_lo,    ht_pwr_lo,    hrxc_pwr_lo,    hs_pwr_lo,    hisn_pwr_lo,    1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_hi			(major_mode, pwr_hi,    ht_pwr_hi,    hrxc_pwr_hi,    hs_pwr_hi,    hisn_pwr_hi,    1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_adc_clk		(major_mode, adc_clk,   ht_adc_clk,   hrxc_adc_clk,   hs_adc_clk,   hisn_adc_clk,   1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_dbg			(major_mode, dbg,       ht_dbg,       hrxc_dbg,       hs_dbg,       hisn_dbg,       1'b0, 1'b0, 1'b0, 1'b0);
+
+// In all modes, let the ADC's outputs be enabled.
+assign adc_noe = 1'b0;
+
+endmodule
diff --git a/fpga/fpga_lf.bit b/fpga/fpga_lf.bit
new file mode 100644
index 0000000000000000000000000000000000000000..133ea9924b546523b0128737e5082cc723406319
GIT binary patch
literal 42175
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
IQt~1H2Y^weQ~&?~

literal 0
HcmV?d00001

diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v
new file mode 100644
index 00000000..8dea68d7
--- /dev/null
+++ b/fpga/fpga_lf.v
@@ -0,0 +1,125 @@
+//-----------------------------------------------------------------------------
+// The FPGA is responsible for interfacing between the A/D, the coil drivers,
+// and the ARM. In the low-frequency modes it passes the data straight
+// through, so that the ARM gets raw A/D samples over the SSP. In the high-
+// frequency modes, the FPGA might perform some demodulation first, to
+// reduce the amount of data that we must send to the ARM.
+//
+// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
+// could be improved.
+//
+// Jonathan Westhues, March 2006
+// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
+//-----------------------------------------------------------------------------
+
+`include "lo_read.v"
+`include "lo_passthru.v"
+`include "lo_edge_detect.v"
+`include "util.v"
+`include "clk_divider.v"
+
+module fpga_lf(
+	input spck, output miso, input mosi, input ncs,
+	input pck0, input ck_1356meg, input ck_1356megb,
+	output pwr_lo, output pwr_hi,
+	output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
+	input [7:0] adc_d, output adc_clk, output adc_noe,
+	output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk,
+	input cross_hi, input cross_lo,
+	output dbg
+);
+
+//-----------------------------------------------------------------------------
+// The SPI receiver. This sets up the configuration word, which the rest of
+// the logic looks at to determine how to connect the A/D and the coil
+// drivers (i.e., which section gets it). Also assign some symbolic names
+// to the configuration bits, for use below.
+//-----------------------------------------------------------------------------
+
+reg [15:0] shift_reg;
+reg [7:0] divisor;
+reg [7:0] conf_word;
+
+// We switch modes between transmitting to the 13.56 MHz tag and receiving
+// from it, which means that we must make sure that we can do so without
+// glitching, or else we will glitch the transmitted carrier.
+always @(posedge ncs)
+begin
+	case(shift_reg[15:12])
+		4'b0001: conf_word <= shift_reg[7:0];		// FPGA_CMD_SET_CONFREG
+		4'b0010: divisor <= shift_reg[7:0];		// FPGA_CMD_SET_DIVISOR
+	endcase
+end
+
+always @(posedge spck)
+begin
+	if(~ncs)
+	begin
+		shift_reg[15:1] <= shift_reg[14:0];
+		shift_reg[0] <= mosi;
+	end
+end
+
+wire [2:0] major_mode;
+assign major_mode = conf_word[7:5];
+
+// For the low-frequency configuration:
+wire lf_field = conf_word[0];
+
+//-----------------------------------------------------------------------------
+// And then we instantiate the modules corresponding to each of the FPGA's
+// major modes, and use muxes to connect the outputs of the active mode to
+// the output pins.
+//-----------------------------------------------------------------------------
+wire [7:0] pck_cnt;
+wire pck_divclk;
+clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk);
+
+lo_read lr(
+	pck0, pck_cnt, pck_divclk,
+	lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4,
+	adc_d, lr_adc_clk,
+	lr_ssp_frame, lr_ssp_din, lr_ssp_clk,
+	lr_dbg
+);
+
+lo_passthru lp(
+	pck_divclk,
+	lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4,
+	lp_adc_clk,
+	lp_ssp_din, ssp_dout,
+	cross_lo,
+	lp_dbg
+);
+
+lo_edge_detect le(
+	pck0, pck_cnt, pck_divclk,
+	le_pwr_lo, le_pwr_hi, le_pwr_oe1, le_pwr_oe2, le_pwr_oe3, le_pwr_oe4,
+	adc_d, le_adc_clk,
+	le_ssp_frame, ssp_dout, le_ssp_clk,
+	cross_lo,
+	le_dbg,
+	lf_field
+);
+
+// Major modes:
+//   000 --  LF reader (generic)
+//   001 --  LF edge detect (generic)
+//   010 --  LF passthrough
+
+mux8 mux_ssp_clk		(major_mode, ssp_clk,   lr_ssp_clk,   le_ssp_clk,         1'b0,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_ssp_din		(major_mode, ssp_din,   lr_ssp_din,         1'b0,         1'b0,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_ssp_frame		(major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame,       1'b0,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+mux8 mux_pwr_oe1		(major_mode, pwr_oe1,   lr_pwr_oe1,   le_pwr_oe1,   lp_pwr_oe1,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe2		(major_mode, pwr_oe2,   lr_pwr_oe2,   le_pwr_oe2,   lp_pwr_oe2,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+mux8 mux_pwr_oe3		(major_mode, pwr_oe3,   lr_pwr_oe3,   le_pwr_oe3,   lp_pwr_oe3,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe4		(major_mode, pwr_oe4,   lr_pwr_oe4,   le_pwr_oe4,   lp_pwr_oe4,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+mux8 mux_pwr_lo			(major_mode, pwr_lo,    lr_pwr_lo,    le_pwr_lo,    lp_pwr_lo,    1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+mux8 mux_pwr_hi			(major_mode, pwr_hi,    lr_pwr_hi,    le_pwr_hi,    lp_pwr_hi,    1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+mux8 mux_adc_clk		(major_mode, adc_clk,   lr_adc_clk,   le_adc_clk,   lp_adc_clk,   1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+mux8 mux_dbg			(major_mode, dbg,       lr_dbg,       le_dbg,       lp_dbg,       1'b0, 1'b0, 1'b0, 1'b0, 1'b0); 
+
+// In all modes, let the ADC's outputs be enabled.
+assign adc_noe = 1'b0;
+
+endmodule
diff --git a/fpga/go.bat b/fpga/go.bat
index 8600d3cd..d9704e08 100644
--- a/fpga/go.bat
+++ b/fpga/go.bat
@@ -2,37 +2,67 @@
 
 rmdir/s/q xst
 
-del fpga.ngc
-xst -ifn xst.scr
+del fpga_lf.ngc
+xst -ifn xst_lf.scr
 if errorlevel 0 goto ok1
 goto done
 :ok1
 
-del fpga.ngd
-ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga.ngc fpga.ngd
+del fpga_lf.ngd
+ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga_lf.ngc fpga_lf.ngd
 if errorlevel 0 goto ok2
 goto done
 :ok2
 
-del fpga.ncd
-map -p xc2s30-6vq100 fpga.ngd
+del fpga_lf.ncd
+map -p xc2s30-6vq100 fpga_lf.ngd
 if errorlevel 0 goto ok3
 goto done
 :ok3
 
-del fpga-placed.ncd
-par fpga.ncd fpga-placed.ncd
+del fpga_lf-placed.ncd
+par fpga_lf.ncd fpga_lf-placed.ncd
 if errorlevel 0 goto ok4
 goto done
 :ok4
 
-del fpga.bit fpga.drc fpga.rbt
-bitgen -b fpga-placed.ncd fpga.bit
+del fpga_lf.bit fpga_lf.drc fpga_lf.rbt
+bitgen -b fpga_lf-placed.ncd fpga_lf.bit
 if errorlevel 0 goto ok5
 goto done
 :ok5
 
+del fpga_hf.ngc
+xst -ifn xst_hf.scr
+if errorlevel 0 goto ok6
+goto done
+:ok6
+
+del fpga_hf.ngd
+ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga_hf.ngc fpga_hf.ngd
+if errorlevel 0 goto ok7
+goto done
+:ok7
+
+del fpga_hf.ncd
+map -p xc2s30-6vq100 fpga_hf.ngd
+if errorlevel 0 goto ok8
+goto done
+:ok8
+
+del fpga_hf-placed.ncd
+par fpga_hf.ncd fpga_hf-placed.ncd
+if errorlevel 0 goto ok9
+goto done
+:ok9
+
+del fpga_hf.bit fpga_hf.drc fpga_hf.rbt
+bitgen -b fpga_hf-placed.ncd fpga_hf.bit
+if errorlevel 0 goto ok10
+goto done
+:ok10
+
 echo okay
-perl ..\tools\rbt2c.pl fpga.rbt > ..\armsrc\fpgaimg.c
+perl ..\tools\rbt2c.pl fpga_lf.rbt > ..\armsrc\fpgaimg.c
 
 :done
diff --git a/fpga/lo_edge_detect.v b/fpga/lo_edge_detect.v
index 8458ee69..af600b83 100644
--- a/fpga/lo_edge_detect.v
+++ b/fpga/lo_edge_detect.v
@@ -7,34 +7,18 @@
 //-----------------------------------------------------------------------------
 
 module lo_edge_detect(
-    pck0, ck_1356meg, ck_1356megb,
-    pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
-    adc_d, adc_clk,
-    ssp_frame, ssp_din, ssp_dout, ssp_clk,
-    cross_hi, cross_lo,
-    dbg,
-	  divisor,
-		lf_field
+	input pck0, input [7:0] pck_cnt, input pck_divclk,
+	output pwr_lo, output pwr_hi,
+	output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
+	input [7:0] adc_d, output adc_clk,
+	output ssp_frame, input ssp_dout, output ssp_clk,
+	input cross_lo,
+	output dbg,
+	input lf_field
 );
-    input pck0, ck_1356meg, ck_1356megb;
-    output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
-    input [7:0] adc_d;
-    output adc_clk;
-    input ssp_dout;
-    output ssp_frame, ssp_din, ssp_clk;
-    input cross_hi, cross_lo;
-    output dbg;
-	  input [7:0] divisor;
-		input lf_field;
 
-// Divide the clock to be used for the ADC
-reg [7:0] pck_divider;
-reg clk_state;
-
-wire tag_modulation; 
-assign tag_modulation = ssp_dout & !lf_field;
-wire reader_modulation; 
-assign reader_modulation = !ssp_dout & lf_field & clk_state;
+wire tag_modulation = ssp_dout & !lf_field;
+wire reader_modulation = !ssp_dout & lf_field & pck_divclk;
 
 // No logic, straight through.
 assign pwr_oe1 = 1'b0; // not used in LF mode
@@ -46,20 +30,7 @@ assign pwr_lo = reader_modulation;
 assign pwr_hi = 1'b0;
 assign dbg = ssp_frame;
 
-always @(posedge pck0)
-begin
-	if(pck_divider == divisor[7:0])
-		begin
-			pck_divider <= 8'd0;
-			clk_state = !clk_state;
-		end
-	else
-	begin
-		pck_divider <= pck_divider + 1;
-	end
-end
-
-assign adc_clk = ~clk_state;
+assign adc_clk = ~pck_divclk;
 
 // Toggle the output with hysteresis
 //  Set to high if the ADC value is above 200
@@ -70,7 +41,7 @@ reg output_state;
 
 always @(posedge pck0)
 begin
-	if((pck_divider == 8'd7) && !clk_state) begin
+	if((pck_cnt == 8'd7) && !pck_divclk) begin
 		is_high = (adc_d >= 8'd190);
 		is_low = (adc_d <= 8'd70);
 	end
diff --git a/fpga/lo_passthru.v b/fpga/lo_passthru.v
index 5c59d11c..933728eb 100644
--- a/fpga/lo_passthru.v
+++ b/fpga/lo_passthru.v
@@ -4,42 +4,14 @@
 //-----------------------------------------------------------------------------
 
 module lo_passthru(
-    pck0, ck_1356meg, ck_1356megb,
-    pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
-    adc_d, adc_clk,
-    ssp_frame, ssp_din, ssp_dout, ssp_clk,
-    cross_hi, cross_lo,
-    dbg, divisor
+	input pck_divclk,
+	output pwr_lo, output pwr_hi,
+	output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
+	output adc_clk,
+	output ssp_din, input ssp_dout,
+	input cross_lo,
+	output dbg
 );
-    input pck0, ck_1356meg, ck_1356megb;
-    output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
-    input [7:0] adc_d;
-    output adc_clk;
-    input ssp_dout;
-    output ssp_frame, ssp_din, ssp_clk;
-    input cross_hi, cross_lo;
-    output dbg;
-    input [7:0] divisor;
-
-reg [7:0] pck_divider;
-reg ant_lo;
-
-// this task runs on the rising egde of pck0 clock (24Mhz) and creates ant_lo
-// which is high for (divisor+1) pck0 cycles and low for the same duration
-// ant_lo is therefore a 50% duty cycle clock signal with a frequency of
-// 12Mhz/(divisor+1) which drives the antenna as well as the ADC clock adc_clk
-always @(posedge pck0)
-begin
-	if(pck_divider == divisor[7:0])
-		begin
-			pck_divider <= 8'd0;
-			ant_lo = !ant_lo;
-		end
-	else
-	begin
-		pck_divider <= pck_divider + 1;
-	end
-end
 
 // the antenna is modulated when ssp_dout = 1, when 0 the
 // antenna drivers stop modulating and go into listen mode
@@ -47,7 +19,7 @@ assign pwr_oe3 = 1'b0;
 assign pwr_oe1 = ssp_dout;
 assign pwr_oe2 = ssp_dout;
 assign pwr_oe4 = ssp_dout;
-assign pwr_lo = ant_lo && ssp_dout;
+assign pwr_lo = pck_divclk && ssp_dout;
 assign pwr_hi = 1'b0;
 assign adc_clk = 1'b0;
 assign ssp_din = cross_lo;
diff --git a/fpga/lo_read.v b/fpga/lo_read.v
index e6f245ca..f2d79127 100644
--- a/fpga/lo_read.v
+++ b/fpga/lo_read.v
@@ -7,65 +7,34 @@
 //-----------------------------------------------------------------------------
 
 module lo_read(
-    pck0, ck_1356meg, ck_1356megb,
-    pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
-    adc_d, adc_clk,
-    ssp_frame, ssp_din, ssp_dout, ssp_clk,
-    cross_hi, cross_lo,
-    dbg,
-    lo_is_125khz, divisor
+	input pck0, input [7:0] pck_cnt, input pck_divclk,
+	output pwr_lo, output pwr_hi,
+	output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
+	input [7:0] adc_d, output adc_clk,
+	output ssp_frame, output ssp_din, output ssp_clk,
+	output dbg
 );
-    input pck0, ck_1356meg, ck_1356megb;
-    output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
-    input [7:0] adc_d;
-    output adc_clk;
-    input ssp_dout;
-    output ssp_frame, ssp_din, ssp_clk;
-    input cross_hi, cross_lo;
-    output dbg;
-    input lo_is_125khz; // redundant signal, no longer used anywhere
-    input [7:0] divisor;
 
 reg [7:0] to_arm_shiftreg;
-reg [7:0] pck_divider;
-reg ant_lo;
-
-// this task runs on the rising egde of pck0 clock (24Mhz) and creates ant_lo
-// which is high for (divisor+1) pck0 cycles and low for the same duration
-// ant_lo is therefore a 50% duty cycle clock signal with a frequency of
-// 12Mhz/(divisor+1) which drives the antenna as well as the ADC clock adc_clk
-always @(posedge pck0)
-begin
-	if(pck_divider == divisor[7:0])
-		begin
-			pck_divider <= 8'd0;
-			ant_lo = !ant_lo;
-		end
-	else
-	begin
-		pck_divider <= pck_divider + 1;
-	end
-end
 
 // this task also runs at pck0 frequency (24Mhz) and is used to serialize
 // the ADC output which is then clocked into the ARM SSP.
 
-// because ant_lo always transitions when pck_divider = 0 we use the
-// pck_divider counter to sync our other signals off it
-// we read the ADC value when pck_divider=7 and shift it out on counts 8..15
+// because pck_divclk always transitions when pck_cnt = 0 we use the
+// pck_div counter to sync our other signals off it
+// we read the ADC value when pck_cnt=7 and shift it out on counts 8..15
 always @(posedge pck0)
 begin
-	if((pck_divider == 8'd7) && !ant_lo)
-        to_arm_shiftreg <= adc_d;
-    else
-	begin
-        to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];
+	if((pck_cnt == 8'd7) && !pck_divclk)
+		to_arm_shiftreg <= adc_d;
+	else begin
+		to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];
 		// simulation showed a glitch occuring due to the LSB of the shifter
 		// not being set as we shift bits out
 		// this ensures the ssp_din remains low after a transfer and suppresses
 		// the glitch that would occur when the last data shifted out ended in
 		// a 1 bit and the next data shifted out started with a 0 bit
-        to_arm_shiftreg[0] <= 1'b0;
+		to_arm_shiftreg[0] <= 1'b0;
 	end
 end
 
@@ -83,11 +52,11 @@ end
 // ssp_clk  |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
 
 // serialized SSP data is gated by ant_lo to suppress unwanted signal
-assign ssp_din = to_arm_shiftreg[7] && !ant_lo;
+assign ssp_din = to_arm_shiftreg[7] && !pck_divclk;
 // SSP clock always runs at 24Mhz
 assign ssp_clk = pck0;
 // SSP frame is gated by ant_lo and goes high when pck_divider=8..15
-assign ssp_frame = (pck_divider[7:3] == 5'd1) && !ant_lo;
+assign ssp_frame = (pck_cnt[7:3] == 5'd1) && !pck_divclk;
 // unused signals tied low
 assign pwr_hi = 1'b0;
 assign pwr_oe1 = 1'b0;
@@ -95,9 +64,9 @@ assign pwr_oe2 = 1'b0;
 assign pwr_oe3 = 1'b0;
 assign pwr_oe4 = 1'b0;
 // this is the antenna driver signal
-assign pwr_lo = ant_lo;
+assign pwr_lo = pck_divclk;
 // ADC clock out of phase with antenna driver
-assign adc_clk = ~ant_lo;
+assign adc_clk = ~pck_divclk;
 // ADC clock also routed to debug pin
 assign dbg = adc_clk;
 endmodule
diff --git a/fpga/xst.scr b/fpga/xst.scr
deleted file mode 100644
index 406bbeee..00000000
--- a/fpga/xst.scr
+++ /dev/null
@@ -1 +0,0 @@
-run -ifn fpga.v -ifmt Verilog -ofn fpga.ngc -ofmt NGC -p xc2s30-5-vq100 -opt_mode Speed -opt_level 1 -ent fpga
diff --git a/fpga/xst_hf.scr b/fpga/xst_hf.scr
new file mode 100644
index 00000000..dd2fdc85
--- /dev/null
+++ b/fpga/xst_hf.scr
@@ -0,0 +1 @@
+run -ifn fpga_hf.v -ifmt Verilog -ofn fpga_hf.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_hf -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact
diff --git a/fpga/xst_lf.scr b/fpga/xst_lf.scr
new file mode 100644
index 00000000..2d6c7e95
--- /dev/null
+++ b/fpga/xst_lf.scr
@@ -0,0 +1 @@
+run -ifn fpga_lf.v -ifmt Verilog -ofn fpga_lf.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_lf -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact
diff --git a/include/proxmark3.h b/include/proxmark3.h
index ce263ca1..8c9417da 100644
--- a/include/proxmark3.h
+++ b/include/proxmark3.h
@@ -60,6 +60,10 @@
 #define SPI_FPGA_MODE	0
 #define SPI_LCD_MODE	1
 
+#define FPGA_BITSTREAM_ERR 0
+#define FPGA_BITSTREAM_LF 1
+#define FPGA_BITSTREAM_HF 2
+
 #define TRUE 1
 #define FALSE 0
 
-- 
2.39.5