From 7cc204bff881ce1d1833d8e93469f6bbba80c70e Mon Sep 17 00:00:00 2001 From: iZsh 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 +// +// 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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

eu*}zWMx6WDri0MtNP{{*8u|VkeY~bQJ-m} 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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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 ..\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.2