From: pwpiwi Date: Sun, 24 Mar 2019 17:11:41 +0000 (+0100) Subject: FPGA changes (#803) X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/5ea2a24839c71ba6e58af937a392a6204b8b4696 FPGA changes (#803) * merge hf_rx_xcorr and hf_tx modes into one module with common ssp_clk and ssp_frame * get rid of most of the warnings when compiling the HF verilog sources * refactoring the constants in Verilog sources --- diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8824847e..926ac52e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -24,6 +24,7 @@ #include "legicrfsim.h" #include "hitag2.h" #include "hitagS.h" +#include "iso14443b.h" #include "iso15693.h" #include "lfsampling.h" #include "BigBuf.h" @@ -243,7 +244,7 @@ void MeasureAntennaTuningHfOnly(int *vHf) // Let the FPGA drive the high-frequency antenna around 13.56 MHz. LED_A_ON(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER); SpinDelay(20); *vHf = AvgAdc_Voltage_HF(); LED_A_OFF(); @@ -285,7 +286,7 @@ void MeasureAntennaTuningHf(void) // Let the FPGA drive the high-frequency antenna around 13.56 MHz. FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER); for (;;) { SpinDelay(500); diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index d1d527c4..214f4843 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -130,21 +130,21 @@ void FpgaSetupSsc(uint8_t FPGA_mode) // Now set up the SSC proper, starting from a known state. AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - // RX clock comes from TX clock, RX starts when TX starts, data changes - // on RX clock rising edge, sampled on falling edge + // RX clock comes from TX clock, RX starts on Transmit Start, + // data and frame signal is sampled on falling edge of RK AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); // 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync // pulse, no output sync - if ((FPGA_mode & 0xe0) == FPGA_MAJOR_MODE_HF_READER_RX_XCORR) { + if ((FPGA_mode & 0xe0) == FPGA_MAJOR_MODE_HF_READER) { AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); } else { AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); } // TX clock comes from TK pin, no clock output, outputs change on falling - // edge of TK, sample on rising edge of TK, start on positive-going edge of sync - AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); + // edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF + AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); // tx framing is the same as the rx framing AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR; diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 006de8de..42f9ccc6 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -49,12 +49,11 @@ void SetAdcMuxFor(uint32_t whichGpio); #define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<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) -#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) -#define FPGA_MAJOR_MODE_HF_GET_TRACE (5<<5) +#define FPGA_MAJOR_MODE_HF_READER (0<<5) +#define FPGA_MAJOR_MODE_HF_SIMULATOR (1<<5) +#define FPGA_MAJOR_MODE_HF_ISO14443A (2<<5) +#define FPGA_MAJOR_MODE_HF_SNOOP (3<<5) +#define FPGA_MAJOR_MODE_HF_GET_TRACE (4<<5) // BOTH #define FPGA_MAJOR_MODE_OFF (7<<5) @@ -66,14 +65,19 @@ void SetAdcMuxFor(uint32_t whichGpio); #define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0) #define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1) -// Options for the HF reader, tx to tag -#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0) +// Options for the HF reader +#define FPGA_HF_READER_MODE_RECEIVE_IQ (0<<0) +#define FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE (1<<0) +#define FPGA_HF_READER_MODE_RECEIVE_PHASE (2<<0) +#define FPGA_HF_READER_MODE_SEND_FULL_MOD (3<<0) +#define FPGA_HF_READER_MODE_SEND_SHALLOW_MOD (4<<0) +#define FPGA_HF_READER_MODE_SNOOP_IQ (5<<0) +#define FPGA_HF_READER_MODE_SNOOP_AMPLITUDE (6<<0) +#define FPGA_HF_READER_MODE_SNOOP_PHASE (7<<0) -// 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_AMPLITUDE (1<<3) +#define FPGA_HF_READER_SUBCARRIER_848_KHZ (0<<3) +#define FPGA_HF_READER_SUBCARRIER_424_KHZ (1<<3) +#define FPGA_HF_READER_SUBCARRIER_212_KHZ (2<<3) // Options for the HF simulated tag, how to modulate #define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 5e770a77..f276158f 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -18,8 +18,9 @@ #include "string.h" #include "iso14443crc.h" #include "fpgaloader.h" +#include "BigBuf.h" -#define RECEIVE_SAMPLES_TIMEOUT 1000 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA. 1000 seems to be much too high? +#define RECEIVE_SAMPLES_TIMEOUT 64 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA #define ISO14443B_DMA_BUFFER_SIZE 128 // PCB Block number for APDUs @@ -692,7 +693,7 @@ static void DemodInit(uint8_t *data) * Demodulate the samples we received from the tag, also log to tracebuffer * quiet: set to 'true' to disable debug output */ -static void GetSamplesFor14443bDemod(int n, bool quiet) +static void GetSamplesFor14443bDemod(int timeout, bool quiet) { int maxBehindBy = 0; bool gotFrame = false; @@ -716,7 +717,7 @@ static void GetSamplesFor14443bDemod(int n, bool quiet) while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) // Setup and start DMA. - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE); uint16_t *upTo = dmaBuf; @@ -725,7 +726,7 @@ static void GetSamplesFor14443bDemod(int n, bool quiet) // Signal field is ON with the appropriate LED: LED_D_ON(); // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); for(;;) { int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1); @@ -754,7 +755,8 @@ static void GetSamplesFor14443bDemod(int n, bool quiet) break; } - if(samples > n) { + if(samples > timeout && Demod.state < DEMOD_PHASE_REF_TRAINING) { + LED_C_OFF(); break; } } @@ -774,28 +776,21 @@ static void GetSamplesFor14443bDemod(int n, bool quiet) //----------------------------------------------------------------------------- static void TransmitFor14443b(void) { - int c; - - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX); - - // Signal field is ON with the appropriate Red LED - LED_D_ON(); - // Signal we are transmitting with the Green LED + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); LED_B_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); - - c = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = ~ToSend[c]; - c++; - if(c >= ToSendMax) { - break; - } + for(int c = 0; c < ToSendMax; c++) { + uint8_t data = ToSend[c]; + for (int i = 0; i < 8; i++) { + uint16_t send_word = (data & 0x80) ? 0x0000 : 0xffff; + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; + AT91C_BASE_SSC->SSC_THR = send_word; + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; + AT91C_BASE_SSC->SSC_THR = send_word; + data <<= 1; } WDT_HIT(); } - LED_B_OFF(); // Finished sending + LED_B_OFF(); } @@ -942,13 +937,13 @@ int iso14443b_select_card() void iso14443b_setup() { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Set up the synchronous serial port - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // connect Demodulated Signal to ADC: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // Signal field is on with the appropriate LED LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); DemodReset(); UartReset(); @@ -976,12 +971,12 @@ void ReadSTMemoryIso14443b(uint32_t dwLast) SpinDelay(200); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // Now give it time to spin up. // Signal field is on with the appropriate LED LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); SpinDelay(200); clear_trace(); @@ -1143,15 +1138,15 @@ void RAMFUNC SnoopIso14443b(void) Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE); Dbprintf(" DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE); - // Signal field is off, no reader signal, no tag signal - LEDsoff(); + // Signal field is off + LED_D_OFF(); // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_SNOOP_IQ); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // Setup for the DMA. - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); upTo = dmaBuf; lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE); @@ -1255,12 +1250,14 @@ void RAMFUNC SnoopIso14443b(void) */ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, uint8_t data[]) { + LED_A_ON(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // switch field on and give tag some time to power up LED_D_ON(); - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); SpinDelay(10); if (datalen){ @@ -1282,5 +1279,7 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); } + + LED_A_OFF(); } diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index de6faa92..3326ab12 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -10,12 +10,18 @@ // Routines to support ISO 14443 type B. //----------------------------------------------------------------------------- -#ifndef __ISO14443B_H -#define __ISO14443B_H -#include "common.h" +#ifndef ISO14443B_H__ +#define ISO14443B_H__ -int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); -void iso14443b_setup(); -int iso14443b_select_card(); +#include +#include + +extern int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); +extern void iso14443b_setup(); +extern int iso14443b_select_card(); +extern void SimulateIso14443bTag(void); +extern void ReadSTMemoryIso14443b(uint32_t); +extern void SnoopIso14443b(void); +extern void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]); #endif /* __ISO14443B_H */ diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index d988e2b9..e3524375 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -80,11 +80,14 @@ static int DEBUG = 0; #define ISO15693_MAX_RESPONSE_LENGTH 36 // allows read single block with the maximum block size of 256bits. Read multiple blocks not supported yet #define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet -// timing. Delays in SSP_CLK ticks. -#define DELAY_READER_TO_ARM 8 -#define DELAY_ARM_TO_READER 1 -#define DELAY_ISO15693_VCD_TO_VICC 132 // 132/423.75kHz = 311.5us from end of EOF to start of tag response -#define DELAY_ISO15693_VICC_TO_VCD 1017 // 1017/3.39MHz = 300us between end of tag response and next reader command +// timing. Delays in SSP_CLK ticks. +// SSP_CLK runs at 13,56MHz / 32 = 423.75kHz when simulating a tag +#define DELAY_READER_TO_ARM_SIM 8 +#define DELAY_ARM_TO_READER_SIM 1 +#define DELAY_ISO15693_VCD_TO_VICC_SIM 132 // 132/423.75kHz = 311.5us from end of command EOF to start of tag response +//SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when acting as reader +#define DELAY_ISO15693_VCD_TO_VICC_READER 1056 // 1056/3,39MHz = 311.5us from end of command EOF to start of tag response +#define DELAY_ISO15693_VICC_TO_VCD_READER 1017 // 1017/3.39MHz = 300us between end of tag response and next reader command // --------------------------- // Signal Processing @@ -269,22 +272,28 @@ static void CodeIso15693AsTag(uint8_t *cmd, int n) // Transmit the command (to the tag) that was placed in cmd[]. static void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t start_time) { - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_FULL_MOD); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); - while (GetCountSspClk() < start_time); + while (GetCountSspClk() < start_time) ; LED_B_ON(); - for(int c = 0; c < len; ) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = ~cmd[c]; - c++; - } - WDT_HIT(); - } + for(int c = 0; c < len; c++) { + uint8_t data = cmd[c]; + for (int i = 0; i < 8; i++) { + uint16_t send_word = (data & 0x80) ? 0x0000 : 0xffff; + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; + AT91C_BASE_SSC->SSC_THR = send_word; + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; + AT91C_BASE_SSC->SSC_THR = send_word; + data <<= 1; + } + WDT_HIT(); + } LED_B_OFF(); } + //----------------------------------------------------------------------------- // Transmit the tag response (to the reader) that was placed in cmd[]. //----------------------------------------------------------------------------- @@ -562,10 +571,10 @@ static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int tim while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_AMPLITUDE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); // Setup and start DMA. - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE); uint16_t *upTo = dmaBuf; @@ -927,7 +936,7 @@ static int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint3 for (int i = 7; i >= 0; i--) { if (Handle15693SampleFromReader((b >> i) & 0x01, &DecodeReader)) { - *eof_time = bit_time + samples - DELAY_READER_TO_ARM; // end of EOF + *eof_time = bit_time + samples - DELAY_READER_TO_ARM_SIM; // end of EOF gotFrame = true; break; } @@ -954,7 +963,7 @@ static int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint3 samples, gotFrame, DecodeReader.state, DecodeReader.byteCount, DecodeReader.bitCount, DecodeReader.posCount); if (DecodeReader.byteCount > 0) { - LogTrace(DecodeReader.output, DecodeReader.byteCount, 0, 0, NULL, true); + LogTrace(DecodeReader.output, DecodeReader.byteCount, 0, *eof_time, NULL, true); } return DecodeReader.byteCount; @@ -997,34 +1006,23 @@ void AcquireRawAdcSamplesIso15693(void) uint8_t *dest = BigBuf_get_addr(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - BuildIdentifyRequest(); - + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + BuildIdentifyRequest(); + // Give the tags time to energize LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(100); // Now send the command - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); - - LED_B_ON(); - for(int c = 0; c < ToSendMax; ) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = ~ToSend[c]; - c++; - } - WDT_HIT(); - } - LED_B_OFF(); + TransmitTo15693Tag(ToSend, ToSendMax, 0); // wait for last transfer to complete - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); + while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) ; - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_AMPLITUDE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); for(int c = 0; c < 4000; ) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { @@ -1047,7 +1045,6 @@ void SnoopIso15693(void) clear_trace(); set_tracing(true); - // The DMA buffer, used to stream samples from the FPGA uint16_t* dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t)); uint16_t *upTo; @@ -1072,13 +1069,13 @@ void SnoopIso15693(void) Dbprintf(" tag -> Reader: %i bytes", ISO15693_MAX_RESPONSE_LENGTH); Dbprintf(" DMA: %i bytes", ISO15693_DMA_BUFFER_SIZE * sizeof(uint16_t)); } - Dbprintf("Snoop started. Press button to stop."); + Dbprintf("Snoop started. Press PM3 Button to stop."); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_SNOOP | FPGA_HF_READER_RX_XCORR_AMPLITUDE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNOOP_AMPLITUDE); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // Setup for the DMA. - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); upTo = dmaBuf; FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE); @@ -1173,7 +1170,6 @@ void SnoopIso15693(void) // Initialize the proxmark as iso15k reader -// (this might produces glitches that confuse some tags static void Iso15693InitReader() { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Setup SSC @@ -1185,11 +1181,11 @@ static void Iso15693InitReader() { SpinDelay(10); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // Give the tags time to energize LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER); SpinDelay(250); } @@ -1284,7 +1280,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *recv, // Now wait for a response if (recv != NULL) { - answerLen = GetIso15693AnswerFromTag(recv, max_recv_len, DELAY_ISO15693_VCD_TO_VICC * 2); + answerLen = GetIso15693AnswerFromTag(recv, max_recv_len, DELAY_ISO15693_VCD_TO_VICC_READER * 2); } LED_A_OFF(); @@ -1368,10 +1364,10 @@ void SetDebugIso15693(uint32_t debug) { } -//----------------------------------------------------------------------------- -// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector +//--------------------------------------------------------------------------------------- +// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector. // all demodulation performed in arm rather than host. - greg -//----------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- void ReaderIso15693(uint32_t parameter) { LEDsoff(); @@ -1388,7 +1384,7 @@ void ReaderIso15693(uint32_t parameter) SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // Setup SSC - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // Start from off (no field generated) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1396,7 +1392,7 @@ void ReaderIso15693(uint32_t parameter) // Give the tags time to energize LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER); SpinDelay(200); StartCountSspClk(); @@ -1407,10 +1403,10 @@ void ReaderIso15693(uint32_t parameter) // Now send the IDENTIFY command BuildIdentifyRequest(); TransmitTo15693Tag(ToSend, ToSendMax, 0); - + // Now wait for a response - answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC * 2) ; - uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD; + answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC_READER * 2) ; + uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER; if (answerLen >=12) // we should do a better check than this { @@ -1446,22 +1442,17 @@ void ReaderIso15693(uint32_t parameter) // read all pages if (answerLen >= 12 && DEBUG) { - - // debugptr = BigBuf_get_addr(); - - int i = 0; - while (i < 32) { // sanity check, assume max 32 pages + for (int i = 0; i < 32; i++) { // sanity check, assume max 32 pages BuildReadBlockRequest(TagUID, i); TransmitTo15693Tag(ToSend, ToSendMax, start_time); - int answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC * 2); - start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD; + int answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC_READER * 2); + start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER; if (answerLen > 0) { Dbprintf("READ SINGLE BLOCK %d returned %d octets:", i, answerLen); DbdecodeIso15693Answer(answerLen, answer); Dbhexdump(answerLen, answer, false); if ( *((uint32_t*) answer) == 0x07160101 ) break; // exit on NoPageErr } - i++; } } @@ -1501,7 +1492,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) if ((cmd_len >= 5) && (cmd[0] & ISO15693_REQ_INVENTORY) && (cmd[1] == ISO15693_INVENTORY)) { // TODO: check more flags bool slow = !(cmd[0] & ISO15693_REQ_DATARATE_HIGH); - start_time = eof_time + DELAY_ISO15693_VCD_TO_VICC - DELAY_ARM_TO_READER; + start_time = eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM - DELAY_ARM_TO_READER_SIM; TransmitTo15693Reader(ToSend, ToSendMax, start_time, slow); } @@ -1509,6 +1500,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) Dbhexdump(cmd_len, cmd, false); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -1536,7 +1528,7 @@ void BruteforceIso15693Afi(uint32_t speed) data[2] = 0; // mask length datalen = AddCrc(data,3); recvlen = SendDataTag(data, datalen, false, speed, recv, sizeof(recv), 0); - uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VCD_TO_VICC; + uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER; WDT_HIT(); if (recvlen>=12) { Dbprintf("NoAFI UID=%s", sprintUID(NULL, &recv[2])); @@ -1553,7 +1545,7 @@ void BruteforceIso15693Afi(uint32_t speed) data[2] = i & 0xFF; datalen = AddCrc(data,4); recvlen = SendDataTag(data, datalen, false, speed, recv, sizeof(recv), start_time); - start_time = GetCountSspClk() + DELAY_ISO15693_VCD_TO_VICC; + start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER; WDT_HIT(); if (recvlen >= 12) { Dbprintf("AFI=%i UID=%s", i, sprintUID(NULL, &recv[2])); @@ -1614,8 +1606,8 @@ static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid) uint8_t cmd[12]; uint16_t crc; - // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block - // followed by teh block data + // If we set the Option_Flag in this request, the VICC will respond with the security status of the block + // followed by the block data // one sub-carrier, inventory, 1 slot, fast rate cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit // System Information command code @@ -1645,8 +1637,8 @@ static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid) uint8_t cmd[14]; uint16_t crc; - // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block - // followed by teh block data + // If we set the Option_Flag in this request, the VICC will respond with the security status of the block + // followed by the block data // one sub-carrier, inventory, 1 slot, fast rate cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit // READ Multi BLOCK command code @@ -1679,8 +1671,8 @@ static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t C uint8_t cmd[14]; uint16_t crc; - // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block - // followed by teh block data + // If we set the Option_Flag in this request, the VICC will respond with the security status of the block + // followed by the block data // one sub-carrier, inventory, 1 slot, fast rate cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit // READ BLOCK command code @@ -1714,8 +1706,8 @@ static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], u uint8_t cmd[14]; uint16_t crc; - // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block - // followed by teh block data + // If we set the Option_Flag in this request, the VICC will respond with the security status of the block + // followed by the block data // one sub-carrier, inventory, 1 slot, fast rate cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit // READ BLOCK command code @@ -1731,7 +1723,7 @@ static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], u cmd[8] = 0x05; cmd[9]= 0xe0; // always e0 (not exactly unique) // Parameter - cmd[10] = 0x05; // for custom codes this must be manufcturer code + cmd[10] = 0x05; // for custom codes this must be manufacturer code cmd[11] = 0x00; // cmd[12] = 0x00; diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 947d6cd5..c848e647 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -152,7 +152,7 @@ static inline void tx_bit(bool bit) { //----------------------------------------------------------------------------- static void tx_frame(uint32_t frame, uint8_t len) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_FULL_MOD); // wait for next tx timeslot last_frame_end += RWD_FRAME_WAIT; @@ -173,9 +173,7 @@ static void tx_frame(uint32_t frame, uint8_t len) { } static uint32_t rx_frame(uint8_t len) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR - | FPGA_HF_READER_RX_XCORR_848_KHZ - | FPGA_HF_READER_RX_XCORR_QUARTER_FREQ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_212_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); // hold sampling until card is expected to respond last_frame_end += TAG_FRAME_WAIT; @@ -196,9 +194,7 @@ static uint32_t rx_frame(uint8_t len) { static bool rx_ack() { // change fpga into rx mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR - | FPGA_HF_READER_RX_XCORR_848_KHZ - | FPGA_HF_READER_RX_XCORR_QUARTER_FREQ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_212_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); // hold sampling until card is expected to respond last_frame_end += TAG_FRAME_WAIT; @@ -258,14 +254,12 @@ static int init_card(uint8_t cardtype, legic_card_select_t *p_card) { static void init_reader(bool clear_mem) { // configure FPGA FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR - | FPGA_HF_READER_RX_XCORR_848_KHZ - | FPGA_HF_READER_RX_XCORR_QUARTER_FREQ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_212_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); LED_D_ON(); // configure SSC with defaults - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // re-claim GPIO_SSC_DOUT as GPIO and enable output AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; diff --git a/fpga/Makefile b/fpga/Makefile index 70b0b5fe..01b848fb 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -1,11 +1,11 @@ -include ../common/Makefile.common +include ../common/Makefile.common # for $(DETECTED_OS) all: fpga_lf.bit fpga_hf.bit clean: $(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_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 hi_sniffer.v hi_get_trace.v +fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_reader.v hi_iso14443a.v hi_sniffer.v hi_get_trace.v $(DELETE) $@ $(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr diff --git a/fpga/fpga.ucf b/fpga/fpga.ucf index f20e2da0..545ce5d0 100644 --- a/fpga/fpga.ucf +++ b/fpga/fpga.ucf @@ -1,38 +1,38 @@ # See the schematic for the pin assignment. -NET "adc_d<0>" LOC = "P62" ; -NET "adc_d<1>" LOC = "P60" ; -NET "adc_d<2>" LOC = "P58" ; -NET "adc_d<3>" LOC = "P57" ; -NET "adc_d<4>" LOC = "P56" ; -NET "adc_d<5>" LOC = "P55" ; -NET "adc_d<6>" LOC = "P54" ; -NET "adc_d<7>" LOC = "P53" ; -#NET "cross_hi" LOC = "P88" ; -#NET "miso" LOC = "P40" ; +NET "adc_d<0>" LOC = "P62" ; +NET "adc_d<1>" LOC = "P60" ; +NET "adc_d<2>" LOC = "P58" ; +NET "adc_d<3>" LOC = "P57" ; +NET "adc_d<4>" LOC = "P56" ; +NET "adc_d<5>" LOC = "P55" ; +NET "adc_d<6>" LOC = "P54" ; +NET "adc_d<7>" LOC = "P53" ; +NET "cross_hi" LOC = "P88" ; +#NET "miso" LOC = "P40" ; #PACE: Start of Constraints generated by PACE #PACE: Start of PACE I/O Pin Assignments -NET "adc_clk" LOC = "P46" ; -NET "adc_noe" LOC = "P47" ; -NET "ck_1356meg" LOC = "P91" ; -NET "ck_1356megb" LOC = "P93" ; -NET "cross_lo" LOC = "P87" ; -NET "dbg" LOC = "P22" ; -NET "mosi" LOC = "P43" ; -NET "ncs" LOC = "P44" ; -NET "pck0" LOC = "P36" ; -NET "pwr_hi" LOC = "P80" ; -NET "pwr_lo" LOC = "P81" ; -NET "pwr_oe1" LOC = "P82" ; -NET "pwr_oe2" LOC = "P83" ; -NET "pwr_oe3" LOC = "P84" ; -NET "pwr_oe4" LOC = "P86" ; -NET "spck" LOC = "P39" ; -NET "ssp_clk" LOC = "P71" ; -NET "ssp_din" LOC = "P32" ; -NET "ssp_dout" LOC = "P34" ; -NET "ssp_frame" LOC = "P31" ; +NET "adc_clk" LOC = "P46" ; +NET "adc_noe" LOC = "P47" ; +NET "ck_1356meg" LOC = "P91" ; +NET "ck_1356megb" LOC = "P93" ; +NET "cross_lo" LOC = "P87" ; +NET "dbg" LOC = "P22" ; +NET "mosi" LOC = "P43" ; +NET "ncs" LOC = "P44" ; +NET "pck0" LOC = "P36" ; +NET "pwr_hi" LOC = "P80" ; +NET "pwr_lo" LOC = "P81" ; +NET "pwr_oe1" LOC = "P82" ; +NET "pwr_oe2" LOC = "P83" ; +NET "pwr_oe3" LOC = "P84" ; +NET "pwr_oe4" LOC = "P86" ; +NET "spck" LOC = "P39" ; +NET "ssp_clk" LOC = "P71" ; +NET "ssp_din" LOC = "P32" ; +NET "ssp_dout" LOC = "P34" ; +NET "ssp_frame" LOC = "P31" ; #PACE: Start of PACE Area Constraints diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit index 2ea2c24e..665f7bcb 100644 Binary files a/fpga/fpga_hf.bit and b/fpga/fpga_hf.bit differ diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index ef935260..01c6ebb2 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -13,8 +13,47 @@ // iZsh , June 2014 //----------------------------------------------------------------------------- -`include "hi_read_tx.v" -`include "hi_read_rx_xcorr.v" +// Defining modes and options. This must be aligned to the definitions in fpgaloader.h +// Note: the definitions here are without shifts +// Major modes: +`define FPGA_MAJOR_MODE_LF_ADC 0 +`define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 +`define FPGA_MAJOR_MODE_LF_PASSTHRU 2 +`define FPGA_MAJOR_MODE_HF_READER 0 +`define FPGA_MAJOR_MODE_HF_SIMULATOR 1 +`define FPGA_MAJOR_MODE_HF_ISO14443A 2 +`define FPGA_MAJOR_MODE_HF_SNOOP 3 +`define FPGA_MAJOR_MODE_HF_GET_TRACE 4 +`define FPGA_MAJOR_MODE_OFF 7 + +// Options for the generic HF reader +`define FPGA_HF_READER_MODE_RECEIVE_IQ 0 +`define FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE 1 +`define FPGA_HF_READER_MODE_RECEIVE_PHASE 2 +`define FPGA_HF_READER_MODE_SEND_FULL_MOD 3 +`define FPGA_HF_READER_MODE_SEND_SHALLOW_MOD 4 +`define FPGA_HF_READER_MODE_SNIFF_IQ 5 +`define FPGA_HF_READER_MODE_SNIFF_AMPLITUDE 6 +`define FPGA_HF_READER_MODE_SNIFF_PHASE 7 +`define FPGA_HF_READER_SUBCARRIER_848_KHZ 0 +`define FPGA_HF_READER_SUBCARRIER_424_KHZ 1 +`define FPGA_HF_READER_SUBCARRIER_212_KHZ 2 + +// Options for the HF simulated tag, how to modulate +`define FPGA_HF_SIMULATOR_NO_MODULATION 0 +`define FPGA_HF_SIMULATOR_MODULATE_BPSK 1 +`define FPGA_HF_SIMULATOR_MODULATE_212K 2 +`define FPGA_HF_SIMULATOR_MODULATE_424K 4 +`define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 5 + +// Options for ISO14443A +`define FPGA_HF_ISO14443A_SNIFFER 0 +`define FPGA_HF_ISO14443A_TAGSIM_LISTEN 1 +`define FPGA_HF_ISO14443A_TAGSIM_MOD 2 +`define FPGA_HF_ISO14443A_READER_LISTEN 3 +`define FPGA_HF_ISO14443A_READER_MOD 4 + +`include "hi_reader.v" `include "hi_simulate.v" `include "hi_iso14443a.v" `include "hi_sniffer.v" @@ -49,8 +88,8 @@ reg trace_enable; always @(posedge ncs) begin case(shift_reg[15:12]) - 4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG - 4'b0010: trace_enable <= shift_reg[0]; // FPGA_CMD_TRACE_ENABLE + 4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG + 4'b0010: trace_enable <= shift_reg[0]; // FPGA_CMD_TRACE_ENABLE endcase end @@ -63,26 +102,12 @@ begin 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 subcarrier frequency by 4 -wire hi_read_rx_xcorr_quarter = conf_word[2]; -// send amplitude only instead of ci/cq pair -wire hi_read_rx_xcorr_amplitude = conf_word[3]; +// select module (outputs) based on major mode +wire [2:0] major_mode = conf_word[7:5]; -// For the high-frequency simulated tag: what kind of modulation to use. -wire [2:0] hi_simulate_mod_type = conf_word[2:0]; +// configuring the HF reader +wire [1:0] subcarrier_frequency = conf_word[4:3]; +wire [2:0] minor_mode = conf_word[2:0]; //----------------------------------------------------------------------------- // And then we instantiate the modules corresponding to each of the FPGA's @@ -90,85 +115,71 @@ wire [2:0] hi_simulate_mod_type = conf_word[2:0]; // 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_read_rx_xcorr_amplitude +hi_reader hr( + ck_1356megb, + hr_pwr_lo, hr_pwr_hi, hr_pwr_oe1, hr_pwr_oe2, hr_pwr_oe3, hr_pwr_oe4, + adc_d, hr_adc_clk, + hr_ssp_frame, hr_ssp_din, ssp_dout, hr_ssp_clk, + hr_dbg, + subcarrier_frequency, minor_mode ); hi_simulate hs( - pck0, ck_1356meg, ck_1356megb, + ck_1356meg, 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 + minor_mode ); 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, + ck_1356meg, + 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 + minor_mode ); hi_sniffer he( - pck0, ck_1356meg, ck_1356megb, - he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3, he_pwr_oe4, - adc_d, he_adc_clk, - he_ssp_frame, he_ssp_din, ssp_dout, he_ssp_clk, - cross_hi, cross_lo, - he_dbg, - hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter + ck_1356megb, + he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3, he_pwr_oe4, + adc_d, he_adc_clk, + he_ssp_frame, he_ssp_din, he_ssp_clk ); hi_get_trace gt( - ck_1356megb, - adc_d, trace_enable, major_mode, - gt_ssp_frame, gt_ssp_din, gt_ssp_clk + ck_1356megb, + adc_d, trace_enable, major_mode, + gt_ssp_frame, gt_ssp_din, gt_ssp_clk ); // 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 -// 100 -- HF Snoop -// 101 -- HF get trace +// 000 -- HF reader; subcarrier frequency and modulation depth selectable +// 001 -- HF simulated tag +// 010 -- HF ISO14443-A +// 011 -- HF Snoop +// 100 -- HF get trace // 111 -- everything off -mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, gt_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, gt_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, gt_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, 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, he_pwr_oe2, 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, he_pwr_oe3, 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, he_pwr_oe4, 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, he_pwr_lo, 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, he_pwr_hi, 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, he_adc_clk, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_clk (major_mode, ssp_clk, hr_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, gt_ssp_clk, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, hr_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, gt_ssp_din, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, hr_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, gt_ssp_frame, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, hr_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, hr_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, hr_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, hr_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, hr_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, hr_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, hr_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, hr_dbg, hs_dbg, hisn_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; +// not used +assign miso = 1'b0; + endmodule diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v index 7acecf80..3e7412f7 100644 --- a/fpga/hi_get_trace.v +++ b/fpga/hi_get_trace.v @@ -14,11 +14,6 @@ module hi_get_trace( input [2:0] major_mode; output ssp_frame, ssp_din, ssp_clk; -// constants for some major_modes: -`define OFF 3'b111 -`define GET_TRACE 3'b101 - - // clock divider reg [6:0] clock_cnt; always @(negedge ck_1356megb) @@ -30,7 +25,7 @@ end reg [2:0] sample_clock; always @(negedge ck_1356megb) begin - if (sample_clock == 3'd3) + if (sample_clock == 3'd7) sample_clock <= 3'd0; else sample_clock <= sample_clock + 1; @@ -45,11 +40,11 @@ reg write_enable2; always @(negedge ck_1356megb) begin previous_major_mode <= major_mode; - if (major_mode == `GET_TRACE) + if (major_mode == `FPGA_MAJOR_MODE_HF_GET_TRACE) begin write_enable1 <= 1'b0; write_enable2 <= 1'b0; - if (previous_major_mode != `GET_TRACE) // just switched into GET_TRACE mode + if (previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched into GET_TRACE mode addr <= start_addr; if (clock_cnt == 7'd0) begin @@ -59,7 +54,7 @@ begin addr <= addr + 1; end end - else if (major_mode != `OFF) + else if (major_mode != `FPGA_MAJOR_MODE_OFF) begin if (trace_enable) begin @@ -92,11 +87,11 @@ begin start_addr <= addr; end end - else // major_mode == `OFF + else // major_mode == `FPGA_MAJOR_MODE_OFF begin write_enable1 <= 1'b0; write_enable2 <= 1'b0; - if (previous_major_mode != `OFF && previous_major_mode != `GET_TRACE) // just switched off + if (previous_major_mode != `FPGA_MAJOR_MODE_OFF && previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched off start_addr <= addr; end end diff --git a/fpga/hi_iso14443a.v b/fpga/hi_iso14443a.v index b1b7b141..e460a2cc 100644 --- a/fpga/hi_iso14443a.v +++ b/fpga/hi_iso14443a.v @@ -3,29 +3,20 @@ // Gerhard de Koning Gans, April 2008 //----------------------------------------------------------------------------- -// constants for the different modes: -`define SNIFFER 3'b000 -`define TAGSIM_LISTEN 3'b001 -`define TAGSIM_MOD 3'b010 -`define READER_LISTEN 3'b011 -`define READER_MOD 3'b100 - module hi_iso14443a( - pck0, ck_1356meg, ck_1356megb, + ck_1356meg, 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, mod_type ); - input pck0, ck_1356meg, ck_1356megb; + input ck_1356meg; 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 [2:0] mod_type; @@ -151,7 +142,7 @@ begin end // adjust internal timer counter if necessary: - if (negedge_cnt[3:0] == 4'd13 && (mod_type == `SNIFFER || mod_type == `TAGSIM_LISTEN) && deep_modulation) + if (negedge_cnt[3:0] == 4'd13 && (mod_type == `FPGA_HF_ISO14443A_SNIFFER || mod_type == `FPGA_HF_ISO14443A_TAGSIM_LISTEN) && deep_modulation) begin if (reader_falling_edge_time == 4'd1) // reader signal changes right after sampling. Better sample earlier next time. begin @@ -185,7 +176,7 @@ reg [3:0] mod_detect_reset_time; always @(negedge adc_clk) begin - if (mod_type == `READER_LISTEN) + if (mod_type == `FPGA_HF_ISO14443A_READER_LISTEN) // (our) reader signal changes at negedge_cnt[3:0]=9, tag response expected to start n*16+4 ticks later, further delayed by // 3 ticks ADC conversion. The maximum filter output (edge detected) will be detected after subcarrier zero crossing (+7 ticks). // To allow some timing variances, we want to have the maximum filter outputs well within the detection window, i.e. @@ -195,7 +186,7 @@ begin mod_detect_reset_time <= 4'd4; end else - if (mod_type == `SNIFFER) + if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) begin // detect a rising edge of reader's signal and sync modulation detector to the tag's answer: if (~pre_after_hysteresis && after_hysteresis && deep_modulation) @@ -320,7 +311,7 @@ reg [3:0] sub_carrier_cnt; // response window of 1128 - 774 = 354 ticks. // reset on a pause in listen mode. I.e. the counter starts when the pause is over: -assign fdt_reset = ~after_hysteresis && mod_type == `TAGSIM_LISTEN; +assign fdt_reset = ~after_hysteresis && mod_type == `FPGA_HF_ISO14443A_TAGSIM_LISTEN; always @(negedge adc_clk) begin @@ -363,7 +354,7 @@ reg mod_sig_coil; always @(negedge adc_clk) begin - if (mod_type == `TAGSIM_MOD) // need to take care of proper fdt timing + if (mod_type == `FPGA_HF_ISO14443A_TAGSIM_MOD) // need to take care of proper fdt timing begin if(fdt_counter == `FDT_COUNT) begin @@ -438,7 +429,7 @@ always @(negedge adc_clk) begin if (negedge_cnt[5:0] == 6'd63) // fill the buffer begin - if (mod_type == `SNIFFER) + if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) begin if(deep_modulation) // a reader is sending (or there's no field at all) begin @@ -455,7 +446,7 @@ begin end end - if(negedge_cnt[2:0] == 3'b000 && mod_type == `SNIFFER) // shift at double speed + if(negedge_cnt[2:0] == 3'b000 && mod_type == `FPGA_HF_ISO14443A_SNIFFER) // shift at double speed begin // Don't shift if we just loaded new data, obviously. if(negedge_cnt[5:0] != 6'd0) @@ -464,7 +455,7 @@ begin end end - if(negedge_cnt[3:0] == 4'b0000 && mod_type != `SNIFFER) + if(negedge_cnt[3:0] == 4'b0000 && mod_type != `FPGA_HF_ISO14443A_SNIFFER) begin // Don't shift if we just loaded new data, obviously. if(negedge_cnt[6:0] != 7'd0) @@ -484,8 +475,8 @@ reg ssp_frame; always @(negedge adc_clk) begin - if(mod_type == `SNIFFER) - // SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)): + if(mod_type == `FPGA_HF_ISO14443A_SNIFFER) + // FPGA_HF_ISO14443A_SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)): begin if(negedge_cnt[2:0] == 3'd0) ssp_clk <= 1'b1; @@ -505,7 +496,7 @@ begin if(negedge_cnt[3:0] == 4'd8) ssp_clk <= 1'b0; - if(negedge_cnt[6:0] == 7'd7) // ssp_frame rising edge indicates start of frame + if(negedge_cnt[6:0] == 7'd7) // ssp_frame rising edge indicates start of frame, sampled on falling edge of ssp_clk ssp_frame <= 1'b1; if(negedge_cnt[6:0] == 7'd23) ssp_frame <= 1'b0; @@ -525,23 +516,23 @@ begin if(negedge_cnt[3:0] == 4'd0) begin // What do we communicate to the ARM - if(mod_type == `TAGSIM_LISTEN) + if(mod_type == `FPGA_HF_ISO14443A_TAGSIM_LISTEN) sendbit = after_hysteresis; - else if(mod_type == `TAGSIM_MOD) + else if(mod_type == `FPGA_HF_ISO14443A_TAGSIM_MOD) /* if(fdt_counter > 11'd772) sendbit = mod_sig_coil; // huh? else */ sendbit = fdt_indicator; - else if (mod_type == `READER_LISTEN) + else if (mod_type == `FPGA_HF_ISO14443A_READER_LISTEN) sendbit = curbit; else sendbit = 1'b0; end - if(mod_type == `SNIFFER) + if(mod_type == `FPGA_HF_ISO14443A_SNIFFER) // send sampled reader and tag data: bit_to_arm = to_arm[7]; - else if (mod_type == `TAGSIM_MOD && fdt_elapsed && temp_buffer_reset) + else if (mod_type == `FPGA_HF_ISO14443A_TAGSIM_MOD && fdt_elapsed && temp_buffer_reset) // send timing information: bit_to_arm = to_arm[7]; else @@ -554,22 +545,22 @@ end assign ssp_din = bit_to_arm; -// Subcarrier (adc_clk/16, for TAGSIM_MOD only). +// Subcarrier (adc_clk/16, for FPGA_HF_ISO14443A_TAGSIM_MOD only). wire sub_carrier; assign sub_carrier = ~sub_carrier_cnt[3]; -// in READER_MOD: drop carrier for mod_sig_coil==1 (pause); in READER_LISTEN: carrier always on; in other modes: carrier always off -assign pwr_hi = (ck_1356megb & (((mod_type == `READER_MOD) & ~mod_sig_coil) || (mod_type == `READER_LISTEN))); +// in FPGA_HF_ISO14443A_READER_MOD: drop carrier for mod_sig_coil==1 (pause); in FPGA_HF_ISO14443A_READER_LISTEN: carrier always on; in other modes: carrier always off +assign pwr_hi = (ck_1356meg & (((mod_type == `FPGA_HF_ISO14443A_READER_MOD) & ~mod_sig_coil) || (mod_type == `FPGA_HF_ISO14443A_READER_LISTEN))); // Enable HF antenna drivers: assign pwr_oe1 = 1'b0; assign pwr_oe3 = 1'b0; -// TAGSIM_MOD: short circuit antenna with different resistances (modulated by sub_carrier modulated by mod_sig_coil) +// FPGA_HF_ISO14443A_TAGSIM_MOD: short circuit antenna with different resistances (modulated by sub_carrier modulated by mod_sig_coil) // for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms // for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms -assign pwr_oe4 = mod_sig_coil & sub_carrier & (mod_type == `TAGSIM_MOD); +assign pwr_oe4 = mod_sig_coil & sub_carrier & (mod_type == `FPGA_HF_ISO14443A_TAGSIM_MOD); // This is all LF, so doesn't matter. assign pwr_oe2 = 1'b0; diff --git a/fpga/hi_read_rx_xcorr.v b/fpga/hi_read_rx_xcorr.v deleted file mode 100644 index 503c8d67..00000000 --- a/fpga/hi_read_rx_xcorr.v +++ /dev/null @@ -1,271 +0,0 @@ -//----------------------------------------------------------------------------- -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -module hi_read_rx_xcorr( - 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, - xcorr_is_848, snoop, xcorr_quarter_freq, hi_read_rx_xcorr_amplitude -); - 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 xcorr_is_848, snoop, xcorr_quarter_freq, hi_read_rx_xcorr_amplitude; - -// Carrier is steady on through this, unless we're snooping. -assign pwr_hi = ck_1356megb & (~snoop); -assign pwr_oe1 = 1'b0; -assign pwr_oe3 = 1'b0; -assign pwr_oe4 = 1'b0; -// Unused. -assign pwr_lo = 1'b0; -assign pwr_oe2 = 1'b0; - -assign adc_clk = ck_1356megb; // sample frequency is 13,56 MHz - -// When we're a reader, we just need to do the BPSK demod; but when we're an -// eavesdropper, we also need to pick out the commands sent by the reader, -// using AM. Do this the same way that we do it for the simulated tag. -reg after_hysteresis, after_hysteresis_prev, after_hysteresis_prev_prev; -reg [11:0] has_been_low_for; -always @(negedge adc_clk) -begin - if(& adc_d[7:0]) after_hysteresis <= 1'b1; - else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0; - - if(after_hysteresis) - begin - has_been_low_for <= 7'b0; - end - else - begin - if(has_been_low_for == 12'd4095) - begin - has_been_low_for <= 12'd0; - after_hysteresis <= 1'b1; - end - else - has_been_low_for <= has_been_low_for + 1; - end -end - - -// Let us report a correlation every 64 samples. I.e. -// one Q/I pair after 4 subcarrier cycles for the 848kHz subcarrier, -// one Q/I pair after 2 subcarrier cycles for the 424kHz subcarriers, -// one Q/I pair for each subcarrier cyle for the 212kHz subcarrier. -// We need a 6-bit counter for the timing. -reg [5:0] corr_i_cnt; -always @(negedge adc_clk) -begin - corr_i_cnt <= corr_i_cnt + 1; -end - -// And a couple of registers in which to accumulate the correlations. From the 64 samples -// we would add at most 32 times the difference between unmodulated and modulated signal. It should -// be safe to assume that a tag will not be able to modulate the carrier signal by more than 25%. -// 32 * 255 * 0,25 = 2040, which can be held in 11 bits. Add 1 bit for sign. -// Temporary we might need more bits. For the 212kHz subcarrier we could possible add 32 times the -// maximum signal value before a first subtraction would occur. 32 * 255 = 8160 can be held in 13 bits. -// Add one bit for sign -> need 14 bit registers but final result will fit into 12 bits. -reg signed [13:0] corr_i_accum; -reg signed [13:0] corr_q_accum; -// we will report maximum 8 significant bits -reg signed [7:0] corr_i_out; -reg signed [7:0] corr_q_out; - -// clock and frame signal for communication to ARM -reg ssp_clk; -reg ssp_frame; - - - -// the amplitude of the subcarrier is sqrt(ci^2 + cq^2). -// approximate by amplitude = max(|ci|,|cq|) + 1/2*min(|ci|,|cq|) -reg [13:0] corr_amplitude, abs_ci, abs_cq, max_ci_cq, min_ci_cq; - - -always @(corr_i_accum or corr_q_accum) -begin - if (corr_i_accum[13] == 1'b0) - abs_ci <= corr_i_accum; - else - abs_ci <= -corr_i_accum; - - if (corr_q_accum[13] == 1'b0) - abs_cq <= corr_q_accum; - else - abs_cq <= -corr_q_accum; - - if (abs_ci > abs_cq) - begin - max_ci_cq <= abs_ci; - min_ci_cq <= abs_cq; - end - else - begin - max_ci_cq <= abs_cq; - min_ci_cq <= abs_ci; - end - - corr_amplitude <= max_ci_cq + min_ci_cq/2; - -end - - -// The subcarrier reference signals -reg subcarrier_I; -reg subcarrier_Q; - -always @(corr_i_cnt or xcorr_is_848 or xcorr_quarter_freq) -begin - if (xcorr_is_848 & ~xcorr_quarter_freq) // 848 kHz - begin - subcarrier_I = ~corr_i_cnt[3]; - subcarrier_Q = ~(corr_i_cnt[3] ^ corr_i_cnt[2]); - end - else if (xcorr_is_848 & xcorr_quarter_freq) // 212 kHz - begin - subcarrier_I = ~corr_i_cnt[5]; - subcarrier_Q = ~(corr_i_cnt[5] ^ corr_i_cnt[4]); - end - else - begin // 424 kHz - subcarrier_I = ~corr_i_cnt[4]; - subcarrier_Q = ~(corr_i_cnt[4] ^ corr_i_cnt[3]); - end -end - - -// ADC data appears on the rising edge, so sample it on the falling edge -always @(negedge adc_clk) -begin - // These are the correlators: we correlate against in-phase and quadrature - // versions of our reference signal, and keep the (signed) results or the - // resulting amplitude to send out later over the SSP. - if(corr_i_cnt == 6'd0) - begin - if(snoop) - begin - if (hi_read_rx_xcorr_amplitude) - begin - // send amplitude plus 2 bits reader signal - corr_i_out <= corr_amplitude[13:6]; - corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev}; - end - else - begin - // Send 7 most significant bits of in phase tag signal (signed), plus 1 bit reader signal - if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) - corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev}; - else // truncate to maximum value - if (corr_i_accum[13] == 1'b0) - corr_i_out <= {7'b0111111, after_hysteresis_prev_prev}; - else - corr_i_out <= {7'b1000000, after_hysteresis_prev_prev}; - // Send 7 most significant bits of quadrature phase tag signal (signed), plus 1 bit reader signal - if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111) - corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev}; - else // truncate to maximum value - if (corr_q_accum[13] == 1'b0) - corr_q_out <= {7'b0111111, after_hysteresis_prev}; - else - corr_q_out <= {7'b1000000, after_hysteresis_prev}; - end - end - else - begin - if (hi_read_rx_xcorr_amplitude) - begin - // send amplitude - corr_i_out <= {2'b00, corr_amplitude[13:8]}; - corr_q_out <= corr_amplitude[7:0]; - end - else - begin - // Send 8 bits of in phase tag signal - if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) - corr_i_out <= corr_i_accum[11:4]; - else // truncate to maximum value - if (corr_i_accum[13] == 1'b0) - corr_i_out <= 8'b01111111; - else - corr_i_out <= 8'b10000000; - // Send 8 bits of quadrature phase tag signal - if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111) - corr_q_out <= corr_q_accum[11:4]; - else // truncate to maximum value - if (corr_q_accum[13] == 1'b0) - corr_q_out <= 8'b01111111; - else - corr_q_out <= 8'b10000000; - end - end - - // for each Q/I pair report two reader signal samples when sniffing. Store the 1st. - after_hysteresis_prev_prev <= after_hysteresis; - // Initialize next correlation. - // Both I and Q reference signals are high when corr_i_nct == 0. Therefore need to accumulate. - corr_i_accum <= $signed({1'b0,adc_d}); - corr_q_accum <= $signed({1'b0,adc_d}); - end - else - begin - if (subcarrier_I) - corr_i_accum <= corr_i_accum + $signed({1'b0,adc_d}); - else - corr_i_accum <= corr_i_accum - $signed({1'b0,adc_d}); - - if (subcarrier_Q) - corr_q_accum <= corr_q_accum + $signed({1'b0,adc_d}); - else - corr_q_accum <= corr_q_accum - $signed({1'b0,adc_d}); - end - - // for each Q/I pair report two reader signal samples when sniffing. Store the 2nd. - if(corr_i_cnt == 6'd32) - after_hysteresis_prev <= after_hysteresis; - - // Then the result from last time is serialized and send out to the ARM. - // We get one report each cycle, and each report is 16 bits, so the - // ssp_clk should be the adc_clk divided by 64/16 = 4. - // ssp_clk frequency = 13,56MHz / 4 = 3.39MHz - - if(corr_i_cnt[1:0] == 2'b10) - ssp_clk <= 1'b0; - - if(corr_i_cnt[1:0] == 2'b00) - begin - ssp_clk <= 1'b1; - // Don't shift if we just loaded new data, obviously. - if(corr_i_cnt != 6'd0) - begin - corr_i_out[7:0] <= {corr_i_out[6:0], corr_q_out[7]}; - corr_q_out[7:1] <= corr_q_out[6:0]; - end - end - - // set ssp_frame signal for corr_i_cnt = 0..3 - // (send one frame with 16 Bits) - if(corr_i_cnt[5:2] == 4'b0000) - ssp_frame = 1'b1; - else - ssp_frame = 1'b0; - -end - -assign ssp_din = corr_i_out[7]; - -assign dbg = corr_i_cnt[3]; - -endmodule diff --git a/fpga/hi_read_tx.v b/fpga/hi_read_tx.v deleted file mode 100644 index 819f1697..00000000 --- a/fpga/hi_read_tx.v +++ /dev/null @@ -1,78 +0,0 @@ -//----------------------------------------------------------------------------- -// The way that we connect things when transmitting a command to an ISO -// 15693 tag, using 100% modulation only for now. -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -module hi_read_tx( - 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, - shallow_modulation -); - 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 shallow_modulation; - -// low frequency outputs, not relevant -assign pwr_lo = 1'b0; -assign pwr_oe2 = 1'b0; - -// The high-frequency stuff. For now, for testing, just bring out the carrier, -// and allow the ARM to modulate it over the SSP. -reg pwr_hi; -reg pwr_oe1; -reg pwr_oe3; -reg pwr_oe4; - -always @(ck_1356megb or ssp_dout or shallow_modulation) -begin - if(shallow_modulation) - begin - pwr_hi <= ck_1356megb; - pwr_oe1 <= 1'b0; - pwr_oe3 <= 1'b0; - pwr_oe4 <= ssp_dout; - end - else - begin - pwr_hi <= ck_1356megb & ~ssp_dout; - pwr_oe1 <= 1'b0; - pwr_oe3 <= 1'b0; - pwr_oe4 <= 1'b0; - end -end - - -// Then just divide the 13.56 MHz clock down to produce appropriate clocks -// for the synchronous serial port. - -reg [6:0] hi_div_by_128; - -always @(posedge ck_1356meg) - hi_div_by_128 <= hi_div_by_128 + 1; - -assign ssp_clk = hi_div_by_128[6]; - -reg [2:0] hi_byte_div; - -always @(negedge ssp_clk) - hi_byte_div <= hi_byte_div + 1; - -assign ssp_frame = (hi_byte_div == 3'b000); - -assign ssp_din = 1'b0; - -assign dbg = ssp_frame; - -endmodule \ No newline at end of file diff --git a/fpga/hi_reader.v b/fpga/hi_reader.v new file mode 100644 index 00000000..b0b21e30 --- /dev/null +++ b/fpga/hi_reader.v @@ -0,0 +1,300 @@ +//----------------------------------------------------------------------------- +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +module hi_reader( + ck_1356meg, + pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, + adc_d, adc_clk, + ssp_frame, ssp_din, ssp_dout, ssp_clk, + dbg, + subcarrier_frequency, minor_mode +); + input ck_1356meg; + 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; + output dbg; + input [1:0] subcarrier_frequency; + input [2:0] minor_mode; + +assign adc_clk = ck_1356meg; // sample frequency is 13,56 MHz + +// When we're a reader, we just need to do the BPSK demod; but when we're an +// eavesdropper, we also need to pick out the commands sent by the reader, +// using AM. Do this the same way that we do it for the simulated tag. +reg after_hysteresis, after_hysteresis_prev, after_hysteresis_prev_prev; +reg [11:0] has_been_low_for; +always @(negedge adc_clk) +begin + if(& adc_d[7:0]) after_hysteresis <= 1'b1; + else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0; + + if(after_hysteresis) + begin + has_been_low_for <= 7'b0; + end + else + begin + if(has_been_low_for == 12'd4095) + begin + has_been_low_for <= 12'd0; + after_hysteresis <= 1'b1; + end + else + has_been_low_for <= has_been_low_for + 1; + end +end + + +// Let us report a correlation every 64 samples. I.e. +// one Q/I pair after 4 subcarrier cycles for the 848kHz subcarrier, +// one Q/I pair after 2 subcarrier cycles for the 424kHz subcarriers, +// one Q/I pair for each subcarrier cyle for the 212kHz subcarrier. +// We need a 6-bit counter for the timing. +reg [5:0] corr_i_cnt; +always @(negedge adc_clk) +begin + corr_i_cnt <= corr_i_cnt + 1; +end + + +// A couple of registers in which to accumulate the correlations. From the 64 samples +// we would add at most 32 times the difference between unmodulated and modulated signal. It should +// be safe to assume that a tag will not be able to modulate the carrier signal by more than 25%. +// 32 * 255 * 0,25 = 2040, which can be held in 11 bits. Add 1 bit for sign. +// Temporary we might need more bits. For the 212kHz subcarrier we could possible add 32 times the +// maximum signal value before a first subtraction would occur. 32 * 255 = 8160 can be held in 13 bits. +// Add one bit for sign -> need 14 bit registers but final result will fit into 12 bits. +reg signed [13:0] corr_i_accum; +reg signed [13:0] corr_q_accum; +// we will report maximum 8 significant bits +reg signed [7:0] corr_i_out; +reg signed [7:0] corr_q_out; + + +// the amplitude of the subcarrier is sqrt(ci^2 + cq^2). +// approximate by amplitude = max(|ci|,|cq|) + 1/2*min(|ci|,|cq|) +reg [13:0] corr_amplitude, abs_ci, abs_cq, max_ci_cq; +reg [12:0] min_ci_cq_2; // min_ci_cq / 2 + +always @(*) +begin + if (corr_i_accum[13] == 1'b0) + abs_ci <= corr_i_accum; + else + abs_ci <= -corr_i_accum; + + if (corr_q_accum[13] == 1'b0) + abs_cq <= corr_q_accum; + else + abs_cq <= -corr_q_accum; + + if (abs_ci > abs_cq) + begin + max_ci_cq <= abs_ci; + min_ci_cq_2 <= abs_cq / 2; + end + else + begin + max_ci_cq <= abs_cq; + min_ci_cq_2 <= abs_ci / 2; + end + + corr_amplitude <= max_ci_cq + min_ci_cq_2; + +end + + +// The subcarrier reference signals +reg subcarrier_I; +reg subcarrier_Q; + +always @(*) +begin + if (subcarrier_frequency == `FPGA_HF_READER_SUBCARRIER_848_KHZ) + begin + subcarrier_I = ~corr_i_cnt[3]; + subcarrier_Q = ~(corr_i_cnt[3] ^ corr_i_cnt[2]); + end + else if (subcarrier_frequency == `FPGA_HF_READER_SUBCARRIER_212_KHZ) + begin + subcarrier_I = ~corr_i_cnt[5]; + subcarrier_Q = ~(corr_i_cnt[5] ^ corr_i_cnt[4]); + end + else + begin // 424 kHz + subcarrier_I = ~corr_i_cnt[4]; + subcarrier_Q = ~(corr_i_cnt[4] ^ corr_i_cnt[3]); + end +end + + +// ADC data appears on the rising edge, so sample it on the falling edge +always @(negedge adc_clk) +begin + // These are the correlators: we correlate against in-phase and quadrature + // versions of our reference signal, and keep the (signed) results or the + // resulting amplitude to send out later over the SSP. + if(corr_i_cnt == 6'd0) + begin + if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE) + begin + // send amplitude plus 2 bits reader signal + corr_i_out <= corr_amplitude[13:6]; + corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev}; + end + else if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_IQ) + begin + // Send 7 most significant bits of in phase tag signal (signed), plus 1 bit reader signal + if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) + corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev}; + else // truncate to maximum value + if (corr_i_accum[13] == 1'b0) + corr_i_out <= {7'b0111111, after_hysteresis_prev_prev}; + else + corr_i_out <= {7'b1000000, after_hysteresis_prev_prev}; + // Send 7 most significant bits of quadrature phase tag signal (signed), plus 1 bit reader signal + if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111) + corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev}; + else // truncate to maximum value + if (corr_q_accum[13] == 1'b0) + corr_q_out <= {7'b0111111, after_hysteresis_prev}; + else + corr_q_out <= {7'b1000000, after_hysteresis_prev}; + end + else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE) + begin + // send amplitude + corr_i_out <= {2'b00, corr_amplitude[13:8]}; + corr_q_out <= corr_amplitude[7:0]; + end + else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_IQ) + begin + // Send 8 bits of in phase tag signal + if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111) + corr_i_out <= corr_i_accum[11:4]; + else // truncate to maximum value + if (corr_i_accum[13] == 1'b0) + corr_i_out <= 8'b01111111; + else + corr_i_out <= 8'b10000000; + // Send 8 bits of quadrature phase tag signal + if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111) + corr_q_out <= corr_q_accum[11:4]; + else // truncate to maximum value + if (corr_q_accum[13] == 1'b0) + corr_q_out <= 8'b01111111; + else + corr_q_out <= 8'b10000000; + end + + // for each Q/I pair report two reader signal samples when sniffing. Store the 1st. + after_hysteresis_prev_prev <= after_hysteresis; + // Initialize next correlation. + // Both I and Q reference signals are high when corr_i_nct == 0. Therefore need to accumulate. + corr_i_accum <= $signed({1'b0,adc_d}); + corr_q_accum <= $signed({1'b0,adc_d}); + end + else + begin + if (subcarrier_I) + corr_i_accum <= corr_i_accum + $signed({1'b0,adc_d}); + else + corr_i_accum <= corr_i_accum - $signed({1'b0,adc_d}); + + if (subcarrier_Q) + corr_q_accum <= corr_q_accum + $signed({1'b0,adc_d}); + else + corr_q_accum <= corr_q_accum - $signed({1'b0,adc_d}); + end + + // for each Q/I pair report two reader signal samples when sniffing. Store the 2nd. + if(corr_i_cnt == 6'd32) + after_hysteresis_prev <= after_hysteresis; + + // Then the result from last time is serialized and send out to the ARM. + // We get one report each cycle, and each report is 16 bits, so the + // ssp_clk should be the adc_clk divided by 64/16 = 4. + // ssp_clk frequency = 13,56MHz / 4 = 3.39MHz + + if(corr_i_cnt[1:0] == 2'b00) + begin + // Don't shift if we just loaded new data, obviously. + if(corr_i_cnt != 6'd0) + begin + corr_i_out[7:0] <= {corr_i_out[6:0], corr_q_out[7]}; + corr_q_out[7:1] <= corr_q_out[6:0]; + end + end + +end + + +// ssp clock and frame signal for communication to and from ARM +reg ssp_clk; +reg ssp_frame; + +always @(negedge adc_clk) +begin + if (corr_i_cnt[1:0] == 2'b00) + ssp_clk <= 1'b1; + if (corr_i_cnt[1:0] == 2'b10) + ssp_clk <= 1'b0; + + // set ssp_frame signal for corr_i_cnt = 1..3 + // (send one frame with 16 Bits) + if (corr_i_cnt == 6'd2) + ssp_frame <= 1'b1; + if (corr_i_cnt == 6'd14) + ssp_frame <= 1'b0; +end + + +assign ssp_din = corr_i_out[7]; + + +// Antenna drivers +reg pwr_hi, pwr_oe4; + +always @(*) +begin + if (minor_mode == `FPGA_HF_READER_MODE_SEND_SHALLOW_MOD) + begin + pwr_hi = ck_1356meg; + pwr_oe4 = ssp_dout; + end + else if (minor_mode == `FPGA_HF_READER_MODE_SEND_FULL_MOD) + begin + pwr_hi = ck_1356meg & ~ssp_dout; + pwr_oe4 = 1'b0; + end + else if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_IQ + || minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE + || minor_mode == `FPGA_HF_READER_MODE_SNIFF_PHASE) + begin + pwr_hi = 1'b0; + pwr_oe4 = 1'b0; + end + else // receiving from tag + begin + pwr_hi = ck_1356meg; + pwr_oe4 = 1'b0; + end +end + +// always on +assign pwr_oe1 = 1'b0; +assign pwr_oe3 = 1'b0; + +// Unused. +assign pwr_lo = 1'b0; +assign pwr_oe2 = 1'b0; + +// Debug Output +assign dbg = corr_i_cnt[3]; + +endmodule diff --git a/fpga/hi_simulate.v b/fpga/hi_simulate.v index 8d70bb1b..de58a74e 100644 --- a/fpga/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -16,29 +16,20 @@ // Jonathan Westhues, October 2006 //----------------------------------------------------------------------------- -// possible mod_types: -`define NO_MODULATION 3'b000 -`define MODULATE_BPSK 3'b001 -`define MODULATE_212K 3'b010 -`define MODULATE_424K 3'b100 -`define MODULATE_424K_8BIT 3'b101 - module hi_simulate( - pck0, ck_1356meg, ck_1356megb, + ck_1356meg, 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, mod_type ); - input pck0, ck_1356meg, ck_1356megb; + input ck_1356meg; 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 [2:0] mod_type; @@ -49,8 +40,8 @@ assign adc_clk = ck_1356meg; always @(negedge adc_clk) begin - if(& adc_d[7:5]) after_hysteresis = 1'b1; - else if(~(| adc_d[7:5])) after_hysteresis = 1'b0; + if(& adc_d[7:5]) after_hysteresis = 1'b1; // if (adc_d >= 224) + else if(~(| adc_d[7:5])) after_hysteresis = 1'b0; // if (adc_d <= 31) end @@ -65,10 +56,10 @@ reg ssp_clk; always @(negedge adc_clk) begin - if(mod_type == `MODULATE_424K_8BIT) + if(mod_type == `FPGA_HF_SIMULATOR_MODULATE_424K_8BIT) // Get bit every at 53KHz (every 8th carrier bit of 424kHz) ssp_clk <= ssp_clk_divider[7]; - else if(mod_type == `MODULATE_212K) + else if(mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K) // Get next bit at 212kHz ssp_clk <= ssp_clk_divider[5]; else @@ -92,7 +83,7 @@ always @(negedge ssp_clk) reg ssp_frame; always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type) - if(mod_type == `NO_MODULATION) // not modulating, so listening, to ARM + if(mod_type == `FPGA_HF_SIMULATOR_NO_MODULATION) // not modulating, so listening, to ARM ssp_frame = (ssp_frame_divider_to_arm == 3'b000); else ssp_frame = (ssp_frame_divider_from_arm == 3'b000); @@ -104,14 +95,14 @@ always @(posedge ssp_clk) // Modulating carrier frequency is fc/64 (212kHz) to fc/16 (848kHz). Reuse ssp_clk divider for that. reg modulating_carrier; -always @(mod_type or ssp_clk or ssp_dout) - if (mod_type == `NO_MODULATION) +always @(*) + if (mod_type == `FPGA_HF_SIMULATOR_NO_MODULATION) modulating_carrier <= 1'b0; // no modulation - else if (mod_type == `MODULATE_BPSK) + else if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_BPSK) modulating_carrier <= ssp_dout ^ ssp_clk_divider[3]; // XOR means BPSK - else if (mod_type == `MODULATE_212K) + else if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K) modulating_carrier <= ssp_dout & ssp_clk_divider[5]; // switch 212kHz subcarrier on/off - else if (mod_type == `MODULATE_424K || mod_type == `MODULATE_424K_8BIT) + else if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_424K || mod_type == `FPGA_HF_SIMULATOR_MODULATE_424K_8BIT) modulating_carrier <= ssp_dout & ssp_clk_divider[4]; // switch 424kHz modulation on/off else modulating_carrier <= 1'b0; // yet unused diff --git a/fpga/hi_sniffer.v b/fpga/hi_sniffer.v index 3a989ce6..c2dc844a 100644 --- a/fpga/hi_sniffer.v +++ b/fpga/hi_sniffer.v @@ -1,21 +1,14 @@ module hi_sniffer( - pck0, ck_1356meg, ck_1356megb, + ck_1356meg, 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, - xcorr_is_848, snoop, xcorr_quarter_freq // not used. + ssp_frame, ssp_din, ssp_clk ); - input pck0, ck_1356meg, ck_1356megb; + input ck_1356meg; 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 xcorr_is_848, snoop, xcorr_quarter_freq; // not used. // We are only snooping, all off. assign pwr_hi = 1'b0;