* 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
#include "legicrfsim.h"
#include "hitag2.h"
#include "hitagS.h"
+#include "iso14443b.h"
#include "iso15693.h"
#include "lfsampling.h"
#include "BigBuf.h"
// 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();
// 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);
// 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;
#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)
#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)
#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
* 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;
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;
// 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);
break;
}
- if(samples > n) {
+ if(samples > timeout && Demod.state < DEMOD_PHASE_REF_TRAINING) {
+ LED_C_OFF();
break;
}
}
//-----------------------------------------------------------------------------
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();
}
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();
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();
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);
*/
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){
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
}
+
+ LED_A_OFF();
}
// 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 <stdint.h>
+#include <stddef.h>
+
+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 */
#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
// 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[].
//-----------------------------------------------------------------------------
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;
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;
}
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;
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)) {
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;
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);
// Initialize the proxmark as iso15k reader
-// (this might produces glitches that confuse some tags
static void Iso15693InitReader() {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Setup SSC
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);
}
// 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();
}
-//-----------------------------------------------------------------------------
-// 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();
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);
// 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();
// 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
{
// 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++;
}
}
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);
}
Dbhexdump(cmd_len, cmd, false);
}
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
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]));
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]));
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
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
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
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
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;
//-----------------------------------------------------------------------------
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;
}
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;
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;
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;
-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
# 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
// iZsh <izsh at fail0verflow.com>, 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"
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
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
// 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
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)
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;
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
addr <= addr + 1;
end
end
- else if (major_mode != `OFF)
+ else if (major_mode != `FPGA_MAJOR_MODE_OFF)
begin
if (trace_enable)
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
// 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;
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
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.
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)
// 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
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
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
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)
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)
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;
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;
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
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;
+++ /dev/null
-//-----------------------------------------------------------------------------
-//
-// 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
+++ /dev/null
-//-----------------------------------------------------------------------------
-// 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
--- /dev/null
+//-----------------------------------------------------------------------------
+//
+// 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
// 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;
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
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
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);
// 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
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;