mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-20 13:23:25 -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);
|
uint8_t *resp_cc = BigBuf_malloc(18);
|
||||||
int resp_cc_len;
|
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)
|
// Application Issuer Area (block 5)
|
||||||
uint8_t *resp_aia = BigBuf_malloc(22);
|
uint8_t *resp_aia = BigBuf_malloc(22);
|
||||||
int resp_aia_len;
|
int resp_aia_len;
|
||||||
|
@ -897,14 +903,19 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
memcpy(resp_cc, ToSend, ToSendMax);
|
memcpy(resp_cc, ToSend, ToSendMax);
|
||||||
resp_cc_len = 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)
|
// Application Issuer Area (block 5)
|
||||||
CodeIso15693AsTag(aia_data, sizeof(aia_data));
|
CodeIso15693AsTag(aia_data, sizeof(aia_data));
|
||||||
memcpy(resp_aia, ToSend, ToSendMax);
|
memcpy(resp_aia, ToSend, ToSendMax);
|
||||||
resp_aia_len = ToSendMax;
|
resp_aia_len = ToSendMax;
|
||||||
|
|
||||||
//This is used for responding to READ-block commands or other data which is dynamically generated
|
//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_generic_trace = BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
|
||||||
uint8_t *data_response = BigBuf_malloc( (8 + 2) * 2 + 2);
|
uint8_t *data_response = BigBuf_malloc( (32 + 2) * 2 + 2);
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
bool buttonPressed = false;
|
bool buttonPressed = false;
|
||||||
|
@ -931,6 +942,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
modulated_response_size = 0;
|
modulated_response_size = 0;
|
||||||
trace_data = NULL;
|
trace_data = NULL;
|
||||||
trace_data_size = 0;
|
trace_data_size = 0;
|
||||||
|
|
||||||
if (receivedCmd[0] == ICLASS_CMD_ACTALL) {
|
if (receivedCmd[0] == ICLASS_CMD_ACTALL) {
|
||||||
// Reader in anticollission phase
|
// Reader in anticollission phase
|
||||||
modulated_response = resp_sof;
|
modulated_response = resp_sof;
|
||||||
|
@ -944,12 +956,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
modulated_response_size = resp_anticoll_len;
|
modulated_response_size = resp_anticoll_len;
|
||||||
trace_data = anticoll_data;
|
trace_data = anticoll_data;
|
||||||
trace_data_size = sizeof(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
|
} else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // read block
|
||||||
uint16_t blockNo = receivedCmd[1];
|
uint16_t blockNo = receivedCmd[1];
|
||||||
if (simulationMode != ICLASS_SIM_MODE_FULL) {
|
if (simulationMode == ICLASS_SIM_MODE_EXIT_AFTER_MAC) {
|
||||||
// provide defaults for blocks 0, 1, 2, 5
|
// provide defaults for blocks 0 ... 5
|
||||||
switch (blockNo) {
|
switch (blockNo) {
|
||||||
case 0: // csn (block 00)
|
case 0: // csn (block 00)
|
||||||
modulated_response = resp_csn;
|
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);
|
memcpy(reader_mac_buf, card_challenge_data, 8);
|
||||||
}
|
}
|
||||||
break;
|
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)
|
case 5: // Application Issuer Area (block 05)
|
||||||
modulated_response = resp_aia;
|
modulated_response = resp_aia;
|
||||||
modulated_response_size = resp_aia_len;
|
modulated_response_size = resp_aia_len;
|
||||||
|
@ -981,15 +999,22 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
break;
|
break;
|
||||||
// default: don't respond
|
// default: don't respond
|
||||||
}
|
}
|
||||||
} else { // use data from emulator memory
|
} else if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
|
if (blockNo == 3 || blockNo == 4) { // Kd, Kc, always respond with 0xff bytes
|
||||||
AppendCrc(data_generic_trace, 8);
|
modulated_response = resp_ff;
|
||||||
trace_data = data_generic_trace;
|
modulated_response_size = resp_ff_len;
|
||||||
trace_data_size = 10;
|
trace_data = ff_data;
|
||||||
CodeIso15693AsTag(trace_data, trace_data_size);
|
trace_data_size = sizeof(ff_data);
|
||||||
memcpy(data_response, ToSend, ToSendMax);
|
} else { // use data from emulator memory
|
||||||
modulated_response = data_response;
|
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
|
||||||
modulated_response_size = ToSendMax;
|
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) {
|
} 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 = NULL;
|
||||||
trace_data_size = 0;
|
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) {
|
} 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.
|
// 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
|
// 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) {
|
if (modulated_response_size > 0) {
|
||||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM - DELAY_ARM_TO_READER_SIM;
|
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:
|
// setup hardware for simulation:
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
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);
|
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||||
StartCountSspClk();
|
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+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]);
|
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",
|
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+ 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+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);
|
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i*16);
|
||||||
} else if (simType == ICLASS_SIM_MODE_FULL) {
|
} else if (simType == ICLASS_SIM_MODE_FULL) {
|
||||||
|
|
|
@ -21,21 +21,21 @@
|
||||||
//
|
//
|
||||||
// VCD (reader) -> VICC (tag)
|
// VCD (reader) -> VICC (tag)
|
||||||
// 1 out of 256:
|
// 1 out of 256:
|
||||||
// data rate: 1,66 kbit/s (fc/8192)
|
// data rate: 1,66 kbit/s (fc/8192)
|
||||||
// used for long range
|
// used for long range
|
||||||
// 1 out of 4:
|
// 1 out of 4:
|
||||||
// data rate: 26,48 kbit/s (fc/512)
|
// data rate: 26,48 kbit/s (fc/512)
|
||||||
// used for short range, high speed
|
// used for short range, high speed
|
||||||
//
|
//
|
||||||
// VICC (tag) -> VCD (reader)
|
// VICC (tag) -> VCD (reader)
|
||||||
// Modulation:
|
// Modulation:
|
||||||
// ASK / one subcarrier (423,75 khz)
|
// ASK / one subcarrier (423,75 khz)
|
||||||
// FSK / two subcarriers (423,75 khz && 484,28 khz)
|
// FSK / two subcarriers (423,75 khz && 484,28 khz)
|
||||||
// Data Rates / Modes:
|
// Data Rates / Modes:
|
||||||
// low ASK: 6,62 kbit/s
|
// low ASK: 6,62 kbit/s
|
||||||
// low FSK: 6.67 kbit/s
|
// low FSK: 6.67 kbit/s
|
||||||
// high ASK: 26,48 kbit/s
|
// high ASK: 26,48 kbit/s
|
||||||
// high FSK: 26,69 kbit/s
|
// high FSK: 26,69 kbit/s
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,20 +338,20 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t start_time,
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
uint8_t bits_to_shift = 0x00;
|
uint8_t bits_to_shift = 0x00;
|
||||||
uint8_t bits_to_send = 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--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
uint8_t cmd_bits = ((cmd[c] >> i) & 0x01) ? 0xff : 0x00;
|
uint8_t cmd_bits = ((cmd[c] >> i) & 0x01) ? 0xff : 0x00;
|
||||||
for (int j = 0; j < (slow?4:1); ) {
|
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) {
|
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;
|
AT91C_BASE_SSC->SSC_THR = bits_to_send;
|
||||||
|
bits_to_shift = cmd_bits;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
// send the remaining bits, padded with 0:
|
// send the remaining bits, padded with 0:
|
||||||
bits_to_send = bits_to_shift << (8 - shift_delay);
|
bits_to_send = bits_to_shift << (8 - shift_delay);
|
||||||
for ( ; ; ) {
|
for ( ; ; ) {
|
||||||
|
@ -645,7 +645,7 @@ static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int tim
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
||||||
if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
|
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) {
|
if (DecodeTag.len > 0) {
|
||||||
LogTrace(DecodeTag.output, DecodeTag.len, 0, 0, NULL, false);
|
LogTrace(DecodeTag.output, DecodeTag.len, 0, 0, NULL, false);
|
||||||
|
@ -687,7 +687,7 @@ typedef struct DecodeReader {
|
||||||
int byteCount;
|
int byteCount;
|
||||||
int byteCountMax;
|
int byteCountMax;
|
||||||
int posCount;
|
int posCount;
|
||||||
int sum1, sum2;
|
int sum1, sum2;
|
||||||
uint8_t *output;
|
uint8_t *output;
|
||||||
} DecodeReader_t;
|
} DecodeReader_t;
|
||||||
|
|
||||||
|
@ -987,7 +987,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
|
|
||||||
if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
|
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) {
|
if (DecodeReader.byteCount > 0) {
|
||||||
uint32_t sof_time = *eof_time
|
uint32_t sof_time = *eof_time
|
||||||
|
@ -1168,7 +1168,7 @@ void SnoopIso15693(void)
|
||||||
ReaderIsActive = (DecodeReader.state >= STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF);
|
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)) {
|
if (Handle15693SamplesFromTag(snoopdata >> 2, &DecodeTag)) {
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
//Use samples as a time measurement
|
//Use samples as a time measurement
|
||||||
|
@ -1285,10 +1285,10 @@ static void BuildInventoryResponse(uint8_t *uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Universal Method for sending to and recv bytes from a tag
|
// Universal Method for sending to and recv bytes from a tag
|
||||||
// init ... should we initialize the reader?
|
// init ... should we initialize the reader?
|
||||||
// speed ... 0 low speed, 1 hi speed
|
// speed ... 0 low speed, 1 hi speed
|
||||||
// *recv will contain the tag's answer
|
// *recv will contain the tag's answer
|
||||||
// return: lenght of received data
|
// 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) {
|
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();
|
LED_A_ON();
|
||||||
|
@ -1418,8 +1418,8 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
|
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
|
||||||
|
|
||||||
// Start from off (no field generated)
|
// Start from off (no field generated)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelay(200);
|
SpinDelay(200);
|
||||||
|
|
||||||
// Give the tags time to energize
|
// Give the tags time to energize
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
@ -1489,7 +1489,7 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
|
|
||||||
// for the time being, switch field off to protect rdv4.0
|
// 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
|
// 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_D_OFF();
|
||||||
|
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
|
@ -1506,7 +1506,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
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);
|
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||||
|
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
@ -1531,7 +1531,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||||
Dbhexdump(cmd_len, cmd, false);
|
Dbhexdump(cmd_len, cmd, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1584,7 +1584,7 @@ void BruteforceIso15693Afi(uint32_t speed)
|
||||||
}
|
}
|
||||||
Dbprintf("AFI Bruteforcing done.");
|
Dbprintf("AFI Bruteforcing done.");
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
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
|
// 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
|
// 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_D_OFF();
|
||||||
|
|
||||||
LED_A_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).
|
// Set the UID to the tag (based on Iceman work).
|
||||||
void SetTag15693Uid(uint8_t *uid)
|
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;
|
int recvlen = 0;
|
||||||
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
// Command 1 : 02213E00000000
|
// Command 1 : 02213E00000000
|
||||||
cmd[0][0] = 0x02;
|
cmd[0][0] = 0x02;
|
||||||
cmd[0][1] = 0x21;
|
cmd[0][1] = 0x21;
|
||||||
cmd[0][2] = 0x3e;
|
cmd[0][2] = 0x3e;
|
||||||
cmd[0][3] = 0x00;
|
cmd[0][3] = 0x00;
|
||||||
cmd[0][4] = 0x00;
|
cmd[0][4] = 0x00;
|
||||||
cmd[0][5] = 0x00;
|
cmd[0][5] = 0x00;
|
||||||
cmd[0][6] = 0x00;
|
cmd[0][6] = 0x00;
|
||||||
|
|
||||||
// Command 2 : 02213F69960000
|
// Command 2 : 02213F69960000
|
||||||
cmd[1][0] = 0x02;
|
cmd[1][0] = 0x02;
|
||||||
cmd[1][1] = 0x21;
|
cmd[1][1] = 0x21;
|
||||||
cmd[1][2] = 0x3f;
|
cmd[1][2] = 0x3f;
|
||||||
cmd[1][3] = 0x69;
|
cmd[1][3] = 0x69;
|
||||||
cmd[1][4] = 0x96;
|
cmd[1][4] = 0x96;
|
||||||
cmd[1][5] = 0x00;
|
cmd[1][5] = 0x00;
|
||||||
cmd[1][6] = 0x00;
|
cmd[1][6] = 0x00;
|
||||||
|
|
||||||
// Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
|
// Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
|
||||||
cmd[2][0] = 0x02;
|
cmd[2][0] = 0x02;
|
||||||
cmd[2][1] = 0x21;
|
cmd[2][1] = 0x21;
|
||||||
cmd[2][2] = 0x38;
|
cmd[2][2] = 0x38;
|
||||||
cmd[2][3] = uid[7];
|
cmd[2][3] = uid[7];
|
||||||
cmd[2][4] = uid[6];
|
cmd[2][4] = uid[6];
|
||||||
cmd[2][5] = uid[5];
|
cmd[2][5] = uid[5];
|
||||||
cmd[2][6] = uid[4];
|
cmd[2][6] = uid[4];
|
||||||
|
|
||||||
// Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
|
// Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
|
||||||
cmd[3][0] = 0x02;
|
cmd[3][0] = 0x02;
|
||||||
cmd[3][1] = 0x21;
|
cmd[3][1] = 0x21;
|
||||||
cmd[3][2] = 0x39;
|
cmd[3][2] = 0x39;
|
||||||
cmd[3][3] = uid[3];
|
cmd[3][3] = uid[3];
|
||||||
cmd[3][4] = uid[2];
|
cmd[3][4] = uid[2];
|
||||||
cmd[3][5] = uid[1];
|
cmd[3][5] = uid[1];
|
||||||
cmd[3][6] = uid[0];
|
cmd[3][6] = uid[0];
|
||||||
|
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
// Add the CRC
|
// Add the CRC
|
||||||
crc = Iso15693Crc(cmd[i], 7);
|
crc = Iso15693Crc(cmd[i], 7);
|
||||||
cmd[i][7] = crc & 0xff;
|
cmd[i][7] = crc & 0xff;
|
||||||
cmd[i][8] = crc >> 8;
|
cmd[i][8] = crc >> 8;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Dbprintf("SEND:");
|
Dbprintf("SEND:");
|
||||||
Dbhexdump(sizeof(cmd[i]), cmd[i], false);
|
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) {
|
if (DEBUG) {
|
||||||
Dbprintf("RECV:");
|
Dbprintf("RECV:");
|
||||||
Dbhexdump(recvlen, recvbuf, false);
|
Dbhexdump(recvlen, recvbuf, false);
|
||||||
DbdecodeIso15693Answer(recvlen, recvbuf);
|
DbdecodeIso15693Answer(recvlen, recvbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
|
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1801,8 +1801,8 @@ static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t C
|
||||||
cmd[10] = 0x00;
|
cmd[10] = 0x00;
|
||||||
cmd[11] = 0x0a;
|
cmd[11] = 0x0a;
|
||||||
|
|
||||||
// cmd[12] = 0x00;
|
// cmd[12] = 0x00;
|
||||||
// cmd[13] = 0x00; //Now the CRC
|
// cmd[13] = 0x00; //Now the CRC
|
||||||
crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
|
crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
|
||||||
cmd[12] = crc & 0xff;
|
cmd[12] = crc & 0xff;
|
||||||
cmd[13] = crc >> 8;
|
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[10] = 0x05; // for custom codes this must be manufacturer code
|
||||||
cmd[11] = 0x00;
|
cmd[11] = 0x00;
|
||||||
|
|
||||||
// cmd[12] = 0x00;
|
// cmd[12] = 0x00;
|
||||||
// cmd[13] = 0x00; //Now the CRC
|
// cmd[13] = 0x00; //Now the CRC
|
||||||
crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
|
crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
|
||||||
cmd[12] = crc & 0xff;
|
cmd[12] = crc & 0xff;
|
||||||
cmd[13] = crc >> 8;
|
cmd[13] = crc >> 8;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
// Delays in SSP_CLK ticks.
|
// Delays in SSP_CLK ticks.
|
||||||
// SSP_CLK runs at 13,56MHz / 32 = 423.75kHz when simulating a tag
|
// SSP_CLK runs at 13,56MHz / 32 = 423.75kHz when simulating a tag
|
||||||
#define DELAY_READER_TO_ARM_SIM 8
|
#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
|
#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
|
//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_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
|
// Divide 13.56 MHz to produce various frequencies for SSP_CLK
|
||||||
// and modulation.
|
// 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);
|
ssp_clk_divider <= (ssp_clk_divider + 1);
|
||||||
|
|
||||||
reg ssp_clk;
|
reg ssp_clk;
|
||||||
|
|
||||||
always @(negedge adc_clk)
|
always @(negedge adc_clk)
|
||||||
begin
|
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)
|
// Get bit every at 53KHz (every 8th carrier bit of 424kHz)
|
||||||
ssp_clk <= ssp_clk_divider[7];
|
ssp_clk <= ~ssp_clk_divider[7];
|
||||||
else if(mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K)
|
else if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K)
|
||||||
// Get next bit at 212kHz
|
// Get next bit at 212kHz
|
||||||
ssp_clk <= ssp_clk_divider[5];
|
ssp_clk <= ~ssp_clk_divider[5];
|
||||||
else
|
else
|
||||||
// Get next bit at 424Khz
|
// Get next bit at 424Khz
|
||||||
ssp_clk <= ssp_clk_divider[4];
|
ssp_clk <= ~ssp_clk_divider[4];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// Divide SSP_CLK by 8 to produce the byte framing signal; the phase of
|
// Produce the byte framing signal; the phase of this signal
|
||||||
// this is arbitrary, because it's just a bitstream.
|
// is arbitrary, because it's just a bit stream in this module.
|
||||||
// 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);
|
|
||||||
|
|
||||||
|
|
||||||
reg ssp_frame;
|
reg ssp_frame;
|
||||||
always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type)
|
always @(negedge adc_clk)
|
||||||
if(mod_type == `FPGA_HF_SIMULATOR_NO_MODULATION) // not modulating, so listening, to ARM
|
begin
|
||||||
ssp_frame = (ssp_frame_divider_to_arm == 3'b000);
|
if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K)
|
||||||
else
|
begin
|
||||||
ssp_frame = (ssp_frame_divider_from_arm == 3'b000);
|
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.
|
// Synchronize up the after-hysteresis signal, to produce DIN.
|
||||||
reg ssp_din;
|
reg ssp_din;
|
||||||
|
@ -120,6 +122,6 @@ assign pwr_lo = 1'b0;
|
||||||
assign pwr_oe2 = 1'b0;
|
assign pwr_oe2 = 1'b0;
|
||||||
|
|
||||||
|
|
||||||
assign dbg = ssp_din;
|
assign dbg = ssp_frame;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue