mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 21:03:23 -07:00
fix 'hf iclass sim':
* add simulation of block 3 and 4 reads * add simulation of READ4 (4 blocks read) * fixing TransmitTo15693Reader() (again) * FPGA change (hi_simulate.v): avoid spp_clk phase changes * some whitespace fixes
This commit is contained in:
parent
3d2c9c9b06
commit
a66f26da18
5 changed files with 198 additions and 159 deletions
|
@ -860,6 +860,12 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
uint8_t *resp_cc = BigBuf_malloc(18);
|
||||
int resp_cc_len;
|
||||
|
||||
// Kd, Kc (blocks 3 and 4). Cannot be read. Always respond with 0xff bytes only
|
||||
uint8_t *resp_ff = BigBuf_malloc(22);
|
||||
int resp_ff_len;
|
||||
uint8_t ff_data[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
|
||||
AppendCrc(ff_data, 8);
|
||||
|
||||
// Application Issuer Area (block 5)
|
||||
uint8_t *resp_aia = BigBuf_malloc(22);
|
||||
int resp_aia_len;
|
||||
|
@ -897,14 +903,19 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
memcpy(resp_cc, ToSend, ToSendMax);
|
||||
resp_cc_len = ToSendMax;
|
||||
|
||||
// Kd, Kc (blocks 3 and 4)
|
||||
CodeIso15693AsTag(ff_data, sizeof(ff_data));
|
||||
memcpy(resp_ff, ToSend, ToSendMax);
|
||||
resp_ff_len = ToSendMax;
|
||||
|
||||
// Application Issuer Area (block 5)
|
||||
CodeIso15693AsTag(aia_data, sizeof(aia_data));
|
||||
memcpy(resp_aia, ToSend, ToSendMax);
|
||||
resp_aia_len = ToSendMax;
|
||||
|
||||
//This is used for responding to READ-block commands or other data which is dynamically generated
|
||||
uint8_t *data_generic_trace = BigBuf_malloc(8 + 2); // 8 bytes data + 2byte CRC is max tag answer
|
||||
uint8_t *data_response = BigBuf_malloc( (8 + 2) * 2 + 2);
|
||||
uint8_t *data_generic_trace = BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
|
||||
uint8_t *data_response = BigBuf_malloc( (32 + 2) * 2 + 2);
|
||||
|
||||
LED_A_ON();
|
||||
bool buttonPressed = false;
|
||||
|
@ -921,7 +932,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
buttonPressed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//Signal tracer
|
||||
LED_C_ON();
|
||||
|
||||
|
@ -931,6 +942,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
modulated_response_size = 0;
|
||||
trace_data = NULL;
|
||||
trace_data_size = 0;
|
||||
|
||||
if (receivedCmd[0] == ICLASS_CMD_ACTALL) {
|
||||
// Reader in anticollission phase
|
||||
modulated_response = resp_sof;
|
||||
|
@ -944,12 +956,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
modulated_response_size = resp_anticoll_len;
|
||||
trace_data = anticoll_data;
|
||||
trace_data_size = sizeof(anticoll_data);
|
||||
//DbpString("Reader requests anticollission CSN:");
|
||||
|
||||
|
||||
} else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // read block
|
||||
uint16_t blockNo = receivedCmd[1];
|
||||
if (simulationMode != ICLASS_SIM_MODE_FULL) {
|
||||
// provide defaults for blocks 0, 1, 2, 5
|
||||
if (simulationMode == ICLASS_SIM_MODE_EXIT_AFTER_MAC) {
|
||||
// provide defaults for blocks 0 ... 5
|
||||
switch (blockNo) {
|
||||
case 0: // csn (block 00)
|
||||
modulated_response = resp_csn;
|
||||
|
@ -973,6 +984,13 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
memcpy(reader_mac_buf, card_challenge_data, 8);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4: // Kd, Kd, always respond with 0xff bytes
|
||||
modulated_response = resp_ff;
|
||||
modulated_response_size = resp_ff_len;
|
||||
trace_data = ff_data;
|
||||
trace_data_size = sizeof(ff_data);
|
||||
break;
|
||||
case 5: // Application Issuer Area (block 05)
|
||||
modulated_response = resp_aia;
|
||||
modulated_response_size = resp_aia_len;
|
||||
|
@ -981,15 +999,22 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
break;
|
||||
// default: don't respond
|
||||
}
|
||||
} else { // use data from emulator memory
|
||||
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
|
||||
AppendCrc(data_generic_trace, 8);
|
||||
trace_data = data_generic_trace;
|
||||
trace_data_size = 10;
|
||||
CodeIso15693AsTag(trace_data, trace_data_size);
|
||||
memcpy(data_response, ToSend, ToSendMax);
|
||||
modulated_response = data_response;
|
||||
modulated_response_size = ToSendMax;
|
||||
} else if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||
if (blockNo == 3 || blockNo == 4) { // Kd, Kc, always respond with 0xff bytes
|
||||
modulated_response = resp_ff;
|
||||
modulated_response_size = resp_ff_len;
|
||||
trace_data = ff_data;
|
||||
trace_data_size = sizeof(ff_data);
|
||||
} else { // use data from emulator memory
|
||||
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
|
||||
AppendCrc(data_generic_trace, 8);
|
||||
trace_data = data_generic_trace;
|
||||
trace_data_size = 10;
|
||||
CodeIso15693AsTag(trace_data, trace_data_size);
|
||||
memcpy(data_response, ToSend, ToSendMax);
|
||||
modulated_response = data_response;
|
||||
modulated_response_size = ToSendMax;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (receivedCmd[0] == ICLASS_CMD_SELECT) {
|
||||
|
@ -1039,6 +1064,18 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
trace_data = NULL;
|
||||
trace_data_size = 0;
|
||||
|
||||
} else if (simulationMode == ICLASS_SIM_MODE_FULL && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06
|
||||
//Read block
|
||||
//Take the data...
|
||||
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4);
|
||||
AppendCrc(data_generic_trace, 8 * 4);
|
||||
trace_data = data_generic_trace;
|
||||
trace_data_size = 8 * 4 + 2;
|
||||
CodeIso15693AsTag(trace_data, trace_data_size);
|
||||
memcpy(data_response, ToSend, ToSendMax);
|
||||
modulated_response = data_response;
|
||||
modulated_response_size = ToSendMax;
|
||||
|
||||
} else if (receivedCmd[0] == ICLASS_CMD_UPDATE && simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||
// Probably the reader wants to update the nonce. Let's just ignore that for now.
|
||||
// OBS! If this is implemented, don't forget to regenerate the cipher_state
|
||||
|
@ -1072,7 +1109,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
|||
}
|
||||
|
||||
/**
|
||||
A legit tag has about 330us delay between reader EOT and tag SOF.
|
||||
A legit tag has about 311,5us delay between reader EOT and tag SOF.
|
||||
**/
|
||||
if (modulated_response_size > 0) {
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM - DELAY_ARM_TO_READER_SIM;
|
||||
|
@ -1112,7 +1149,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
|||
// setup hardware for simulation:
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||
StartCountSspClk();
|
||||
|
||||
|
@ -1150,8 +1187,8 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
|||
datain[i*8+0], datain[i*8+1], datain[i*8+2], datain[i*8+3],
|
||||
datain[i*8+4], datain[i*8+5], datain[i*8+6], datain[i*8+7]);
|
||||
Dbprintf("NR,MAC: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
datain[i*8+ 8], datain[i*8+ 9], datain[i*8+10], datain[i*8+11],
|
||||
datain[i*8+12], datain[i*8+13], datain[i*8+14], datain[i*8+15]);
|
||||
datain[i*8+ 8], datain[i*8+ 9], datain[i*8+10], datain[i*8+11],
|
||||
datain[i*8+12], datain[i*8+13], datain[i*8+14], datain[i*8+15]);
|
||||
}
|
||||
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i*16);
|
||||
} else if (simType == ICLASS_SIM_MODE_FULL) {
|
||||
|
@ -1319,10 +1356,10 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
|
|||
if (elapsed) (*elapsed)++;
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
if (c < timeout) {
|
||||
c++;
|
||||
} else {
|
||||
return false;
|
||||
if (c < timeout) {
|
||||
c++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
skip = !skip;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Jonathan Westhues, split Nov 2006
|
||||
// Modified by Greg Jones, Jan 2009
|
||||
// Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
|
||||
// Modified by piwi, Oct 2018
|
||||
// Modified by piwi, Oct 2018
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
|
@ -16,26 +16,26 @@
|
|||
// transmission modes from tag to reader. As of Oct 2018 this code supports
|
||||
// both reader modes and the high speed variant with one subcarrier from card to reader.
|
||||
// As long as the card fully support ISO 15693 this is no problem, since the
|
||||
// reader chooses both data rates, but some non-standard tags do not.
|
||||
// reader chooses both data rates, but some non-standard tags do not.
|
||||
// For card simulation, the code supports both high and low speed modes with one subcarrier.
|
||||
//
|
||||
// VCD (reader) -> VICC (tag)
|
||||
// 1 out of 256:
|
||||
// data rate: 1,66 kbit/s (fc/8192)
|
||||
// used for long range
|
||||
// data rate: 1,66 kbit/s (fc/8192)
|
||||
// used for long range
|
||||
// 1 out of 4:
|
||||
// data rate: 26,48 kbit/s (fc/512)
|
||||
// used for short range, high speed
|
||||
// data rate: 26,48 kbit/s (fc/512)
|
||||
// used for short range, high speed
|
||||
//
|
||||
// VICC (tag) -> VCD (reader)
|
||||
// Modulation:
|
||||
// ASK / one subcarrier (423,75 khz)
|
||||
// FSK / two subcarriers (423,75 khz && 484,28 khz)
|
||||
// ASK / one subcarrier (423,75 khz)
|
||||
// FSK / two subcarriers (423,75 khz && 484,28 khz)
|
||||
// Data Rates / Modes:
|
||||
// low ASK: 6,62 kbit/s
|
||||
// low FSK: 6.67 kbit/s
|
||||
// high ASK: 26,48 kbit/s
|
||||
// high FSK: 26,69 kbit/s
|
||||
// low ASK: 6,62 kbit/s
|
||||
// low FSK: 6.67 kbit/s
|
||||
// high ASK: 26,48 kbit/s
|
||||
// high FSK: 26,69 kbit/s
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -161,7 +161,7 @@ static void CodeIso15693AsReader(uint8_t *cmd, int n)
|
|||
for(i = 0; i < 4; i++) {
|
||||
ToSendStuffBit(1);
|
||||
}
|
||||
|
||||
|
||||
ToSendMax++;
|
||||
}
|
||||
|
||||
|
@ -338,20 +338,20 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t start_time,
|
|||
LED_C_ON();
|
||||
uint8_t bits_to_shift = 0x00;
|
||||
uint8_t bits_to_send = 0x00;
|
||||
for(size_t c = 0; c < len; c++) {
|
||||
for(size_t c = 0; c < len; c++) {
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
uint8_t cmd_bits = ((cmd[c] >> i) & 0x01) ? 0xff : 0x00;
|
||||
for (int j = 0; j < (slow?4:1); ) {
|
||||
bits_to_send = bits_to_shift << (8 - shift_delay) | cmd_bits >> shift_delay;
|
||||
bits_to_shift = cmd_bits;
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
bits_to_send = bits_to_shift << (8 - shift_delay) | cmd_bits >> shift_delay;
|
||||
AT91C_BASE_SSC->SSC_THR = bits_to_send;
|
||||
bits_to_shift = cmd_bits;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
}
|
||||
// send the remaining bits, padded with 0:
|
||||
bits_to_send = bits_to_shift << (8 - shift_delay);
|
||||
for ( ; ; ) {
|
||||
|
@ -408,7 +408,7 @@ typedef struct DecodeTag {
|
|||
static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag)
|
||||
{
|
||||
switch(DecodeTag->state) {
|
||||
case STATE_TAG_SOF_LOW:
|
||||
case STATE_TAG_SOF_LOW:
|
||||
// waiting for 12 times low (11 times low is accepted as well)
|
||||
if (amplitude < NOISE_THRESHOLD) {
|
||||
DecodeTag->posCount++;
|
||||
|
@ -422,7 +422,7 @@ static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint1
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case STATE_TAG_SOF_HIGH:
|
||||
// waiting for 10 times high. Take average over the last 8
|
||||
if (amplitude > NOISE_THRESHOLD) {
|
||||
|
@ -592,7 +592,7 @@ static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int tim
|
|||
bool gotFrame = false;
|
||||
|
||||
uint16_t *dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
|
||||
|
||||
|
||||
// the Decoder data structure
|
||||
DecodeTag_t DecodeTag = { 0 };
|
||||
DecodeTagInit(&DecodeTag, response, max_len);
|
||||
|
@ -643,9 +643,9 @@ static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int tim
|
|||
|
||||
FpgaDisableSscDma();
|
||||
BigBuf_free();
|
||||
|
||||
|
||||
if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
|
||||
samples, gotFrame, DecodeTag.state, DecodeTag.len, DecodeTag.bitCount, DecodeTag.posCount);
|
||||
samples, gotFrame, DecodeTag.state, DecodeTag.len, DecodeTag.bitCount, DecodeTag.posCount);
|
||||
|
||||
if (DecodeTag.len > 0) {
|
||||
LogTrace(DecodeTag.output, DecodeTag.len, 0, 0, NULL, false);
|
||||
|
@ -687,7 +687,7 @@ typedef struct DecodeReader {
|
|||
int byteCount;
|
||||
int byteCountMax;
|
||||
int posCount;
|
||||
int sum1, sum2;
|
||||
int sum1, sum2;
|
||||
uint8_t *output;
|
||||
} DecodeReader_t;
|
||||
|
||||
|
@ -985,12 +985,12 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
|||
}
|
||||
|
||||
FpgaDisableSscDma();
|
||||
|
||||
|
||||
if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
|
||||
samples, gotFrame, DecodeReader.state, DecodeReader.byteCount, DecodeReader.bitCount, DecodeReader.posCount);
|
||||
samples, gotFrame, DecodeReader.state, DecodeReader.byteCount, DecodeReader.bitCount, DecodeReader.posCount);
|
||||
|
||||
if (DecodeReader.byteCount > 0) {
|
||||
uint32_t sof_time = *eof_time
|
||||
uint32_t sof_time = *eof_time
|
||||
- DecodeReader.byteCount * (DecodeReader.Coding==CODING_1_OUT_OF_4?128:2048) // time for byte transfers
|
||||
- 32 // time for SOF transfer
|
||||
- 16; // time for EOF transfer
|
||||
|
@ -1101,7 +1101,7 @@ void SnoopIso15693(void)
|
|||
Dbprintf(" DMA: %i bytes", ISO15693_DMA_BUFFER_SIZE * sizeof(uint16_t));
|
||||
}
|
||||
Dbprintf("Snoop started. Press PM3 Button to stop.");
|
||||
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNOOP_AMPLITUDE);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
|
@ -1139,7 +1139,7 @@ void SnoopIso15693(void)
|
|||
}
|
||||
}
|
||||
samples++;
|
||||
|
||||
|
||||
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
|
||||
if (Handle15693SampleFromReader(snoopdata & 0x02, &DecodeReader)) {
|
||||
FpgaDisableSscDma();
|
||||
|
@ -1168,7 +1168,7 @@ void SnoopIso15693(void)
|
|||
ReaderIsActive = (DecodeReader.state >= STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF);
|
||||
}
|
||||
|
||||
if (!ReaderIsActive && ExpectTagAnswer) { // no need to try decoding tag data if the reader is currently sending or no answer expected yet
|
||||
if (!ReaderIsActive && ExpectTagAnswer) { // no need to try decoding tag data if the reader is currently sending or no answer expected yet
|
||||
if (Handle15693SamplesFromTag(snoopdata >> 2, &DecodeTag)) {
|
||||
FpgaDisableSscDma();
|
||||
//Use samples as a time measurement
|
||||
|
@ -1187,7 +1187,7 @@ void SnoopIso15693(void)
|
|||
|
||||
FpgaDisableSscDma();
|
||||
BigBuf_free();
|
||||
|
||||
|
||||
LEDsoff();
|
||||
|
||||
DbpString("Snoop statistics:");
|
||||
|
@ -1234,7 +1234,7 @@ static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
|
|||
uint16_t crc;
|
||||
// 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
|
||||
cmd[0] = ISO15693_REQ_OPTION | ISO15693_REQ_ADDRESS | ISO15693_REQ_DATARATE_HIGH;
|
||||
cmd[0] = ISO15693_REQ_OPTION | ISO15693_REQ_ADDRESS | ISO15693_REQ_DATARATE_HIGH;
|
||||
// READ BLOCK command code
|
||||
cmd[1] = ISO15693_READBLOCK;
|
||||
// UID may be optionally specified here
|
||||
|
@ -1285,10 +1285,10 @@ static void BuildInventoryResponse(uint8_t *uid)
|
|||
}
|
||||
|
||||
// Universal Method for sending to and recv bytes from a tag
|
||||
// init ... should we initialize the reader?
|
||||
// speed ... 0 low speed, 1 hi speed
|
||||
// *recv will contain the tag's answer
|
||||
// return: lenght of received data
|
||||
// init ... should we initialize the reader?
|
||||
// speed ... 0 low speed, 1 hi speed
|
||||
// *recv will contain the tag's answer
|
||||
// return: lenght of received data
|
||||
int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time) {
|
||||
|
||||
LED_A_ON();
|
||||
|
@ -1405,7 +1405,7 @@ void ReaderIso15693(uint32_t parameter)
|
|||
LED_A_ON();
|
||||
|
||||
set_tracing(true);
|
||||
|
||||
|
||||
int answerLen = 0;
|
||||
uint8_t TagUID[8] = {0x00};
|
||||
|
||||
|
@ -1418,8 +1418,8 @@ void ReaderIso15693(uint32_t parameter)
|
|||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
|
||||
|
||||
// Start from off (no field generated)
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
// Give the tags time to energize
|
||||
LED_D_ON();
|
||||
|
@ -1434,7 +1434,7 @@ 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_READER * 2) ;
|
||||
uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||
|
@ -1489,7 +1489,7 @@ void ReaderIso15693(uint32_t parameter)
|
|||
|
||||
// for the time being, switch field off to protect rdv4.0
|
||||
// note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
|
||||
LED_A_OFF();
|
||||
|
@ -1506,7 +1506,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
|||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||
|
||||
StartCountSspClk();
|
||||
|
@ -1531,7 +1531,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
|||
Dbhexdump(cmd_len, cmd, false);
|
||||
}
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
|
@ -1545,12 +1545,12 @@ void BruteforceIso15693Afi(uint32_t speed)
|
|||
|
||||
uint8_t data[6];
|
||||
uint8_t recv[ISO15693_MAX_RESPONSE_LENGTH];
|
||||
|
||||
|
||||
int datalen=0, recvlen=0;
|
||||
|
||||
Iso15693InitReader();
|
||||
StartCountSspClk();
|
||||
|
||||
|
||||
// first without AFI
|
||||
// Tags should respond without AFI and with AFI=0 even when AFI is active
|
||||
|
||||
|
@ -1584,7 +1584,7 @@ void BruteforceIso15693Afi(uint32_t speed)
|
|||
}
|
||||
Dbprintf("AFI Bruteforcing done.");
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
|
@ -1616,7 +1616,7 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
|||
|
||||
// for the time being, switch field off to protect rdv4.0
|
||||
// note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
|
||||
LED_A_OFF();
|
||||
|
@ -1630,76 +1630,76 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
|||
// Set the UID to the tag (based on Iceman work).
|
||||
void SetTag15693Uid(uint8_t *uid)
|
||||
{
|
||||
uint8_t cmd[4][9] = {0x00};
|
||||
uint8_t cmd[4][9] = {0x00};
|
||||
|
||||
uint16_t crc;
|
||||
uint16_t crc;
|
||||
|
||||
int recvlen = 0;
|
||||
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||
int recvlen = 0;
|
||||
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||
|
||||
LED_A_ON();
|
||||
LED_A_ON();
|
||||
|
||||
// Command 1 : 02213E00000000
|
||||
cmd[0][0] = 0x02;
|
||||
cmd[0][1] = 0x21;
|
||||
cmd[0][2] = 0x3e;
|
||||
cmd[0][3] = 0x00;
|
||||
cmd[0][4] = 0x00;
|
||||
cmd[0][5] = 0x00;
|
||||
cmd[0][6] = 0x00;
|
||||
// Command 1 : 02213E00000000
|
||||
cmd[0][0] = 0x02;
|
||||
cmd[0][1] = 0x21;
|
||||
cmd[0][2] = 0x3e;
|
||||
cmd[0][3] = 0x00;
|
||||
cmd[0][4] = 0x00;
|
||||
cmd[0][5] = 0x00;
|
||||
cmd[0][6] = 0x00;
|
||||
|
||||
// Command 2 : 02213F69960000
|
||||
cmd[1][0] = 0x02;
|
||||
cmd[1][1] = 0x21;
|
||||
cmd[1][2] = 0x3f;
|
||||
cmd[1][3] = 0x69;
|
||||
cmd[1][4] = 0x96;
|
||||
cmd[1][5] = 0x00;
|
||||
cmd[1][6] = 0x00;
|
||||
// Command 2 : 02213F69960000
|
||||
cmd[1][0] = 0x02;
|
||||
cmd[1][1] = 0x21;
|
||||
cmd[1][2] = 0x3f;
|
||||
cmd[1][3] = 0x69;
|
||||
cmd[1][4] = 0x96;
|
||||
cmd[1][5] = 0x00;
|
||||
cmd[1][6] = 0x00;
|
||||
|
||||
// Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
|
||||
cmd[2][0] = 0x02;
|
||||
cmd[2][1] = 0x21;
|
||||
cmd[2][2] = 0x38;
|
||||
cmd[2][3] = uid[7];
|
||||
cmd[2][4] = uid[6];
|
||||
cmd[2][5] = uid[5];
|
||||
cmd[2][6] = uid[4];
|
||||
// Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
|
||||
cmd[2][0] = 0x02;
|
||||
cmd[2][1] = 0x21;
|
||||
cmd[2][2] = 0x38;
|
||||
cmd[2][3] = uid[7];
|
||||
cmd[2][4] = uid[6];
|
||||
cmd[2][5] = uid[5];
|
||||
cmd[2][6] = uid[4];
|
||||
|
||||
// Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
|
||||
cmd[3][0] = 0x02;
|
||||
cmd[3][1] = 0x21;
|
||||
cmd[3][2] = 0x39;
|
||||
cmd[3][3] = uid[3];
|
||||
cmd[3][4] = uid[2];
|
||||
cmd[3][5] = uid[1];
|
||||
cmd[3][6] = uid[0];
|
||||
// Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
|
||||
cmd[3][0] = 0x02;
|
||||
cmd[3][1] = 0x21;
|
||||
cmd[3][2] = 0x39;
|
||||
cmd[3][3] = uid[3];
|
||||
cmd[3][4] = uid[2];
|
||||
cmd[3][5] = uid[1];
|
||||
cmd[3][6] = uid[0];
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
// Add the CRC
|
||||
crc = Iso15693Crc(cmd[i], 7);
|
||||
cmd[i][7] = crc & 0xff;
|
||||
cmd[i][8] = crc >> 8;
|
||||
for (int i=0; i<4; i++) {
|
||||
// Add the CRC
|
||||
crc = Iso15693Crc(cmd[i], 7);
|
||||
cmd[i][7] = crc & 0xff;
|
||||
cmd[i][8] = crc >> 8;
|
||||
|
||||
if (DEBUG) {
|
||||
Dbprintf("SEND:");
|
||||
Dbhexdump(sizeof(cmd[i]), cmd[i], false);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Dbprintf("SEND:");
|
||||
Dbhexdump(sizeof(cmd[i]), cmd[i], false);
|
||||
}
|
||||
|
||||
recvlen = SendDataTag(cmd[i], sizeof(cmd[i]), true, 1, recvbuf, sizeof(recvbuf), 0);
|
||||
recvlen = SendDataTag(cmd[i], sizeof(cmd[i]), true, 1, recvbuf, sizeof(recvbuf), 0);
|
||||
|
||||
if (DEBUG) {
|
||||
Dbprintf("RECV:");
|
||||
Dbhexdump(recvlen, recvbuf, false);
|
||||
DbdecodeIso15693Answer(recvlen, recvbuf);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Dbprintf("RECV:");
|
||||
Dbhexdump(recvlen, recvbuf, false);
|
||||
DbdecodeIso15693Answer(recvlen, recvbuf);
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
|
||||
}
|
||||
|
||||
LED_D_OFF();
|
||||
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
LED_D_OFF();
|
||||
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1801,8 +1801,8 @@ static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t C
|
|||
cmd[10] = 0x00;
|
||||
cmd[11] = 0x0a;
|
||||
|
||||
// cmd[12] = 0x00;
|
||||
// cmd[13] = 0x00; //Now the CRC
|
||||
// cmd[12] = 0x00;
|
||||
// cmd[13] = 0x00; //Now the CRC
|
||||
crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
|
||||
cmd[12] = crc & 0xff;
|
||||
cmd[13] = crc >> 8;
|
||||
|
@ -1836,8 +1836,8 @@ static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], u
|
|||
cmd[10] = 0x05; // for custom codes this must be manufacturer code
|
||||
cmd[11] = 0x00;
|
||||
|
||||
// cmd[12] = 0x00;
|
||||
// cmd[13] = 0x00; //Now the CRC
|
||||
// cmd[12] = 0x00;
|
||||
// cmd[13] = 0x00; //Now the CRC
|
||||
crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
|
||||
cmd[12] = crc & 0xff;
|
||||
cmd[13] = crc >> 8;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// 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_ARM_TO_READER_SIM 0
|
||||
#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
|
||||
|
|
BIN
fpga/fpga_hf.bit
BIN
fpga/fpga_hf.bit
Binary file not shown.
|
@ -47,46 +47,48 @@ end
|
|||
|
||||
// Divide 13.56 MHz to produce various frequencies for SSP_CLK
|
||||
// and modulation.
|
||||
reg [7:0] ssp_clk_divider;
|
||||
reg [8:0] ssp_clk_divider;
|
||||
|
||||
always @(posedge adc_clk)
|
||||
always @(negedge adc_clk)
|
||||
ssp_clk_divider <= (ssp_clk_divider + 1);
|
||||
|
||||
reg ssp_clk;
|
||||
|
||||
always @(negedge adc_clk)
|
||||
begin
|
||||
if(mod_type == `FPGA_HF_SIMULATOR_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 == `FPGA_HF_SIMULATOR_MODULATE_212K)
|
||||
ssp_clk <= ~ssp_clk_divider[7];
|
||||
else if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K)
|
||||
// Get next bit at 212kHz
|
||||
ssp_clk <= ssp_clk_divider[5];
|
||||
ssp_clk <= ~ssp_clk_divider[5];
|
||||
else
|
||||
// Get next bit at 424Khz
|
||||
ssp_clk <= ssp_clk_divider[4];
|
||||
ssp_clk <= ~ssp_clk_divider[4];
|
||||
end
|
||||
|
||||
|
||||
// Divide SSP_CLK by 8 to produce the byte framing signal; the phase of
|
||||
// this is arbitrary, because it's just a bitstream.
|
||||
// One nasty issue, though: I can't make it work with both rx and tx at
|
||||
// once. The phase wrt ssp_clk must be changed. TODO to find out why
|
||||
// that is and make a better fix.
|
||||
reg [2:0] ssp_frame_divider_to_arm;
|
||||
always @(posedge ssp_clk)
|
||||
ssp_frame_divider_to_arm <= (ssp_frame_divider_to_arm + 1);
|
||||
reg [2:0] ssp_frame_divider_from_arm;
|
||||
always @(negedge ssp_clk)
|
||||
ssp_frame_divider_from_arm <= (ssp_frame_divider_from_arm + 1);
|
||||
|
||||
|
||||
// Produce the byte framing signal; the phase of this signal
|
||||
// is arbitrary, because it's just a bit stream in this module.
|
||||
reg ssp_frame;
|
||||
always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type)
|
||||
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);
|
||||
always @(negedge adc_clk)
|
||||
begin
|
||||
if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K)
|
||||
begin
|
||||
if (ssp_clk_divider[8:5] == 4'd1)
|
||||
ssp_frame <= 1'b1;
|
||||
if (ssp_clk_divider[8:5] == 4'd5)
|
||||
ssp_frame <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (ssp_clk_divider[7:4] == 4'd1)
|
||||
ssp_frame <= 1'b1;
|
||||
if (ssp_clk_divider[7:4] == 4'd5)
|
||||
ssp_frame <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Synchronize up the after-hysteresis signal, to produce DIN.
|
||||
reg ssp_din;
|
||||
|
@ -120,6 +122,6 @@ assign pwr_lo = 1'b0;
|
|||
assign pwr_oe2 = 1'b0;
|
||||
|
||||
|
||||
assign dbg = ssp_din;
|
||||
assign dbg = ssp_frame;
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue