diff --git a/.gitignore b/.gitignore index 8469c8449..30cc1020a 100644 --- a/.gitignore +++ b/.gitignore @@ -80,17 +80,7 @@ tools/mfd_aes_brute/mfd_aes_brute tools/mfd_aes_brute/mfd_multi_brute tools/mfd_aes_brute/brute_key -fpga/* -!fpga/tests -!fpga/fpga_lf.bit -!fpga/fpga_hf.bit -!fpga/*.v -!fpga/Makefile -!fpga/fpga.ucf -!fpga/xst_lf.scr -!fpga/xst_hf.scr -!fpga/go.bat -!fpga/sim.tcl +fpga/__build* # offcial dumps folder dumps/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 57d0c4f7f..75606a26a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Added support for Apple Wallet NFC Passes with the Value Added Services protocol implementation (@gm3197) + - Fixed the timeout of TCP connections (@wh201906) + - Made the connection timeout configurable (@wh201906) ## [Seven.4.16717][2023-06-25] - Change `hf 14a info` - now identifes QL88 tags (@iceman1001) diff --git a/armsrc/Makefile b/armsrc/Makefile index 5203b0292..c481a6f22 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -103,9 +103,6 @@ endif # Generic standalone Mode injection of source code include Standalone/Makefile.inc -#the FPGA bitstream files. Note: order matters! -FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit fpga_felica.bit fpga_hf_15.bit - #the lz4 source files required for decompressing the fpga config at run time SRC_LZ4 = lz4.c #additional defines required to compile lz4 diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 2da9a582a..91fa971eb 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -821,7 +821,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { } for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) { - if (isOK && mifare_classic_readblock(pcs, colin_cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { + if (isOK && mifare_classic_readblock(pcs, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { isOK = false; break; }; @@ -838,7 +838,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { } } - int res = mifare_classic_halt(pcs, colin_cjcuid); + int res = mifare_classic_halt(pcs); (void)res; crypto1_deinit(pcs); @@ -986,7 +986,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data break; }; - if (mifare_classic_halt(NULL, colin_cjcuid)) { + if (mifare_classic_halt(NULL)) { DbprintfEx(FLAG_NEWLINE, "Halt error"); break; }; @@ -1006,7 +1006,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data break; }; - if (mifare_classic_halt(NULL, colin_cjcuid)) { + if (mifare_classic_halt(NULL)) { DbprintfEx(FLAG_NEWLINE, "Halt error"); break; }; @@ -1043,7 +1043,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data }; if (workFlags & 0x04) { - if (mifare_classic_halt(NULL, colin_cjcuid)) { + if (mifare_classic_halt(NULL)) { cjSetCursFRight(); DbprintfEx(FLAG_NEWLINE, "Halt error"); diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 97a02a278..9b41f18c4 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -109,7 +109,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_ break; }; - if (mifare_classic_halt(NULL, mattyrun_cuid)) { + if (mifare_classic_halt(NULL)) { DbprintfEx(FLAG_NEWLINE, "Halt error"); break; }; @@ -129,7 +129,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_ break; }; - if (mifare_classic_halt(NULL, mattyrun_cuid)) { + if (mifare_classic_halt(NULL)) { DbprintfEx(FLAG_NEWLINE, "Halt error"); break; }; @@ -165,7 +165,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_ }; if (workFlags & 0x04) { - if (mifare_classic_halt(NULL, mattyrun_cuid)) { + if (mifare_classic_halt(NULL)) { DbprintfEx(FLAG_NEWLINE, "Halt error"); break; }; @@ -267,7 +267,7 @@ static int saMifareECardLoad(uint32_t numofsectors, uint8_t keytype) { // failure to read one block, skips to next sector. for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(s); blockNo++) { - if (mifare_classic_readblock(pcs, mattyrun_cuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { + if (mifare_classic_readblock(pcs, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { retval = PM3_ESOFT; break; }; @@ -283,7 +283,7 @@ static int saMifareECardLoad(uint32_t numofsectors, uint8_t keytype) { } } - int res = mifare_classic_halt(pcs, mattyrun_cuid); + int res = mifare_classic_halt(pcs); (void)res; out: diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 184307042..6cdff3eb6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -60,6 +60,7 @@ #include "ticks.h" #include "commonutil.h" #include "crc16.h" +#include "protocols.h" #ifdef WITH_LCD @@ -1556,7 +1557,9 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_HF_MIFARE_READBL: { mf_readblock_t *payload = (mf_readblock_t *)packet->data.asBytes; - MifareReadBlock(payload->blockno, payload->keytype, payload->key); + uint8_t outbuf[16]; + int16_t retval = mifare_cmd_readblocks(MIFARE_AUTH_KEYA + (payload->keytype & 1), payload->key, ISO14443A_CMD_READBLOCK, payload->blockno, 1, outbuf); + reply_ng(CMD_HF_MIFARE_READBL, retval, outbuf, sizeof(outbuf)); break; } case CMD_HF_MIFAREU_READBL: { @@ -1580,7 +1583,19 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_WRITEBL: { - MifareWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); + uint8_t block_no = packet->oldarg[0]; + uint8_t key_type = packet->oldarg[1]; + uint8_t *key = packet->data.asBytes; + uint8_t *block_data = packet->data.asBytes + 10; + + int16_t retval = mifare_cmd_writeblocks(MIFARE_AUTH_KEYA + (key_type & 1), key, ISO14443A_CMD_WRITEBLOCK, block_no, 1, block_data); + + // convert ng style retval to old status + if (retval >= 0) { + retval = 1; + } + + reply_mix(CMD_ACK, retval, 0, 0, 0, 0); break; } case CMD_HF_MIFARE_VALUE: { @@ -1740,7 +1755,9 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t key[6]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareReadConfigBlockGDM(payload->key); + uint8_t outbuf[16]; + int16_t retval = mifare_cmd_readblocks(MIFARE_MAGIC_GDM_AUTH_KEY, payload->key, MIFARE_MAGIC_GDM_READ_CFG, 0, 1, outbuf); + reply_ng(CMD_HF_MIFARE_G4_GDM_CONFIG, retval, outbuf, sizeof(outbuf)); break; } case CMD_HF_MIFARE_G4_GDM_WRCFG: { @@ -1748,18 +1765,20 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t data[16]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareWriteConfigBlockGDM(payload->data); + uint8_t key[6] = {0, 0, 0, 0, 0, 0}; + int16_t retval = mifare_cmd_writeblocks(MIFARE_MAGIC_GDM_AUTH_KEY, key, MIFARE_MAGIC_GDM_WRITE_CFG, 0, 1, payload->data); + reply_ng(CMD_HF_MIFARE_G4_GDM_WRCFG, retval, NULL, 0); break; } case CMD_HF_MIFARE_G4_GDM_WRBL: { struct p { uint8_t blockno; - uint8_t keytype; uint8_t key[6]; uint8_t data[16]; // data to be written } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareWriteBlockGDM(payload->blockno, payload->keytype, payload->key, payload->data); + int16_t retval = mifare_cmd_writeblocks(MIFARE_MAGIC_GDM_AUTH_KEY, payload->key, MIFARE_MAGIC_GDM_WRITEBLOCK, payload->blockno, 1, payload->data); + reply_ng(CMD_HF_MIFARE_G4_GDM_WRBL, retval, NULL, 0); break; } case CMD_HF_MIFARE_PERSONALIZE_UID: { diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 6f8dd7a0b..5c5b6f8c5 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -404,16 +404,22 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 /* Four byte length field */ current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 24; current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16; - numbytes += 2; - default: /* Fall through, two byte length field */ + current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8; + current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0; + numbytes += 4; + if (current_length > 300 * 1024) { + /* section e should never exceed about 300KB, if the length is too big limit it but still send the bitstream just in case */ + current_length = 300 * 1024; + } + break; + default: /* Two byte length field */ current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8; current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0; numbytes += 2; - } - - if (current_name != 'e' && current_length > 255) { - /* Maybe a parse error */ - break; + if (current_length > 64) { + /* if text field is too long, keep it but truncate it */ + current_length = 64; + } } if (current_name == section_name) { diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 9cff73f63..5416f2917 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2538,7 +2538,7 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags bool first_try = true; uint32_t retry_timeout = use_ecp ? ECP_RETRY_TIMEOUT : WUPA_RETRY_TIMEOUT; - uint32_t start_time = GetTickCount(); + uint32_t start_time; int len; // we may need several tries if we did send an unknown command or a wrong authentication before... @@ -2562,6 +2562,11 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags // Receive the ATQA len = ReaderReceive(resp, resp_par); + // We set the start_time here otherwise in some cases we miss the window and only ever try once + if (first_try) { + start_time = GetTickCount(); + } + first_try = false; } while (len == 0 && GetTickCountDelta(start_time) <= retry_timeout); @@ -2830,10 +2835,9 @@ int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) { // which case we need to make a cascade 2 request and select - this is a long UID // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. for (; sak & 0x04; cascade_level++) { - uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x20 }; uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) - sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; + sel_uid[0] = ISO14443A_CMD_ANTICOLL_OR_SELECT + cascade_level * 2; if (cascade_level < num_cascades - 1) { uid_resp[0] = 0x88; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index c8a2d5fa2..145527a7e 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -58,21 +58,19 @@ static uint8_t dummy_answer = 0; //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. -// read block +// key_auth_cmd is one of MIFARE_AUTH_KEYA, MIFARE_AUTH_KEYB, or MIFARE_MAGIC_GDM_AUTH_KEY +// read_cmd is one of ISO14443A_CMD_READBLOCK, MIFARE_MAGIC_GDM_READBLOCK, or MIFARE_MAGIC_GDM_READ_CFG +// block_data must be 16*count bytes large +// block_no through block_no+count-1 normally needs to be within the same sector //----------------------------------------------------------------------------- -void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) { - // params - uint64_t ui64Key = 0; - ui64Key = bytes_to_num(datain, 6); +int16_t mifare_cmd_readblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t read_cmd, uint8_t block_no, uint8_t count, uint8_t *block_data) { + + uint64_t ui64key = bytes_to_num(key, 6); - // variables - uint8_t dataoutbuf[16] = {0x00}; uint8_t uid[10] = {0x00}; - uint32_t cuid = 0, status = PM3_EOPABORTED; - + uint32_t cuid = 0; struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + struct Crypto1State *pcs = &mpcs; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -83,41 +81,125 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) { LED_B_OFF(); LED_C_OFF(); - while (true) { - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); - break; - }; + int retval = PM3_SUCCESS; - if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); - break; - }; - - if (mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Read block error"); - break; - }; - - if (mifare_classic_halt(pcs, cuid)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); - break; - }; - - status = PM3_SUCCESS; - break; + if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); + retval = PM3_ESOFT; + goto OUT; } + if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); + retval = PM3_ESOFT; + goto OUT; + }; + + for (uint8_t i = 0; i < count; i++) { + if (mifare_classic_readblock_ex(pcs, block_no + i, block_data + (i * 16), read_cmd)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Read block error"); + retval = PM3_ESOFT; + goto OUT; + }; + } + + if (mifare_classic_halt(pcs)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); + retval = PM3_ESOFT; + goto OUT; + }; + +OUT: crypto1_deinit(pcs); - if (g_dbglevel >= 2) DbpString("READ BLOCK FINISHED"); - - LED_B_ON(); - reply_ng(CMD_HF_MIFARE_READBL, status, dataoutbuf, 16); - LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); + set_tracing(false); + BigBuf_free(); + + return retval; +} + +//----------------------------------------------------------------------------- +// Select, Authenticate, Write a MIFARE tag. +// key_auth_cmd is one of MIFARE_AUTH_KEYA, MIFARE_AUTH_KEYB, or MIFARE_MAGIC_GDM_AUTH_KEY +// write_cmd is one of ISO14443A_CMD_WRITEBLOCK, MIFARE_MAGIC_GDM_WRITEBLOCK, or MIFARE_MAGIC_GDM_WRITE_CFG +// block_data must be 16*count bytes large +// block_no through block_no+count-1 normally needs to be within the same sector +//----------------------------------------------------------------------------- +int16_t mifare_cmd_writeblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t write_cmd, uint8_t block_no, uint8_t count, uint8_t *block_data) { + + uint64_t ui64key = bytes_to_num(key, 6); + + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs = &mpcs; + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + clear_trace(); + set_tracing(true); + + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); + + uint8_t retval = PM3_SUCCESS; + + if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); + retval = PM3_ESOFT; + goto OUT; + }; + + if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); + retval = PM3_ESOFT; + goto OUT; + }; + + for (uint8_t i = 0; i < count; i++) { + int res = mifare_classic_writeblock_ex(pcs, block_no + i, block_data + (i * 16), write_cmd); + if (res == PM3_ETEAROFF) { + retval = PM3_ETEAROFF; + goto OUT; + } else if (res != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); + retval = PM3_ESOFT; + goto OUT; + } + } + + if (mifare_classic_halt(pcs)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); + retval = PM3_ESOFT; + goto OUT; + }; + +OUT: + crypto1_deinit(pcs); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); + BigBuf_free(); + + return retval; +} + +//----------------------------------------------------------------------------- +// Select, Authenticate, Read a MIFARE tag. +// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes) +//----------------------------------------------------------------------------- +void MifareReadSector(uint8_t sector_no, uint8_t key_type, uint8_t *key) { + uint8_t block_no = FirstBlockOfSector(sector_no); + uint8_t num_blocks = NumBlocksPerSector(sector_no); + + uint8_t outbuf[16 * 16]; + int16_t retval = mifare_cmd_readblocks(MIFARE_AUTH_KEYA + (key_type & 1), key, ISO14443A_CMD_READBLOCK, block_no, num_blocks, outbuf); + + reply_old(CMD_ACK, retval == PM3_SUCCESS, 0, 0, outbuf, 16 * num_blocks); } void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) { @@ -214,131 +296,6 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { LEDsoff(); } -void MifareReadConfigBlockGDM(uint8_t *key) { - - int retval = PM3_SUCCESS; - - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); - if (par == NULL) { - retval = PM3_EMALLOC; - goto OUT; - } - - uint8_t *uid = BigBuf_malloc(10); - if (uid == NULL) { - retval = PM3_EMALLOC; - goto OUT; - } - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); - - // variables - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - - uint64_t ui64key = bytes_to_num(key, 6); - uint8_t outbuf[16] = {0x00}; - - if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { - retval = PM3_ESOFT; - goto OUT; - } - - if (mifare_classic_authex_2(pcs, cuid, 0, 0, ui64key, AUTH_FIRST, NULL, NULL, true)) { - retval = PM3_ESOFT; - goto OUT; - }; - - if (mifare_classic_readblock_ex(pcs, cuid, 0, outbuf, MIFARE_MAGIC_GDM_READ_CFG)) { - retval = PM3_ESOFT; - goto OUT; - }; - - if (mifare_classic_halt(pcs, cuid)) { - retval = PM3_ESOFT; - goto OUT; - }; - -OUT: - crypto1_deinit(pcs); - - reply_ng(CMD_HF_MIFARE_G4_GDM_CONFIG, retval, outbuf, sizeof(outbuf)); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); - BigBuf_free(); -} - -//----------------------------------------------------------------------------- -// Select, Authenticate, Read a MIFARE tag. -// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes) -//----------------------------------------------------------------------------- -void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain) { - // params - uint8_t sectorNo = arg0; - uint8_t keyType = arg1; - uint64_t ui64Key = 0; - ui64Key = bytes_to_num(datain, 6); - - // variables - uint8_t isOK = 0; - uint8_t dataoutbuf[16 * 16]; - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - clear_trace(); - set_tracing(true); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - isOK = 1; - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - isOK = 0; - if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); - } - - - if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { - isOK = 0; - if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); - } - - for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { - if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) { - isOK = 0; - if (g_dbglevel >= DBG_ERROR) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo); - break; - } - } - - if (mifare_classic_halt(pcs, cuid)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); - } - - if (g_dbglevel >= 2) DbpString("READ SECTOR FINISHED"); - - crypto1_deinit(pcs); - - LED_B_ON(); - reply_old(CMD_ACK, isOK, 0, 0, dataoutbuf, 16 * NumBlocksPerSector(sectorNo)); - LED_B_OFF(); - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); -} - // arg0 = blockNo (start) // arg1 = Pages (number of blocks) // arg2 = useKey @@ -438,210 +395,6 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) set_tracing(false); } -//----------------------------------------------------------------------------- -// Select, Authenticate, Write a MIFARE tag. -// read block -//----------------------------------------------------------------------------- -void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { - // params - uint8_t blockNo = arg0; - uint8_t keyType = arg1; - uint64_t ui64Key = 0; - uint8_t blockdata[16] = {0x00}; - - ui64Key = bytes_to_num(datain, 6); - memcpy(blockdata, datain + 10, 16); - - // variables - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - clear_trace(); - set_tracing(true); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - uint8_t retval = 0; - - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); - goto OUT; - }; - - if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); - goto OUT; - }; - - int res = mifare_classic_writeblock(pcs, cuid, blockNo, blockdata); - if (res == PM3_ETEAROFF) { - retval = PM3_ETEAROFF; - goto OUT; - } else if (res != PM3_SUCCESS) { - if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); - retval = PM3_ESOFT; - goto OUT; - } - - if (mifare_classic_halt(pcs, cuid)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); - goto OUT; - }; - - retval = 1; - -OUT: - crypto1_deinit(pcs); - - reply_mix(CMD_ACK, retval, 0, 0, 0, 0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); -} - -void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain) { - - int retval = PM3_SUCCESS; - - // check args - if (datain == NULL) { - retval = PM3_EINVARG; - goto OUT; - } - - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); - if (par == NULL) { - retval = PM3_EMALLOC; - goto OUT; - } - - uint8_t *uid = BigBuf_malloc(10); - if (uid == NULL) { - retval = PM3_EMALLOC; - goto OUT; - } - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); - - // variables - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - - uint64_t ui64key = bytes_to_num(key, 6); - - if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { - retval = PM3_ESOFT; - goto OUT; - } - - if (mifare_classic_authex_2(pcs, cuid, blockno, keytype, ui64key, AUTH_FIRST, NULL, NULL, true)) { - retval = PM3_ESOFT; - goto OUT; - }; - - int res = mifare_classic_writeblock_ex(pcs, cuid, blockno, datain, true); - if (res == PM3_ETEAROFF) { - retval = PM3_ETEAROFF; - goto OUT; - } else if (res != PM3_SUCCESS) { - retval = PM3_ESOFT; - goto OUT; - } - - if (mifare_classic_halt(pcs, cuid)) { - retval = PM3_ESOFT; - goto OUT; - }; - -OUT: - crypto1_deinit(pcs); - - reply_ng(CMD_HF_MIFARE_G4_GDM_WRBL, retval, NULL, 0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); - BigBuf_free(); -} - -void MifareWriteConfigBlockGDM(uint8_t *datain) { - - int retval = PM3_SUCCESS; - - // check args - if (datain == NULL) { - retval = PM3_EINVARG; - goto OUT; - } - - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); - if (par == NULL) { - retval = PM3_EMALLOC; - goto OUT; - } - - uint8_t *uid = BigBuf_malloc(10); - if (uid == NULL) { - retval = PM3_EMALLOC; - goto OUT; - } - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); - - // variables - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - - if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { - retval = PM3_ESOFT; - goto OUT; - } - - uint64_t key = 0; - if (mifare_classic_authex_2(pcs, cuid, 0, 0, key, AUTH_FIRST, NULL, NULL, true)) { - retval = PM3_ESOFT; - goto OUT; - }; - - int res = mifare_classic_write_cfg_block_gdm(pcs, cuid, datain); - if (res == PM3_ETEAROFF) { - retval = PM3_ETEAROFF; - goto OUT; - } else if (res) { - retval = PM3_ESOFT; - goto OUT; - } - - if (mifare_classic_halt(pcs, cuid)) { - retval = PM3_ESOFT; - goto OUT; - }; - -OUT: - crypto1_deinit(pcs); - - reply_ng(CMD_HF_MIFARE_G4_GDM_WRCFG, retval, NULL, 0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); - BigBuf_free(); -} - - void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { // params uint8_t blockNo = arg0; @@ -688,7 +441,7 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { break; }; - if (mifare_classic_value(pcs, cuid, blockNo, blockdata, action) != PM3_SUCCESS) { + if (mifare_classic_value(pcs, blockNo, blockdata, action) != PM3_SUCCESS) { if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); break; }; @@ -708,7 +461,7 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { break; } - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); break; }; @@ -1145,7 +898,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } // nested authentication - uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL); + uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL); // wait for the card to become ready again CHK_TIMEOUT(); @@ -1267,7 +1020,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 } // prepare next select. No need to power down the card. - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { if (g_dbglevel >= DBG_INFO) Dbprintf("Nested: Halt error"); rtr--; continue; @@ -1369,7 +1122,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 } // prepare next select. No need to power down the card. - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { if (g_dbglevel >= DBG_INFO) Dbprintf("Nested: Halt error"); continue; } @@ -1491,7 +1244,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, // Main loop - get crypted nonces for target sector for (uint8_t rtr = 0; rtr < 2; rtr++) { - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { continue; } @@ -1522,7 +1275,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, target_ks[0] = nt2 ^ target_nt[0]; // second collection - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { continue; } @@ -1618,7 +1371,7 @@ static uint8_t chkKey(struct chk_t *c) { // if successful auth, send HALT // if ( !res ) - // mifare_classic_halt_ex(c->pcs); + // mifare_classic_halt(c->pcs); break; } return res; @@ -1633,7 +1386,7 @@ static uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { return 1; uint8_t data[16] = {0x00}; - uint8_t res = mifare_classic_readblock(c->pcs, c->cuid, c->block, data); + uint8_t res = mifare_classic_readblock(c->pcs, c->block, data); // successful read if (!res) { @@ -1644,7 +1397,7 @@ static uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { } else { res = 3; } - mifare_classic_halt_ex(c->pcs); + mifare_classic_halt(c->pcs); } return res; } @@ -2229,7 +1982,7 @@ void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) { break; } - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); break; } @@ -2372,7 +2125,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { for (uint8_t r = 0; r < MAX_RETRIES; r++) { - if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + b, data)) { + if (mifare_classic_readblock(pcs, FirstBlockOfSector(s) + b, data)) { retval |= PM3_EPARTIAL; if (g_dbglevel > DBG_ERROR) { Dbprintf("Error reading sector %2d block %2d", s, b); @@ -2398,7 +2151,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { } } - int res = mifare_classic_halt(pcs, cuid); + int res = mifare_classic_halt(pcs); (void)res; crypto1_deinit(pcs); @@ -2460,10 +2213,10 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); errormsg = MAGIC_UID; - mifare_classic_halt_ex(NULL); + mifare_classic_halt(NULL); break; } - mifare_classic_halt_ex(NULL); + mifare_classic_halt(NULL); } // wipe tag, fill it with zeros @@ -2489,7 +2242,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } iso14a_set_timeout(old_timeout); - mifare_classic_halt_ex(NULL); + mifare_classic_halt(NULL); } // write block @@ -2528,7 +2281,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } if (workFlags & MAGIC_HALT) - mifare_classic_halt_ex(NULL); + mifare_classic_halt(NULL); isOK = true; break; @@ -2600,7 +2353,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { // send HALT if (workFlags & MAGIC_HALT) - mifare_classic_halt_ex(NULL); + mifare_classic_halt(NULL); isOK = true; break; @@ -2628,7 +2381,7 @@ void MifareCIdent(bool is_mfc) { uint8_t rats[4] = {ISO14443A_CMD_RATS, 0x80, 0x31, 0x73}; uint8_t rdblf0[4] = {ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; uint8_t rdbl00[4] = {ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; - uint8_t gen4gmd[4] = {MIFARE_MAGIC_GDM_AUTH_KEY, 0x00, 0x6C, 0x92}; + uint8_t gen4gdm[4] = {MIFARE_MAGIC_GDM_AUTH_KEY, 0x00, 0x6C, 0x92}; uint8_t gen4GetConf[8] = {GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t superGen1[9] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D}; @@ -2782,7 +2535,7 @@ void MifareCIdent(bool is_mfc) { iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - ReaderTransmit(gen4gmd, sizeof(gen4gmd), NULL); + ReaderTransmit(gen4gdm, sizeof(gen4gdm), NULL); res = ReaderReceive(buf, par); if (res == 4) { isGen = MAGIC_GEN_4GDM; @@ -3227,12 +2980,12 @@ void MifareSetMod(uint8_t *datain) { } int respLen; - if (((respLen = mifare_sendcmd_short(pcs, CRYPT_ALL, 0x43, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { + if (((respLen = mifare_sendcmd_short(pcs, CRYPT_ALL, MIFARE_EV1_SETMOD, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("SetMod error; response[0]: %hhX, len: %d", receivedAnswer[0], respLen); break; } - if (mifare_classic_halt(pcs, cuid)) { + if (mifare_classic_halt(pcs)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); break; } diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index a6623c006..b7f7d6379 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -19,19 +19,18 @@ #include "common.h" -void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain); +int16_t mifare_cmd_readblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t read_cmd, uint8_t block_no, uint8_t count, uint8_t *block_data); +int16_t mifare_cmd_writeblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t write_cmd, uint8_t block_no, uint8_t count, uint8_t *block_data); +void MifareReadSector(uint8_t sector_no, uint8_t key_type, uint8_t *key); +void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes); void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); -void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain); - void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key); +void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key); void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, uint8_t *key); void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain); @@ -58,11 +57,6 @@ void MifareGen3UID(uint8_t uidlen, uint8_t *uid); // Gen 3 magic card set UID wi void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overwrite manufacturer block void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes -// MFC GEN4 GDM -void MifareReadConfigBlockGDM(uint8_t *key); -void MifareWriteConfigBlockGDM(uint8_t *datain); -void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain); - // MFC GEN4 GTU void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags); void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index b17ac19bc..e94d09f40 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -139,9 +139,9 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { - return mifare_classic_authex_2(pcs, uid, blockNo, keyType, ui64Key, isNested, ntptr, timing, false); + return mifare_classic_authex_cmd(pcs, uid, blockNo, keyType ? MIFARE_AUTH_KEYA : MIFARE_AUTH_KEYB, ui64Key, isNested, ntptr, timing); } -int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm) { +int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { // "random" reader nonce: uint8_t nr[4]; @@ -150,9 +150,8 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // Transmit MIFARE_CLASSIC_AUTH 0x60, 0x61 or GDM 0x80 - uint8_t cmdbyte = (is_gdm) ? MIFARE_MAGIC_GDM_AUTH_KEY : MIFARE_AUTH_KEYA + (keyType & 0x01); - int len = mifare_sendcmd_short(pcs, isNested, cmdbyte, blockNo, receivedAnswer, receivedAnswerPar, timing); + // Transmit MIFARE_CLASSIC_AUTH, 0x60 for key A, 0x61 for key B, or 0x80 for GDM backdoor + int len = mifare_sendcmd_short(pcs, isNested, cmd, blockNo, receivedAnswer, receivedAnswerPar, timing); if (len != 4) return 1; // Save the tag nonce (nt) @@ -229,10 +228,10 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc return 0; } -int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { - return mifare_classic_readblock_ex(pcs, uid, blockNo, blockData, ISO14443A_CMD_READBLOCK); +int mifare_classic_readblock(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData) { + return mifare_classic_readblock_ex(pcs, blockNo, blockData, ISO14443A_CMD_READBLOCK); } -int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte) { +int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte) { uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; @@ -415,22 +414,18 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { return res; } -int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { - return mifare_classic_writeblock_ex(pcs, uid, blockNo, blockData, false); +int mifare_classic_writeblock(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData) { + return mifare_classic_writeblock_ex(pcs, blockNo, blockData, ISO14443A_CMD_WRITEBLOCK); } -int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm) { +int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t cmd) { // variables uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // command MIFARE_MAGIC_GDM_WRITEBLOCK - uint16_t len; - if (is_gdm) { - len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - } else { - len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - } + // cmd is ISO14443A_CMD_WRITEBLOCK for normal tags, but could also be + // MIFARE_MAGIC_GDM_WRITEBLOCK or MIFARE_MAGIC_GDM_WRITE_CFG for certain magic tags + uint16_t len = mifare_sendcmd_short(pcs, 1, cmd, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); @@ -441,15 +436,19 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t memcpy(d_block, blockData, 16); AddCrc14A(d_block, 16); - // enough for 18 Bytes to send - uint8_t par[3] = {0x00, 0x00, 0x00}; - // crypto - for (uint32_t pos = 0; pos < 18; pos++) { - d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; - par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007))); - } + if (pcs) { + // enough for 18 Bytes to send + uint8_t par[3] = {0x00, 0x00, 0x00}; + // crypto + for (uint32_t pos = 0; pos < 18; pos++) { + d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; + par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007))); + } - ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); + ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); + } else { + ReaderTransmit(d_block, sizeof(d_block), NULL); + } // tearoff occurred if (tearoff_hook() == PM3_ETEAROFF) { @@ -459,10 +458,14 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t len = ReaderReceive(receivedAnswer, receivedAnswerPar); uint8_t res = 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; + if (pcs) { + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; + } else { + res = receivedAnswer[0]; + } if ((len != 1) || (res != 0x0A)) { if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd send data2 Error: %02x", res); @@ -472,52 +475,7 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t return PM3_SUCCESS; } -int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, uint8_t *blockData) { - - // variables - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - - uint16_t len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITE_CFG, 0, receivedAnswer, receivedAnswerPar, NULL); - if ((len != 1) || (receivedAnswer[0] != 0x0A)) { - return PM3_EFAILED; - } - - uint8_t d_block[18], d_block_enc[18]; - memcpy(d_block, blockData, 16); - AddCrc14A(d_block, 16); - - // enough for 18 Bytes to send - uint8_t par[3] = {0x00, 0x00, 0x00}; - // crypto - for (uint32_t pos = 0; pos < 18; pos++) { - d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; - par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007))); - } - - ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); - - // tearoff occurred - if (tearoff_hook() == PM3_ETEAROFF) { - return PM3_ETEAROFF; - } else { - // Receive the response - len = ReaderReceive(receivedAnswer, receivedAnswerPar); - - uint8_t res = 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; - - if ((len != 1) || (res != 0x0A)) { - return PM3_EFAILED; - } - } - return PM3_SUCCESS; -} - -int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action) { +int mifare_classic_value(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t action) { // variables uint16_t len = 0; uint32_t pos = 0; @@ -625,7 +583,8 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { } return PM3_SUCCESS; } -int mifare_classic_halt_ex(struct Crypto1State *pcs) { + +int mifare_classic_halt(struct Crypto1State *pcs) { uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); if (len != 0) { @@ -634,19 +593,9 @@ int mifare_classic_halt_ex(struct Crypto1State *pcs) { } return 0; } -int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { - return mifare_classic_halt_ex(pcs); -} int mifare_ultra_halt(void) { - uint16_t len = 0; - uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; - len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); - if (len != 0) { - if (g_dbglevel >= DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len); - return 1; - } - return 0; + return mifare_classic_halt(NULL); } diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index e5731ce36..9a179a553 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -72,17 +72,15 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t // mifare classic int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing); -int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm); +int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing); -int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); -int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte); +int mifare_classic_readblock(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData); +int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte); -int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); -int mifare_classic_halt_ex(struct Crypto1State *pcs); -int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); -int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm); -int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action); -int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, uint8_t *blockData); +int mifare_classic_halt(struct Crypto1State *pcs); +int mifare_classic_writeblock(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData); +int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t cmd); +int mifare_classic_value(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t action); // Ultralight/NTAG... int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack); diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 3ddd98189..57bba66aa 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -33,6 +33,7 @@ #include "pm3_cmd.h" #include "pmflash.h" // rdv40validation_t #include "cmdflashmem.h" // get_signature.. +#include "uart/uart.h" // configure timeout static int CmdHelp(const char *Cmd); @@ -924,6 +925,46 @@ static int CmdTia(const char *Cmd) { return PM3_SUCCESS; } +static int CmdTimeout(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hw timeout", + "Set the communication timeout on the client side", + "hw timeout --> Show current timeout\n" + "hw timeout -t 20 --> Set the timeout to 20ms\n" + "hw timeout -t 500 --> Set the timeout to 500ms\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("t", "timeout", "", "timeout in ms"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + int32_t arg = arg_get_int_def(ctx, 1, -1); + CLIParserFree(ctx); + + uint32_t oldTimeout = uart_get_timeouts(); + + // timeout is not given/invalid, just show the current timeout then return + if (arg < 0) { + PrintAndLogEx(INFO, "Current communication timeout: %ums", oldTimeout); + return PM3_SUCCESS; + } + + uint32_t newTimeout = arg; + // UART_USB_CLIENT_RX_TIMEOUT_MS is considered as the minimum required timeout. + if (newTimeout < UART_USB_CLIENT_RX_TIMEOUT_MS) { + PrintAndLogEx(WARNING, "Timeout less than %ums might cause errors.", UART_USB_CLIENT_RX_TIMEOUT_MS); + } else if (newTimeout > 5000) { + PrintAndLogEx(WARNING, "Timeout greater than 5000ms makes the client unresponsive."); + } + uart_reconfigure_timeouts(newTimeout); + PrintAndLogEx(INFO, "Old communication timeout: %ums", oldTimeout); + PrintAndLogEx(INFO, "New communication timeout: %ums", newTimeout); + return PM3_SUCCESS; +} + static int CmdPing(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hw ping", @@ -1062,6 +1103,7 @@ static command_t CommandTable[] = { {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, {"tearoff", CmdTearoff, IfPm3Present, "Program a tearoff hook for the next command supporting tearoff"}, {"tia", CmdTia, IfPm3Present, "Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider"}, + {"timeout", CmdTimeout, AlwaysAvailable, "Set the communication timeout on the client side"}, {"tune", CmdTune, IfPm3Present, "Measure antenna tuning"}, {"version", CmdVersion, AlwaysAvailable, "Show version information about the client and the connected Proxmark3, if any"}, {NULL, NULL, NULL, NULL} diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 323c7ef7e..326a646b9 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -910,11 +910,19 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr uint8_t crcc = iso14443A_CRC_check(hdr->isResponse, mfData, mfDataLen); //iceman: colorise crc bytes here will need a refactor of code from above. - PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s", - str_padder, - sprint_hex_inrow_spaces(mfData, mfDataLen, 2), - (crcc == 0 ? _RED_(" !! ") : (crcc == 1 ? _GREEN_(" ok ") : " ")), - explanation); + if (hdr->isResponse) { + PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s", + str_padder, + sprint_hex_inrow_spaces(mfData, mfDataLen, 2), + (crcc == 0 ? _RED_(" !! ") : (crcc == 1 ? _GREEN_(" ok ") : " ")), + explanation); + } else { + PrintAndLogEx(NORMAL, " | | * |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), + str_padder, + sprint_hex_inrow_spaces(mfData, mfDataLen, 2), + (crcc == 0 ? _RED_(" !! ") : (crcc == 1 ? _GREEN_(" ok ") : " ")), + explanation); + } } } diff --git a/client/src/comms.c b/client/src/comms.c index 64bea9f65..a17bdbaf9 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -623,6 +623,7 @@ int TestProxmark(pm3_device_t *dev) { PacketResponseNG resp; uint16_t len = 32; + bool is_tcp_conn = false; uint8_t data[len]; for (uint16_t i = 0; i < len; i++) data[i] = i & 0xFF; @@ -665,16 +666,17 @@ int TestProxmark(pm3_device_t *dev) { memcpy(&g_pm3_capabilities, resp.data.asBytes, MIN(sizeof(capabilities_t), resp.length)); g_conn.send_via_fpc_usart = g_pm3_capabilities.via_fpc; g_conn.uart_speed = g_pm3_capabilities.baudrate; + is_tcp_conn = memcmp(g_conn.serial_port_name, "tcp:", 4) == 0; PrintAndLogEx(INFO, "Communicating with PM3 over %s%s%s", g_conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"), - memcmp(g_conn.serial_port_name, "tcp:", 4) == 0 ? " over " _YELLOW_("TCP") : "", + is_tcp_conn ? " over " _YELLOW_("TCP") : "", memcmp(g_conn.serial_port_name, "bt:", 3) == 0 ? " over " _YELLOW_("BT") : ""); if (g_conn.send_via_fpc_usart) { PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", g_conn.uart_speed); } else { - int res = uart_reconfigure_timeouts(UART_USB_CLIENT_RX_TIMEOUT_MS); + int res = uart_reconfigure_timeouts(is_tcp_conn ? UART_TCP_CLIENT_RX_TIMEOUT_MS : UART_USB_CLIENT_RX_TIMEOUT_MS); if (res != PM3_SUCCESS) { return res; } diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index ffad57057..7284af351 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,767 +31,767 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data num" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixwritepwd" }, - { 0, "hf 15 slixeasdisable" }, - { 0, "hf 15 slixeasenable" }, - { 0, "hf 15 slixprivacydisable" }, - { 0, "hf 15 slixprivacyenable" }, - { 0, "hf 15 passprotectafi" }, - { 0, "hf 15 passprotecteas" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 0, "hf legic einfo" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf gdmcfg" }, - { 0, "hf mf gdmsetcfg" }, - { 0, "hf mf gdmsetblk" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 1, "hf mfp list" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp dump" }, - { 0, "hf mfp info" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp ndefformat" }, - { 0, "hf mfp ndefread" }, - { 0, "hf mfp ndefwrite" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu tamper" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf tesla help" }, - { 0, "hf tesla info" }, - { 1, "hf tesla list" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 1, "hf topaz list" }, - { 0, "hf topaz dump" }, - { 0, "hf topaz info" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 brute" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data num" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 0, "hf legic einfo" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf gdmcfg" }, + { 0, "hf mf gdmsetcfg" }, + { 0, "hf mf gdmsetblk" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 1, "hf mfp list" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp dump" }, + { 0, "hf mfp info" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp ndefformat" }, + { 0, "hf mfp ndefread" }, + { 0, "hf mfp ndefwrite" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu tamper" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 1, "hf topaz list" }, + { 0, "hf topaz dump" }, + { 0, "hf topaz info" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 brute" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -799,4 +799,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif \ No newline at end of file +#endif diff --git a/client/src/uart/uart.h b/client/src/uart/uart.h index ba4537769..ae3896f73 100644 --- a/client/src/uart/uart.h +++ b/client/src/uart/uart.h @@ -74,8 +74,12 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed); */ uint32_t uart_get_speed(const serial_port sp); -/* Reconfigure timeouts +/* Reconfigure timeouts (ms) */ int uart_reconfigure_timeouts(uint32_t value); -#endif // _UART_H_ +/* Get timeouts (ms) + */ +uint32_t uart_get_timeouts(void); + +#endif // _UART_H_ diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index c64d85db6..106c8d209 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -69,6 +69,10 @@ int uart_reconfigure_timeouts(uint32_t value) { return PM3_SUCCESS; } +uint32_t uart_get_timeouts(void) { + return newtimeout_value; +} + serial_port uart_open(const char *pcPortName, uint32_t speed) { serial_port_unix_t_t *sp = calloc(sizeof(serial_port_unix_t_t), sizeof(uint8_t)); diff --git a/client/src/uart/uart_win32.c b/client/src/uart/uart_win32.c index cb8b92a73..541804a24 100644 --- a/client/src/uart/uart_win32.c +++ b/client/src/uart/uart_win32.c @@ -54,6 +54,10 @@ int uart_reconfigure_timeouts(uint32_t value) { return PM3_SUCCESS; } +uint32_t uart_get_timeouts(void) { + return newtimeout_value; +} + static int uart_reconfigure_timeouts_polling(serial_port sp) { if (newtimeout_pending == false) return PM3_SUCCESS; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 99f4d9ecd..18d931b46 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -44,7 +44,7 @@ OBJDIR = obj INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the lz4 directory -VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/lz4 ../fpga-$(PLATFORM_FPGA) ../armsrc/Standalone +VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/lz4 ../fpga ../armsrc/Standalone INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index a65514784..9679382ce 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -92,18 +92,26 @@ PLTNAME = Unknown Platform PLATFORM_FPGA = fpga-undefined ifeq ($(PLATFORM),PM3RDV4) + # FPGA bitstream files, the order matters! + FPGA_BITSTREAMS = fpga_pm3_lf.bit fpga_pm3_hf.bit fpga_pm3_felica.bit fpga_pm3_hf_15.bit PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4 PLTNAME = Proxmark3 RDV4 PLATFORM_FPGA = xc2s30 RDV4 = yes else ifeq ($(PLATFORM),PM3OTHER) $(warning PLATFORM=PM3OTHER is deprecated, please use PLATFORM=PM3GENERIC) + # FPGA bitstream files, the order matters! + FPGA_BITSTREAMS = fpga_pm3_lf.bit fpga_pm3_hf.bit fpga_pm3_felica.bit fpga_pm3_hf_15.bit PLTNAME = Proxmark3 generic target PLATFORM_FPGA = xc2s30 else ifeq ($(PLATFORM),PM3GENERIC) + # FPGA bitstream files, the order matters! + FPGA_BITSTREAMS = fpga_pm3_lf.bit fpga_pm3_hf.bit fpga_pm3_felica.bit fpga_pm3_hf_15.bit PLTNAME = Proxmark3 generic target PLATFORM_FPGA = xc2s30 else ifeq ($(PLATFORM),PM3ICOPYX) + # FPGA bitstream files, the order matters - only hf has a bitstream, the other 3 files are 0 bytes + FPGA_BITSTREAMS = fpga_icopyx_lf.bit fpga_icopyx_hf.bit fpga_icopyx_felica.bit fpga_icopyx_hf_15.bit PLATFORM_DEFS = -DWITH_FLASH -DICOPYX -DXC3 PLTNAME = iCopy-X with XC3S100E PLATFORM_FPGA = xc3s100e @@ -246,6 +254,7 @@ export PLATFORM_DEFS export PLATFORM_DEFS_INFO export PLATFORM_DEFS_INFO_STANDALONE export PLATFORM_CHANGED +export FPGA_BITSTREAMS $(info ===================================================================) $(info Version info: $(shell tools/mkversion.sh --short 2>/dev/null || ../tools/mkversion.sh --short 2>/dev/null)) diff --git a/fpga-xc2s30/Makefile b/fpga-xc2s30/Makefile deleted file mode 100644 index 2bf9273ba..000000000 --- a/fpga-xc2s30/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# FPGA Makefile -# -RMDIR = rm -rf -# rmdir only if dir is empty, tolerate failure -RMDIR_SOFT = -rmdir -# -all: fpga_lf.bit fpga_hf.bit fpga_felica.bit fpga_hf_15.bit -clean: - $(Q)$(RM) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp xst_felica.srp xst_hf_15.srp - $(Q)$(RM) *.map *.ngc *.xrpt *.pcf *.rbt *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst - $(Q)$(RMDIR) *_auto_* xst - -#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_flite.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 - $(Q)$(RM) $@ - $(info [-] XST $@) - $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr - -fpga_felica.ngc: fpga_felica.v fpga.ucf xst_felica.scr util.v hi_simulate.v hi_reader.v hi_sniffer.v hi_flite.v hi_get_trace.v - $(Q)$(RM) $@ - $(info [-] XST $@) - $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_felica.scr - -fpga_hf_15.ngc: fpga_hf_15.v fpga.ucf xst_hf_15.scr util.v hi_simulate.v hi_reader_15.v hi_sniffer.v hi_get_trace.v - $(Q)$(RM) $@ - $(info [-] XST $@) - $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf_15.scr - -fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v lp20khz_1MSa_iir_filter.v min_max_tracker.v lf_edge_detect.v - $(Q)$(RM) $@ - $(info [-] XST $@) - $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr - -%.ngd: %.ngc - $(Q)$(RM) $@ - $(info [-] NGD $@) - $(Q)$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf $< $@ - -%.ncd: %.ngd - $(Q)$(RM) $@ - $(info [-] MAP $@) - $(Q)$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 $< - -%-placed.ncd: %.ncd - $(Q)$(RM) $@ - $(info [-] PAR $@) - $(Q)$(XILINX_TOOLS_PREFIX)par $< $@ - -%.bit: %-placed.ncd - $(Q)$(RM) $@ $*.drc $*.rbt - $(info [=] BITGEN $@) - $(Q)$(XILINX_TOOLS_PREFIX)bitgen $< $@ - -.PHONY: all clean help -help: - @echo Possible targets: - @echo + all - Make fpga.bit, the FPGA bitstream - @echo + clean - Clean intermediate files, does not clean fpga.bit - diff --git a/fpga-xc2s30/fpga.ucf b/fpga-xc2s30/fpga.ucf deleted file mode 100644 index f20e2da02..000000000 --- a/fpga-xc2s30/fpga.ucf +++ /dev/null @@ -1,54 +0,0 @@ -# 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" ; -#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" ; - -#PACE: Start of PACE Area Constraints - -#PACE: Start of PACE Prohibit Constraints - -#PACE: End of Constraints generated by PACE - -# definition of Clock nets: -NET "ck_1356meg" TNM_NET = "clk_net_1356" ; -NET "ck_1356megb" TNM_NET = "clk_net_1356b" ; -NET "pck0" TNM_NET = "clk_net_pck0" ; -NET "spck" TNM_NET = "clk_net_spck" ; - -# Timing specs of clock nets: -TIMEGRP "clk_net_1356_all" = "clk_net_1356" "clk_net_1356b" ; -TIMESPEC "TS_1356MHz" = PERIOD "clk_net_1356_all" 74 ns HIGH 37 ns ; -TIMESPEC "TS_24MHz" = PERIOD "clk_net_pck0" 42 ns HIGH 21 ns ; -TIMESPEC "TS_4MHz" = PERIOD "clk_net_spck" 250 ns HIGH 125 ns ; - diff --git a/fpga-xc2s30/fpga_felica.bit b/fpga-xc2s30/fpga_felica.bit deleted file mode 100644 index 30ea16e33..000000000 Binary files a/fpga-xc2s30/fpga_felica.bit and /dev/null differ diff --git a/fpga-xc2s30/fpga_felica.v b/fpga-xc2s30/fpga_felica.v deleted file mode 100644 index 6fb53927c..000000000 --- a/fpga-xc2s30/fpga_felica.v +++ /dev/null @@ -1,240 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// -// The FPGA is responsible for interfacing between the A/D, the coil drivers, -// and the ARM. In the low-frequency modes it passes the data straight -// through, so that the ARM gets raw A/D samples over the SSP. In the high- -// frequency modes, the FPGA might perform some demodulation first, to -// reduce the amount of data that we must send to the ARM. -// -// I am not really an FPGA/ASIC designer, so I am sure that a lot of this -// could be improved. -// -// Jonathan Westhues, March 2006 -// -// Added ISO14443-A support -// - - -// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h -// Note: the definitions here are without shifts - -// Commands: -`define FPGA_CMD_SET_CONFREG 1 -`define FPGA_CMD_TRACE_ENABLE 2 - -// Major modes: -`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_SNIFF 3 -`define FPGA_MAJOR_MODE_HF_ISO18092 4 -`define FPGA_MAJOR_MODE_HF_GET_TRACE 5 -`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_MODE_SEND_JAM 8 - -`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 - -//options for ISO18092 / Felica -`define FPGA_HF_ISO18092_FLAG_NOMOD 1 // 0001 disable modulation module -`define FPGA_HF_ISO18092_FLAG_424K 2 // 0010 should enable 414k mode (untested). No autodetect -`define FPGA_HF_ISO18092_FLAG_READER 4 // 0100 enables antenna power, to act as a reader instead of tag - -`include "hi_reader.v" -`include "hi_simulate.v" -//`include "hi_iso14443a.v" -`include "hi_sniffer.v" -`include "util.v" -`include "hi_flite.v" -`include "hi_get_trace.v" - -module fpga_felica( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg -); - -//----------------------------------------------------------------------------- -// The SPI receiver. This sets up the configuration word, which the rest of -// the logic looks at to determine how to connect the A/D and the coil -// drivers (i.e., which section gets it). Also assign some symbolic names -// to the configuration bits, for use below. -//----------------------------------------------------------------------------- - -/* - Attempt to write up how its hooked up. Iceman 2020. - - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA - The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where - C is 4bit command - D is 12bit data - - shift_reg receive this 16bit frame - - ------+--------- frame layout -------------------- -bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------+------------------------------------------- -cmd | x x x x -major| x x x -opt | x x x -divi | x x x x x x x x -thres| x x x x x x x x ------+------------------------------------------- -*/ - -reg [15:0] shift_reg; -reg [8:0] conf_word; -reg trace_enable; - -// We switch modes between transmitting to the 13.56 MHz tag and receiving -// from it, which means that we must make sure that we can do so without -// glitching, or else we will glitch the transmitted carrier. -always @(posedge ncs) -begin - case(shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; - `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; - endcase -end - -always @(posedge spck) -begin - if(~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end -end - -// select module (outputs) based on major mode -wire [2:0] major_mode = conf_word[8:6]; - -// configuring the HF reader -wire [1:0] subcarrier_frequency = conf_word[5:4]; -wire [3:0] minor_mode = conf_word[3:0]; - -//----------------------------------------------------------------------------- -// And then we instantiate the modules corresponding to each of the FPGA's -// major modes, and use muxes to connect the outputs of the active mode to -// the output pins. -//----------------------------------------------------------------------------- - -// 000 - HF reader -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 -); - -// 001 - HF simulated tag -hi_simulate hs( - 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, - hs_dbg, - minor_mode -); - -// 011 - HF sniff -hi_sniffer he( - 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 -); - -// 100 - HF ISO18092 FeliCa -hi_flite hfl( - ck_1356megb, - hfl_pwr_lo, hfl_pwr_hi, hfl_pwr_oe1, hfl_pwr_oe2, hfl_pwr_oe3, hfl_pwr_oe4, - adc_d, hfl_adc_clk, - hfl_ssp_frame, hfl_ssp_din, ssp_dout, hfl_ssp_clk, - hfl_dbg, - minor_mode -); - -// 101 - HF get trace -hi_get_trace gt( - ck_1356megb, - adc_d, trace_enable, major_mode, - gt_ssp_frame, gt_ssp_din, gt_ssp_clk -); - -// Major modes: -// 000 -- HF reader; subcarrier frequency and modulation depth selectable -// 001 -- HF simulated tag -// 010 -- HF ISO14443-A - removed for space... -// 011 -- HF sniff -// 100 -- HF ISO18092 FeliCa -// 101 -- HF get trace -// 110 -- unused -// 111 -- FPGA_MAJOR_MODE_OFF - -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, hr_ssp_clk, hs_ssp_clk, 1'b0, he_ssp_clk, hfl_ssp_clk, gt_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, hr_ssp_din, hs_ssp_din, 1'b0, he_ssp_din, hfl_ssp_din, gt_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, hr_ssp_frame, hs_ssp_frame, 1'b0, he_ssp_frame, hfl_ssp_frame, gt_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, hr_pwr_oe1, hs_pwr_oe1, 1'b0, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, hr_pwr_oe2, hs_pwr_oe2, 1'b0, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, hr_pwr_oe3, hs_pwr_oe3, 1'b0, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, hr_pwr_oe4, hs_pwr_oe4, 1'b0, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, hr_pwr_lo, hs_pwr_lo, 1'b0, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, hr_pwr_hi, hs_pwr_hi, 1'b0, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, hr_adc_clk, hs_adc_clk, 1'b0, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, hr_dbg, hs_dbg, 1'b0, he_dbg, hfl_dbg, 1'b0, 1'b0, 1'b0); - -// In all modes, let the ADC's outputs be enabled. -assign adc_noe = 1'b0; - -endmodule diff --git a/fpga-xc2s30/fpga_hf.bit b/fpga-xc2s30/fpga_hf.bit deleted file mode 100644 index 72f3d619e..000000000 Binary files a/fpga-xc2s30/fpga_hf.bit and /dev/null differ diff --git a/fpga-xc2s30/fpga_hf.v b/fpga-xc2s30/fpga_hf.v deleted file mode 100644 index 8ee85e26b..000000000 --- a/fpga-xc2s30/fpga_hf.v +++ /dev/null @@ -1,255 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// -// The FPGA is responsible for interfacing between the A/D, the coil drivers, -// and the ARM. In the low-frequency modes it passes the data straight -// through, so that the ARM gets raw A/D samples over the SSP. In the high- -// frequency modes, the FPGA might perform some demodulation first, to -// reduce the amount of data that we must send to the ARM. -// -// I am not really an FPGA/ASIC designer, so I am sure that a lot of this -// could be improved. -// -// Jonathan Westhues, March 2006 -//----------------------------------------------------------------------------- -// Added ISO14443-A support -// - - -// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h -// Note: the definitions here are without shifts - -// Commands: -`define FPGA_CMD_SET_CONFREG 1 -`define FPGA_CMD_TRACE_ENABLE 2 - -// Major modes: -`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_SNIFF 3 -`define FPGA_MAJOR_MODE_HF_ISO18092 4 -`define FPGA_MAJOR_MODE_HF_GET_TRACE 5 -`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_MODE_SEND_JAM 8 - -`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 - -//options for ISO18092 / Felica -`define FPGA_HF_ISO18092_FLAG_NOMOD 1 // 0001 disable modulation module -`define FPGA_HF_ISO18092_FLAG_424K 2 // 0010 should enable 414k mode (untested). No autodetect -`define FPGA_HF_ISO18092_FLAG_READER 4 // 0100 enables antenna power, to act as a reader instead of tag - -`include "hi_reader.v" -`include "hi_simulate.v" -`include "hi_iso14443a.v" -`include "hi_sniffer.v" -`include "util.v" -// `include "hi_flite.v" -`include "hi_get_trace.v" - -module fpga_hf( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg -); - -//----------------------------------------------------------------------------- -// The SPI receiver. This sets up the configuration word, which the rest of -// the logic looks at to determine how to connect the A/D and the coil -// drivers (i.e., which section gets it). Also assign some symbolic names -// to the configuration bits, for use below. -//----------------------------------------------------------------------------- - -/* - Attempt to write up how its hooked up. - / Iceman, 2020 - - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA - The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where - C is 4bit command - D is 12bit data - - shift_reg receive this 16bit frame - - ------+--------- frame layout -------------------- -bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------+------------------------------------------- -cmd | x x x x -major| x x x -opt | x x x x -sub | x x -divi | x x x x x x x x -thres| x x x x x x x x ------+------------------------------------------- -*/ - -reg [15:0] shift_reg; -reg [8:0] conf_word; -reg trace_enable; - -// We switch modes between transmitting to the 13.56 MHz tag and receiving -// from it, which means that we must make sure that we can do so without -// glitching, or else we will glitch the transmitted carrier. -always @(posedge ncs) -begin - case(shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; - `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; - endcase -end - -always @(posedge spck) -begin - if(~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end -end - -// select module (outputs) based on major mode -wire [2:0] major_mode = conf_word[8:6]; - -// configuring the HF reader -wire [1:0] subcarrier_frequency = conf_word[5:4]; -wire [3:0] minor_mode = conf_word[3:0]; - -//----------------------------------------------------------------------------- -// And then we instantiate the modules corresponding to each of the FPGA's -// major modes, and use muxes to connect the outputs of the active mode to -// the output pins. -//----------------------------------------------------------------------------- - -// 000 - HF reader -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 -); - -// 001 - HF simulated tag -hi_simulate hs( - 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, - hs_dbg, - minor_mode -); - -// 010 - HF ISO14443-A -hi_iso14443a hisn( - 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, - hisn_dbg, - minor_mode -); - -// 011 - HF sniff -hi_sniffer he( - 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 -); - -// 100 - HF ISO18092 FeliCa -/* -hi_flite hfl( - ck_1356megb, - hfl_pwr_lo, hfl_pwr_hi, hfl_pwr_oe1, hfl_pwr_oe2, hfl_pwr_oe3, hfl_pwr_oe4, - adc_d, hfl_adc_clk, - hfl_ssp_frame, hfl_ssp_din, ssp_dout, hfl_ssp_clk, - hfl_dbg, - minor_mode -); -*/ - -// 101 - HF get trace -hi_get_trace gt( - ck_1356megb, - adc_d, trace_enable, major_mode, - gt_ssp_frame, gt_ssp_din, gt_ssp_clk -); - -// Major modes: -// 000 -- HF reader; subcarrier frequency and modulation depth selectable -// 001 -- HF simulated tag -// 010 -- HF ISO14443-A -// 011 -- HF sniff -// 100 -- HF ISO18092 FeliCa -// 101 -- HF get trace -// 110 -- unused -// 111 -- FPGA_MAJOR_MODE_OFF - -// 000 001 010 011 100 101 110 111 - -mux8 mux_ssp_clk (major_mode, ssp_clk, hr_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, gt_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, hr_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, gt_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, hr_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, gt_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, hr_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 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, hfl_pwr_oe2, 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, hfl_pwr_oe3, 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, hfl_pwr_oe4, 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, hfl_pwr_lo, 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, hfl_pwr_hi, 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, hfl_adc_clk, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, hr_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0, 1'b0); - -// In all modes, let the ADC's outputs be enabled. -assign adc_noe = 1'b0; - -endmodule diff --git a/fpga-xc2s30/fpga_hf_15.bit b/fpga-xc2s30/fpga_hf_15.bit deleted file mode 100644 index 5d99a0032..000000000 Binary files a/fpga-xc2s30/fpga_hf_15.bit and /dev/null differ diff --git a/fpga-xc2s30/fpga_hf_15.v b/fpga-xc2s30/fpga_hf_15.v deleted file mode 100644 index b107ec180..000000000 --- a/fpga-xc2s30/fpga_hf_15.v +++ /dev/null @@ -1,233 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// -// The FPGA is responsible for interfacing between the A/D, the coil drivers, -// and the ARM. In the low-frequency modes it passes the data straight -// through, so that the ARM gets raw A/D samples over the SSP. In the high- -// frequency modes, the FPGA might perform some demodulation first, to -// reduce the amount of data that we must send to the ARM. -//----------------------------------------------------------------------------- - - -// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h -// Note: the definitions here are without shifts - -// Commands: -`define FPGA_CMD_SET_CONFREG 1 -`define FPGA_CMD_TRACE_ENABLE 2 - -// Major modes: -`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_SNIFF 3 -`define FPGA_MAJOR_MODE_HF_ISO18092 4 -`define FPGA_MAJOR_MODE_HF_GET_TRACE 5 -`define FPGA_MAJOR_MODE_HF_FSK_READER 6 -`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_MODE_SEND_JAM 8 - -`define FPGA_HF_READER_SUBCARRIER_848_KHZ 0 -`define FPGA_HF_READER_SUBCARRIER_424_KHZ 1 -`define FPGA_HF_READER_SUBCARRIER_212_KHZ 2 -`define FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ 3 - -`define FPGA_HF_FSK_READER_OUTPUT_1695_KHZ 0 -`define FPGA_HF_FSK_READER_OUTPUT_848_KHZ 1 -`define FPGA_HF_FSK_READER_OUTPUT_424_KHZ 2 -`define FPGA_HF_FSK_READER_OUTPUT_212_KHZ 3 - -`define FPGA_HF_FSK_READER_NOPOWER 0 -`define FPGA_HF_FSK_READER_WITHPOWER 1 - -// 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 - -//options for ISO18092 / Felica -`define FPGA_HF_ISO18092_FLAG_NOMOD 1 // 0001 disable modulation module -`define FPGA_HF_ISO18092_FLAG_424K 2 // 0010 should enable 414k mode (untested). No autodetect -`define FPGA_HF_ISO18092_FLAG_READER 4 // 0100 enables antenna power, to act as a reader instead of tag - -`include "hi_reader_15.v" -`include "hi_simulate.v" -`include "hi_sniffer.v" -`include "util.v" -`include "hi_get_trace.v" - -module fpga_hf_15( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg -); - -//----------------------------------------------------------------------------- -// The SPI receiver. This sets up the configuration word, which the rest of -// the logic looks at to determine how to connect the A/D and the coil -// drivers (i.e., which section gets it). Also assign some symbolic names -// to the configuration bits, for use below. -//----------------------------------------------------------------------------- - -/* - Attempt to write up how its hooked up. - / Iceman, 2020 - - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA - The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where - C is 4bit command - D is 12bit data - - shift_reg receive this 16bit frame - - ------+--------- frame layout -------------------- -bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------+------------------------------------------- -cmd | x x x x -major| x x x -opt | x x x x -sub | x x -divi | x x x x x x x x -thres| x x x x x x x x ------+------------------------------------------- -*/ - -reg [15:0] shift_reg; -reg [8:0] conf_word; -reg trace_enable; - -// We switch modes between transmitting to the 13.56 MHz tag and receiving -// from it, which means that we must make sure that we can do so without -// glitching, or else we will glitch the transmitted carrier. -always @(posedge ncs) -begin - case(shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; - `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; - endcase -end - -always @(posedge spck) -begin - if(~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end -end - -// select module (outputs) based on major mode -wire [2:0] major_mode = conf_word[8:6]; - -// configuring the HF reader -wire [1:0] subcarrier_frequency = conf_word[5:4]; -wire [3:0] minor_mode = conf_word[3:0]; - -//----------------------------------------------------------------------------- -// And then we instantiate the modules corresponding to each of the FPGA's -// major modes, and use muxes to connect the outputs of the active mode to -// the output pins. -//----------------------------------------------------------------------------- - -// 000 - HF 15 reader -hi_15_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 -); - -// 001 - HF simulated tag -hi_simulate hs( - 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, - hs_dbg, - minor_mode -); - -// 011 - HF sniff -hi_sniffer he( - 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 -); - -// 101 - HF get trace -hi_get_trace gt( - ck_1356megb, - adc_d, trace_enable, major_mode, - gt_ssp_frame, gt_ssp_din, gt_ssp_clk -); - -// Major modes: -// 000 -- HF 15 reader; subcarrier frequency and modulation depth selectable -// 001 -- HF simulated tag -// 010 -- -// 011 -- HF sniff -// 100 -- -// 101 -- HF get trace -// 110 -- unused -// 111 -- FPGA_MAJOR_MODE_OFF - -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, hr_ssp_clk, hs_ssp_clk, 1'b0, he_ssp_clk, 1'b0, gt_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, hr_ssp_din, hs_ssp_din, 1'b0, he_ssp_din, 1'b0, gt_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, hr_ssp_frame, hs_ssp_frame, 1'b0, he_ssp_frame, 1'b0, gt_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, hr_pwr_oe1, hs_pwr_oe1, 1'b0, 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, 1'b0, 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, 1'b0, 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, 1'b0, 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, 1'b0, 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, 1'b0, 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, 1'b0, he_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, hr_dbg, hs_dbg, 1'b0, he_dbg, 1'b0, 1'b0, 1'b0, 1'b0); - -// In all modes, let the ADC's outputs be enabled. -assign adc_noe = 1'b0; - -endmodule diff --git a/fpga-xc2s30/fpga_lf.bit b/fpga-xc2s30/fpga_lf.bit deleted file mode 100644 index f5e5ce630..000000000 Binary files a/fpga-xc2s30/fpga_lf.bit and /dev/null differ diff --git a/fpga-xc2s30/fpga_lf.v b/fpga-xc2s30/fpga_lf.v deleted file mode 100644 index bb9116f10..000000000 --- a/fpga-xc2s30/fpga_lf.v +++ /dev/null @@ -1,245 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// - - -// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h -// Note: the definitions here are without shifts - -// Commands: -`define FPGA_CMD_SET_CONFREG 1 -`define FPGA_CMD_SET_DIVISOR 2 -`define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD 3 - -// Major modes: -`define FPGA_MAJOR_MODE_LF_READER 0 -`define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 -`define FPGA_MAJOR_MODE_LF_PASSTHRU 2 -`define FPGA_MAJOR_MODE_LF_ADC 3 - -// Options for LF_READER -`define FPGA_LF_ADC_READER_FIELD 1 - -// Options for LF_EDGE_DETECT -`define FPGA_LF_EDGE_DETECT_READER_FIELD 1 -`define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 2 - -`include "lo_read.v" -`include "lo_passthru.v" -`include "lo_edge_detect.v" -`include "lo_adc.v" -`include "util.v" -`include "clk_divider.v" - -module fpga_lf( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg -); - -//----------------------------------------------------------------------------- -// The SPI receiver. This sets up the configuration word, which the rest of -// the logic looks at to determine how to connect the A/D and the coil -// drivers (i.e., which section gets it). Also assign some symbolic names -// to the configuration bits, for use below. -//----------------------------------------------------------------------------- - -/* - Attempt to write up how its hooked up. Iceman 2020. - - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA - The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where - C is 4bit command - D is 12bit data - - shift_reg receive this 16bit frame - - LF command - ---------- - shift_reg[15:12] == 4bit command - LF has three commands (FPGA_CMD_SET_CONFREG, FPGA_CMD_SET_DIVISOR, FPGA_CMD_SET_EDGE_DETECT_THRESHOLD) - Current commands uses only 2bits. We have room for up to 4bits of commands total (7). - - LF data - ------- - shift_reg[11:0] == 12bit data - lf data is divided into MAJOR MODES and configuration values. - - The major modes uses 3bits (0,1,2,3,7 | 000, 001, 010, 011, 111) - 000 FPGA_MAJOR_MODE_LF_READER = Act as LF reader (modulate) - 001 FPGA_MAJOR_MODE_LF_EDGE_DETECT = Simulate LF - 010 FPGA_MAJOR_MODE_LF_PASSTHRU = Passthrough mode, CROSS_LO line connected to SSP_DIN. SSP_DOUT logic level controls if we modulate / listening - 011 FPGA_MAJOR_MODE_LF_ADC = refactor hitag2, clear ADC sampling - 111 FPGA_MAJOR_MODE_OFF = turn off sampling. - - Each one of this major modes can have options. Currently these two major modes uses options. - - FPGA_MAJOR_MODE_LF_READER - - FPGA_MAJOR_MODE_LF_EDGE_DETECT - - FPGA_MAJOR_MODE_LF_READER - ------------------------------------- - lf_field = 1bit (FPGA_LF_ADC_READER_FIELD) - - You can send FPGA_CMD_SET_DIVISOR to set with FREQUENCY the fpga should sample at - divisor = 8bits shift_reg[7:0] - - FPGA_MAJOR_MODE_LF_EDGE_DETECT - ------------------------------------------ - lf_ed_toggle_mode = 1bits - lf_ed_threshold = 8bits threshold defaults to 127 - - You can send FPGA_CMD_SET_EDGE_DETECT_THRESHOLD to set a custom threshold - lf_ed_threshold = 8bits threshold value. - - conf_word 12bits - conf_word[8:6] = 3bit major mode. - conf_word[0] = 1bit lf_field - conf_word[1] = 1bit lf_ed_toggle_mode - conf_word[7:0] = 8bit divisor - conf_word[7:0] = 8bit threshold - ------+--------- frame layout -------------------- -bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------+------------------------------------------- -cmd | x x x x -major| x x x -opt | x x -divi | x x x x x x x x -thres| x x x x x x x x ------+------------------------------------------- -*/ - -reg [15:0] shift_reg; -reg [7:0] divisor; -reg [7:0] lf_ed_threshold; -reg [11:0] conf_word; - -wire [2:0] major_mode = conf_word[8:6]; -wire lf_field = conf_word[0]; -wire lf_ed_toggle_mode = conf_word[1]; - -// Handles cmd / data frame from ARM -always @(posedge ncs) -begin - // 4 bit command - case (shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: - begin - // 12 bit data - conf_word <= shift_reg[11:0]; - if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) - begin - lf_ed_threshold <= 127; // default threshold - end - end - - `FPGA_CMD_SET_DIVISOR: - divisor <= shift_reg[7:0]; // 8bits - - `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: - lf_ed_threshold <= shift_reg[7:0]; // 8 bits - endcase -end - -// Receive 16bits of data from ARM here. -always @(posedge spck) -begin - if (~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end -end - -//----------------------------------------------------------------------------- -// And then we instantiate the modules corresponding to each of the FPGA's -// major modes, and use muxes to connect the outputs of the active mode to -// the output pins. -//----------------------------------------------------------------------------- -wire [7:0] pck_cnt; -wire pck_divclk; -clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk); - -lo_read lr( - pck0, pck_cnt, pck_divclk, - lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4, - adc_d, lr_adc_clk, - lr_ssp_frame, lr_ssp_din, lr_ssp_clk, - lr_dbg, lf_field -); - -lo_passthru lp( - pck_divclk, - lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4, - lp_adc_clk, - lp_ssp_din, ssp_dout, - cross_lo, - lp_dbg -); - -lo_edge_detect le( - pck0, pck_divclk, - le_pwr_lo, le_pwr_hi, le_pwr_oe1, le_pwr_oe2, le_pwr_oe3, le_pwr_oe4, - adc_d, le_adc_clk, - le_ssp_frame, ssp_dout, le_ssp_clk, - cross_lo, - le_dbg, - lf_field, - lf_ed_toggle_mode, lf_ed_threshold -); - -lo_adc la( - pck0, - la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, - adc_d, la_adc_clk, - la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, - la_dbg, divisor, - lf_field -); - -// Major modes: -// 000 -- LF reader (generic) -// 001 -- LF edge detect (generic) -// 010 -- LF passthrough -// 011 -- LF ADC (read/write) -// 100 -- unused -// 101 -- unused -// 110 -- unused -// 111 -- FPGA_MAJOR_MODE_OFF -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); - -// In all modes, let the ADC's outputs be enabled. -assign adc_noe = 1'b0; - -endmodule diff --git a/fpga-xc2s30/go.bat b/fpga-xc2s30/go.bat deleted file mode 100644 index d9704e08d..000000000 --- a/fpga-xc2s30/go.bat +++ /dev/null @@ -1,68 +0,0 @@ -@echo off - -rmdir/s/q xst - -del fpga_lf.ngc -xst -ifn xst_lf.scr -if errorlevel 0 goto ok1 -goto done -:ok1 - -del fpga_lf.ngd -ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga_lf.ngc fpga_lf.ngd -if errorlevel 0 goto ok2 -goto done -:ok2 - -del fpga_lf.ncd -map -p xc2s30-6vq100 fpga_lf.ngd -if errorlevel 0 goto ok3 -goto done -:ok3 - -del fpga_lf-placed.ncd -par fpga_lf.ncd fpga_lf-placed.ncd -if errorlevel 0 goto ok4 -goto done -:ok4 - -del fpga_lf.bit fpga_lf.drc fpga_lf.rbt -bitgen -b fpga_lf-placed.ncd fpga_lf.bit -if errorlevel 0 goto ok5 -goto done -:ok5 - -del fpga_hf.ngc -xst -ifn xst_hf.scr -if errorlevel 0 goto ok6 -goto done -:ok6 - -del fpga_hf.ngd -ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga_hf.ngc fpga_hf.ngd -if errorlevel 0 goto ok7 -goto done -:ok7 - -del fpga_hf.ncd -map -p xc2s30-6vq100 fpga_hf.ngd -if errorlevel 0 goto ok8 -goto done -:ok8 - -del fpga_hf-placed.ncd -par fpga_hf.ncd fpga_hf-placed.ncd -if errorlevel 0 goto ok9 -goto done -:ok9 - -del fpga_hf.bit fpga_hf.drc fpga_hf.rbt -bitgen -b fpga_hf-placed.ncd fpga_hf.bit -if errorlevel 0 goto ok10 -goto done -:ok10 - -echo okay -perl ..\tools\rbt2c.pl fpga_lf.rbt > ..\armsrc\fpgaimg.c - -:done diff --git a/fpga-xc2s30/xst_felica.scr b/fpga-xc2s30/xst_felica.scr deleted file mode 100644 index b069fab13..000000000 --- a/fpga-xc2s30/xst_felica.scr +++ /dev/null @@ -1 +0,0 @@ -run -ifn fpga_felica.v -ifmt Verilog -ofn fpga_felica.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_felica -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact diff --git a/fpga-xc2s30/xst_hf.scr b/fpga-xc2s30/xst_hf.scr deleted file mode 100644 index dd2fdc859..000000000 --- a/fpga-xc2s30/xst_hf.scr +++ /dev/null @@ -1 +0,0 @@ -run -ifn fpga_hf.v -ifmt Verilog -ofn fpga_hf.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_hf -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact diff --git a/fpga-xc2s30/xst_hf_15.scr b/fpga-xc2s30/xst_hf_15.scr deleted file mode 100644 index d8bb5ae7c..000000000 --- a/fpga-xc2s30/xst_hf_15.scr +++ /dev/null @@ -1 +0,0 @@ -run -ifn fpga_hf_15.v -ifmt Verilog -ofn fpga_hf_15.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_hf_15 -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact diff --git a/fpga-xc2s30/xst_lf.scr b/fpga-xc2s30/xst_lf.scr deleted file mode 100644 index 2d6c7e951..000000000 --- a/fpga-xc2s30/xst_lf.scr +++ /dev/null @@ -1 +0,0 @@ -run -ifn fpga_lf.v -ifmt Verilog -ofn fpga_lf.ngc -ofmt NGC -p xc2s30-5-vq100 -top fpga_lf -opt_mode area -opt_level 2 -resource_sharing yes -fsm_style bram -fsm_encoding compact diff --git a/fpga-xc3s100e/.gitignore b/fpga-xc3s100e/.gitignore deleted file mode 100644 index b21d41545..000000000 --- a/fpga-xc3s100e/.gitignore +++ /dev/null @@ -1,68 +0,0 @@ -# intermediate build files -*.bgn -*.bit -*.bld -*.cmd_log -*.drc -*.ll -*.lso -*.msd -*.msk -*.ncd -*.ngc -*.ngd -*.ngr -*.pad -*.par -*.pcf -*.prj -*.ptwx -*.rbb -*.rbd -*.stx -*.syr -*.twr -*.twx -*.unroutes -*.ut -*.xpi -*.xst -*_bitgen.xwbt -*_envsettings.html -*_map.map -*_map.mrp -*_map.ngm -*_map.xrpt -*_ngdbuild.xrpt -*_pad.csv -*_pad.txt -*_par.xrpt -*_summary.html -*_summary.xml -*_usage.xml -*_xst.xrpt - -# iMPACT generated files -_impactbatch.log -impact.xsl -impact_impact.xwbt -ise_impact.cmd -webtalk_impact.xml - -# Core Generator generated files -xaw2verilog.log - -# project-wide generated files -*.gise -par_usage_statistics.html -usage_statistics_webtalk.html -webtalk.log -webtalk_pn.xml - -# generated folders -iseconfig/ -xlnx_auto_0_xdb/ -xst/ -_ngo/ -_xmsgs/ -fpga_hf_xdb/tmp/ diff --git a/fpga-xc3s100e/clk_divider.v b/fpga-xc3s100e/clk_divider.v deleted file mode 100644 index 9a57879b0..000000000 --- a/fpga-xc3s100e/clk_divider.v +++ /dev/null @@ -1,25 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -module clk_divider(input clk, input [7:0] divisor, output [7:0] div_cnt, output div_clk); - - reg [7:0] div_cnt_ = 0; - reg div_clk_; - assign div_cnt = div_cnt_; - assign div_clk = div_clk_; - - always @(posedge clk) - begin - if(div_cnt == divisor) begin - div_cnt_ <= 8'd0; - div_clk_ = !div_clk_; - end else - div_cnt_ <= div_cnt_ + 1; - end - -endmodule - diff --git a/fpga-xc3s100e/compile.sh b/fpga-xc3s100e/compile.sh deleted file mode 100755 index 741ed0bb8..000000000 --- a/fpga-xc3s100e/compile.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -( - cd iseproj/fpga_hf - xtclsh fpga_hf.tcl run_process - mv fpga_hf.bit ../.. - git checkout fpga_hf.ise - git clean -dfx . -) diff --git a/fpga-xc3s100e/define.v b/fpga-xc3s100e/define.v deleted file mode 100644 index adced9003..000000000 --- a/fpga-xc3s100e/define.v +++ /dev/null @@ -1,49 +0,0 @@ -// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h -// Note: the definitions here are without shifts - -// Commands: -`define FPGA_CMD_SET_CONFREG 1 -`define FPGA_CMD_TRACE_ENABLE 2 - -// Major modes: -`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_SNIFF 3 -`define FPGA_MAJOR_MODE_HF_ISO18092 4 -`define FPGA_MAJOR_MODE_HF_GET_TRACE 5 -`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_MODE_SEND_JAM 8 - -`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 - -//options for ISO18092 / Felica -`define FPGA_HF_ISO18092_FLAG_NOMOD 1 // 0001 disable modulation module -`define FPGA_HF_ISO18092_FLAG_424K 2 // 0010 should enable 414k mode (untested). No autodetect -`define FPGA_HF_ISO18092_FLAG_READER 4 // 0100 enables antenna power, to act as a reader instead of tag diff --git a/fpga-xc3s100e/fpga.ucf b/fpga-xc3s100e/fpga.ucf deleted file mode 100644 index 4cb06a9d6..000000000 --- a/fpga-xc3s100e/fpga.ucf +++ /dev/null @@ -1,56 +0,0 @@ -# See the schematic for the pin assignment. - -#NET "cross_hi" LOC = "P88" ; -#NET "miso" LOC = "P40" ; - -# definition of Clock nets: -NET "ck_1356meg" TNM_NET = "clk_net_1356" ; -NET "ck_1356megb" TNM_NET = "clk_net_1356b" ; -NET "pck0" TNM_NET = "clk_net_pck0" ; -NET "spck" TNM_NET = "clk_net_spck" ; - -# Timing specs of clock nets: -TIMEGRP "clk_net_1356_all" = "clk_net_1356" "clk_net_1356b" ; -TIMESPEC "TS_1356MHz" = PERIOD "clk_net_1356_all" 74 ns HIGH 37 ns ; -TIMESPEC "TS_24MHz" = PERIOD "clk_net_pck0" 42 ns HIGH 21 ns ; -TIMESPEC "TS_4MHz" = PERIOD "clk_net_spck" 250 ns HIGH 125 ns ; -NET "FPGA_SWITCH" CLOCK_DEDICATED_ROUTE = FALSE ; -#PACE: Start of Constraints generated by PACE - -#PACE: Start of PACE I/O Pin Assignments -NET "adc_clk" LOC = "P65" ; -NET "adc_d<0>" LOC = "P79" ; -NET "adc_d<1>" LOC = "P78" ; -NET "adc_d<2>" LOC = "P71" ; -NET "adc_d<3>" LOC = "P70" ; -NET "adc_d<4>" LOC = "P69" ; -NET "adc_d<5>" LOC = "P68" ; -NET "adc_d<6>" LOC = "P67" ; -NET "adc_d<7>" LOC = "P66" ; -NET "adc_noe" LOC = "P62" ; -NET "ck_1356meg" LOC = "p88" ; -NET "ck_1356megb" LOC = "p89" ; -NET "cross_lo" LOC = "P90" ; -NET "dbg" LOC = "P22" ; -NET "FPGA_SWITCH" LOC = "P38" ; -NET "mosi" LOC = "P43" ; -NET "ncs" LOC = "P40" ; -NET "pck0" LOC = "P36" ; -NET "pwr_hi" LOC = "P85" ; -NET "pwr_lo" LOC = "P83" ; -NET "PWR_LO_EN" LOC = "P94" ; -NET "pwr_oe1" LOC = "P84" ; -NET "pwr_oe2" LOC = "P91" ; -NET "pwr_oe3" LOC = "P92" ; -NET "pwr_oe4" LOC = "P86" ; -NET "spck" LOC = "P39" ; -NET "ssp_clk" LOC = "P33" ; -NET "ssp_din" LOC = "P32" ; -NET "ssp_dout" LOC = "P34" ; -NET "ssp_frame" LOC = "P27" ; - -#PACE: Start of PACE Area Constraints - -#PACE: Start of PACE Prohibit Constraints - -#PACE: End of Constraints generated by PACE diff --git a/fpga-xc3s100e/fpga_hf.bit b/fpga-xc3s100e/fpga_hf.bit deleted file mode 100644 index df1fb45f6..000000000 Binary files a/fpga-xc3s100e/fpga_hf.bit and /dev/null differ diff --git a/fpga-xc3s100e/fpga_hfmod.v b/fpga-xc3s100e/fpga_hfmod.v deleted file mode 100644 index 53040aead..000000000 --- a/fpga-xc3s100e/fpga_hfmod.v +++ /dev/null @@ -1,193 +0,0 @@ -//----------------------------------------------------------------------------- -// The FPGA is responsible for interfacing between the A/D, the coil drivers, -// and the ARM. In the low-frequency modes it passes the data straight -// through, so that the ARM gets raw A/D samples over the SSP. In the high- -// frequency modes, the FPGA might perform some demodulation first, to -// reduce the amount of data that we must send to the ARM. -// -// I am not really an FPGA/ASIC designer, so I am sure that a lot of this -// could be improved. -// -// Jonathan Westhues, March 2006 -// Added ISO14443-A support by Gerhard de Koning Gans, April 2008 -// iZsh , June 2014 -// Piwi, Feb 2019 -//----------------------------------------------------------------------------- - -//For ISE 10.1 PROJ,IDE cannot apply definition to all files -`include "define.v" - - -//For ISE 10.1 PROJ,IDE auto include -//`include "hi_reader.v" -//`include "hi_simulate.v" -//`include "hi_iso14443a.v" -//`include "hi_sniffer.v" -//`include "util.v" -//`include "hi_flite.v" -//`include "hi_get_trace.v" - -module fpga_hfmod( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg -); - -//----------------------------------------------------------------------------- -// The SPI receiver. This sets up the configuration word, which the rest of -// the logic looks at to determine how to connect the A/D and the coil -// drivers (i.e., which section gets it). Also assign some symbolic names -// to the configuration bits, for use below. -//----------------------------------------------------------------------------- - -/* - Attempt to write up how its hooked up. Iceman 2020. - - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA - The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where - C is 4bit command - D is 12bit data - - shift_reg receive this 16bit frame - - ------+--------- frame layout -------------------- -bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------+------------------------------------------- -cmd | x x x x -major| x x x -opt | x x x -divi | x x x x x x x x -thres| x x x x x x x x ------+------------------------------------------- -*/ - -reg [15:0] shift_reg; -reg [8:0] conf_word; -reg trace_enable; - -// We switch modes between transmitting to the 13.56 MHz tag and receiving -// from it, which means that we must make sure that we can do so without -// glitching, or else we will glitch the transmitted carrier. -always @(posedge ncs) -begin - case(shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; - `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; - endcase -end - -always @(posedge spck) -begin - if(~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end -end - -// select module (outputs) based on major mode -wire [2:0] major_mode = conf_word[8:6]; - -// configuring the HF reader -wire [1:0] subcarrier_frequency = conf_word[5:4]; -wire [3:0] minor_mode = conf_word[3:0]; - -//----------------------------------------------------------------------------- -// And then we instantiate the modules corresponding to each of the FPGA's -// major modes, and use muxes to connect the outputs of the active mode to -// the output pins. -//----------------------------------------------------------------------------- - -// 000 - HF reader -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 -); - -// 001 - HF simulated tag -hi_simulate hs( - 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, - hs_dbg, - minor_mode -); - -// 010 - HF ISO14443-A -hi_iso14443a hisn( - 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, - hisn_dbg, - minor_mode -); - -// 011 - HF sniff -hi_sniffer he( - 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 -); - -// 100 - HF ISO18092 FeliCa - -hi_flite hfl( - ck_1356megb, - hfl_pwr_lo, hfl_pwr_hi, hfl_pwr_oe1, hfl_pwr_oe2, hfl_pwr_oe3, hfl_pwr_oe4, - adc_d, hfl_adc_clk, - hfl_ssp_frame, hfl_ssp_din, ssp_dout, hfl_ssp_clk, - hfl_dbg, - minor_mode -); - - -// 101 - HF get trace -hi_get_trace gt( - ck_1356megb, - adc_d, trace_enable, major_mode, - gt_ssp_frame, gt_ssp_din, gt_ssp_clk -); - -// Major modes: -// 000 -- HF reader; subcarrier frequency and modulation depth selectable -// 001 -- HF simulated tag -// 010 -- HF ISO14443-A -// 011 -- HF sniff -// 100 -- HF ISO18092 FeliCa -// 101 -- HF get trace -// 110 -- unused -// 111 -- FPGA_MAJOR_MODE_OFF - -// 000 001 010 011 100 101 110 111 - -mux8 mux_ssp_clk (major_mode, ssp_clk, hr_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, gt_ssp_clk, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, hr_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, gt_ssp_din, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, hr_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, gt_ssp_frame, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, hr_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 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, hfl_pwr_oe2, 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, hfl_pwr_oe3, 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, hfl_pwr_oe4, 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, hfl_pwr_lo, 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, hfl_pwr_hi, 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, hfl_adc_clk, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, hr_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0, 1'b0); - -// In all modes, let the ADC's outputs be enabled. -assign adc_noe = 1'b0; - -endmodule diff --git a/fpga-xc3s100e/fpga_lfmod.v b/fpga-xc3s100e/fpga_lfmod.v deleted file mode 100644 index 5982a74e8..000000000 --- a/fpga-xc3s100e/fpga_lfmod.v +++ /dev/null @@ -1,236 +0,0 @@ -//----------------------------------------------------------------------------- -// Jonathan Westhues, March 2006 -// iZsh , June 2014 -// Piwi, Feb 2019 -// Anon, 2019 -//----------------------------------------------------------------------------- -// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h -// Note: the definitions here are without shifts - -// Commands: -`define FPGA_CMD_SET_CONFREG 1 -`define FPGA_CMD_SET_DIVISOR 2 -`define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD 3 - -// Major modes: -`define FPGA_MAJOR_MODE_LF_READER 0 -`define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 -`define FPGA_MAJOR_MODE_LF_PASSTHRU 2 -`define FPGA_MAJOR_MODE_LF_ADC 3 - -// Options for LF_READER -`define FPGA_LF_ADC_READER_FIELD 1 - -// Options for LF_EDGE_DETECT -`define FPGA_LF_EDGE_DETECT_READER_FIELD 1 -`define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 2 - -//For ISE 10.1 PROJ,IDE auto include -//`include "lo_read.v" -//`include "lo_passthru.v" -//`include "lo_edge_detect.v" -//`include "lo_adc.v" -//`include "util.v" -//`include "clk_divider.v" - -module fpga_lfmod( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, - output dbg, - output PWR_LO_EN -); - -//----------------------------------------------------------------------------- -// The SPI receiver. This sets up the configuration word, which the rest of -// the logic looks at to determine how to connect the A/D and the coil -// drivers (i.e., which section gets it). Also assign some symbolic names -// to the configuration bits, for use below. -//----------------------------------------------------------------------------- - -/* - Attempt to write up how its hooked up. Iceman 2020. - - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA - The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - where - C is 4bit command - D is 12bit data - - shift_reg receive this 16bit frame - - LF command - ---------- - shift_reg[15:12] == 4bit command - LF has three commands (FPGA_CMD_SET_CONFREG, FPGA_CMD_SET_DIVISOR, FPGA_CMD_SET_EDGE_DETECT_THRESHOLD) - Current commands uses only 2bits. We have room for up to 4bits of commands total (7). - - LF data - ------- - shift_reg[11:0] == 12bit data - lf data is divided into MAJOR MODES and configuration values. - - The major modes uses 3bits (0,1,2,3,7 | 000, 001, 010, 011, 111) - 000 FPGA_MAJOR_MODE_LF_READER = Act as LF reader (modulate) - 001 FPGA_MAJOR_MODE_LF_EDGE_DETECT = Simulate LF - 010 FPGA_MAJOR_MODE_LF_PASSTHRU = Passthrough mode, CROSS_LO line connected to SSP_DIN. SSP_DOUT logic level controls if we modulate / listening - 011 FPGA_MAJOR_MODE_LF_ADC = refactor hitag2, clear ADC sampling - 111 FPGA_MAJOR_MODE_OFF = turn off sampling. - - Each one of this major modes can have options. Currently these two major modes uses options. - - FPGA_MAJOR_MODE_LF_READER - - FPGA_MAJOR_MODE_LF_EDGE_DETECT - - FPGA_MAJOR_MODE_LF_READER - ------------------------------------- - lf_field = 1bit (FPGA_LF_ADC_READER_FIELD) - - You can send FPGA_CMD_SET_DIVISOR to set with FREQUENCY the fpga should sample at - divisor = 8bits shift_reg[7:0] - - FPGA_MAJOR_MODE_LF_EDGE_DETECT - ------------------------------------------ - lf_ed_toggle_mode = 1bits - lf_ed_threshold = 8bits threshold defaults to 127 - - You can send FPGA_CMD_SET_EDGE_DETECT_THRESHOLD to set a custom threshold - lf_ed_threshold = 8bits threshold value. - - conf_word 12bits - conf_word[7:5] = 3bit major mode. - conf_word[0] = 1bit lf_field - conf_word[1] = 1bit lf_ed_toggle_mode - conf_word[7:0] = 8bit divisor - conf_word[7:0] = 8bit threshold - ------+--------- frame layout -------------------- -bit | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------+------------------------------------------- -cmd | x x x x -major| x x x -opt | x x -divi | x x x x x x x x -thres| x x x x x x x x ------+------------------------------------------- -*/ - -reg [15:0] shift_reg; -reg [7:0] divisor; -reg [7:0] lf_ed_threshold; -reg [11:0] conf_word; - -wire [2:0] major_mode = conf_word[8:6]; -wire lf_field = conf_word[0]; -wire lf_ed_toggle_mode = conf_word[1]; - -// Handles cmd / data frame from ARM -always @(posedge ncs) -begin - // 4 bit command - case (shift_reg[15:12]) - `FPGA_CMD_SET_CONFREG: - begin - // 12 bit data - conf_word <= shift_reg[11:0]; - if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) - begin - lf_ed_threshold <= 127; // default threshold - end - end - - `FPGA_CMD_SET_DIVISOR: - divisor <= shift_reg[7:0]; // 8bits - - `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: - lf_ed_threshold <= shift_reg[7:0]; // 8 bits - endcase -end - -// Receive 16bits of data from ARM here. -always @(posedge spck) -begin - if (~ncs) - begin - shift_reg[15:1] <= shift_reg[14:0]; - shift_reg[0] <= mosi; - end -end - -//----------------------------------------------------------------------------- -// And then we instantiate the modules corresponding to each of the FPGA's -// major modes, and use muxes to connect the outputs of the active mode to -// the output pins. -//----------------------------------------------------------------------------- -wire [7:0] pck_cnt; -wire pck_divclk; -clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk); - -lo_read lr( - pck0, pck_cnt, pck_divclk, - lr_pwr_lo, lr_pwr_hi, lr_pwr_oe1, lr_pwr_oe2, lr_pwr_oe3, lr_pwr_oe4, - adc_d, lr_adc_clk, - lr_ssp_frame, lr_ssp_din, lr_ssp_clk, - lr_dbg, lf_field -); - -lo_passthru lp( - pck_divclk, - lp_pwr_lo, lp_pwr_hi, lp_pwr_oe1, lp_pwr_oe2, lp_pwr_oe3, lp_pwr_oe4, - lp_adc_clk, - lp_ssp_din, ssp_dout, - cross_lo, - lp_dbg -); - -lo_edge_detect le( - pck0, pck_divclk, - le_pwr_lo, le_pwr_hi, le_pwr_oe1, le_pwr_oe2, le_pwr_oe3, le_pwr_oe4, - adc_d, le_adc_clk, - le_ssp_frame, ssp_dout, le_ssp_clk, - cross_lo, - le_dbg, - lf_field, - lf_ed_toggle_mode, lf_ed_threshold -); - -lo_adc la( - pck0, - la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, - adc_d, la_adc_clk, - la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, - la_dbg, divisor, - lf_field -); - -// Major modes: -// 000 -- LF reader (generic) -// 001 -- LF edge detect (generic) -// 010 -- LF passthrough -// 011 -- LF ADC (read/write) -// 100 -- unused -// 101 -- unused -// 110 -- unused -// 111 -- FPGA_MAJOR_MODE_OFF -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ant (major_mode, PWR_LO_EN, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0); - -// In all modes, let the ADC's outputs be enabled. -assign adc_noe = 1'b0; - -endmodule diff --git a/fpga-xc3s100e/hi_flite.v b/fpga-xc3s100e/hi_flite.v deleted file mode 100644 index 6cb87825e..000000000 --- a/fpga-xc3s100e/hi_flite.v +++ /dev/null @@ -1,368 +0,0 @@ -/* - This code demodulates and modulates signal as described in ISO/IEC 18092. - That includes packets used for Felica, NFC Tag 3, etc. (which do overlap) - simple envelope following algorithm is used (modification of fail0verflow LF one) - is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave) - - Speeds supported: only 212 kbps (fc/64) for now. Todo: 414 kbps - though for reader, the selection has to come from ARM. modulation waits for market sprocket -doesn't really mean anything - - mod_type: bits 210: - bit 2 : reader drive/power on/off - bit 1 : speed bit, 0 : 212, 1 :424 - bit 0 : listen or modulate -*/ - -module hi_flite( - 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, - mod_type -); - 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 [3:0] mod_type; - -assign dbg = 0; - -wire power = mod_type[2]; -wire speed = mod_type[1]; -wire disabl = mod_type[0]; - -// Most off, oe4 for modulation; -// Trying reader emulation (would presumably just require switching power on, but I am not sure) -assign pwr_lo = 1'b0; - -// 512x64/fc -wait before ts0, 32768 ticks -// tslot: 256*64/fc -assign adc_clk = ck_1356meg; - -///heuristic values for initial thresholds. seem to work OK -`define imin 70 // (13'd256) -`define imax 180 // (-13'd256) -`define ithrmin 91 // -13'd8 -`define ithrmax 160 // 13'd8 - -`define min_bitdelay_212 8 -//minimum values and corresponding thresholds -reg [8:0] curmin=`imin; -reg [8:0] curminthres=`ithrmin; -reg [8:0] curmaxthres=`ithrmax; -reg [8:0] curmax=`imax; - -//signal state, 1-not modulated, 0 -modulated -reg after_hysteresis = 1'b1; - -//state machine for envelope tracking -reg [1:0] state=1'd0; - -//lower edge detected, trying to detect first bit of SYNC (b24d, 1011001001001101) -reg try_sync=1'b0; - -//detected first sync bit, phase frozen -reg did_sync=0; - -`define bithalf_212 32 // half-bit length for 212 kbit -`define bitmlen_212 63 // bit transition edge - -`define bithalf_424 16 // half-bit length for 212 kbit -`define bitmlen_424 31 // bit transition edge - -wire [7:0] bithalf = speed ? `bithalf_424 : `bithalf_212; -wire [7:0] bitmlen = speed ? `bitmlen_424 : `bitmlen_212; - - -//ssp clock and current values -reg ssp_clk; -reg ssp_frame; -reg curbit = 1'b0; - -reg [7:0] fccount = 8'd0; // in-bit tick counter. Counts carrier cycles from the first lower edge detected, reset on every manchester bit detected - -reg [7:0] tsinceedge = 8'd0;// ticks from last edge, desync if the valye is too large - -reg zero = 1'b0; // Manchester first halfbit low second high corresponds to this value. It has been known to change. SYNC is used to set it - -//ssp counter for transfer and framing -reg [8:0] ssp_cnt = 9'd0; - -always @(posedge adc_clk) - ssp_cnt <= (ssp_cnt + 1); - -//maybe change it so that ARM sends preamble as well. -//then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation - -always @(negedge adc_clk) -begin - //count fc/64 - transfer bits to ARM at the rate they are received - if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed && (ssp_cnt[4:0] == 5'b00000))) - begin - ssp_clk <= 1'b1; - ssp_din <= curbit; - end - if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) - ssp_clk <= 1'b0; - //create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason - // took me a day to figure THAT out. - if(( (~speed) && (ssp_cnt[8:0] == 9'd31)) || (speed && ssp_cnt[7:0] == 8'd15)) - begin - ssp_frame <= 1'b1; - end - if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111)) || (speed &&ssp_cnt[7:0] == 8'b101111) ) - begin - ssp_frame <= 1'b0; - end -end - -//send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) -reg ssp_din; - -//previous signal value, mostly to detect SYNC -reg prv = 1'b1; - -// for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry. -reg[7:0] mid = 8'd128; - -// set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...) -// start sending over 1s on ssp->arm when we start sending preamble -// reg sending = 1'b0; // are we actively modulating? -reg [11:0] bit_counts = 12'd0; // for timeslots. only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those? - - -//we need some way to flush bit_counts triggers on mod_type changes don't compile -reg dlay; -always @(negedge adc_clk) // every data ping? -begin - //envelope follow code... - //////////// - if (fccount == bitmlen) - begin - if ((~try_sync) && (adc_d < curminthres) && disabl ) - begin - fccount <= 1; - end - else - begin - fccount <= 0; - end - dlay <= ssp_dout; - if (bit_counts > 768) // should be over ts0 now, without ARM interference... stop counting... - begin - bit_counts <= 0; - end - else - if (power) - bit_counts <= 0; - else - bit_counts <= bit_counts + 1; - end - else - begin - if((~try_sync) && (adc_d < curminthres) && disabl) - begin - fccount <= 1; - end - else - begin - fccount <= fccount + 1; - end - end - - // rising edge - if (adc_d > curmaxthres) - begin - case (state) - 0: begin - curmax <= adc_d > `imax? adc_d : `imax; - state <= 2; - end - 1: begin - curminthres <= ((curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); //threshold: 0.1875 max + 0.8125 min - curmaxthres <= ((curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); - curmax <= adc_d > 155 ? adc_d : 155; // to hopefully prevent overflow from spikes going up to 255 - state <= 2; - end - 2: begin - if (adc_d > curmax) - curmax <= adc_d; - end - default: - begin - end - endcase - after_hysteresis <= 1'b1; - if(try_sync) - tsinceedge <= 0; - end - else if (adc_d> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); - curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); - curmin <= adc_d < `imin ? adc_d : `imin; - state <= 1; - end - default: - begin - end - endcase - after_hysteresis <= 0; - if (~try_sync ) //begin modulation, lower edge... - begin - try_sync <= 1; - fccount <= 1; - did_sync <= 0; - curbit <= 0; - mid <= 8'd127; - tsinceedge <= 0; - prv <= 1; - end - else - begin - tsinceedge <= 0; - end - end - else //stable state, low or high - begin - curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); - curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4)); - state <= 0; - - if (try_sync ) - begin - if (tsinceedge >= (128)) - begin - //we might need to start counting... assuming ARM wants to reply to the frame. - bit_counts <= 1;// i think? 128 is about 2 bits passed... but 1 also works - try_sync <= 0; - did_sync <= 0;//desync - curmin <= `imin; //reset envelope - curmax <= `imax; - curminthres <= `ithrmin; - curmaxthres <= `ithrmax; - prv <= 1; - tsinceedge <= 0; - after_hysteresis <= 1'b1; - curbit <= 0; - mid <= 8'd128; - end - else - tsinceedge <= (tsinceedge + 1); - end - end - - - if (try_sync && tsinceedge < 128) - begin - //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order - if (fccount == bithalf) - begin - if ((~did_sync) && ((prv == 1 && (mid > 128))||(prv == 0 && (mid <= 128)))) - begin - //sync the Zero, and set curbit roperly - did_sync <= 1'b1; - zero <= ~prv;// 1-prv - curbit <= 1; - end - else - curbit <= (mid > 128) ? (~zero) : zero; - - prv <= (mid > 128) ? 1 : 0; - - if (adc_d > curmaxthres) - mid <= 8'd129; - else if (adc_d < curminthres) - mid <= 8'd127; - else - begin - if (after_hysteresis) - begin - mid <= 8'd129; - end - else - begin - mid <= 8'd127; - end - end - - end - else - begin - if (fccount==bitmlen) - begin - // fccount <= 0; - prv <= (mid > 128) ? 1 : 0; - mid <= 128; - end - else - begin - // minimum-maximum calc - if(adc_d > curmaxthres) - mid <= mid + 1; - else if (adc_d < curminthres) - mid <= mid - 1; - else - begin - if (after_hysteresis) - begin - mid <= mid + 1; - end - else - begin - mid <= mid - 1; - end - end - end - end - end - else - begin - end -// sending <= 0; -end -//put modulation here to maintain the correct clock. Seems that some readers are sensitive to that -reg pwr_hi; -reg pwr_oe1; -reg pwr_oe2; -reg pwr_oe3; -reg pwr_oe4; - -wire mod = ((fccount >= bithalf) ^ dlay) & (~disabl); - -always @(ck_1356meg or ssp_dout or power or disabl or mod) -begin - if (power) - begin - pwr_hi <= ck_1356meg; - pwr_oe1 <= 1'b0;//mod; - pwr_oe2 <= 1'b0;//mod; - pwr_oe3 <= 1'b0;//mod; - pwr_oe4 <= mod;//1'b0; - end - else - begin - pwr_hi <= 1'b0; - pwr_oe1 <= 1'b0; - pwr_oe2 <= 1'b0; - pwr_oe3 <= 1'b0; - pwr_oe4 <= mod; - end -end - -endmodule diff --git a/fpga-xc3s100e/hi_get_trace.v b/fpga-xc3s100e/hi_get_trace.v deleted file mode 100644 index 2b1cf393b..000000000 --- a/fpga-xc3s100e/hi_get_trace.v +++ /dev/null @@ -1,164 +0,0 @@ -//----------------------------------------------------------------------------- -// -// piwi, Feb 2019 -//----------------------------------------------------------------------------- -//For ISE 10.1 PROJ,IDE cannot apply definition to all files -`include "define.v" - -module hi_get_trace( - ck_1356megb, - adc_d, trace_enable, major_mode, - ssp_frame, ssp_din, ssp_clk -); - input ck_1356megb; - input [7:0] adc_d; - input trace_enable; - input [2:0] major_mode; - output ssp_frame, ssp_din, ssp_clk; - -// clock divider -reg [6:0] clock_cnt; -always @(negedge ck_1356megb) -begin - clock_cnt <= clock_cnt + 1; -end - -// sample at 13,56MHz / 8. The highest signal frequency (subcarrier) is 848,5kHz, i.e. in this case we oversample by a factor of 2 -reg [2:0] sample_clock; -always @(negedge ck_1356megb) -begin - if (sample_clock == 3'd7) - sample_clock <= 3'd0; - else - sample_clock <= sample_clock + 1; -end - - -reg [11:0] addr; -reg [11:0] start_addr; -reg [2:0] previous_major_mode; -reg write_enable1; -reg write_enable2; -always @(negedge ck_1356megb) -begin - previous_major_mode <= major_mode; - if (major_mode == `FPGA_MAJOR_MODE_HF_GET_TRACE) - begin - write_enable1 <= 1'b0; - write_enable2 <= 1'b0; - 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 - if (addr == 12'd3071) - addr <= 12'd0; - else - addr <= addr + 1; - end - end - else if (major_mode != `FPGA_MAJOR_MODE_OFF) - begin - if (trace_enable) - begin - if (addr[11] == 1'b0) - begin - write_enable1 <= 1'b1; - write_enable2 <= 1'b0; - end - else - begin - write_enable1 <= 1'b0; - write_enable2 <= 1'b1; - end - if (sample_clock == 3'b000) - begin - if (addr == 12'd3071) - begin - addr <= 12'd0; - write_enable1 <= 1'b1; - write_enable2 <= 1'b0; - end - else - begin - addr <= addr + 1; - end - end - end - else - begin - write_enable1 <= 1'b0; - write_enable2 <= 1'b0; - start_addr <= addr; - end - end - else // major_mode == `FPGA_MAJOR_MODE_OFF - begin - write_enable1 <= 1'b0; - write_enable2 <= 1'b0; - if (previous_major_mode != `FPGA_MAJOR_MODE_OFF && previous_major_mode != `FPGA_MAJOR_MODE_HF_GET_TRACE) // just switched off - begin - start_addr <= addr; - end - end -end - - -// (2+1)k RAM -reg [7:0] D_out1, D_out2; -reg [7:0] ram1 [2047:0]; // 2048 u8 -reg [7:0] ram2 [1023:0]; // 1024 u8 - -always @(negedge ck_1356megb) -begin - if (write_enable1) - begin - ram1[addr[10:0]] <= adc_d; - D_out1 <= adc_d; - end - else - D_out1 <= ram1[addr[10:0]]; - if (write_enable2) -begin - ram2[addr[9:0]] <= adc_d; - D_out2 <= adc_d; - end - else - D_out2 <= ram2[addr[9:0]]; -end - - -// SSC communication to ARM -reg ssp_clk; -reg ssp_frame; -reg [7:0] shift_out; - -always @(negedge ck_1356megb) -begin - if (clock_cnt[3:0] == 4'd0) // update shift register every 16 clock cycles - begin - if (clock_cnt[6:4] == 3'd0) // either load new value - begin - if (addr[11] == 1'b0) - shift_out <= D_out1; - else - shift_out <= D_out2; - end - else - begin - // or shift left - shift_out[7:1] <= shift_out[6:0]; - end - end - - ssp_clk <= ~clock_cnt[3]; // ssp_clk frequency = 13,56MHz / 16 = 847,5 kHz - - if (clock_cnt[6:4] == 3'b000) // set ssp_frame for 0...31 - ssp_frame <= 1'b1; - else - ssp_frame <= 1'b0; - -end - -assign ssp_din = shift_out[7]; - -endmodule diff --git a/fpga-xc3s100e/hi_iso14443a.v b/fpga-xc3s100e/hi_iso14443a.v deleted file mode 100644 index 26ab0f9d9..000000000 --- a/fpga-xc3s100e/hi_iso14443a.v +++ /dev/null @@ -1,584 +0,0 @@ -//----------------------------------------------------------------------------- -// ISO14443-A support for the Proxmark III -// Gerhard de Koning Gans, April 2008 -//----------------------------------------------------------------------------- - -module hi_iso14443a( - 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, - mod_type -); - 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 [3:0] mod_type; - - -wire adc_clk = ck_1356meg; - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Reader -> PM3: -// detecting and shaping the reader's signal. Reader will modulate the carrier by 100% (signal is either on or off). Use a -// hysteresis (Schmitt Trigger) to avoid false triggers during slowly increasing or decreasing carrier amplitudes -reg after_hysteresis; -reg [11:0] has_been_low_for; - -always @(negedge adc_clk) -begin - if(adc_d >= 16) after_hysteresis <= 1'b1; // U >= 1,14V -> after_hysteresis = 1 - else if(adc_d < 8) after_hysteresis <= 1'b0; // U < 1,04V -> after_hysteresis = 0 - // Note: was >= 3,53V and <= 1,19V. The new trigger values allow more reliable detection of the first bit - // (it might not reach 3,53V due to the high time constant of the high pass filter in the analogue RF part). - // In addition, the new values are more in line with ISO14443-2: "The PICC shall detect the ”End of Pause” after the field exceeds - // 5% of H_INITIAL and before it exceeds 60% of H_INITIAL." Depending on the signal strength, 60% might well be less than 3,53V. - - - // detecting a loss of reader's field (adc_d < 192 for 4096 clock cycles). If this is the case, - // set the detected reader signal (after_hysteresis) to '1' (unmodulated) - if(adc_d >= 192) - begin - has_been_low_for <= 12'd0; - end - else - begin - if(has_been_low_for == 12'd4095) - begin - has_been_low_for <= 12'd0; - after_hysteresis <= 1'b1; - end - else - begin - has_been_low_for <= has_been_low_for + 1; - end - end - -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Reader -> PM3 -// detect when a reader is active (modulating). We assume that the reader is active, if we see the carrier off for at least 8 -// carrier cycles. We assume that the reader is inactive, if the carrier stayed high for at least 256 carrier cycles. -reg deep_modulation; -reg [2:0] deep_counter; -reg [8:0] saw_deep_modulation; - -always @(negedge adc_clk) -begin - if(~(| adc_d[7:0])) // if adc_d == 0 (U <= 0,94V) - begin - if(deep_counter == 3'd7) // adc_d == 0 for 8 adc_clk ticks -> deep_modulation (by reader) - begin - deep_modulation <= 1'b1; - saw_deep_modulation <= 8'd0; - end - else - deep_counter <= deep_counter + 1; - end - else - begin - deep_counter <= 3'd0; - if(saw_deep_modulation == 8'd255) // adc_d != 0 for 256 adc_clk ticks -> deep_modulation is over, probably waiting for tag's response - deep_modulation <= 1'b0; - else - saw_deep_modulation <= saw_deep_modulation + 1; - end -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Tag -> PM3 -// filter the input for a tag's signal. The filter box needs the 4 previous input values and is a gaussian derivative filter -// for noise reduction and edge detection. -// store 4 previous samples: -reg [7:0] input_prev_4, input_prev_3, input_prev_2, input_prev_1; - -always @(negedge adc_clk) -begin - input_prev_4 <= input_prev_3; - input_prev_3 <= input_prev_2; - input_prev_2 <= input_prev_1; - input_prev_1 <= adc_d; -end - -// adc_d_filtered = 2*input_prev4 + 1*input_prev3 + 0*input_prev2 - 1*input_prev1 - 2*input -// = (2*input_prev4 + input_prev3) - (2*input + input_prev1) -wire [8:0] input_prev_4_times_2 = input_prev_4 << 1; -wire [8:0] adc_d_times_2 = adc_d << 1; - -wire [9:0] tmp1 = input_prev_4_times_2 + input_prev_3; -wire [9:0] tmp2 = adc_d_times_2 + input_prev_1; - -// convert intermediate signals to signed and calculate the filter output -wire signed [10:0] adc_d_filtered = {1'b0, tmp1} - {1'b0, tmp2}; - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a -// 7 bit counter). Adjust its frequency to external reader's clock when simulating a tag or sniffing. -reg pre_after_hysteresis; -reg [3:0] reader_falling_edge_time; -reg [6:0] negedge_cnt; - -always @(negedge adc_clk) -begin - // detect a reader signal's falling edge and remember its timing: - pre_after_hysteresis <= after_hysteresis; - if (pre_after_hysteresis && ~after_hysteresis) - begin - reader_falling_edge_time[3:0] <= negedge_cnt[3:0]; - end - - // adjust internal timer counter if necessary: - 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 - negedge_cnt <= negedge_cnt + 2; // time warp - end - else if (reader_falling_edge_time == 4'd0) // reader signal changes right before sampling. Better sample later next time. - begin - negedge_cnt <= negedge_cnt; // freeze time - end - else - begin - negedge_cnt <= negedge_cnt + 1; // Continue as usual - end - reader_falling_edge_time[3:0] <= 4'd8; // adjust only once per detected edge - end - else if (negedge_cnt == 7'd127) // normal operation: count from 0 to 127 - begin - negedge_cnt <= 0; - end - else - begin - negedge_cnt <= negedge_cnt + 1; - end -end - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Tag -> PM3: -// determine best possible time for starting/resetting the modulation detector. -reg [3:0] mod_detect_reset_time; - -always @(negedge adc_clk) -begin - 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. - // at mod_detect_reset_time+4 and mod_detect_reset_time+12 (-4 ticks). - // 9 + 4 + 3 + 7 - 4 = 19. 19 mod 16 = 3 - begin - mod_detect_reset_time <= 4'd4; - end - else - 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) - // reader signal rising edge detected at negedge_cnt[3:0]. This signal had been delayed - // 9 ticks by the RF part + 3 ticks by the A/D converter + 1 tick to assign to after_hysteresis. - // Then the same as above. - // - 9 - 3 - 1 + 4 + 3 + 7 - 4 = -3 - begin - mod_detect_reset_time <= negedge_cnt[3:0] - 4'd3; - end - end -end - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Tag -> PM3: -// modulation detector. Looks for the steepest falling and rising edges within a 16 clock period. If there is both a significant -// falling and rising edge (in any order), a modulation is detected. -reg signed [10:0] rx_mod_falling_edge_max; -reg signed [10:0] rx_mod_rising_edge_max; -reg curbit; - -`define EDGE_DETECT_THRESHOLD 3 -`define EDGE_DETECT_THRESHOLDHIGH 20 - -always @(negedge adc_clk) -begin - if(negedge_cnt[3:0] == mod_detect_reset_time) - begin - if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) - begin - // detect modulation signal: if modulating, there must have been a falling AND a rising edge - if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLDHIGH) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLDHIGH)) - curbit <= 1'b1; // modulation - else - curbit <= 1'b0; // no modulation - end - else - begin - // detect modulation signal: if modulating, there must have been a falling AND a rising edge - if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD)) - curbit <= 1'b1; // modulation - else - curbit <= 1'b0; // no modulation - end - // reset modulation detector - rx_mod_rising_edge_max <= 0; - rx_mod_falling_edge_max <= 0; - end - else // look for steepest edges (slopes) - begin - if (adc_d_filtered > 0) - begin - if (adc_d_filtered > rx_mod_falling_edge_max) - rx_mod_falling_edge_max <= adc_d_filtered; - end - else - begin - if (adc_d_filtered < rx_mod_rising_edge_max) - rx_mod_rising_edge_max <= adc_d_filtered; - end - end - -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Tag+Reader -> PM3 -// sample 4 bits reader data and 4 bits tag data for sniffing -reg [3:0] reader_data; -reg [3:0] tag_data; - -always @(negedge adc_clk) -begin - if(negedge_cnt[3:0] == 4'd0) - begin - reader_data[3:0] <= {reader_data[2:0], after_hysteresis}; - tag_data[3:0] <= {tag_data[2:0], curbit}; - end -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PM3 -> Reader: -// a delay line to ensure that we send the (emulated) tag's answer at the correct time according to ISO14443-3 -reg [31:0] mod_sig_buf; -reg [4:0] mod_sig_ptr; -reg mod_sig; - -always @(negedge adc_clk) -begin - if(negedge_cnt[3:0] == 4'd0) // sample data at rising edge of ssp_clk - ssp_dout changes at the falling edge. - begin - mod_sig_buf[31:2] <= mod_sig_buf[30:1]; // shift - if (~ssp_dout && ~mod_sig_buf[1]) - mod_sig_buf[1] <= 1'b0; // delete the correction bit (a single 1 preceded and succeeded by 0) - else - mod_sig_buf[1] <= mod_sig_buf[0]; - mod_sig_buf[0] <= ssp_dout; // add new data to the delay line - - mod_sig = mod_sig_buf[mod_sig_ptr]; // the delayed signal. - end -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PM3 -> Reader, internal timing: -// a timer for the 1172 cycles fdt (Frame Delay Time). Start the timer with a rising edge of the reader's signal. -// set fdt_elapsed when we no longer need to delay data. Set fdt_indicator when we can start sending data. -// Note: the FPGA only takes care for the 1172 delay. To achieve an additional 1236-1172=64 ticks delay, the ARM must send -// a correction bit (before the start bit). The correction bit will be coded as 00010000, i.e. it adds 4 bits to the -// transmission stream, causing the required additional delay. -reg [10:0] fdt_counter; -reg fdt_indicator, fdt_elapsed; -reg [3:0] mod_sig_flip; -reg [3:0] sub_carrier_cnt; - -// we want to achieve a delay of 1172. The RF part already has delayed the reader signals's rising edge -// by 9 ticks, the ADC took 3 ticks and there is always a delay of 32 ticks by the mod_sig_buf. Therefore need to -// count to 1172 - 9 - 3 - 32 = 1128 -`define FDT_COUNT 11'd1128 - -// The ARM must not send too early, otherwise the mod_sig_buf will overflow, therefore signal that we are ready -// with fdt_indicator. The mod_sig_buf can buffer 29 excess data bits, i.e. a maximum delay of 29 * 16 = 464 adc_clk ticks. -// fdt_indicator is assigned to sendbit after at least 1 tick, the transfer to ARM needs minimum 8 ticks. Response from -// ARM could appear at ssp_dout 8 ticks later. -// 1128 - 464 - 1 - 8 - 8 = 647 -`define FDT_INDICATOR_COUNT 11'd647 -// Note: worst case, assignment to sendbit takes 15 ticks more, and transfer to ARM needs 7*16 = 112 ticks more. -// When the ARM's response then appears, the fdt_count is already 647 + 15 + 112 = 774, which still allows the ARM a possible -// 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 == `FPGA_HF_ISO14443A_TAGSIM_LISTEN; - -always @(negedge adc_clk) -begin - if (fdt_reset) - begin - fdt_counter <= 11'd0; - fdt_elapsed <= 1'b0; - fdt_indicator <= 1'b0; - end - else - begin - if(fdt_counter == `FDT_COUNT) - begin - if(~fdt_elapsed) // just reached fdt. - begin - mod_sig_flip <= negedge_cnt[3:0]; // start modulation at this time - sub_carrier_cnt <= 4'd0; // subcarrier phase in sync with start of modulation - fdt_elapsed <= 1'b1; - end - else - begin - sub_carrier_cnt <= sub_carrier_cnt + 1; - end - end - else - begin - fdt_counter <= fdt_counter + 1; - end - end - - if(fdt_counter == `FDT_INDICATOR_COUNT) fdt_indicator <= 1'b1; -end - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PM3 -> Reader or Tag -// assign a modulation signal to the antenna. This signal is either a delayed signal (to achieve fdt when sending to a reader) -// or undelayed when sending to a tag -reg mod_sig_coil; - -always @(negedge adc_clk) -begin - if (mod_type == `FPGA_HF_ISO14443A_TAGSIM_MOD) // need to take care of proper fdt timing - begin - if(fdt_counter == `FDT_COUNT) - begin - if(fdt_elapsed) - begin - if(negedge_cnt[3:0] == mod_sig_flip) mod_sig_coil <= mod_sig; - end - else - begin - mod_sig_coil <= mod_sig; // just reached fdt. Immediately assign signal to coil - end - end - end - else // other modes: don't delay - begin - mod_sig_coil <= ssp_dout; - end -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PM3 -> Reader -// determine the required delay in the mod_sig_buf (set mod_sig_ptr). -reg temp_buffer_reset; - -always @(negedge adc_clk) -begin - if(fdt_reset) - begin - mod_sig_ptr <= 5'd0; - temp_buffer_reset = 1'b0; - end - else - begin - if(fdt_counter == `FDT_COUNT && ~fdt_elapsed) // if we just reached fdt - if(~(| mod_sig_ptr[4:0])) - mod_sig_ptr <= 5'd8; // ... but didn't buffer a 1 yet, delay next 1 by n*128 ticks. - else - temp_buffer_reset = 1'b1; // else no need for further delays. - - if(negedge_cnt[3:0] == 4'd0) // at rising edge of ssp_clk - ssp_dout changes at the falling edge. - begin - if((ssp_dout || (| mod_sig_ptr[4:0])) && ~fdt_elapsed) // buffer a 1 (and all subsequent data) until fdt is reached. - if (mod_sig_ptr == 5'd31) - mod_sig_ptr <= 5'd0; // buffer overflow - data loss. - else - mod_sig_ptr <= mod_sig_ptr + 1; // increase buffer (= increase delay by 16 adc_clk ticks). mod_sig_ptr always points ahead of first 1. - else if(fdt_elapsed && ~temp_buffer_reset) - begin - // wait for the next 1 after fdt_elapsed before fixing the delay and starting modulation. This ensures that the response can only happen - // at intervals of 8 * 16 = 128 adc_clk ticks (as defined in ISO14443-3) - if(ssp_dout) - temp_buffer_reset = 1'b1; - if(mod_sig_ptr == 5'd1) - mod_sig_ptr <= 5'd8; // still nothing received, need to go for the next interval - else - mod_sig_ptr <= mod_sig_ptr - 1; // decrease buffer. - end - end - end -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FPGA -> ARM communication: -// buffer 8 bits data to be sent to ARM. Shift them out bit by bit. -reg [7:0] to_arm; - -always @(negedge adc_clk) -begin - if (negedge_cnt[5:0] == 6'd63) // fill the buffer - begin - if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) - begin - if(deep_modulation) // a reader is sending (or there's no field at all) - begin - to_arm <= {reader_data[3:0], 4'b0000}; // don't send tag data - end - else - begin - to_arm <= {reader_data[3:0], tag_data[3:0]}; - end - end - else - begin - to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]}; // feedback timing information - end - end - - 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) - begin - to_arm[7:1] <= to_arm[6:0]; - end - end - - 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) - begin - to_arm[7:1] <= to_arm[6:0]; - end - end - -end - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FPGA <-> ARM communication: -// generate a ssp clock and ssp frame signal for the synchronous transfer from/to the ARM -reg ssp_clk; -reg ssp_frame; - -always @(negedge adc_clk) -begin - 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[2:0] == 3'd4) - ssp_clk <= 1'b0; - - if(negedge_cnt[5:0] == 6'd0) // ssp_frame rising edge indicates start of frame - ssp_frame <= 1'b1; - if(negedge_cnt[5:0] == 6'd8) - ssp_frame <= 1'b0; - end - else - // all other modes (ssp_clk = adc_clk / 16, ssp_frame clock = adc_clk / 128): - begin - if(negedge_cnt[3:0] == 4'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, sampled on falling edge of ssp_clk - ssp_frame <= 1'b1; - if(negedge_cnt[6:0] == 7'd23) - ssp_frame <= 1'b0; - end -end - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FPGA -> ARM communication: -// select the data to be sent to ARM -reg bit_to_arm; -reg sendbit; - -always @(negedge adc_clk) -begin - if(negedge_cnt[3:0] == 4'd0) - begin - // What do we communicate to the ARM - if(mod_type == `FPGA_HF_ISO14443A_TAGSIM_LISTEN) - sendbit = after_hysteresis; - 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 == `FPGA_HF_ISO14443A_READER_LISTEN) - sendbit = curbit; - else - sendbit = 1'b0; - end - - - if(mod_type == `FPGA_HF_ISO14443A_SNIFFER) - // send sampled reader and tag data: - bit_to_arm = to_arm[7]; - else if (mod_type == `FPGA_HF_ISO14443A_TAGSIM_MOD && fdt_elapsed && temp_buffer_reset) - // send timing information: - bit_to_arm = to_arm[7]; - else - // send data or fdt_indicator - bit_to_arm = sendbit; -end - - - - -assign ssp_din = bit_to_arm; - -// Subcarrier (adc_clk/16, for FPGA_HF_ISO14443A_TAGSIM_MOD only). -wire sub_carrier; -assign sub_carrier = ~sub_carrier_cnt[3]; - -// 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; - -// 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 == `FPGA_HF_ISO14443A_TAGSIM_MOD); - -// This is all LF, so doesn't matter. -assign pwr_oe2 = 1'b0; -assign pwr_lo = 1'b0; - - -assign dbg = negedge_cnt[3]; - -endmodule diff --git a/fpga-xc3s100e/hi_reader.v b/fpga-xc3s100e/hi_reader.v deleted file mode 100644 index c5ffa7b85..000000000 --- a/fpga-xc3s100e/hi_reader.v +++ /dev/null @@ -1,335 +0,0 @@ -//----------------------------------------------------------------------------- -// -// 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 [3: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 <= 12'd0; - 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 -// _____ _____ _____ _ -// ssp_clk | |_____| |_____| |_____| -// _____ -// ssp_frame ___| |____________________________ -// ___________ ___________ ___________ _ -// ssp_d_in X___________X___________X___________X_ -// -// corr_i_cnt 0 1 2 3 4 5 6 7 8 9 10 11 12 ... -// - -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'd1) - ssp_frame <= 1'b1; - - if (corr_i_cnt == 6'd3) - ssp_frame <= 1'b0; -end - - -assign ssp_din = corr_i_out[7]; - - -// a jamming signal -reg jam_signal; -reg [3:0] jam_counter; - -always @(negedge adc_clk) -begin - if (corr_i_cnt == 6'd0) - begin - jam_counter <= jam_counter + 1; - jam_signal <= jam_counter[1] ^ jam_counter[3]; - end -end - -// 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_SEND_JAM) - begin - pwr_hi = ck_1356meg & jam_signal; - 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 // all off - pwr_hi = 1'b0; - pwr_oe4 = 1'b0; - end - else // receiving from tag - begin - pwr_hi = ck_1356meg; - pwr_oe4 = 1'b0; - end -end - -// always on -assign pwr_oe1 = 1'b0; -assign pwr_oe3 = 1'b0; - -// Unused. -assign pwr_lo = 1'b0; -assign pwr_oe2 = 1'b0; - -// Debug Output -assign dbg = corr_i_cnt[3]; - -endmodule diff --git a/fpga-xc3s100e/hi_simulate.v b/fpga-xc3s100e/hi_simulate.v deleted file mode 100644 index cf951279a..000000000 --- a/fpga-xc3s100e/hi_simulate.v +++ /dev/null @@ -1,152 +0,0 @@ -//----------------------------------------------------------------------------- -// Pretend to be an ISO 14443 tag. We will do this by alternately short- -// circuiting and open-circuiting the antenna coil, with the tri-state -// pins. -// -// We communicate over the SSP, as a bitstream (i.e., might as well be -// unframed, though we still generate the word sync signal). The output -// (ARM -> FPGA) tells us whether to modulate or not. The input (FPGA -// -> ARM) is us using the A/D as a fancy comparator; this is with -// (software-added) hysteresis, to undo the high-pass filter. -// -// At this point only Type A is implemented. This means that we are using a -// bit rate of 106 kbit/s, or fc/128. Oversample by 4, which ought to make -// things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s) -// -// Jonathan Westhues, October 2006 -//----------------------------------------------------------------------------- - -//For ISE 10.1 PROJ,IDE cannot apply definition to all files -`include "define.v" - - -module hi_simulate( - 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, - mod_type -); - 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 [3:0] mod_type; - -// Power amp goes between LOW and tri-state, so pwr_hi (and pwr_lo) can -// always be low. -assign pwr_hi = 1'b0; // HF antenna connected to GND -assign pwr_lo = 1'b0; // LF antenna connected to GND - -// This one is all LF, so doesn't matter -assign pwr_oe2 = 1'b0; - -assign adc_clk = ck_1356meg; -assign dbg = ssp_frame; - -// The comparator with hysteresis on the output from the peak detector. -reg after_hysteresis; -reg [11:0] has_been_low_for; - -always @(negedge adc_clk) -begin - 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) - - if (adc_d >= 224) - begin - has_been_low_for <= 12'd0; - end - else - begin - if (has_been_low_for == 12'd4095) - begin - has_been_low_for <= 12'd0; - after_hysteresis <= 1'b1; - end - else - begin - has_been_low_for <= has_been_low_for + 1; - end - end -end - - -// Divide 13.56 MHz to produce various frequencies for SSP_CLK -// and modulation. -reg [8:0] ssp_clk_divider; - -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) - // 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) - // Get next bit at 212kHz - ssp_clk <= ~ssp_clk_divider[5]; - else - // Get next bit at 424kHz - ssp_clk <= ~ssp_clk_divider[4]; -end - - -// 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 @(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; -always @(posedge ssp_clk) - ssp_din = after_hysteresis; - -// Modulating carrier frequency is fc/64 (212kHz) to fc/16 (848kHz). Reuse ssp_clk divider for that. -reg modulating_carrier; -always @(*) - if(mod_type == `FPGA_HF_SIMULATOR_NO_MODULATION) - modulating_carrier <= 1'b0; // no modulation - else if(mod_type == `FPGA_HF_SIMULATOR_MODULATE_BPSK) - modulating_carrier <= ssp_dout ^ ssp_clk_divider[3]; // XOR means BPSK - 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 == `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 - - - -// Load modulation. Toggle only one of these, since we are already producing much deeper -// modulation than a real tag would. -assign pwr_oe1 = 1'b0; // 33 Ohms Load -assign pwr_oe4 = modulating_carrier; // 33 Ohms Load -// This one is always on, so that we can watch the carrier. -assign pwr_oe3 = 1'b0; // 10k Load - -endmodule diff --git a/fpga-xc3s100e/hi_sniffer.v b/fpga-xc3s100e/hi_sniffer.v deleted file mode 100644 index c2dc844a7..000000000 --- a/fpga-xc3s100e/hi_sniffer.v +++ /dev/null @@ -1,50 +0,0 @@ -module hi_sniffer( - ck_1356meg, - pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, - adc_d, adc_clk, - ssp_frame, ssp_din, ssp_clk -); - input ck_1356meg; - output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; - input [7:0] adc_d; - output adc_clk; - output ssp_frame, ssp_din, ssp_clk; - -// We are only snooping, all off. -assign pwr_hi = 1'b0; -assign pwr_lo = 1'b0; -assign pwr_oe1 = 1'b0; -assign pwr_oe2 = 1'b0; -assign pwr_oe3 = 1'b0; -assign pwr_oe4 = 1'b0; - -reg ssp_frame; -reg [7:0] adc_d_out = 8'd0; -reg [2:0] ssp_cnt = 3'd0; - -assign adc_clk = ck_1356meg; -assign ssp_clk = ~ck_1356meg; - -always @(posedge ssp_clk) -begin - if(ssp_cnt[2:0] == 3'd7) - ssp_cnt[2:0] <= 3'd0; - else - ssp_cnt <= ssp_cnt + 1; - - if(ssp_cnt[2:0] == 3'b000) // set frame length - begin - adc_d_out[7:0] <= adc_d; - ssp_frame <= 1'b1; - end - else - begin - adc_d_out[7:0] <= {1'b0, adc_d_out[7:1]}; - ssp_frame <= 1'b0; - end - -end - -assign ssp_din = adc_d_out[0]; - -endmodule diff --git a/fpga-xc3s100e/iseproj/fpga_hf/fpga_hf.ise b/fpga-xc3s100e/iseproj/fpga_hf/fpga_hf.ise deleted file mode 100644 index 40e5eeffd..000000000 Binary files a/fpga-xc3s100e/iseproj/fpga_hf/fpga_hf.ise and /dev/null differ diff --git a/fpga-xc3s100e/iseproj/fpga_hf/fpga_hf.tcl b/fpga-xc3s100e/iseproj/fpga_hf/fpga_hf.tcl deleted file mode 100644 index 114f0df18..000000000 --- a/fpga-xc3s100e/iseproj/fpga_hf/fpga_hf.tcl +++ /dev/null @@ -1,479 +0,0 @@ -# -# Project automation script for fpga_hf -# -# Created for ISE version 10.1 -# -# This file contains several Tcl procedures (procs) that you can use to automate -# your project by running from xtclsh or the Project Navigator Tcl console. -# If you load this file (using the Tcl command: source fpga_hf.tcl, then you can -# run any of the procs included here. -# You may also edit any of these procs to customize them. See comments in each -# proc for more instructions. -# -# This file contains the following procedures: -# -# Top Level procs (meant to be called directly by the user): -# run_process: you can use this top-level procedure to run any processes -# that you choose to by adding and removing comments, or by -# adding new entries. -# rebuild_project: you can alternatively use this top-level procedure -# to recreate your entire project, and the run selected processes. -# -# Lower Level (helper) procs (called under in various cases by the top level procs): -# show_help: print some basic information describing how this script works -# add_source_files: adds the listed source files to your project. -# set_project_props: sets the project properties that were in effect when this -# script was generated. -# create_libraries: creates and adds file to VHDL libraries that were defined when -# this script was generated. -# create_partitions: adds any partitions that were defined when this script was generated. -# set_process_props: set the process properties as they were set for your project -# when this script was generated. -# - -set myProject "fpga_hf.ise" -set myScript "fpga_hf.tcl" - -# -# Main (top-level) routines -# - -# -# run_process -# This procedure is used to run processes on an existing project. You may comment or -# uncomment lines to control which processes are run. This routine is set up to run -# the Implement Design and Generate Programming File processes by default. This proc -# also sets process properties as specified in the "set_process_props" proc. Only -# those properties which have values different from their current settings in the project -# file will be modified in the project. -# -proc run_process {} { - - global myScript - global myProject - - ## put out a 'heartbeat' - so we know something's happening. - puts "\n$myScript: running ($myProject)...\n" - - if { ! [ open_project ] } { - return false - } - - set_process_props - # - # Remove the comment characters (#'s) to enable the following commands - # process run "Synthesize" - # process run "Translate" - # process run "Map" - # process run "Place & Route" - # - puts "Running 'Implement Design'" - if { ! [ process run "Implement Design" ] } { - puts "$myScript: Implementation run failed, check run output for details." - project close - return - } - puts "Running 'Generate Programming File'" - if { ! [ process run "Generate Programming File" ] } { - puts "$myScript: Generate Programming File run failed, check run output for details." - project close - return - } - - puts "Run completed." - project close - -} - -# -# rebuild_project -# -# This procedure renames the project file (if it exists) and recreates the project. -# It then sets project properties and adds project sources as specified by the -# set_project_props and add_source_files support procs. It recreates VHDL libraries -# and partitions as they existed at the time this script was generated. -# -# It then calls run_process to set process properties and run selected processes. -# -proc rebuild_project {} { - - global myScript - global myProject - - ## put out a 'heartbeat' - so we know something's happening. - puts "\n$myScript: rebuilding ($myProject)...\n" - - if { [ file exists $myProject ] } { - puts "$myScript: Removing existing project file." - file delete $myProject - } - - puts "$myScript: Rebuilding project $myProject" - project new $myProject - set_project_props - add_source_files - create_libraries - create_partitions - puts "$myScript: project rebuild completed." - - run_process - -} - -# -# Support Routines -# - -# -# show_help: print information to help users understand the options available when -# running this script. -# -proc show_help {} { - - global myScript - - puts "" - puts "usage: xtclsh $myScript " - puts " or you can run xtclsh and then enter 'source $myScript'." - puts "" - puts "options:" - puts " run_process - set properties and run processes." - puts " rebuild_project - rebuild the project from scratch and run processes." - puts " set_project_props - set project properties (device, speed, etc.)" - puts " add_source_files - add source files" - puts " create_libraries - create vhdl libraries" - puts " create_partitions - create partitions" - puts " set_process_props - set process property values" - puts " show_help - print this message" - puts "" -} - -proc open_project {} { - - global myScript - global myProject - - if { ! [ file exists $myProject ] } { - ## project file isn't there, rebuild it. - puts "Project $myProject not found. Use ${myProject}_rebuild to recreate it." - return false - } - - project open $myProject - - return true - -} -# -# set_project_props -# -# This procedure sets the project properties as they were set in the project -# at the time this script was generated. -# -proc set_project_props {} { - - global myScript - - if { ! [ open_project ] } { - return false - } - - puts "$myScript: Setting project properties..." - - project set family "Spartan3E" - project set device "xc3s100e" - project set package "vq100" - project set speed "-4" - project set top_level_module_type "HDL" - project set synthesis_tool "XST (VHDL/Verilog)" - project set simulator "ISE Simulator (VHDL/Verilog)" - project set "Preferred Language" "Verilog" - project set "Enable Message Filtering" "false" - project set "Display Incremental Messages" "false" - -} - - -# -# add_source_files -# -# This procedure add the source files that were known to the project at the -# time this script was generated. -# -proc add_source_files {} { - - global myScript - - if { ! [ open_project ] } { - return false - } - - puts "$myScript: Adding sources to project..." - - xfile add "../../clk_divider.v" - xfile add "../../define.v" - xfile add "../../fpga.ucf" - xfile add "../../fpga_allinone.v" - xfile add "../../fpga_hfmod.v" - xfile add "../../fpga_lfmod.v" - xfile add "../../hi_flite.v" - xfile add "../../hi_get_trace.v" - xfile add "../../hi_iso14443a.v" - xfile add "../../hi_reader.v" - xfile add "../../hi_simulate.v" - xfile add "../../hi_sniffer.v" - xfile add "../../lf_edge_detect.v" - xfile add "../../lo_adc.v" - xfile add "../../lo_edge_detect.v" - xfile add "../../lo_passthru.v" - xfile add "../../lo_read.v" - xfile add "../../lp20khz_1MSa_iir_filter.v" - xfile add "../../mux2_onein.v" - xfile add "../../mux2_oneout.v" - xfile add "../../util.v" - - # Set the Top Module as well... - project set top "fpga_hf" - - puts "$myScript: project sources reloaded." - -} ; # end add_source_files - -# -# create_libraries -# -# This procedure defines VHDL libraries and associates files with those libraries. -# It is expected to be used when recreating the project. Any libraries defined -# when this script was generated are recreated by this procedure. -# -proc create_libraries {} { - - global myScript - - if { ! [ open_project ] } { - return false - } - - puts "$myScript: Creating libraries..." - - - # must close the project or library definitions aren't saved. - project close - -} ; # end create_libraries - -# -# create_partitions -# -# This procedure creates partitions on instances in your project. -# It is expected to be used when recreating the project. Any partitions -# defined when this script was generated are recreated by this procedure. -# -proc create_partitions {} { - - global myScript - - if { ! [ open_project ] } { - return false - } - - puts "$myScript: Creating Partitions..." - - - # must close the project or partition definitions aren't saved. - project close - -} ; # end create_partitions - -# -# set_process_props -# -# This procedure sets properties as requested during script generation (either -# all of the properties, or only those modified from their defaults). -# -proc set_process_props {} { - - global myScript - - if { ! [ open_project ] } { - return false - } - - puts "$myScript: setting process properties..." - - project set "Compiled Library Directory" "\$XILINX//" - project set "Use SmartGuide" "false" - project set "SmartGuide Filename" "fpga_hf_guide.ncd" - project set "Multiplier Style" "Auto" -process "Synthesize - XST" - project set "Configuration Rate" "Default (1)" -process "Generate Programming File" - project set "Map to Input Functions" "4" -process "Map" - project set "Number of Clock Buffers" "24" -process "Synthesize - XST" - project set "Max Fanout" "500" -process "Synthesize - XST" - project set "Case Implementation Style" "None" -process "Synthesize - XST" - project set "Decoder Extraction" "true" -process "Synthesize - XST" - project set "Priority Encoder Extraction" "Yes" -process "Synthesize - XST" - project set "Mux Extraction" "Yes" -process "Synthesize - XST" - project set "RAM Extraction" "true" -process "Synthesize - XST" - project set "ROM Extraction" "true" -process "Synthesize - XST" - project set "FSM Encoding Algorithm" "Auto" -process "Synthesize - XST" - project set "Logical Shifter Extraction" "true" -process "Synthesize - XST" - project set "Optimization Goal" "Speed" -process "Synthesize - XST" - project set "Optimization Effort" "Normal" -process "Synthesize - XST" - project set "Resource Sharing" "true" -process "Synthesize - XST" - project set "Shift Register Extraction" "true" -process "Synthesize - XST" - project set "XOR Collapsing" "true" -process "Synthesize - XST" - project set "Other Bitgen Command Line Options" "" -process "Generate Programming File" - project set "Show All Models" "false" -process "Generate IBIS Model" - project set "Target UCF File Name" "" -process "Back-annotate Pin Locations" - project set "Ignore User Timing Constraints" "false" -process "Map" - project set "Use RLOC Constraints" "true" -process "Map" - project set "Other Map Command Line Options" "" -process "Map" - project set "Use LOC Constraints" "true" -process "Translate" - project set "Other Ngdbuild Command Line Options" "" -process "Translate" - project set "Ignore User Timing Constraints" "false" -process "Place & Route" - project set "Other Place & Route Command Line Options" "" -process "Place & Route" - project set "UserID Code (8 Digit Hexadecimal)" "0xFFFFFFFF" -process "Generate Programming File" - project set "Reset DCM if SHUTDOWN & AGHIGH performed" "false" -process "Generate Programming File" - project set "Configuration Pin Done" "Pull Up" -process "Generate Programming File" - project set "Create ASCII Configuration File" "false" -process "Generate Programming File" - project set "Create Binary Configuration File" "false" -process "Generate Programming File" - project set "Create Bit File" "true" -process "Generate Programming File" - project set "Enable BitStream Compression" "false" -process "Generate Programming File" - project set "Run Design Rules Checker (DRC)" "true" -process "Generate Programming File" - project set "Enable Cyclic Redundancy Checking (CRC)" "true" -process "Generate Programming File" - project set "Create IEEE 1532 Configuration File" "false" -process "Generate Programming File" - project set "Configuration Pin Program" "Pull Up" -process "Generate Programming File" - project set "JTAG Pin TCK" "Pull Up" -process "Generate Programming File" - project set "JTAG Pin TDI" "Pull Up" -process "Generate Programming File" - project set "JTAG Pin TDO" "Pull Up" -process "Generate Programming File" - project set "JTAG Pin TMS" "Pull Up" -process "Generate Programming File" - project set "Unused IOB Pins" "Pull Down" -process "Generate Programming File" - project set "Security" "Enable Readback and Reconfiguration" -process "Generate Programming File" - project set "FPGA Start-Up Clock" "CCLK" -process "Generate Programming File" - project set "Done (Output Events)" "Default (4)" -process "Generate Programming File" - project set "Drive Done Pin High" "false" -process "Generate Programming File" - project set "Enable Outputs (Output Events)" "Default (5)" -process "Generate Programming File" - project set "Release DLL (Output Events)" "Default (NoWait)" -process "Generate Programming File" - project set "Release Write Enable (Output Events)" "Default (6)" -process "Generate Programming File" - project set "Enable Internal Done Pipe" "false" -process "Generate Programming File" - project set "Allow Logic Optimization Across Hierarchy" "false" -process "Map" - project set "Optimization Strategy (Cover Mode)" "Area" -process "Map" - project set "Disable Register Ordering" "false" -process "Map" - project set "Pack I/O Registers/Latches into IOBs" "Off" -process "Map" - project set "Replicate Logic to Allow Logic Level Reduction" "true" -process "Map" - project set "Generate Detailed MAP Report" "false" -process "Map" - project set "Map Slice Logic into Unused Block RAMs" "false" -process "Map" - project set "Perform Timing-Driven Packing and Placement" "false" -process "Map" - project set "Trim Unconnected Signals" "true" -process "Map" - project set "Create I/O Pads from Ports" "false" -process "Translate" - project set "Macro Search Path" "" -process "Translate" - project set "Netlist Translation Type" "Timestamp" -process "Translate" - project set "User Rules File for Netlister Launcher" "" -process "Translate" - project set "Allow Unexpanded Blocks" "false" -process "Translate" - project set "Allow Unmatched LOC Constraints" "false" -process "Translate" - project set "Starting Placer Cost Table (1-100)" "1" -process "Place & Route" - project set "Placer Effort Level (Overrides Overall Level)" "None" -process "Place & Route" - project set "Router Effort Level (Overrides Overall Level)" "None" -process "Place & Route" - project set "Place And Route Mode" "Normal Place and Route" -process "Place & Route" - project set "Use Bonded I/Os" "false" -process "Place & Route" - project set "Add I/O Buffers" "true" -process "Synthesize - XST" - project set "Global Optimization Goal" "AllClockNets" -process "Synthesize - XST" - project set "Keep Hierarchy" "No" -process "Synthesize - XST" - project set "Register Balancing" "No" -process "Synthesize - XST" - project set "Register Duplication" "true" -process "Synthesize - XST" - project set "Asynchronous To Synchronous" "false" -process "Synthesize - XST" - project set "Automatic BRAM Packing" "false" -process "Synthesize - XST" - project set "BRAM Utilization Ratio" "100" -process "Synthesize - XST" - project set "Bus Delimiter" "<>" -process "Synthesize - XST" - project set "Case" "Maintain" -process "Synthesize - XST" - project set "Cores Search Directories" "" -process "Synthesize - XST" - project set "Cross Clock Analysis" "false" -process "Synthesize - XST" - project set "Equivalent Register Removal" "true" -process "Synthesize - XST" - project set "FSM Style" "LUT" -process "Synthesize - XST" - project set "Generate RTL Schematic" "Yes" -process "Synthesize - XST" - project set "Generics, Parameters" "" -process "Synthesize - XST" - project set "Hierarchy Separator" "/" -process "Synthesize - XST" - project set "HDL INI File" "" -process "Synthesize - XST" - project set "Library Search Order" "" -process "Synthesize - XST" - project set "Netlist Hierarchy" "As Optimized" -process "Synthesize - XST" - project set "Optimize Instantiated Primitives" "false" -process "Synthesize - XST" - project set "Pack I/O Registers into IOBs" "Auto" -process "Synthesize - XST" - project set "Read Cores" "true" -process "Synthesize - XST" - project set "Slice Packing" "true" -process "Synthesize - XST" - project set "Slice Utilization Ratio" "100" -process "Synthesize - XST" - project set "Use Clock Enable" "Yes" -process "Synthesize - XST" - project set "Use Synchronous Reset" "Yes" -process "Synthesize - XST" - project set "Use Synchronous Set" "Yes" -process "Synthesize - XST" - project set "Use Synthesis Constraints File" "true" -process "Synthesize - XST" - project set "Custom Compile File List" "" -process "Synthesize - XST" - project set "Verilog Include Directories" "" -process "Synthesize - XST" - project set "Verilog 2001" "true" -process "Synthesize - XST" - project set "Verilog Macros" "" -process "Synthesize - XST" - project set "Work Directory" "./xst" -process "Synthesize - XST" - project set "Write Timing Constraints" "false" -process "Synthesize - XST" - project set "Other XST Command Line Options" "" -process "Synthesize - XST" - project set "Map Effort Level" "Medium" -process "Map" - project set "Combinatorial Logic Optimization" "false" -process "Map" - project set "Starting Placer Cost Table (1-100)" "1" -process "Map" - project set "Power Reduction" "false" -process "Map" - project set "Register Duplication" "false" -process "Map" - project set "Synthesis Constraints File" "" -process "Synthesize - XST" - project set "Mux Style" "Auto" -process "Synthesize - XST" - project set "RAM Style" "Auto" -process "Synthesize - XST" - project set "Timing Mode" "Non Timing Driven" -process "Map" - project set "Generate Asynchronous Delay Report" "false" -process "Place & Route" - project set "Generate Clock Region Report" "false" -process "Place & Route" - project set "Generate Post-Place & Route Simulation Model" "false" -process "Place & Route" - project set "Generate Post-Place & Route Static Timing Report" "true" -process "Place & Route" - project set "Nodelist File (Unix Only)" "" -process "Place & Route" - project set "Number of PAR Iterations (0-100)" "3" -process "Place & Route" - project set "Save Results in Directory (.dir will be appended)" "" -process "Place & Route" - project set "Number of Results to Save (0-100)" "" -process "Place & Route" - project set "Power Reduction" "false" -process "Place & Route" - project set "Timing Mode" "Performance Evaluation" -process "Place & Route" - project set "Enable Debugging of Serial Mode BitStream" "false" -process "Generate Programming File" - project set "CLB Pack Factor Percentage" "100" -process "Map" - project set "Place & Route Effort Level (Overall)" "Standard" -process "Place & Route" - project set "Move First Flip-Flop Stage" "true" -process "Synthesize - XST" - project set "Move Last Flip-Flop Stage" "true" -process "Synthesize - XST" - project set "ROM Style" "Auto" -process "Synthesize - XST" - project set "Safe Implementation" "No" -process "Synthesize - XST" - project set "Extra Effort" "None" -process "Map" - project set "Power Activity File" "" -process "Map" - project set "Power Activity File" "" -process "Place & Route" - project set "Extra Effort (Highest PAR level only)" "None" -process "Place & Route" - - puts "$myScript: project property values set." - -} ; # end set_process_props - -proc main {} { - - if { [llength $::argv] == 0 } { - show_help - return true - } - - foreach option $::argv { - switch $option { - "show_help" { show_help } - "run_process" { run_process } - "rebuild_project" { rebuild_project } - "set_project_props" { set_project_props } - "add_source_files" { add_source_files } - "create_libraries" { create_libraries } - "create_partitions" { create_partitions } - "set_process_props" { set_process_props } - default { puts "unrecognized option: $option"; show_help } - } - } -} - -if { $tcl_interactive } { - show_help -} else { - if {[catch {main} result]} { - puts "$myScript failed: $result." - } -} - diff --git a/fpga-xc3s100e/lf_edge_detect.v b/fpga-xc3s100e/lf_edge_detect.v deleted file mode 100644 index d086f95fc..000000000 --- a/fpga-xc3s100e/lf_edge_detect.v +++ /dev/null @@ -1,77 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// input clk is 24MHz -`include "min_max_tracker.v" - -module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, - output [7:0] max, output [7:0] min, - output [7:0] high_threshold, output [7:0] highz_threshold, - output [7:0] lowz_threshold, output [7:0] low_threshold, - output edge_state, output edge_toggle); - - min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max); - - // auto-tune - assign high_threshold = (max + min) / 2 + (max - min) / 4; - assign highz_threshold = (max + min) / 2 + (max - min) / 8; - assign lowz_threshold = (max + min) / 2 - (max - min) / 8; - assign low_threshold = (max + min) / 2 - (max - min) / 4; - - // heuristic to see if it makes sense to try to detect an edge - wire enabled = - (high_threshold > highz_threshold) - & (highz_threshold > lowz_threshold) - & (lowz_threshold > low_threshold) - & ((high_threshold - highz_threshold) > 8) - & ((highz_threshold - lowz_threshold) > 16) - & ((lowz_threshold - low_threshold) > 8); - - // Toggle the output with hysteresis - // Set to high if the ADC value is above the threshold - // Set to low if the ADC value is below the threshold - reg is_high = 0; - reg is_low = 0; - reg is_zero = 0; - reg trigger_enabled = 1; - reg output_edge = 0; - reg output_state; - - always @(posedge clk) - begin - is_high <= (adc_d >= high_threshold); - is_low <= (adc_d <= low_threshold); - is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); - end - - // all edges detection - always @(posedge clk) - if (enabled) begin - // To enable detecting two consecutive peaks at the same level - // (low or high) we check whether or not we went back near 0 in-between. - // This extra check is necessary to prevent from noise artifacts - // around the threshold values. - if (trigger_enabled & (is_high | is_low)) begin - output_edge <= ~output_edge; - trigger_enabled <= 0; - end else - trigger_enabled <= trigger_enabled | is_zero; - end - - // edge states - always @(posedge clk) - if (enabled) begin - if (is_high) - output_state <= 1'd1; - else if (is_low) - output_state <= 1'd0; - end - - assign edge_state = output_state; - assign edge_toggle = output_edge; - -endmodule diff --git a/fpga-xc3s100e/lo_adc.v b/fpga-xc3s100e/lo_adc.v deleted file mode 100644 index bba090afb..000000000 --- a/fpga-xc3s100e/lo_adc.v +++ /dev/null @@ -1,91 +0,0 @@ -//----------------------------------------------------------------------------- -// The way that we connect things in low-frequency simulation mode. In this -// case just pass everything through to the ARM, which can bit-bang this -// (because it is so slow). -// -// Jonathan Westhues, April 2006 -//----------------------------------------------------------------------------- - -module lo_adc( - pck0, - 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, divisor, - lf_field -); - input pck0; - 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 [7:0] divisor; - input lf_field; - -reg [7:0] to_arm_shiftreg; -reg [7:0] pck_divider; -reg clk_state; - -// Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) -wire tag_modulation = ssp_dout & !lf_field; -wire reader_modulation = !ssp_dout & lf_field & clk_state; - -// always on (High Frequency outputs, unused) -assign pwr_oe1 = 1'b0; -assign pwr_hi = 1'b0; - -// low frequency outputs -assign pwr_lo = reader_modulation; -assign pwr_oe2 = 1'b0; // 33 Ohms -assign pwr_oe3 = tag_modulation; // base antenna load = 33 Ohms -assign pwr_oe4 = 1'b0; // 10k Ohms - -// Debug Output ADC clock -assign dbg = adc_clk; - -// ADC clock out of phase with antenna driver -assign adc_clk = ~clk_state; - -// serialized SSP data is gated by clk_state to suppress unwanted signal -assign ssp_din = to_arm_shiftreg[7] && !clk_state; - -// SSP clock always runs at 24MHz -assign ssp_clk = pck0; - -// SSP frame is gated by clk_state and goes high when pck_divider=8..15 -assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; - -// divide 24mhz down to 3mhz -always @(posedge pck0) -begin - if (pck_divider == divisor[7:0]) - begin - pck_divider <= 8'd0; - clk_state = !clk_state; - end - else - begin - pck_divider <= pck_divider + 1; - end -end - -// this task also runs at pck0 frequency (24Mhz) and is used to serialize -// the ADC output which is then clocked into the ARM SSP. -always @(posedge pck0) -begin - if ((pck_divider == 8'd7) && !clk_state) - to_arm_shiftreg <= adc_d; - else begin - to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - // simulation showed a glitch occurring due to the LSB of the shifter - // not being set as we shift bits out - // this ensures the ssp_din remains low after a transfer and suppresses - // the glitch that would occur when the last data shifted out ended in - // a 1 bit and the next data shifted out started with a 0 bit - to_arm_shiftreg[0] <= 1'b0; - end -end - -endmodule diff --git a/fpga-xc3s100e/lo_edge_detect.v b/fpga-xc3s100e/lo_edge_detect.v deleted file mode 100644 index d91bf3845..000000000 --- a/fpga-xc3s100e/lo_edge_detect.v +++ /dev/null @@ -1,70 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// -// There are two modes: -// - lf_ed_toggle_mode == 0: the output is set low (resp. high) when a low -// (resp. high) edge/peak is detected, with hysteresis -// - lf_ed_toggle_mode == 1: the output is toggling whenever an edge/peak -// is detected. -// That way you can detect two consecutive edges/peaks at the same level (L/H) -// -// Output: -// - ssp_frame (wired to TIOA1 on the arm) for the edge detection/state -// - ssp_clk: cross_lo - -//For ISE 10.1 PROJ,IDE auto include -//`include "lp20khz_1MSa_iir_filter.v" -//`include "lf_edge_detect.v" - -module lo_edge_detect( - input pck0, input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, - output ssp_frame, input ssp_dout, output ssp_clk, - input cross_lo, - output dbg, - input lf_field, - input lf_ed_toggle_mode, input [7:0] lf_ed_threshold -); - -wire tag_modulation = ssp_dout & !lf_field; -wire reader_modulation = !ssp_dout & lf_field & pck_divclk; - -// No logic, straight through. -assign pwr_oe1 = 1'b0; // not used in LF mode -assign pwr_oe3 = 1'b0; // base antenna load = 33 Ohms -// when modulating, add another 33 Ohms and 10k Ohms in parallel: -assign pwr_oe2 = tag_modulation; -assign pwr_oe4 = tag_modulation; - -assign ssp_clk = cross_lo; -assign pwr_lo = reader_modulation; -assign pwr_hi = 1'b0; - -// filter the ADC values -wire data_rdy; -wire [7:0] adc_filtered; -assign adc_clk = pck0; -lp20khz_1MSa_iir_filter adc_filter(pck0, adc_d, data_rdy, adc_filtered); - -// detect edges -wire [7:0] high_threshold, highz_threshold, lowz_threshold, low_threshold; -wire [7:0] max, min; -wire edge_state, edge_toggle; -lf_edge_detect lf_ed(pck0, adc_filtered, lf_ed_threshold, - max, min, - high_threshold, highz_threshold, lowz_threshold, low_threshold, - edge_state, edge_toggle); - -assign dbg = lf_ed_toggle_mode ? edge_toggle : edge_state; - -assign ssp_frame = lf_ed_toggle_mode ? edge_toggle : edge_state; - -endmodule - diff --git a/fpga-xc3s100e/lo_passthru.v b/fpga-xc3s100e/lo_passthru.v deleted file mode 100644 index f0f2847a0..000000000 --- a/fpga-xc3s100e/lo_passthru.v +++ /dev/null @@ -1,29 +0,0 @@ -//----------------------------------------------------------------------------- -// For reading TI tags, we need to place the FPGA in pass through mode -// and pass everything through to the ARM -//----------------------------------------------------------------------------- -// iZsh , June 2014 - -module lo_passthru( - input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - output adc_clk, - output ssp_din, input ssp_dout, - input cross_lo, - output dbg -); - -// the antenna is modulated when ssp_dout = 1, when 0 the -// antenna drivers stop modulating and go into listen mode -assign pwr_oe3 = 1'b0; -assign pwr_oe1 = ssp_dout; -assign pwr_oe2 = ssp_dout; -assign pwr_oe4 = ssp_dout; -assign pwr_lo = pck_divclk && ssp_dout; -assign pwr_hi = 1'b0; -assign adc_clk = 1'b0; -assign ssp_din = cross_lo; -assign dbg = cross_lo; - -endmodule diff --git a/fpga-xc3s100e/lo_read.v b/fpga-xc3s100e/lo_read.v deleted file mode 100644 index 8ac58721e..000000000 --- a/fpga-xc3s100e/lo_read.v +++ /dev/null @@ -1,74 +0,0 @@ -//----------------------------------------------------------------------------- -// The way that we connect things in low-frequency read mode. In this case -// we are generating the unmodulated low frequency carrier. -// The A/D samples at that same rate and the result is serialized. -// -// Jonathan Westhues, April 2006 -// iZsh , June 2014 -//----------------------------------------------------------------------------- - -module lo_read( - input pck0, input [7:0] pck_cnt, input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, - output ssp_frame, output ssp_din, output ssp_clk, - output dbg, - input lf_field -); - -reg [7:0] to_arm_shiftreg; - -// this task also runs at pck0 frequency (24MHz) and is used to serialize -// the ADC output which is then clocked into the ARM SSP. - -// because pck_divclk always transitions when pck_cnt = 0 we use the -// pck_div counter to sync our other signals off it -// we read the ADC value when pck_cnt=7 and shift it out on counts 8..15 -always @(posedge pck0) -begin - if((pck_cnt == 8'd7) && !pck_divclk) - to_arm_shiftreg <= adc_d; - else begin - to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - // simulation showed a glitch occurring due to the LSB of the shifter - // not being set as we shift bits out - // this ensures the ssp_din remains low after a transfer and suppresses - // the glitch that would occur when the last data shifted out ended in - // a 1 bit and the next data shifted out started with a 0 bit - to_arm_shiftreg[0] <= 1'b0; - end -end - -// ADC samples on falling edge of adc_clk, data available on the rising edge - -// example of ssp transfer of binary value 1100101 -// start of transfer is indicated by the rise of the ssp_frame signal -// ssp_din changes on the rising edge of the ssp_clk clock and is clocked into -// the ARM by the falling edge of ssp_clk -// _______________________________ -// ssp_frame__| |__ -// _______ ___ ___ -// ssp_din __| |_______| |___| |______ -// _ _ _ _ _ _ _ _ _ _ -// ssp_clk |_| |_| |_| |_| |_| |_| |_| |_| |_| |_ - -// serialized SSP data is gated by ant_lo to suppress unwanted signal -assign ssp_din = to_arm_shiftreg[7] && !pck_divclk; -// SSP clock always runs at 24MHz -assign ssp_clk = pck0; -// SSP frame is gated by ant_lo and goes high when pck_divider=8..15 -assign ssp_frame = (pck_cnt[7:3] == 5'd1) && !pck_divclk; -// unused signals tied low -assign pwr_hi = 1'b0; -assign pwr_oe1 = 1'b0; -assign pwr_oe2 = 1'b0; -assign pwr_oe3 = 1'b0; -assign pwr_oe4 = 1'b0; -// this is the antenna driver signal -assign pwr_lo = lf_field & pck_divclk; -// ADC clock out of phase with antenna driver -assign adc_clk = ~pck_divclk; -// ADC clock also routed to debug pin -assign dbg = adc_clk; -endmodule diff --git a/fpga-xc3s100e/lp20khz_1MSa_iir_filter.v b/fpga-xc3s100e/lp20khz_1MSa_iir_filter.v deleted file mode 100644 index 2dbfd6945..000000000 --- a/fpga-xc3s100e/lp20khz_1MSa_iir_filter.v +++ /dev/null @@ -1,81 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Butterworth low pass IIR filter -// input: 8bit ADC signal, 1MS/s -// output: 8bit value, Fc=20khz -// -// coef: (using http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html) -// Recurrence relation: -// y[n] = ( 1 * x[n- 2]) -// + ( 2 * x[n- 1]) -// + ( 1 * x[n- 0]) - -// + ( -0.8371816513 * y[n- 2]) -// + ( 1.8226949252 * y[n- 1]) -// -// therefore: -// a = [1,2,1] -// b = [-0.8371816513, 1.8226949252] -// b is approximated to b = [-0xd6/0x100, 0x1d3 / 0x100] (for optimization) -// gain = 2.761139367e2 -// -// See details about its design see -// https://fail0verflow.com/blog/2014/proxmark3-fpga-iir-filter.html -module lp20khz_1MSa_iir_filter(input clk, input [7:0] adc_d, output rdy, output [7:0] out); - - // clk is 24MHz, the IIR filter is designed for 1MS/s - // hence we need to divide it by 24 - // using a shift register takes less area than a counter - reg [23:0] cnt = 1; - assign rdy = cnt[0]; - always @(posedge clk) - cnt <= {cnt[22:0], cnt[23]}; - - reg [7:0] x0 = 0; - reg [7:0] x1 = 0; - reg [16:0] y0 = 0; - reg [16:0] y1 = 0; - - always @(posedge clk) - begin - if (rdy) - begin - x0 <= x1; - x1 <= adc_d; - y0 <= y1; - y1 <= - // center the signal: - // input range is [0; 255] - // We want "128" to be at the center of the 17bit register - // (128+z)*gain = 17bit center - // z = (1<<16)/gain - 128 = 109 - // We could use 9bit x registers for that, but that would be - // a waste, let's just add the constant during the computation - // (x0+109) + 2*(x1+109) + (x2+109) = x0 + 2*x1 + x2 + 436 - x0 + {x1, 1'b0} + adc_d + 436 - // we want "- y0 * 0xd6 / 0x100" using only shift and add - // 0xd6 == 0b11010110 - // so *0xd6/0x100 is equivalent to - // ((x << 1) + (x << 2) + (x << 4) + (x << 6) + (x << 7)) >> 8 - // which is also equivalent to - // (x >> 7) + (x >> 6) + (x >> 4) + (x >> 2) + (x >> 1) - - ((y0 >> 7) + (y0 >> 6) + (y0 >> 4) + (y0 >> 2) + (y0 >> 1)) // - y0 * 0xd6 / 0x100 - // we want "+ y1 * 0x1d3 / 0x100" - // 0x1d3 == 0b111010011 - // so this is equivalent to - // ((x << 0) + (x << 1) + (x << 4) + (x << 6) + (x << 7) + (x << 8)) >> 8 - // which is also equivalent to - // (x >> 8) + (x >> 7) + (x >> 4) + (x >> 2) + (x >> 1) + (x >> 0) - + ((y1 >> 8) + (y1 >> 7) + (y1 >> 4) + (y1 >> 2) + (y1 >> 1) + y1); - end - end - - // output: reduce to 8bit - assign out = y1[16:9]; - -endmodule diff --git a/fpga-xc3s100e/min_max_tracker.v b/fpga-xc3s100e/min_max_tracker.v deleted file mode 100644 index 5e8bbedf1..000000000 --- a/fpga-xc3s100e/min_max_tracker.v +++ /dev/null @@ -1,65 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// track min and max peak values (envelope follower) -// -// NB: the min value (resp. max value) is updated only when the next high peak -// (resp. low peak) is reached/detected, since you can't know it isn't a -// local minima (resp. maxima) until then. -// This also means the peaks are detected with an unpredictable delay. -// This algorithm therefore can't be used directly for realtime peak detections, -// but it can be used as a simple envelope follower. -module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, - output [7:0] min, output [7:0] max); - - reg [7:0] min_val = 255; - reg [7:0] max_val = 0; - reg [7:0] cur_min_val = 255; - reg [7:0] cur_max_val = 0; - reg [1:0] state = 0; - - always @(posedge clk) - begin - case (state) - 0: // initialize - begin - if (cur_max_val >= ({1'b0, adc_d} + threshold)) - state <= 2; - else if (adc_d >= ({1'b0, cur_min_val} + threshold)) - state <= 1; - if (cur_max_val <= adc_d) - cur_max_val <= adc_d; - else if (adc_d <= cur_min_val) - cur_min_val <= adc_d; - end - 1: // high phase - begin - if (cur_max_val <= adc_d) - cur_max_val <= adc_d; - else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin - state <= 2; - cur_min_val <= adc_d; - max_val <= cur_max_val; - end - end - 2: // low phase - begin - if (adc_d <= cur_min_val) - cur_min_val <= adc_d; - else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin - state <= 1; - cur_max_val <= adc_d; - min_val <= cur_min_val; - end - end - endcase - end - - assign min = min_val; - assign max = max_val; - -endmodule diff --git a/fpga-xc3s100e/util.v b/fpga-xc3s100e/util.v deleted file mode 100644 index 0842ac64f..000000000 --- a/fpga-xc3s100e/util.v +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// General-purpose miscellany. -// -// Jonathan Westhues, April 2006. -//----------------------------------------------------------------------------- - -module mux8(sel, y, x0, x1, x2, x3, x4, x5, x6, x7); - input [2:0] sel; - input x0, x1, x2, x3, x4, x5, x6, x7; - output y; - reg y; - -always @(x0 or x1 or x2 or x3 or x4 or x5 or x6 or x7 or sel) -begin - case (sel) - 3'b000: y = x0; - 3'b001: y = x1; - 3'b010: y = x2; - 3'b011: y = x3; - 3'b100: y = x4; - 3'b101: y = x5; - 3'b110: y = x6; - 3'b111: y = x7; - endcase -end - -endmodule diff --git a/fpga/Makefile b/fpga/Makefile new file mode 100644 index 000000000..068b75255 --- /dev/null +++ b/fpga/Makefile @@ -0,0 +1,226 @@ +# +# FPGA Makefile for all targets +# +# The top part of this Makefile is used to define custom options for a number of compilation targets +# To define an additional target simply look at the other defined targets and add a new TARGET entry with a unique number and the custom options required + +XILINX_TOOLS_PREFIX= + +# Copy update (only when destination is older or missing) +CP = cp -u + +# Make directory, no error if already existing +MKDIR = mkdir -p + +# Remove recursive, force +RMDIR = rm -rf + +# Path to make +MAKE = make + +# Custom prefix for build directories, each target is built into its own separate directory name formed by combining the PREFIX and TARGET names. +# This way the source is not polluted with build files and the build directories are left behind after compilation so logs and reports can be +# examined or can be easily deleted with "make clean" +PREFIX = __ + +# Options to be passed to XST +XST_OPTS_BASE = run +XST_OPTS_BASE += -ifn xst.prj +XST_OPTS_BASE += -ifmt mixed +XST_OPTS_BASE += -ofmt NGC +XST_OPTS_BASE += -lso xst.lso +XST_OPTS_BASE += -top fpga_top +XST_OPTS_BASE += -resource_sharing yes + +# Optimizations for speed (default) +XST_OPTS_SPEED = -opt_mode Speed +XST_OPTS_SPEED += -opt_level 1 +XST_OPTS_SPEED += -fsm_style lut +XST_OPTS_SPEED += -fsm_encoding auto + +# Optimization for reduced space +XST_OPTS_AREA = -opt_mode area +XST_OPTS_AREA += -opt_level 2 +XST_OPTS_AREA += -fsm_style bram +XST_OPTS_AREA += -fsm_encoding compact + +# Types of selective module compilation: +# WITH_LF Enables selection of LF modules (and disables all HF) + +# To enable these modules WITH_LF _MUST_ be defined +# WITH_LF0 enable LF reader (generic) +# WITH_LF1 enable LF edge detect (generic) +# WITH_LF2 enable LF passthrough +# WITH_LF3 enable LF ADC (read/write) + +# To enable these modules WITH_LF _MUST_NOT_ be defined +# WITH_HF0 enable HF reader (see also WITH_HF_15 below) +# WITH_HF_15 select "iso15 2sc mode" extensions instead of original +# WITH_HF1 enable HF simulated tag +# WITH_HF2 enable HF ISO14443-A +# WITH_HF3 enable sniff +# WITH_HF4 enable HF ISO18092 FeliCa +# WITH_HF5 enable HF get trace + +# RDV40/Generic - Enable LF and all the LF modules +TARGET1_OPTIONS = -define \{WITH_LF WITH_LF0 WITH_LF1 WITH_LF2 WITH_LF3\} +# RDV40/Generic - Enable all HF modules except Felica +TARGET2_OPTIONS = -define \{WITH_HF0 WITH_HF1 WITH_HF2 WITH_HF3 WITH_HF5\} +# RDV40/Generic - Enable all HF modules except Felica and ISO14443, select HF_15 instead of HF +TARGET3_OPTIONS = -define \{WITH_HF0 WITH_HF1 WITH_HF3 WITH_HF5 WITH_HF_15\} +# RDV40/Generic - Enable all HF modules except ISO14443 +TARGET4_OPTIONS = -define \{WITH_HF0 WITH_HF1 WITH_HF3 WITH_HF4 WITH_HF5\} +# ICOPYX +TARGET5_OPTIONS = -define {PM3ICOPYX} -rtlview Yes + +# Here we list the target names +TARGET1_NAME = fpga_pm3_lf +TARGET2_NAME = fpga_pm3_hf +TARGET3_NAME = fpga_pm3_hf_15 +TARGET4_NAME = fpga_pm3_felica +TARGET5_NAME = fpga_icopyx_hf + +# Targets can be compiled for different FPGA flavours +TARGET1_FPGA = xc2s30-5-vq100 +TARGET2_FPGA = $(TARGET1_FPGA) +TARGET3_FPGA = $(TARGET1_FPGA) +TARGET4_FPGA = $(TARGET1_FPGA) +TARGET5_FPGA = xc3s100e-4-vq100 + +# Assemble the final XST options for each target +TARGET1_XST_OPTS = $(XST_OPTS_BASE) $(XST_OPTS_AREA) -p $(TARGET1_FPGA) -ofn $(TARGET1_NAME) $(TARGET1_OPTIONS) +TARGET2_XST_OPTS = $(XST_OPTS_BASE) $(XST_OPTS_AREA) -p $(TARGET2_FPGA) -ofn $(TARGET2_NAME) $(TARGET2_OPTIONS) +TARGET3_XST_OPTS = $(XST_OPTS_BASE) $(XST_OPTS_AREA) -p $(TARGET3_FPGA) -ofn $(TARGET3_NAME) $(TARGET3_OPTIONS) +TARGET4_XST_OPTS = $(XST_OPTS_BASE) $(XST_OPTS_AREA) -p $(TARGET4_FPGA) -ofn $(TARGET4_NAME) $(TARGET4_OPTIONS) +TARGET5_XST_OPTS = $(XST_OPTS_BASE) $(XST_OPTS_SPEED) -p $(TARGET5_FPGA) -ofn $(TARGET5_NAME) $(TARGET5_OPTIONS) + +# these files are common for all targets +TARGET_COMMON_FILES = define.v +TARGET_COMMON_FILES += mux8.v +TARGET_COMMON_FILES += clk_divider.v +TARGET_COMMON_FILES += lp20khz_1MSa_iir_filter.v +TARGET_COMMON_FILES += min_max_tracker.v +TARGET_COMMON_FILES += hi_flite.v +TARGET_COMMON_FILES += hi_get_trace.v +TARGET_COMMON_FILES += hi_iso14443a.v +TARGET_COMMON_FILES += hi_reader.v +TARGET_COMMON_FILES += hi_reader_15.v +TARGET_COMMON_FILES += hi_simulate.v +TARGET_COMMON_FILES += hi_sniffer.v +TARGET_COMMON_FILES += lf_edge_detect.v +TARGET_COMMON_FILES += lo_adc.v +TARGET_COMMON_FILES += lo_edge_detect.v +TARGET_COMMON_FILES += lo_passthru.v +TARGET_COMMON_FILES += lo_read.v + +# Add the files that are unique per target and all the common files +TARGET1_FILES = $(TARGET_COMMON_FILES) fpga_pm3_top.v +TARGET2_FILES = $(TARGET1_FILES) +TARGET3_FILES = $(TARGET1_FILES) +TARGET4_FILES = $(TARGET1_FILES) +TARGET5_FILES = $(TARGET_COMMON_FILES) mux2_onein.v mux2_oneout.v fpga_icopyx_hf.v fpga_icopyx_lf.v fpga_icopyx_top.v + +# List of all valid target FPGA images to build +TARGETS = $(TARGET1_NAME) $(TARGET2_NAME) $(TARGET3_NAME) $(TARGET4_NAME) $(TARGET5_NAME) + +# Verbosity type for ISE tools ise|xflow|silent +VERBOSITY = -intstyle silent +# Echo (Q=) or not echo (Q=@) build commands to the terminal +Q=@ + +# Pass the custom variables to the lower make rules +$(TARGET1_NAME).bit: TARGET_FPGA = $(TARGET1_FPGA) +$(TARGET1_NAME).bit: TARGET_FILES = $(TARGET1_FILES) +$(TARGET1_NAME).bit: TARGET_XST_OPTS = $(TARGET1_XST_OPTS) + +$(TARGET2_NAME).bit: TARGET_FPGA = $(TARGET2_FPGA) +$(TARGET2_NAME).bit: TARGET_FILES = $(TARGET2_FILES) +$(TARGET2_NAME).bit: TARGET_XST_OPTS = $(TARGET2_XST_OPTS) + +$(TARGET3_NAME).bit: TARGET_FPGA = $(TARGET3_FPGA) +$(TARGET3_NAME).bit: TARGET_FILES = $(TARGET3_FILES) +$(TARGET3_NAME).bit: TARGET_XST_OPTS = $(TARGET3_XST_OPTS) + +$(TARGET4_NAME).bit: TARGET_FPGA = $(TARGET4_FPGA) +$(TARGET4_NAME).bit: TARGET_FILES = $(TARGET4_FILES) +$(TARGET4_NAME).bit: TARGET_XST_OPTS = $(TARGET4_XST_OPTS) + +$(TARGET5_NAME).bit: TARGET_FPGA = $(TARGET5_FPGA) +$(TARGET5_NAME).bit: TARGET_FILES = $(TARGET5_FILES) +$(TARGET5_NAME).bit: TARGET_XST_OPTS = $(TARGET5_XST_OPTS) + +$(TARGETS): + $(Q)$(MKDIR) $(PREFIX)build_$@ + $(Q)$(MAKE) -C $(PREFIX)build_$@ -f ../Makefile $(notdir $@).bit + +work: + $(Q)$(RM) xst.prj + $(Q)for item in $(TARGET_FILES); do echo verilog work ../$$item>>xst.prj; done + $(Q)echo work> xst.lso + +%.xst: work + $(Q)$(RM) $@ + $(Q)echo $(TARGET_XST_OPTS)> $@ + +%.ngc: %.xst + $(Q)$(RM) $@ + $(info [-] XST $@) + $(Q)$(XILINX_TOOLS_PREFIX)xst $(VERBOSITY) -ifn $< + +%.ngd: %.ngc + $(Q)$(RM) $@ + $(info [-] NGD $@) + $(Q)$(XILINX_TOOLS_PREFIX)ngdbuild $(VERBOSITY) -quiet -p $(TARGET_FPGA) -nt timestamp -uc ../$(TARGET_FPGA).ucf $< $@ + +%_map.ncd: %.ngd + $(Q)$(RM) $@ + $(info [-] MAP $@) + $(Q)$(XILINX_TOOLS_PREFIX)map $(VERBOSITY) -p $(TARGET_FPGA) -o $*_map $* + +%.ncd: %_map.ncd + $(Q)$(RM) $@ + $(info [-] PAR $@) + $(Q)$(XILINX_TOOLS_PREFIX)par $(VERBOSITY) -w $< $@ + +%.bit: %.ncd + # Hacky hack, make empty files for icopyx + if echo "$@" | grep -qi "icopyx"; then \ + truncate -s0 ../fpga_icopyx_lf.bit; \ + truncate -s0 ../fpga_icopyx_hf_15.bit; \ + truncate -s0 ../fpga_icopyx_felica.bit; \ + fi + $(Q)$(RM) $@ $*.drc $*.rbt + $(info [=] BITGEN $@) + $(Q)$(XILINX_TOOLS_PREFIX)bitgen $(VERBOSITY) -w $* $@ + $(Q)$(CP) $@ .. + +# Build all targets +all: $(TARGETS) + +# ALWAYS have some hardcoded text after $(PREFIX) to avoid rm -rf * or rm -rf /* situations if PREFIX is incorrectly set to empty "" or just "/" +clean: + $(Q)$(RMDIR) $(PREFIX)build_* + $(info [-] Build files deleted) + +.DEFAULT: + @if [ "$@" != "all" ] && [ ! "$(filter $@,$(TARGETS))" ]; then \ + make help; \ + else \ + make all; \ + fi + +.PHONY: all help clean + +help: + @echo "################################################################" + @echo "#" + @echo "# - Builds only one of the above listed targets" + @echo "# all - Builds the FPGA bitstreams for all targets" + @echo "# clean - Keeps .bit files but cleans intermediate build files for all targets" + @echo "#" + @echo "#" + @echo "# Valid targets are:" + @echo "# $(TARGETS)" + @echo "#" + @echo "################################################################" + diff --git a/fpga-xc2s30/clk_divider.v b/fpga/clk_divider.v similarity index 91% rename from fpga-xc2s30/clk_divider.v rename to fpga/clk_divider.v index fbb3250f1..0bcc2e608 100644 --- a/fpga-xc2s30/clk_divider.v +++ b/fpga/clk_divider.v @@ -14,7 +14,12 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -module clk_divider(input clk, input [7:0] divisor, output [7:0] div_cnt, output div_clk); +module clk_divider( + input clk, + input [7:0] divisor, + output [7:0] div_cnt, + output div_clk +); reg [7:0] div_cnt_ = 0; reg div_clk_; diff --git a/fpga/define.v b/fpga/define.v new file mode 100644 index 000000000..b7423278b --- /dev/null +++ b/fpga/define.v @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// +// The FPGA is responsible for interfacing between the A/D, the coil drivers, +// and the ARM. In the low-frequency modes it passes the data straight +// through, so that the ARM gets raw A/D samples over the SSP. In the high- +// frequency modes, the FPGA might perform some demodulation first, to +// reduce the amount of data that we must send to the ARM. +//----------------------------------------------------------------------------- + +/* + Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() + Send 16 bit command / data pair to FPGA with the bit format: + ++------ frame layout circa 2020 ------------------+ +| 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | ++-------------------------------------------------+ +| C C C C M M M M P P P P P P P P | C = FPGA_CMD_SET_CONFREG, M = FPGA_MAJOR_MODE_*, P = FPGA_LF_* or FPGA_HF_* parameter +| C C C C D D D D D D D D | C = FPGA_CMD_SET_DIVISOR, D = divisor +| C C C C T T T T T T T T | C = FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, T = threshold +| C C C C E | C = FPGA_CMD_TRACE_ENABLE, E=0 off, E=1 on ++-------------------------------------------------+ + ++------ frame layout current ---------------------+ +| 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | ++-------------------------------------------------+ +| C C C C M M M P P P P P P | C = FPGA_CMD_SET_CONFREG, M = FPGA_MAJOR_MODE_*, P = FPGA_LF_* or FPGA_HF_* parameter +| C C C C D D D D D D D D | C = FPGA_CMD_SET_DIVISOR, D = divisor +| C C C C T T T T T T T T | C = FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, T = threshold +| C C C C E | C = FPGA_CMD_TRACE_ENABLE, E=0 off, E=1 on ++-------------------------------------------------+ + + shift_reg receive this 16bit frame + + LF command + ---------- + shift_reg[15:12] == 4bit command + LF has three commands (FPGA_CMD_SET_CONFREG, FPGA_CMD_SET_DIVISOR, FPGA_CMD_SET_EDGE_DETECT_THRESHOLD) + Current commands uses only 2bits. We have room for up to 4bits of commands total (7). + + LF data + ------- + shift_reg[11:0] == 12bit data + lf data is divided into MAJOR MODES and configuration values. + + The major modes uses 3bits (0,1,2,3,7 | 000, 001, 010, 011, 111) + 000 FPGA_MAJOR_MODE_LF_READER = Act as LF reader (modulate) + 001 FPGA_MAJOR_MODE_LF_EDGE_DETECT = Simulate LF + 010 FPGA_MAJOR_MODE_LF_PASSTHRU = Passthrough mode, CROSS_LO line connected to SSP_DIN. SSP_DOUT logic level controls if we modulate / listening + 011 FPGA_MAJOR_MODE_LF_ADC = refactor hitag2, clear ADC sampling + 111 FPGA_MAJOR_MODE_OFF = turn off sampling. + + Each one of this major modes can have options. Currently these two major modes uses options. + - FPGA_MAJOR_MODE_LF_READER + - FPGA_MAJOR_MODE_LF_EDGE_DETECT + + FPGA_MAJOR_MODE_LF_READER + ------------------------------------- + lf_field = 1bit (FPGA_LF_ADC_READER_FIELD) + + You can send FPGA_CMD_SET_DIVISOR to set with FREQUENCY the fpga should sample at + divisor = 8bits shift_reg[7:0] + + FPGA_MAJOR_MODE_LF_EDGE_DETECT + ------------------------------------------ + lf_ed_toggle_mode = 1bits + lf_ed_threshold = 8bits threshold defaults to 127 + + You can send FPGA_CMD_SET_EDGE_DETECT_THRESHOLD to set a custom threshold + lf_ed_threshold = 8bits threshold value. + + conf_word 12bits + conf_word[7:5] = 3bit major mode. + conf_word[0] = 1bit lf_field + conf_word[1] = 1bit lf_ed_toggle_mode + conf_word[7:0] = 8bit divisor + conf_word[7:0] = 8bit threshold + +*/ +// Defining commands, modes and options. This must be aligned to the definitions in armsrc/fpgaloader.h +// Note: the definitions here are without shifts + +// Definitions for the FPGA commands. +`define FPGA_CMD_SET_CONFREG 1 +`define FPGA_CMD_SET_DIVISOR 2 +`define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD 3 +`define FPGA_CMD_TRACE_ENABLE 2 + +// Major modes +`define FPGA_MAJOR_MODE_LF_READER 0 +`define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 +`define FPGA_MAJOR_MODE_LF_PASSTHRU 2 +`define FPGA_MAJOR_MODE_LF_ADC 3 +`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_SNIFF 3 +`define FPGA_MAJOR_MODE_HF_ISO18092 4 +`define FPGA_MAJOR_MODE_HF_GET_TRACE 5 +`define FPGA_MAJOR_MODE_OFF 7 + +// Options for LF_READER +`define FPGA_LF_ADC_READER_FIELD 1 + +// Options for LF_EDGE_DETECT +`define FPGA_LF_EDGE_DETECT_READER_FIELD 1 +`define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 2 + +// 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_MODE_SEND_JAM 8 + +`define FPGA_HF_READER_SUBCARRIER_848_KHZ 0 +`define FPGA_HF_READER_SUBCARRIER_424_KHZ 1 +`define FPGA_HF_READER_SUBCARRIER_212_KHZ 2 +`define FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ 3 + +// 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 + +// Options for ISO18092 / Felica +`define FPGA_HF_ISO18092_FLAG_NOMOD 1 // 0001 disable modulation module +`define FPGA_HF_ISO18092_FLAG_424K 2 // 0010 should enable 414k mode (untested). No autodetect +`define FPGA_HF_ISO18092_FLAG_READER 4 // 0100 enables antenna power, to act as a reader instead of tag diff --git a/fpga-xc3s100e/fpga_felica.bit b/fpga/fpga_icopyx_felica.bit similarity index 100% rename from fpga-xc3s100e/fpga_felica.bit rename to fpga/fpga_icopyx_felica.bit diff --git a/fpga/fpga_icopyx_hf.bit b/fpga/fpga_icopyx_hf.bit new file mode 100644 index 000000000..b62cdace6 Binary files /dev/null and b/fpga/fpga_icopyx_hf.bit differ diff --git a/fpga/fpga_icopyx_hf.v b/fpga/fpga_icopyx_hf.v new file mode 100644 index 000000000..b7730875d --- /dev/null +++ b/fpga/fpga_icopyx_hf.v @@ -0,0 +1,227 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// +// The FPGA is responsible for interfacing between the A/D, the coil drivers, +// and the ARM. In the low-frequency modes it passes the data straight +// through, so that the ARM gets raw A/D samples over the SSP. In the high- +// frequency modes, the FPGA might perform some demodulation first, to +// reduce the amount of data that we must send to the ARM. +//----------------------------------------------------------------------------- +//`include "define.v" + +//`include "hi_reader.v" +//`include "hi_simulate.v" +//`include "hi_iso14443a.v" +//`include "hi_flite.v" +//`include "hi_sniffer.v" +//`include "hi_get_trace.v" + +module fpga_hf( + input spck, + output miso, + input mosi, + input ncs, + input pck0, + input ck_1356meg, + input ck_1356megb, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + input [7:0] adc_d, + output adc_clk, + output adc_noe, + output ssp_frame, + output ssp_din, + input ssp_dout, + output ssp_clk, + input cross_hi, + input cross_lo, + output debug +); + +//----------------------------------------------------------------------------- +// The SPI receiver. This sets up the configuration word, which the rest of +// the logic looks at to determine how to connect the A/D and the coil +// drivers (i.e., which section gets it). Also assign some symbolic names +// to the configuration bits, for use below. +//----------------------------------------------------------------------------- + +// Receive 16bits of data from ARM here. +reg [15:0] shift_reg; +always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi}; + +reg [8:0] conf_word; +reg trace_enable; + +// select module (outputs) based on major mode +wire [2:0] major_mode = conf_word[8:6]; +// parameter to be passed to modules +wire [3:0] minor_mode = conf_word[3:0]; + +// configuring the HF reader +wire [1:0] subcarrier_frequency = conf_word[5:4]; + +// We switch modes between transmitting to the 13.56 MHz tag and receiving +// from it, which means that we must make sure that we can do so without +// glitching, or else we will glitch the transmitted carrier. +always @(posedge ncs) +begin + // 4 bit command + case (shift_reg[15:12]) + `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; + `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; + endcase +end + +//----------------------------------------------------------------------------- +// And then we instantiate the modules corresponding to each of the FPGA's +// major modes, and use muxes to connect the outputs of the active mode to +// the output pins. +//----------------------------------------------------------------------------- + +// 0 - HF reader +hi_reader hr( + .ck_1356meg (ck_1356megb), + .pwr_lo (hr_pwr_lo), + .pwr_hi (hr_pwr_hi), + .pwr_oe1 (hr_pwr_oe1), + .pwr_oe2 (hr_pwr_oe2), + .pwr_oe3 (hr_pwr_oe3), + .pwr_oe4 (hr_pwr_oe4), + .adc_d (adc_d), + .adc_clk (hr_adc_clk), + .ssp_frame (hr_ssp_frame), + .ssp_din (hr_ssp_din), + .ssp_dout (ssp_dout), + .ssp_clk (hr_ssp_clk), + .debug (hr_debug), + .subcarrier_frequency (subcarrier_frequency), + .minor_mode (minor_mode) +); + +// 1 - HF simulated tag +hi_simulate hs( + .ck_1356meg (ck_1356meg), + .pwr_lo (hs_pwr_lo), + .pwr_hi (hs_pwr_hi), + .pwr_oe1 (hs_pwr_oe1), + .pwr_oe2 (hs_pwr_oe2), + .pwr_oe3 (hs_pwr_oe3), + .pwr_oe4 (hs_pwr_oe4), + .adc_d (adc_d), + .adc_clk (hs_adc_clk), + .ssp_frame (hs_ssp_frame), + .ssp_din (hs_ssp_din), + .ssp_dout (ssp_dout), + .ssp_clk (hs_ssp_clk), + .debug (hs_debug), + .mod_type (minor_mode) +); + +// 2 - HF ISO14443-A +hi_iso14443a hisn( + .ck_1356meg (ck_1356meg), + .pwr_lo (hisn_pwr_lo), + .pwr_hi (hisn_pwr_hi), + .pwr_oe1 (hisn_pwr_oe1), + .pwr_oe2 (hisn_pwr_oe2), + .pwr_oe3 (hisn_pwr_oe3), + .pwr_oe4 (hisn_pwr_oe4), + .adc_d (adc_d), + .adc_clk (hisn_adc_clk), + .ssp_frame (hisn_ssp_frame), + .ssp_din (hisn_ssp_din), + .ssp_dout (ssp_dout), + .ssp_clk (hisn_ssp_clk), + .debug (hisn_debug), + .mod_type (minor_mode) +); + +// 3 - HF sniff +hi_sniffer he( + .ck_1356meg (ck_1356megb), + .pwr_lo (he_pwr_lo), + .pwr_hi (he_pwr_hi), + .pwr_oe1 (he_pwr_oe1), + .pwr_oe2 (he_pwr_oe2), + .pwr_oe3 (he_pwr_oe3), + .pwr_oe4 (he_pwr_oe4), + .adc_d (adc_d), + .adc_clk (he_adc_clk), + .ssp_frame (he_ssp_frame), + .ssp_din (he_ssp_din), + .ssp_clk (he_ssp_clk) +); + +// 4 - HF ISO18092 FeliCa +hi_flite hfl( + .ck_1356meg (ck_1356megb), + .pwr_lo (hfl_pwr_lo), + .pwr_hi (hfl_pwr_hi), + .pwr_oe1 (hfl_pwr_oe1), + .pwr_oe2 (hfl_pwr_oe2), + .pwr_oe3 (hfl_pwr_oe3), + .pwr_oe4 (hfl_pwr_oe4), + .adc_d (adc_d), + .adc_clk (hfl_adc_clk), + .ssp_frame (hfl_ssp_frame), + .ssp_din (hfl_ssp_din), + .ssp_dout (ssp_dout), + .ssp_clk (hfl_ssp_clk), + .debug (hfl_debug), + .mod_type (minor_mode) +); + +// 5 - HF get trace +hi_get_trace gt( + .ck_1356megb (ck_1356megb), + .adc_d (adc_d), + .trace_enable (trace_enable), + .major_mode (major_mode), + .ssp_frame (gt_ssp_frame), + .ssp_din (gt_ssp_din), + .ssp_clk (gt_ssp_clk) +); + +// Major modes: +// x0 = HF reader +// x1 = HF simulated tag +// x2 = HF ISO14443-A +// x3 = HF sniff +// x4 = HF ISO18092 FeliCa +// x5 = HF get trace +// x6 = unused +// x7 = FPGA_MAJOR_MODE_OFF + +mux8 mux_ssp_clk (.sel(major_mode), .y(ssp_clk ), .x0(hr_ssp_clk ), .x1(hs_ssp_clk ), .x2(hisn_ssp_clk ), .x3(he_ssp_clk ), .x4(hfl_ssp_clk ), .x5(gt_ssp_clk ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_ssp_din (.sel(major_mode), .y(ssp_din ), .x0(hr_ssp_din ), .x1(hs_ssp_din ), .x2(hisn_ssp_din ), .x3(he_ssp_din ), .x4(hfl_ssp_din ), .x5(gt_ssp_din ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_ssp_frame (.sel(major_mode), .y(ssp_frame), .x0(hr_ssp_frame ), .x1(hs_ssp_frame), .x2(hisn_ssp_frame), .x3(he_ssp_frame), .x4(hfl_ssp_frame), .x5(gt_ssp_frame), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe1 (.sel(major_mode), .y(pwr_oe1 ), .x0(hr_pwr_oe1 ), .x1(hs_pwr_oe1 ), .x2(hisn_pwr_oe1 ), .x3(he_pwr_oe1 ), .x4(hfl_pwr_oe1 ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe2 (.sel(major_mode), .y(pwr_oe2 ), .x0(hr_pwr_oe2 ), .x1(hs_pwr_oe2 ), .x2(hisn_pwr_oe2 ), .x3(he_pwr_oe2 ), .x4(hfl_pwr_oe2 ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe3 (.sel(major_mode), .y(pwr_oe3 ), .x0(hr_pwr_oe3 ), .x1(hs_pwr_oe3 ), .x2(hisn_pwr_oe3 ), .x3(he_pwr_oe3 ), .x4(hfl_pwr_oe3 ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe4 (.sel(major_mode), .y(pwr_oe4 ), .x0(hr_pwr_oe4 ), .x1(hs_pwr_oe4 ), .x2(hisn_pwr_oe4 ), .x3(he_pwr_oe4 ), .x4(hfl_pwr_oe4 ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_lo (.sel(major_mode), .y(pwr_lo ), .x0(hr_pwr_lo ), .x1(hs_pwr_lo ), .x2(hisn_pwr_lo ), .x3(he_pwr_lo ), .x4(hfl_pwr_lo ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_hi (.sel(major_mode), .y(pwr_hi ), .x0(hr_pwr_hi ), .x1(hs_pwr_hi ), .x2(hisn_pwr_hi ), .x3(he_pwr_hi ), .x4(hfl_pwr_hi ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_adc_clk (.sel(major_mode), .y(adc_clk ), .x0(hr_adc_clk ), .x1(hs_adc_clk ), .x2(hisn_adc_clk ), .x3(he_adc_clk ), .x4(hfl_adc_clk ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); +mux8 mux_dbg (.sel(major_mode), .y(debug ), .x0(hr_debug ), .x1(hs_debug ), .x2(hisn_debug ), .x3(he_debug ), .x4(hfl_debug ), .x5(1'b0 ), .x6(1'b0), .x7(1'b0) ); + +// In all modes, let the ADC's outputs be enabled. +assign adc_noe = 1'b0; + +endmodule diff --git a/fpga-xc3s100e/fpga_lf.bit b/fpga/fpga_icopyx_hf_15.bit similarity index 100% rename from fpga-xc3s100e/fpga_lf.bit rename to fpga/fpga_icopyx_hf_15.bit diff --git a/fpga/fpga_icopyx_lf.bit b/fpga/fpga_icopyx_lf.bit new file mode 100644 index 000000000..e69de29bb diff --git a/fpga/fpga_icopyx_lf.v b/fpga/fpga_icopyx_lf.v new file mode 100644 index 000000000..0ca4739b7 --- /dev/null +++ b/fpga/fpga_icopyx_lf.v @@ -0,0 +1,218 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// +// The FPGA is responsible for interfacing between the A/D, the coil drivers, +// and the ARM. In the low-frequency modes it passes the data straight +// through, so that the ARM gets raw A/D samples over the SSP. In the high- +// frequency modes, the FPGA might perform some demodulation first, to +// reduce the amount of data that we must send to the ARM. +//----------------------------------------------------------------------------- +//`include "define.v" + +//`include "lo_read.v" +//`include "lo_passthru.v" +//`include "lo_edge_detect.v" +//`include "lo_adc.v" +//`include "clk_divider.v" + +module fpga_lf( + input spck, + output miso, + input mosi, + input ncs, + input pck0, + input ck_1356meg, + input ck_1356megb, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + input [7:0] adc_d, + output adc_clk, + output adc_noe, + output ssp_frame, + output ssp_din, + input ssp_dout, + output ssp_clk, + input cross_hi, + input cross_lo, + output debug, + output PWR_LO_EN +); + +//----------------------------------------------------------------------------- +// The SPI receiver. This sets up the configuration word, which the rest of +// the logic looks at to determine how to connect the A/D and the coil +// drivers (i.e., which section gets it). Also assign some symbolic names +// to the configuration bits, for use below. +//----------------------------------------------------------------------------- + +// Receive 16bits of data from ARM here. +reg [15:0] shift_reg; +always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi}; + +reg [11:0] conf_word; + +// select module (outputs) based on major mode +wire [2:0] major_mode = conf_word[8:6]; +// parameter to be passed to modules +wire lf_field = conf_word[0]; +wire lf_ed_toggle_mode = conf_word[1]; +reg [7:0] lf_ed_threshold; + +wire [7:0] pck_cnt; +wire pck_divclk; +reg [7:0] divisor; +clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk); + +// We switch modes between transmitting to the 13.56 MHz tag and receiving +// from it, which means that we must make sure that we can do so without +// glitching, or else we will glitch the transmitted carrier. +always @(posedge ncs) +begin + // 4 bit command + case (shift_reg[15:12]) + `FPGA_CMD_SET_CONFREG: + begin + // 12 bit data + conf_word <= shift_reg[11:0]; + if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) + begin + lf_ed_threshold <= 127; // default threshold + end + end + + `FPGA_CMD_SET_DIVISOR: + divisor <= shift_reg[7:0]; // 8bits + + `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: + lf_ed_threshold <= shift_reg[7:0]; // 8 bits + endcase +end + +//----------------------------------------------------------------------------- +// And then we instantiate the modules corresponding to each of the FPGA's +// major modes, and use muxes to connect the outputs of the active mode to +// the output pins. +//----------------------------------------------------------------------------- + +// 0 -- LF reader (generic) +lo_read lr( + .pck0 (pck0), + .pck_cnt (pck_cnt), + .pck_divclk (pck_divclk), + .pwr_lo (lr_pwr_lo), + .pwr_hi (lr_pwr_hi), + .pwr_oe1 (lr_pwr_oe1), + .pwr_oe2 (lr_pwr_oe2), + .pwr_oe3 (lr_pwr_oe3), + .pwr_oe4 (lr_pwr_oe4), + .adc_d (adc_d), + .adc_clk (lr_adc_clk), + .ssp_frame (lr_ssp_frame), + .ssp_din (lr_ssp_din), + .ssp_clk (lr_ssp_clk), + .debug (lr_debug), + .lf_field (lf_field) +); + +// 1 -- LF edge detect (generic) +lo_edge_detect le( + .pck0 (pck0), + .pck_divclk (pck_divclk), + .pwr_lo (le_pwr_lo), + .pwr_hi (le_pwr_hi), + .pwr_oe1 (le_pwr_oe1), + .pwr_oe2 (le_pwr_oe2), + .pwr_oe3 (le_pwr_oe3), + .pwr_oe4 (le_pwr_oe4), + .adc_d (adc_d), + .adc_clk (le_adc_clk), + .ssp_frame (le_ssp_frame), + .ssp_dout (ssp_dout), + .ssp_clk (le_ssp_clk), + .cross_lo (cross_lo), + .debug (le_debug), + .lf_field (lf_field), + .lf_ed_toggle_mode (lf_ed_toggle_mode), + .lf_ed_threshold (lf_ed_threshold) +); + +// 2 -- LF passthrough +lo_passthru lp( + .pck_divclk (pck_divclk), + .pwr_lo (lp_pwr_lo), + .pwr_hi (lp_pwr_hi), + .pwr_oe1 (lp_pwr_oe1), + .pwr_oe2 (lp_pwr_oe2), + .pwr_oe3 (lp_pwr_oe3), + .pwr_oe4 (lp_pwr_oe4), + .adc_clk (lp_adc_clk), + .ssp_din (lp_ssp_din), + .ssp_dout (ssp_dout), + .cross_lo (cross_lo), + .debug (lp_debug) +); + +// 3 -- LF ADC (read/write) +lo_adc la( + .pck0 (pck0), + .pwr_lo (la_pwr_lo ), + .pwr_hi (la_pwr_hi ), + .pwr_oe1 (la_pwr_oe1), + .pwr_oe2 (la_pwr_oe2), + .pwr_oe3 (la_pwr_oe3), + .pwr_oe4 (la_pwr_oe4), + .adc_d (adc_d), + .adc_clk (la_adc_clk), + .ssp_frame (la_ssp_frame), + .ssp_din (la_ssp_din), + .ssp_dout (ssp_dout), + .ssp_clk (la_ssp_clk), + .debug (la_debug), + .divisor (divisor), + .lf_field (lf_field) +); + +// Major modes: +// x0 = LF reader (generic) +// x1 = LF edge detect (generic) +// x2 = LF passthrough +// x3 = LF ADC (read/write) +// x4 = SPARE +// x5 = SPARE +// x6 = SPARE +// x7 = FPGA_MAJOR_MODE_OFF + +mux8 mux_ssp_clk (.sel(major_mode), .y(ssp_clk ), .x0(lr_ssp_clk ), .x1(le_ssp_clk ), .x2(1'b0 ), .x3(la_ssp_clk ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_ssp_din (.sel(major_mode), .y(ssp_din ), .x0(lr_ssp_din ), .x1(1'b0 ), .x2(lp_ssp_din), .x3(la_ssp_din ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_ssp_frame (.sel(major_mode), .y(ssp_frame), .x0(lr_ssp_frame), .x1(le_ssp_frame), .x2(1'b0 ), .x3(la_ssp_frame), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe1 (.sel(major_mode), .y(pwr_oe1 ), .x0(lr_pwr_oe1 ), .x1(le_pwr_oe1 ), .x2(lp_pwr_oe1), .x3(la_pwr_oe1 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe2 (.sel(major_mode), .y(pwr_oe2 ), .x0(lr_pwr_oe2 ), .x1(le_pwr_oe2 ), .x2(lp_pwr_oe2), .x3(la_pwr_oe2 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe3 (.sel(major_mode), .y(pwr_oe3 ), .x0(lr_pwr_oe3 ), .x1(le_pwr_oe3 ), .x2(lp_pwr_oe3), .x3(la_pwr_oe3 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_oe4 (.sel(major_mode), .y(pwr_oe4 ), .x0(lr_pwr_oe4 ), .x1(le_pwr_oe4 ), .x2(lp_pwr_oe4), .x3(la_pwr_oe4 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_pwr_lo (.sel(major_mode), .y(pwr_lo ), .x0(lr_pwr_lo ), .x1(le_pwr_lo ), .x2(lp_pwr_lo ), .x3(la_pwr_lo ), .x4(1'b0), .x5(1'b0), .x6(1'b1), .x7(1'b0) ); +mux8 mux_pwr_hi (.sel(major_mode), .y(pwr_hi ), .x0(lr_pwr_hi ), .x1(le_pwr_hi ), .x2(lp_pwr_hi ), .x3(la_pwr_hi ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_adc_clk (.sel(major_mode), .y(adc_clk ), .x0(lr_adc_clk ), .x1(le_adc_clk ), .x2(lp_adc_clk), .x3(la_adc_clk ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_dbg (.sel(major_mode), .y(debug ), .x0(lr_debug ), .x1(le_debug ), .x2(lp_debug ), .x3(la_debug ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); +mux8 mux_ant (.sel(major_mode), .y(PWR_LO_EN), .x0(1'b1 ), .x1(1'b1 ), .x2(1'b1 ), .x3(1'b1 ), .x4(1'b0), .x5(1'b0), .x6(1'b0), .x7(1'b0) ); + +// In all modes, let the ADC's outputs be enabled. +assign adc_noe = 1'b0; + +endmodule diff --git a/fpga-xc3s100e/fpga_allinone.v b/fpga/fpga_icopyx_top.v similarity index 61% rename from fpga-xc3s100e/fpga_allinone.v rename to fpga/fpga_icopyx_top.v index e766181f2..81aacb73c 100644 --- a/fpga-xc3s100e/fpga_allinone.v +++ b/fpga/fpga_icopyx_top.v @@ -1,37 +1,61 @@ -////////////////////////////////////////////////////////////////////////////////// -// Company: -// Engineer: +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. // -// Create Date: 16:09:14 05/13/2020 -// Design Name: -// Module Name: fpga_all_in_one -// Project Name: -// Target Devices: -// Tool versions: -// Description: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// Dependencies: +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// Revision: -// Revision 0.01 - File Created -// Additional Comments: +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- // -////////////////////////////////////////////////////////////////////////////////// -module fpga_hf( - input spck, output miso, input mosi, input ncs, - input pck0, input ck_1356meg, input ck_1356megb, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, output adc_noe, - output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk, - input cross_hi, input cross_lo, +// The FPGA is responsible for interfacing between the A/D, the coil drivers, +// and the ARM. In the low-frequency modes it passes the data straight +// through, so that the ARM gets raw A/D samples over the SSP. In the high- +// frequency modes, the FPGA might perform some demodulation first, to +// reduce the amount of data that we must send to the ARM. +//----------------------------------------------------------------------------- +//`include "fpga_lf.v" +//`include "fpga_hf.v" +//`include "mux2_onein.v" +//`include "mux2_oneout.v" +//`include "util.v" + +module fpga_top( + input spck, + output miso, + input mosi, + input ncs, + input pck0, + input ck_1356meg, + input ck_1356megb, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + input [7:0] adc_d, + output adc_clk, + output adc_noe, + output ssp_frame, + output ssp_din, + input ssp_dout, + output ssp_clk, + input cross_hi, + input cross_lo, output dbg, output PWR_LO_EN, input FPGA_SWITCH ); -fpga_hfmod hfmod( +fpga_hf hfmod( hfspck, hfmiso, hfmosi, hfncs, hfpck0, hfck_1356meg, hfck_1356megb, hfpwr_lo, hfpwr_hi, @@ -39,10 +63,10 @@ fpga_hfmod hfmod( adc_d, hfadc_clk, hfadc_noe, hfssp_frame, hfssp_din, hfssp_dout, hfssp_clk, hfcross_hi, hfcross_lo, - hfdbg + hfdebug ); -fpga_lfmod lfmod( +fpga_lf lfmod( lfspck, lfmiso, lfmosi, lfncs, lfpck0, lfck_1356meg, lfck_1356megb, lfpwr_lo, lfpwr_hi, @@ -50,7 +74,7 @@ fpga_lfmod lfmod( adc_d, lfadc_clk, lfadc_noe, lfssp_frame, lfssp_din, lfssp_dout, lfssp_clk, lfcross_hi, lfcross_lo, - lfdbg, + lfdebug, lfPWR_LO_EN ); @@ -75,7 +99,7 @@ mux2_oneout mux_ssp_dout_all (FPGA_SWITCH, ssp_dout, hfss mux2_one mux_ssp_clk_all (FPGA_SWITCH, ssp_clk, hfssp_clk, lfssp_clk); mux2_oneout mux_cross_hi_all (FPGA_SWITCH, cross_hi, hfcross_hi, lfcross_hi); mux2_oneout mux_cross_lo_all (FPGA_SWITCH, cross_lo, hfcross_lo, lfcross_lo); -mux2_one mux_dbg_all (FPGA_SWITCH, dbg, hfdbg, lfdbg); +mux2_one mux_dbg_all (FPGA_SWITCH, dbg, hfdebug, lfdebug); mux2_one mux_PWR_LO_EN_all (FPGA_SWITCH, PWR_LO_EN, 1'b0, lfPWR_LO_EN); endmodule diff --git a/fpga/fpga_pm3_felica.bit b/fpga/fpga_pm3_felica.bit new file mode 100644 index 000000000..a903f180e Binary files /dev/null and b/fpga/fpga_pm3_felica.bit differ diff --git a/fpga/fpga_pm3_hf.bit b/fpga/fpga_pm3_hf.bit new file mode 100644 index 000000000..76dcb8d98 Binary files /dev/null and b/fpga/fpga_pm3_hf.bit differ diff --git a/fpga/fpga_pm3_hf_15.bit b/fpga/fpga_pm3_hf_15.bit new file mode 100644 index 000000000..92a00a357 Binary files /dev/null and b/fpga/fpga_pm3_hf_15.bit differ diff --git a/fpga/fpga_pm3_lf.bit b/fpga/fpga_pm3_lf.bit new file mode 100644 index 000000000..593a9031f Binary files /dev/null and b/fpga/fpga_pm3_lf.bit differ diff --git a/fpga/fpga_pm3_top.v b/fpga/fpga_pm3_top.v new file mode 100644 index 000000000..89bd2e56b --- /dev/null +++ b/fpga/fpga_pm3_top.v @@ -0,0 +1,438 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// +// The FPGA is responsible for interfacing between the A/D, the coil drivers, +// and the ARM. In the low-frequency modes it passes the data straight +// through, so that the ARM gets raw A/D samples over the SSP. In the high- +// frequency modes, the FPGA might perform some demodulation first, to +// reduce the amount of data that we must send to the ARM. +//----------------------------------------------------------------------------- +/* +Once upon a time the FPGA had a 16 input mux so we could have all LF and HF modules enabled and selectable +As the functionality grew, we run out of space in the FPGA and we had to split into an "LF only" and an "HF only" FPGA bitstream +But even then after a while it was not possible to fit all the HF functions at the same time so now we have multiple "HF only" bitstreams +For example "Felica but without ISO14443", or "ISO14443 but without Felica" or "HF_15 but without Felica and ISO14443" + +Because of all of the above, you can not enable both HF and LF modes at the same time, because some LF modules outputs +map to the same mux inputs as some HF modules outputs (thanks to reducing the mux from 16 to 8 inputs) and you can not have +multiple outputs connected together therefore leading to a failed compilation +*/ + +// These defines are meant to be passed by the Makefile so do not uncomment them here +// Proxmark3 RDV4 target +//`define PM3RDV4 +// Proxmark3 generic target +//`define PM3GENERIC +// iCopy-X with XC3S100E +//`define PM3ICOPYX + +// Pass desired defines to compiler to enable required modules +// WITH_LF enables Low Frequency mode when defined else HF is enabled +//`define WITH_LF +// WITH_LF0 enables module reader +//`define WITH_LF0 +// WITH_LF1 enables module edge detect +//`define WITH_LF1 +// WITH_LF2 enables module passthrough +//`define WITH_LF2 +// WITH_LF3 enables module ADC +//`define WITH_LF3 + +// WITH_HF0 enables module HF reader +//`define WITH_HF0 +// WITH_HF1 enables module simulated tag +//`define WITH_HF1 +// WITH_HF2 enables module ISO14443-A +//`define WITH_HF2 +// WITH_HF3 enables module sniff +//`define WITH_HF3 +// WITH_HF4 enables module ISO18092 FeliCa +//`define WITH_HF4 +// WITH_HF5 enables module get trace +//`define WITH_HF5 + +//`include "define.v" +//`include "util.v" +// +//`ifdef WITH_LF `include "clk_divider.v" `endif +//`ifdef WITH_LF0 `include "lo_read.v" `endif +//`ifdef WITH_LF1 `include "lo_edge_detect.v" `endif +//`ifdef WITH_LF2 `include "lo_passthru.v" `endif +//`ifdef WITH_LF3 `include "lo_adc.v" `endif +// +//`ifdef WITH_HF_15 +//`ifdef WITH_HF0 `include "hi_reader_15.v" `endif +//`else +//`ifdef WITH_HF0 `include "hi_reader.v" `endif +//`endif +//`ifdef WITH_HF1 `include "hi_simulate.v" `endif +//`ifdef WITH_HF2 `include "hi_iso14443a.v" `endif +//`ifdef WITH_HF3 `include "hi_sniffer.v" `endif +//`ifdef WITH_HF4 `include "hi_flite.v" `endif +//`ifdef WITH_HF5 `include "hi_get_trace.v" `endif + +module fpga_top( + input ck_1356meg, + input ck_1356megb, + input spck, + input pck0, + input ncs, + input [7:0] adc_d, + input cross_hi, + input cross_lo, + input mosi, + input ssp_dout, + + output ssp_din, + output ssp_frame, + output ssp_clk, + output adc_clk, + output adc_noe, + output miso, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output dbg +); + +// In all modes, let the ADC's outputs be enabled. +assign adc_noe = 1'b0; + +//----------------------------------------------------------------------------- +// The SPI receiver. This sets up the configuration word, which the rest of +// the logic looks at to determine how to connect the A/D and the coil +// drivers (i.e., which section gets it). Also assign some symbolic names +// to the configuration bits, for use below. +//----------------------------------------------------------------------------- + +// Receive 16bits of data from ARM here. +reg [15:0] shift_reg; +always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi}; + +reg trace_enable; + +reg [7:0] lf_ed_threshold; + +// adjustable frequency clock +wire [7:0] pck_cnt; +wire pck_divclk; +reg [7:0] divisor; +clk_divider div_clk(pck0, divisor, pck_cnt, pck_divclk); + +`ifdef WITH_LF +reg [11:0] conf_word; +`else +reg [8:0] conf_word; +`endif + +// We switch modes between transmitting to the 13.56 MHz tag and receiving +// from it, which means that we must make sure that we can do so without +// glitching, or else we will glitch the transmitted carrier. +always @(posedge ncs) +begin + // 4 bit command + case (shift_reg[15:12]) +`ifdef WITH_LF + `FPGA_CMD_SET_CONFREG: + begin + // 12 bit data + conf_word <= shift_reg[11:0]; + if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) lf_ed_threshold <= 127; // default threshold + end + + `FPGA_CMD_SET_DIVISOR: + divisor <= shift_reg[7:0]; // 8bits + + `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: + lf_ed_threshold <= shift_reg[7:0]; // 8 bits +`else + `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; + `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; +`endif + endcase +end + +//----------------------------------------------------------------------------- +// And then we instantiate the modules corresponding to each of the FPGA's +// major modes, and use muxes to connect the outputs of the active mode to +// the output pins. +//----------------------------------------------------------------------------- + +// ############################################################################ +// # Enable Low Frequency Modules +`ifdef WITH_LF + +// LF reader (generic) +`ifdef WITH_LF0 +lo_read lr( + .pck0 (pck0), + .pck_divclk (pck_divclk), + .pck_cnt (pck_cnt), + .adc_d (adc_d), + .lf_field (conf_word[0]), + + .ssp_din (mux0_ssp_din), + .ssp_frame (mux0_ssp_frame), + .ssp_clk (mux0_ssp_clk), + .adc_clk (mux0_adc_clk), + .pwr_lo (mux0_pwr_lo), + .pwr_hi (mux0_pwr_hi), + .pwr_oe1 (mux0_pwr_oe1), + .pwr_oe2 (mux0_pwr_oe2), + .pwr_oe3 (mux0_pwr_oe3), + .pwr_oe4 (mux0_pwr_oe4), + .debug (mux0_debug) +); +`endif + +// LF edge detect (generic) +`ifdef WITH_LF1 +lo_edge_detect le( + .pck0 (pck0), + .pck_divclk (pck_divclk), + .adc_d (adc_d), + .cross_lo (cross_lo), + .lf_field (conf_word[0]), + .lf_ed_toggle_mode (conf_word[1]), + .lf_ed_threshold (lf_ed_threshold), + .ssp_dout (ssp_dout), + + .ssp_frame (mux1_ssp_frame), + .ssp_clk (mux1_ssp_clk), + .adc_clk (mux1_adc_clk), + .pwr_lo (mux1_pwr_lo), + .pwr_hi (mux1_pwr_hi), + .pwr_oe1 (mux1_pwr_oe1), + .pwr_oe2 (mux1_pwr_oe2), + .pwr_oe3 (mux1_pwr_oe3), + .pwr_oe4 (mux1_pwr_oe4), + .debug (mux1_debug) +); +`endif + +// LF passthrough +`ifdef WITH_LF2 +lo_passthru lp( + .pck_divclk (pck_divclk), + .cross_lo (cross_lo), + .ssp_dout (ssp_dout), + + .ssp_din (mux2_ssp_din), + .adc_clk (mux2_adc_clk), + .pwr_lo (mux2_pwr_lo), + .pwr_hi (mux2_pwr_hi), + .pwr_oe1 (mux2_pwr_oe1), + .pwr_oe2 (mux2_pwr_oe2), + .pwr_oe3 (mux2_pwr_oe3), + .pwr_oe4 (mux2_pwr_oe4), + .debug (mux2_debug) +); +`endif + +// LF ADC (read/write) +`ifdef WITH_LF3 +lo_adc la( + .pck0 (pck0), + .adc_d (adc_d), + .divisor (divisor), + .lf_field (conf_word[0]), + .ssp_dout (ssp_dout), + + .ssp_din (mux3_ssp_din), + .ssp_frame (mux3_ssp_frame), + .ssp_clk (mux3_ssp_clk), + .adc_clk (mux3_adc_clk), + .pwr_lo (mux3_pwr_lo ), + .pwr_hi (mux3_pwr_hi ), + .pwr_oe1 (mux3_pwr_oe1), + .pwr_oe2 (mux3_pwr_oe2), + .pwr_oe3 (mux3_pwr_oe3), + .pwr_oe4 (mux3_pwr_oe4), + .debug (mux3_debug) +); +`endif // WITH_LF3 + +assign mux6_pwr_lo = 1'b1; +// 7 -- SPARE + +`else // if WITH_LF not defined +// ############################################################################ +// # Enable High Frequency Modules + +// HF reader +`ifdef WITH_HF0 +`ifdef WITH_HF_15 +hi_reader_15 hr( +`else +hi_reader hr( +`endif + .ck_1356meg (ck_1356megb), + .adc_d (adc_d), + .subcarrier_frequency (conf_word[5:4]), + .minor_mode (conf_word[3:0]), + .ssp_dout (ssp_dout), + + .ssp_din (mux0_ssp_din), + .ssp_frame (mux0_ssp_frame), + .ssp_clk (mux0_ssp_clk), + .adc_clk (mux0_adc_clk), + .pwr_lo (mux0_pwr_lo), + .pwr_hi (mux0_pwr_hi), + .pwr_oe1 (mux0_pwr_oe1), + .pwr_oe2 (mux0_pwr_oe2), + .pwr_oe3 (mux0_pwr_oe3), + .pwr_oe4 (mux0_pwr_oe4), + .debug (mux0_debug) +); +`endif // WITH_HF0 + +// HF simulated tag +`ifdef WITH_HF1 +hi_simulate hs( + .ck_1356meg (ck_1356meg), + .adc_d (adc_d), + .mod_type (conf_word[3:0]), + .ssp_dout (ssp_dout), + + .ssp_din (mux1_ssp_din), + .ssp_frame (mux1_ssp_frame), + .ssp_clk (mux1_ssp_clk), + .adc_clk (mux1_adc_clk), + .pwr_lo (mux1_pwr_lo), + .pwr_hi (mux1_pwr_hi), + .pwr_oe1 (mux1_pwr_oe1), + .pwr_oe2 (mux1_pwr_oe2), + .pwr_oe3 (mux1_pwr_oe3), + .pwr_oe4 (mux1_pwr_oe4), + .debug (mux1_debug) +); +`endif // WITH_HF1 + +// HF ISO14443-A +`ifdef WITH_HF2 +hi_iso14443a hisn( + .ck_1356meg (ck_1356meg), + .adc_d (adc_d), + .mod_type (conf_word[3:0]), + .ssp_dout (ssp_dout), + + .ssp_din (mux2_ssp_din), + .ssp_frame (mux2_ssp_frame), + .ssp_clk (mux2_ssp_clk), + .adc_clk (mux2_adc_clk), + .pwr_lo (mux2_pwr_lo), + .pwr_hi (mux2_pwr_hi), + .pwr_oe1 (mux2_pwr_oe1), + .pwr_oe2 (mux2_pwr_oe2), + .pwr_oe3 (mux2_pwr_oe3), + .pwr_oe4 (mux2_pwr_oe4), + .debug (mux2_debug) +); +`endif // WITH_HF2 + +// HF sniff +`ifdef WITH_HF3 +hi_sniffer he( + .ck_1356meg (ck_1356megb), + .adc_d (adc_d), + + .ssp_din (mux3_ssp_din), + .ssp_frame (mux3_ssp_frame), + .ssp_clk (mux3_ssp_clk), + .adc_clk (mux3_adc_clk), + .pwr_lo (mux3_pwr_lo), + .pwr_hi (mux3_pwr_hi), + .pwr_oe1 (mux3_pwr_oe1), + .pwr_oe2 (mux3_pwr_oe2), + .pwr_oe3 (mux3_pwr_oe3), + .pwr_oe4 (mux3_pwr_oe4) +); +`endif //WITH_HF3 + +// HF ISO18092 FeliCa +`ifdef WITH_HF4 +hi_flite hfl( + .ck_1356meg (ck_1356megb), + .adc_d (adc_d), + .mod_type (conf_word[3:0]), + .ssp_dout (ssp_dout), + + .ssp_din (mux4_ssp_din), + .ssp_frame (mux4_ssp_frame), + .ssp_clk (mux4_ssp_clk), + .adc_clk (mux4_adc_clk), + .pwr_lo (mux4_pwr_lo), + .pwr_hi (mux4_pwr_hi), + .pwr_oe1 (mux4_pwr_oe1), + .pwr_oe2 (mux4_pwr_oe2), + .pwr_oe3 (mux4_pwr_oe3), + .pwr_oe4 (mux4_pwr_oe4), + .debug (mux4_debug) +); +`endif // WITH_HF4 + +// HF get trace +`ifdef WITH_HF5 +hi_get_trace gt( + .ck_1356megb (ck_1356megb), + .adc_d (adc_d), + .trace_enable (trace_enable), + .major_mode (conf_word[8:6]), + .ssp_din (mux5_ssp_din), + .ssp_frame (mux5_ssp_frame), + .ssp_clk (mux5_ssp_clk) +); +`endif // WITH_HF5 + +`endif // WITH_LF + +// These assignments must agree with the defines in fpgaloader.h +// Major modes Low Frequency +// mux0 = LF reader (generic) +// mux1 = LF edge detect (generic) +// mux2 = LF passthrough +// mux3 = LF ADC (read/write) +// mux4 = SPARE +// mux5 = SPARE +// mux6 = SPARE +// mux7 = FPGA_MAJOR_MODE_OFF + +// Major modes High Frequency +// mux0 = HF reader +// mux1 = HF simulated tag +// mux2 = HF ISO14443-A +// mux3 = HF sniff +// mux4 = HF ISO18092 FeliCa +// mux5 = HF get trace +// mux6 = unused +// mux7 = FPGA_MAJOR_MODE_OFF + +mux8 mux_ssp_clk (.sel(conf_word[8:6]), .y(ssp_clk ), .x0(mux0_ssp_clk ), .x1(mux1_ssp_clk ), .x2(mux2_ssp_clk ), .x3(mux3_ssp_clk ), .x4(mux4_ssp_clk ), .x5(mux5_ssp_clk ), .x6(mux6_ssp_clk ), .x7(mux7_ssp_clk ) ); +mux8 mux_ssp_din (.sel(conf_word[8:6]), .y(ssp_din ), .x0(mux0_ssp_din ), .x1(mux1_ssp_din ), .x2(mux2_ssp_din ), .x3(mux3_ssp_din ), .x4(mux4_ssp_din ), .x5(mux5_ssp_din ), .x6(mux6_ssp_din ), .x7(mux7_ssp_din ) ); +mux8 mux_ssp_frame (.sel(conf_word[8:6]), .y(ssp_frame), .x0(mux0_ssp_frame), .x1(mux1_ssp_frame), .x2(mux2_ssp_frame), .x3(mux3_ssp_frame), .x4(mux4_ssp_frame), .x5(mux5_ssp_frame), .x6(mux6_ssp_frame), .x7(mux7_ssp_frame) ); +mux8 mux_pwr_oe1 (.sel(conf_word[8:6]), .y(pwr_oe1 ), .x0(mux0_pwr_oe1 ), .x1(mux1_pwr_oe1 ), .x2(mux2_pwr_oe1 ), .x3(mux3_pwr_oe1 ), .x4(mux4_pwr_oe1 ), .x5(mux5_pwr_oe1 ), .x6(mux6_pwr_oe1 ), .x7(mux7_pwr_oe1 ) ); +mux8 mux_pwr_oe2 (.sel(conf_word[8:6]), .y(pwr_oe2 ), .x0(mux0_pwr_oe2 ), .x1(mux1_pwr_oe2 ), .x2(mux2_pwr_oe2 ), .x3(mux3_pwr_oe2 ), .x4(mux4_pwr_oe2 ), .x5(mux5_pwr_oe2 ), .x6(mux6_pwr_oe2 ), .x7(mux7_pwr_oe2 ) ); +mux8 mux_pwr_oe3 (.sel(conf_word[8:6]), .y(pwr_oe3 ), .x0(mux0_pwr_oe3 ), .x1(mux1_pwr_oe3 ), .x2(mux2_pwr_oe3 ), .x3(mux3_pwr_oe3 ), .x4(mux4_pwr_oe3 ), .x5(mux5_pwr_oe3 ), .x6(mux6_pwr_oe3 ), .x7(mux7_pwr_oe3 ) ); +mux8 mux_pwr_oe4 (.sel(conf_word[8:6]), .y(pwr_oe4 ), .x0(mux0_pwr_oe4 ), .x1(mux1_pwr_oe4 ), .x2(mux2_pwr_oe4 ), .x3(mux3_pwr_oe4 ), .x4(mux4_pwr_oe4 ), .x5(mux5_pwr_oe4 ), .x6(mux6_pwr_oe4 ), .x7(mux7_pwr_oe4 ) ); +mux8 mux_pwr_lo (.sel(conf_word[8:6]), .y(pwr_lo ), .x0(mux0_pwr_lo ), .x1(mux1_pwr_lo ), .x2(mux2_pwr_lo ), .x3(mux3_pwr_lo ), .x4(mux4_pwr_lo ), .x5(mux5_pwr_lo ), .x6(mux6_pwr_lo ), .x7(mux7_pwr_lo ) ); +mux8 mux_pwr_hi (.sel(conf_word[8:6]), .y(pwr_hi ), .x0(mux0_pwr_hi ), .x1(mux1_pwr_hi ), .x2(mux2_pwr_hi ), .x3(mux3_pwr_hi ), .x4(mux4_pwr_hi ), .x5(mux5_pwr_hi ), .x6(mux6_pwr_hi ), .x7(mux7_pwr_hi ) ); +mux8 mux_adc_clk (.sel(conf_word[8:6]), .y(adc_clk ), .x0(mux0_adc_clk ), .x1(mux1_adc_clk ), .x2(mux2_adc_clk ), .x3(mux3_adc_clk ), .x4(mux4_adc_clk ), .x5(mux5_adc_clk ), .x6(mux6_adc_clk ), .x7(mux7_adc_clk ) ); +mux8 mux_dbg (.sel(conf_word[8:6]), .y(dbg ), .x0(mux0_debug ), .x1(mux1_debug ), .x2(mux2_debug ), .x3(mux3_debug ), .x4(mux4_debug ), .x5(mux5_debug ), .x6(mux6_debug ), .x7(mux7_debug ) ); + +endmodule diff --git a/fpga-xc2s30/hi_flite.v b/fpga/hi_flite.v similarity index 92% rename from fpga-xc2s30/hi_flite.v rename to fpga/hi_flite.v index 75ffbc9e5..ac9e7e069 100644 --- a/fpga-xc2s30/hi_flite.v +++ b/fpga/hi_flite.v @@ -30,33 +30,30 @@ */ module hi_flite( - 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, - mod_type + input ck_1356meg, + input [7:0] adc_d, + input [3:0] mod_type, + input ssp_dout, + + output reg ssp_din, + output reg ssp_frame, + output reg ssp_clk, + output adc_clk, + output reg pwr_lo, + output reg pwr_hi, + output reg pwr_oe1, + output reg pwr_oe2, + output reg pwr_oe3, + output reg pwr_oe4, + output debug ); - 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 [3:0] mod_type; -assign dbg = 0; +assign debug = 0; -wire power = mod_type[2]; -wire speed = mod_type[1]; +wire power = mod_type[2]; +wire speed = mod_type[1]; wire disabl = mod_type[0]; -// Most off, oe4 for modulation; -// Trying reader emulation (would presumably just require switching power on, but I am not sure) -assign pwr_lo = 1'b0; -assign pwr_oe2 = 1'b0; - // 512x64/fc -wait before ts0, 32768 ticks // tslot: 256*64/fc assign adc_clk = ck_1356meg; @@ -95,10 +92,6 @@ reg did_sync=0; wire [7:0] bithalf = speed ? `bithalf_424 : `bithalf_212; wire [7:0] bitmlen = speed ? `bitmlen_424 : `bitmlen_212; - -//ssp clock and current values -reg ssp_clk; -reg ssp_frame; reg curbit = 1'b0; reg [7:0] fccount = 8'd0; // in-bit tick counter. Counts carrier cycles from the first lower edge detected, reset on every manchester bit detected @@ -107,6 +100,7 @@ reg [7:0] tsinceedge = 8'd0;// ticks from last edge, desync if the valye is too reg zero = 1'b0; // Manchester first halfbit low second high corresponds to this value. It has been known to change. SYNC is used to set it +//ssp clock and current values //ssp counter for transfer and framing reg [8:0] ssp_cnt = 9'd0; @@ -122,6 +116,7 @@ begin if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed && (ssp_cnt[4:0] == 5'b00000))) begin ssp_clk <= 1'b1; + //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) ssp_din <= curbit; end if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000)) @@ -138,9 +133,6 @@ begin end end -//send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise) -reg ssp_din; - //previous signal value, mostly to detect SYNC reg prv = 1'b1; @@ -353,11 +345,8 @@ begin end // sending <= 0; end + //put modulation here to maintain the correct clock. Seems that some readers are sensitive to that -reg pwr_hi; -reg pwr_oe1; -reg pwr_oe3; -reg pwr_oe4; wire mod = ((fccount >= bithalf) ^ dlay) & (~disabl); @@ -365,21 +354,22 @@ always @(ck_1356meg or ssp_dout or power or disabl or mod) begin if (power) begin - pwr_hi <= ck_1356meg; + pwr_hi <= ck_1356meg; + pwr_lo <= 1'b0; pwr_oe1 <= 1'b0;//mod; + pwr_oe2 <= 1'b0;//mod; pwr_oe3 <= 1'b0;//mod; pwr_oe4 <= mod;//1'b0; end else begin - pwr_hi <= 1'b0; + pwr_hi <= 1'b0; + pwr_lo <= 1'b0; pwr_oe1 <= 1'b0; + pwr_oe2 <= 1'b0; pwr_oe3 <= 1'b0; pwr_oe4 <= mod; end end - - - endmodule diff --git a/fpga-xc2s30/hi_get_trace.v b/fpga/hi_get_trace.v similarity index 86% rename from fpga-xc2s30/hi_get_trace.v rename to fpga/hi_get_trace.v index 6e4369e14..9bf32bc64 100644 --- a/fpga-xc2s30/hi_get_trace.v +++ b/fpga/hi_get_trace.v @@ -13,17 +13,18 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- +//`include "define.v" module hi_get_trace( - ck_1356megb, - adc_d, trace_enable, major_mode, - ssp_frame, ssp_din, ssp_clk + input ck_1356megb, + input [7:0] adc_d, + input trace_enable, + input [2:0] major_mode, + + output ssp_din, + output reg ssp_frame, + output reg ssp_clk ); - input ck_1356megb; - input [7:0] adc_d; - input trace_enable; - input [2:0] major_mode; - output ssp_frame, ssp_din, ssp_clk; // clock divider reg [6:0] clock_cnt; @@ -88,9 +89,9 @@ begin write_enable2 <= 1'b0; end else - begin + begin addr <= addr + 1; - end + end end end else @@ -136,9 +137,6 @@ begin end -// SSC communication to ARM -reg ssp_clk; -reg ssp_frame; reg [7:0] shift_out; always @(negedge ck_1356megb) @@ -147,16 +145,16 @@ begin begin if (clock_cnt[6:4] == 3'd0) // either load new value begin - if (addr[11] == 1'b0) - shift_out <= D_out1; - else - shift_out <= D_out2; + if (addr[11] == 1'b0) + shift_out <= D_out1; + else + shift_out <= D_out2; end else - begin - // or shift left - shift_out[7:1] <= shift_out[6:0]; - end + begin + // or shift left + shift_out[7:1] <= shift_out[6:0]; + end end ssp_clk <= ~clock_cnt[3]; // ssp_clk frequency = 13,56MHz / 16 = 847,5 kHz diff --git a/fpga-xc2s30/hi_iso14443a.v b/fpga/hi_iso14443a.v similarity index 97% rename from fpga-xc2s30/hi_iso14443a.v rename to fpga/hi_iso14443a.v index d52ab4000..7ccd7f610 100644 --- a/fpga-xc2s30/hi_iso14443a.v +++ b/fpga/hi_iso14443a.v @@ -14,29 +14,28 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- // ISO14443-A support for the Proxmark III -// +//`include "define.v" module hi_iso14443a( - 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, - mod_type + input ck_1356meg, + input [7:0] adc_d, + input [3:0] mod_type, + input ssp_dout, + + output ssp_din, + output reg ssp_frame, + output reg ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); - 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 [3:0] mod_type; - - -wire adc_clk = ck_1356meg; - +assign adc_clk = ck_1356meg; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reader -> PM3: @@ -76,8 +75,6 @@ begin end - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reader -> PM3 // detect when a reader is active (modulating). We assume that the reader is active, if we see the carrier off for at least 8 @@ -137,7 +134,6 @@ wire [9:0] tmp2 = adc_d_times_2 + input_prev_1; wire signed [10:0] adc_d_filtered = {1'b0, tmp1} - {1'b0, tmp2}; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // internal FPGA timing. Maximum required period is 128 carrier clock cycles for a full 8 Bit transfer to ARM. (i.e. we need a // 7 bit counter). Adjust its frequency to external reader's clock when simulating a tag or sniffing. @@ -222,7 +218,11 @@ reg signed [10:0] rx_mod_falling_edge_max; reg signed [10:0] rx_mod_rising_edge_max; reg curbit; +`ifdef PM3ICOPYX +`define EDGE_DETECT_THRESHOLD 3 +`else `define EDGE_DETECT_THRESHOLD 5 +`endif `define EDGE_DETECT_THRESHOLDHIGH 20 always @(negedge adc_clk) @@ -266,7 +266,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Tag+Reader -> PM3 // sample 4 bits reader data and 4 bits tag data for sniffing @@ -283,7 +282,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader: // a delay line to ensure that we send the (emulated) tag's answer at the correct time according to ISO14443-3 @@ -307,7 +305,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader, internal timing: // a timer for the 1172 cycles fdt (Frame Delay Time). Start the timer with a rising edge of the reader's signal. @@ -400,7 +397,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PM3 -> Reader // determine the required delay in the mod_sig_buf (set mod_sig_ptr). @@ -444,7 +440,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FPGA -> ARM communication: // buffer 8 bits data to be sent to ARM. Shift them out bit by bit. @@ -495,8 +490,6 @@ end //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FPGA <-> ARM communication: // generate a ssp clock and ssp frame signal for the synchronous transfer from/to the ARM -reg ssp_clk; -reg ssp_frame; always @(negedge adc_clk) begin @@ -529,7 +522,6 @@ begin end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FPGA -> ARM communication: // select the data to be sent to ARM @@ -553,7 +545,6 @@ begin sendbit = 1'b0; end - if(mod_type == `FPGA_HF_ISO14443A_SNIFFER) // send sampled reader and tag data: bit_to_arm = to_arm[7]; @@ -589,6 +580,6 @@ assign pwr_oe4 = mod_sig_coil & sub_carrier & (mod_type == `FPGA_HF_ISO14443A_TA assign pwr_oe2 = 1'b0; assign pwr_lo = 1'b0; -assign dbg = negedge_cnt[3]; +assign debug = negedge_cnt[3]; endmodule diff --git a/fpga-xc2s30/hi_reader.v b/fpga/hi_reader.v similarity index 95% rename from fpga-xc2s30/hi_reader.v rename to fpga/hi_reader.v index dbc38a8a7..ffa2634d8 100644 --- a/fpga-xc2s30/hi_reader.v +++ b/fpga/hi_reader.v @@ -13,24 +13,27 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- +//`include "define.v" 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, + input [7:0] adc_d, + input [1:0] subcarrier_frequency, + input [3:0] minor_mode, + input ssp_dout, + + output ssp_din, + output reg ssp_frame, + output reg ssp_clk, + output adc_clk, + output pwr_lo, + output reg pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output reg pwr_oe4, + output debug ); - 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 [3:0] minor_mode; assign adc_clk = ck_1356meg; // sample frequency is 13,56 MHz @@ -160,7 +163,6 @@ begin 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}; @@ -261,9 +263,6 @@ end // corr_i_cnt 0 1 2 3 4 5 6 7 8 9 10 11 12 ... // -reg ssp_clk; -reg ssp_frame; - always @(negedge adc_clk) begin if (corr_i_cnt[1:0] == 2'b00) @@ -298,9 +297,6 @@ begin end end -// Antenna drivers -reg pwr_hi, pwr_oe4; - always @(*) begin if (minor_mode == `FPGA_HF_READER_MODE_SEND_SHALLOW_MOD) @@ -341,6 +337,6 @@ assign pwr_lo = 1'b0; assign pwr_oe2 = 1'b0; // Debug Output -assign dbg = corr_i_cnt[3]; +assign debug = corr_i_cnt[3]; endmodule diff --git a/fpga-xc2s30/hi_reader_15.v b/fpga/hi_reader_15.v similarity index 96% rename from fpga-xc2s30/hi_reader_15.v rename to fpga/hi_reader_15.v index 0db4fe2a3..ad41e771c 100644 --- a/fpga-xc2s30/hi_reader_15.v +++ b/fpga/hi_reader_15.v @@ -14,25 +14,26 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- // modified to add support for iso15 2sc mode -// -module hi_15_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 +module hi_reader_15( + input ck_1356meg, + input [7:0] adc_d, + input [1:0] subcarrier_frequency, + input [3:0] minor_mode, + input ssp_dout, + + output ssp_din, + output reg ssp_frame, + output reg ssp_clk, + output adc_clk, + output pwr_lo, + output reg pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output reg pwr_oe4, + output debug ); - 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 [3:0] minor_mode; assign adc_clk = ck_1356meg; // sample frequency is 13,56 MHz @@ -379,9 +380,6 @@ end // corr_i_cnt 0 1 2 3 4 5 6 7 8 9 10 11 12 ... // -reg ssp_clk; -reg ssp_frame; - always @(negedge adc_clk) begin if (corr_i_cnt[1:0] == 2'b00) @@ -416,9 +414,6 @@ begin end end -// Antenna drivers -reg pwr_hi, pwr_oe4; - always @(*) begin if (minor_mode == `FPGA_HF_READER_MODE_SEND_SHALLOW_MOD) @@ -459,6 +454,6 @@ assign pwr_lo = 1'b0; assign pwr_oe2 = 1'b0; // Debug Output -assign dbg = corr_i_cnt[3]; +assign debug = corr_i_cnt[3]; endmodule diff --git a/fpga-xc2s30/hi_simulate.v b/fpga/hi_simulate.v similarity index 91% rename from fpga-xc2s30/hi_simulate.v rename to fpga/hi_simulate.v index 2232aedd9..97346eb9b 100644 --- a/fpga-xc2s30/hi_simulate.v +++ b/fpga/hi_simulate.v @@ -30,23 +30,26 @@ // // Jonathan Westhues, October 2006 //----------------------------------------------------------------------------- +//`include "define.v" module hi_simulate( - 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, - mod_type + input ck_1356meg, + input [7:0] adc_d, + input [3:0] mod_type, + input ssp_dout, + + output reg ssp_din, + output reg ssp_frame, + output reg ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); - 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 [3:0] mod_type; // Power amp goes between LOW and tri-state, so pwr_hi (and pwr_lo) can // always be low. @@ -57,7 +60,7 @@ assign pwr_lo = 1'b0; // LF antenna connected to GND assign pwr_oe2 = 1'b0; assign adc_clk = ck_1356meg; -assign dbg = ssp_frame; +assign debug = ssp_frame; // The comparator with hysteresis on the output from the peak detector. reg after_hysteresis; @@ -94,8 +97,6 @@ reg [8:0] ssp_clk_divider; 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) @@ -112,7 +113,6 @@ end // 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 @(negedge adc_clk) begin if (mod_type == `FPGA_HF_SIMULATOR_MODULATE_212K) @@ -133,7 +133,6 @@ end // Synchronize up the after-hysteresis signal, to produce DIN. -reg ssp_din; always @(posedge ssp_clk) ssp_din = after_hysteresis; diff --git a/fpga-xc2s30/hi_sniffer.v b/fpga/hi_sniffer.v similarity index 69% rename from fpga-xc2s30/hi_sniffer.v rename to fpga/hi_sniffer.v index ed62191f1..11781ca5a 100644 --- a/fpga-xc2s30/hi_sniffer.v +++ b/fpga/hi_sniffer.v @@ -15,16 +15,20 @@ //----------------------------------------------------------------------------- module hi_sniffer( - ck_1356meg, - pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, - adc_d, adc_clk, - ssp_frame, ssp_din, ssp_clk + input ck_1356meg, + input [7:0] adc_d, + + output ssp_din, + output reg ssp_frame, + output ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4 ); - input ck_1356meg; - output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; - input [7:0] adc_d; - output adc_clk; - output ssp_frame, ssp_din, ssp_clk; // We are only snooping, all off. assign pwr_hi = 1'b0; @@ -34,12 +38,13 @@ assign pwr_oe2 = 1'b0; assign pwr_oe3 = 1'b0; assign pwr_oe4 = 1'b0; -reg ssp_frame; +//reg ssp_frame; reg [7:0] adc_d_out = 8'd0; -reg [2:0] ssp_cnt = 3'd0; +reg [2:0] ssp_cnt = 3'd0; -assign adc_clk = ck_1356meg; +assign adc_clk = ck_1356meg; assign ssp_clk = ~ck_1356meg; +assign ssp_din = adc_d_out[0]; always @(posedge ssp_clk) begin @@ -49,18 +54,16 @@ begin ssp_cnt <= ssp_cnt + 1; if(ssp_cnt[2:0] == 3'b000) // set frame length - begin - adc_d_out[7:0] <= adc_d; - ssp_frame <= 1'b1; - end + begin + adc_d_out[7:0] <= adc_d; + ssp_frame <= 1'b1; + end else - begin - adc_d_out[7:0] <= {1'b0, adc_d_out[7:1]}; - ssp_frame <= 1'b0; - end + begin + // shift value right one bit + adc_d_out[7:0] <= {1'b0, adc_d_out[7:1]}; + ssp_frame <= 1'b0; + end end - -assign ssp_din = adc_d_out[0]; - endmodule diff --git a/fpga-xc2s30/lf_edge_detect.v b/fpga/lf_edge_detect.v similarity index 72% rename from fpga-xc2s30/lf_edge_detect.v rename to fpga/lf_edge_detect.v index 4b6c0ac01..2a58331d1 100644 --- a/fpga-xc2s30/lf_edge_detect.v +++ b/fpga/lf_edge_detect.v @@ -15,23 +15,37 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- - // input clk is 24MHz -`include "min_max_tracker.v" +//`include "min_max_tracker.v" -module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, - output [7:0] max, output [7:0] min, - output [7:0] high_threshold, output [7:0] highz_threshold, - output [7:0] lowz_threshold, output [7:0] low_threshold, - output edge_state, output edge_toggle); +module lf_edge_detect( + input clk, + input [7:0] adc_d, + input [7:0] lf_ed_threshold, - min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max); + output [7:0] max, + output [7:0] min, + output [7:0] low_threshold, + output [7:0] high_threshold, + output [7:0] lowz_threshold, + output [7:0] highz_threshold, + output edge_state, + output edge_toggle +); + + min_max_tracker tracker( + .clk (clk), + .adc_d (adc_d), + .threshold (lf_ed_threshold), + .min (min), + .max (max) +); // auto-tune - assign high_threshold = (max + min) / 2 + (max - min) / 4; + assign high_threshold = (max + min) / 2 + (max - min) / 4; assign highz_threshold = (max + min) / 2 + (max - min) / 8; - assign lowz_threshold = (max + min) / 2 - (max - min) / 8; - assign low_threshold = (max + min) / 2 - (max - min) / 4; + assign lowz_threshold = (max + min) / 2 - (max - min) / 8; + assign low_threshold = (max + min) / 2 - (max - min) / 4; // heuristic to see if it makes sense to try to detect an edge wire enabled = @@ -55,18 +69,20 @@ module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, always @(posedge clk) begin is_high <= (adc_d >= high_threshold); - is_low <= (adc_d <= low_threshold); + is_low <= (adc_d <= low_threshold); is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); end // all edges detection always @(posedge clk) - if (enabled) begin + if (enabled) + begin // To enable detecting two consecutive peaks at the same level // (low or high) we check whether or not we went back near 0 in-between. // This extra check is necessary to prevent from noise artifacts // around the threshold values. - if (trigger_enabled & (is_high | is_low)) begin + if (trigger_enabled & (is_high | is_low)) + begin output_edge <= ~output_edge; trigger_enabled <= 0; end else @@ -75,14 +91,15 @@ module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, // edge states always @(posedge clk) - if (enabled) begin + if (enabled) + begin if (is_high) output_state <= 1'd1; else if (is_low) output_state <= 1'd0; end - assign edge_state = output_state; + assign edge_state = output_state; assign edge_toggle = output_edge; endmodule diff --git a/fpga-xc2s30/lo_adc.v b/fpga/lo_adc.v similarity index 74% rename from fpga-xc2s30/lo_adc.v rename to fpga/lo_adc.v index 808ec96ed..475cc869f 100644 --- a/fpga-xc2s30/lo_adc.v +++ b/fpga/lo_adc.v @@ -22,22 +22,24 @@ //----------------------------------------------------------------------------- module lo_adc( - pck0, - 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, divisor, - lf_field + input pck0, + input [7:0] adc_d, + input [7:0] divisor, + input lf_field, + input ssp_dout, + + output ssp_din, + output ssp_frame, + output ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); - input pck0; - 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 [7:0] divisor; - input lf_field; reg [7:0] to_arm_shiftreg; reg [7:0] pck_divider; @@ -49,16 +51,16 @@ wire reader_modulation = !ssp_dout & lf_field & clk_state; // always on (High Frequency outputs, unused) assign pwr_oe1 = 1'b0; -assign pwr_hi = 1'b0; +assign pwr_hi = 1'b0; // low frequency outputs -assign pwr_lo = reader_modulation; +assign pwr_lo = reader_modulation; assign pwr_oe2 = 1'b0; // 33 Ohms assign pwr_oe3 = tag_modulation; // base antenna load = 33 Ohms assign pwr_oe4 = 1'b0; // 10k Ohms // Debug Output ADC clock -assign dbg = adc_clk; +assign debug = adc_clk; // ADC clock out of phase with antenna driver assign adc_clk = ~clk_state; @@ -76,10 +78,10 @@ assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; always @(posedge pck0) begin if (pck_divider == divisor[7:0]) - begin + begin pck_divider <= 8'd0; clk_state = !clk_state; - end + end else begin pck_divider <= pck_divider + 1; @@ -92,13 +94,9 @@ always @(posedge pck0) begin if ((pck_divider == 8'd7) && !clk_state) to_arm_shiftreg <= adc_d; - else begin + else + begin to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - // simulation showed a glitch occurring due to the LSB of the shifter - // not being set as we shift bits out - // this ensures the ssp_din remains low after a transfer and suppresses - // the glitch that would occur when the last data shifted out ended in - // a 1 bit and the next data shifted out started with a 0 bit to_arm_shiftreg[0] <= 1'b0; end end diff --git a/fpga-xc2s30/lo_edge_detect.v b/fpga/lo_edge_detect.v similarity index 67% rename from fpga-xc2s30/lo_edge_detect.v rename to fpga/lo_edge_detect.v index 462dfcc46..c820466f7 100644 --- a/fpga-xc2s30/lo_edge_detect.v +++ b/fpga/lo_edge_detect.v @@ -25,19 +25,29 @@ // - ssp_frame (wired to TIOA1 on the arm) for the edge detection/state // - ssp_clk: cross_lo -`include "lp20khz_1MSa_iir_filter.v" -`include "lf_edge_detect.v" +//`include "lp20khz_1MSa_iir_filter.v" +//`include "lf_edge_detect.v" module lo_edge_detect( - input pck0, input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, - output ssp_frame, input ssp_dout, output ssp_clk, + input pck0, + input pck_divclk, + input [7:0] adc_d, input cross_lo, - output dbg, input lf_field, - input lf_ed_toggle_mode, input [7:0] lf_ed_threshold + input lf_ed_toggle_mode, + input [7:0] lf_ed_threshold, + input ssp_dout, + + output ssp_frame, + output ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); wire tag_modulation = ssp_dout & !lf_field; @@ -58,18 +68,34 @@ assign pwr_hi = 1'b0; wire data_rdy; wire [7:0] adc_filtered; assign adc_clk = pck0; -lp20khz_1MSa_iir_filter adc_filter(pck0, adc_d, data_rdy, adc_filtered); + +lp20khz_1MSa_iir_filter adc_filter( + .clk (pck0), + .adc_d (adc_d), + .rdy (data_rdy), + .out (adc_filtered) +); // detect edges wire [7:0] high_threshold, highz_threshold, lowz_threshold, low_threshold; wire [7:0] max, min; wire edge_state, edge_toggle; -lf_edge_detect lf_ed(pck0, adc_filtered, lf_ed_threshold, - max, min, - high_threshold, highz_threshold, lowz_threshold, low_threshold, - edge_state, edge_toggle); -assign dbg = lf_ed_toggle_mode ? edge_toggle : edge_state; +lf_edge_detect lf_ed( + .clk (pck0), + .adc_d (adc_filtered), + .lf_ed_threshold (lf_ed_threshold), + .max (max), + .min (min), + .high_threshold (high_threshold), + .highz_threshold (highz_threshold), + .lowz_threshold (lowz_threshold), + .low_threshold (low_threshold), + .edge_state (edge_state), + .edge_toggle (edge_toggle) +); + +assign debug = lf_ed_toggle_mode ? edge_toggle : edge_state; assign ssp_frame = lf_ed_toggle_mode ? edge_toggle : edge_state; diff --git a/fpga-xc2s30/lo_passthru.v b/fpga/lo_passthru.v similarity index 82% rename from fpga-xc2s30/lo_passthru.v rename to fpga/lo_passthru.v index 52e56d4c5..a5ae1d4e2 100644 --- a/fpga-xc2s30/lo_passthru.v +++ b/fpga/lo_passthru.v @@ -17,27 +17,32 @@ // For reading TI tags, we need to place the FPGA in pass through mode // and pass everything through to the ARM - module lo_passthru( input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - output adc_clk, - output ssp_din, input ssp_dout, input cross_lo, - output dbg + input ssp_dout, + + output ssp_din, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); // the antenna is modulated when ssp_dout = 1, when 0 the // antenna drivers stop modulating and go into listen mode -assign pwr_oe3 = 1'b0; +assign ssp_din = cross_lo; +assign adc_clk = 1'b0; +assign pwr_lo = pck_divclk && ssp_dout; +assign pwr_hi = 1'b0; assign pwr_oe1 = ssp_dout; assign pwr_oe2 = ssp_dout; +assign pwr_oe3 = 1'b0; assign pwr_oe4 = ssp_dout; -assign pwr_lo = pck_divclk && ssp_dout; -assign pwr_hi = 1'b0; -assign adc_clk = 1'b0; -assign ssp_din = cross_lo; -assign dbg = cross_lo; +assign debug = cross_lo; endmodule diff --git a/fpga-xc2s30/lo_read.v b/fpga/lo_read.v similarity index 80% rename from fpga-xc2s30/lo_read.v rename to fpga/lo_read.v index a7e481654..06bd0ae5a 100644 --- a/fpga-xc2s30/lo_read.v +++ b/fpga/lo_read.v @@ -22,13 +22,23 @@ //----------------------------------------------------------------------------- module lo_read( - input pck0, input [7:0] pck_cnt, input pck_divclk, - output pwr_lo, output pwr_hi, - output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4, - input [7:0] adc_d, output adc_clk, - output ssp_frame, output ssp_din, output ssp_clk, - output dbg, - input lf_field + input pck0, + input pck_divclk, + input [7:0] pck_cnt, + input [7:0] adc_d, + input lf_field, + + output ssp_din, + output ssp_frame, + output ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); reg [7:0] to_arm_shiftreg; @@ -43,13 +53,9 @@ always @(posedge pck0) begin if((pck_cnt == 8'd7) && !pck_divclk) to_arm_shiftreg <= adc_d; - else begin + else + begin to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - // simulation showed a glitch occurring due to the LSB of the shifter - // not being set as we shift bits out - // this ensures the ssp_din remains low after a transfer and suppresses - // the glitch that would occur when the last data shifted out ended in - // a 1 bit and the next data shifted out started with a 0 bit to_arm_shiftreg[0] <= 1'b0; end end @@ -74,7 +80,7 @@ assign ssp_clk = pck0; // SSP frame is gated by ant_lo and goes high when pck_divider=8..15 assign ssp_frame = (pck_cnt[7:3] == 5'd1) && !pck_divclk; // unused signals tied low -assign pwr_hi = 1'b0; +assign pwr_hi = 1'b0; assign pwr_oe1 = 1'b0; assign pwr_oe2 = 1'b0; assign pwr_oe3 = 1'b0; @@ -84,5 +90,5 @@ assign pwr_lo = lf_field & pck_divclk; // ADC clock out of phase with antenna driver assign adc_clk = ~pck_divclk; // ADC clock also routed to debug pin -assign dbg = adc_clk; +assign debug = adc_clk; endmodule diff --git a/fpga-xc2s30/lo_simulate.v b/fpga/lo_simulate.v similarity index 79% rename from fpga-xc2s30/lo_simulate.v rename to fpga/lo_simulate.v index 89b548c73..c3f819cd7 100644 --- a/fpga-xc2s30/lo_simulate.v +++ b/fpga/lo_simulate.v @@ -22,23 +22,27 @@ //----------------------------------------------------------------------------- module lo_simulate( - pck0, ck_1356meg, ck_1356megb, - pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, - adc_d, adc_clk, - ssp_frame, ssp_din, ssp_dout, ssp_clk, - cross_hi, cross_lo, - dbg, - divisor + input pck0, + input ck_1356meg, + input ck_1356megb, + input [7:0] adc_d, + input [7:0] divisor, + input cross_hi, + input cross_lo, + input ssp_dout, + + output ssp_din, + output ssp_frame, + output ssp_clk, + output adc_clk, + output pwr_lo, + output pwr_hi, + output pwr_oe1, + output pwr_oe2, + output pwr_oe3, + output pwr_oe4, + output debug ); - input pck0, ck_1356meg, ck_1356megb; - output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; - input [7:0] adc_d; - output adc_clk; - input ssp_dout; - output ssp_frame, ssp_din, ssp_clk; - input cross_hi, cross_lo; - output dbg; - input [7:0] divisor; // No logic, straight through. assign pwr_oe3 = 1'b0; @@ -46,9 +50,9 @@ assign pwr_oe1 = ssp_dout; assign pwr_oe2 = ssp_dout; assign pwr_oe4 = ssp_dout; assign ssp_clk = cross_lo; -assign pwr_lo = 1'b0; -assign pwr_hi = 1'b0; -assign dbg = ssp_frame; +assign pwr_lo = 1'b0; +assign pwr_hi = 1'b0; +assign debug = ssp_frame; // Divide the clock to be used for the ADC reg [7:0] pck_divider; diff --git a/fpga-xc2s30/lp20khz_1MSa_iir_filter.v b/fpga/lp20khz_1MSa_iir_filter.v similarity index 96% rename from fpga-xc2s30/lp20khz_1MSa_iir_filter.v rename to fpga/lp20khz_1MSa_iir_filter.v index 8bc6cca4f..d4a16cde1 100644 --- a/fpga-xc2s30/lp20khz_1MSa_iir_filter.v +++ b/fpga/lp20khz_1MSa_iir_filter.v @@ -36,7 +36,12 @@ // See details about its design see // https://fail0verflow.com/blog/2014/proxmark3-fpga-iir-filter.html -module lp20khz_1MSa_iir_filter(input clk, input [7:0] adc_d, output rdy, output [7:0] out); +module lp20khz_1MSa_iir_filter( + input clk, + input [7:0] adc_d, + output rdy, + output [7:0] out +); // clk is 24MHz, the IIR filter is designed for 1MS/s // hence we need to divide it by 24 diff --git a/fpga-xc2s30/min_max_tracker.v b/fpga/min_max_tracker.v similarity index 95% rename from fpga-xc2s30/min_max_tracker.v rename to fpga/min_max_tracker.v index 210d3c666..2f6e06017 100644 --- a/fpga-xc2s30/min_max_tracker.v +++ b/fpga/min_max_tracker.v @@ -23,8 +23,13 @@ // This algorithm therefore can't be used directly for realtime peak detections, // but it can be used as a simple envelope follower. -module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, - output [7:0] min, output [7:0] max); +module min_max_tracker( + input clk, + input [7:0] adc_d, + input [7:0] threshold, + output [7:0] min, + output [7:0] max +); reg [7:0] min_val = 255; reg [7:0] max_val = 0; diff --git a/fpga/mux16.v b/fpga/mux16.v new file mode 100644 index 000000000..1d9777706 --- /dev/null +++ b/fpga/mux16.v @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// +// General-purpose miscellany. +// + +// 16 inputs to 1 output multiplexer +module mux16( + input [3:0] sel, + output reg y, + input x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 +); + +always @(*) +begin + // y = x[sel]; + case (sel) + 4'd0: y = x0; + 4'd1: y = x1; + 4'd2: y = x2; + 4'd3: y = x3; + 4'd4: y = x4; + 4'd5: y = x5; + 4'd6: y = x6; + 4'd7: y = x7; + 4'd8: y = x8; + 4'd9: y = x9; + 4'd10: y = x10; + 4'd11: y = x11; + 4'd12: y = x12; + 4'd13: y = x13; + 4'd14: y = x14; + 4'd15: y = x15; + endcase +end + +endmodule diff --git a/fpga-xc3s100e/mux2_onein.v b/fpga/mux2_onein.v similarity index 70% rename from fpga-xc3s100e/mux2_onein.v rename to fpga/mux2_onein.v index 86f17a553..baefa72c8 100644 --- a/fpga-xc3s100e/mux2_onein.v +++ b/fpga/mux2_onein.v @@ -4,13 +4,14 @@ // kombi, 2020.05 //----------------------------------------------------------------------------- -module mux2_one(sel, y, x0, x1); - input [1:0] sel; - input x0, x1; - output y; - reg y; +module mux2_one( + input [1:0] sel, + output reg y, + input x0, + input x1 +); -always @(x0 or x1 or sel) +always @(*) begin case (sel) 1'b0: y = x1; diff --git a/fpga-xc3s100e/mux2_oneout.v b/fpga/mux2_oneout.v similarity index 68% rename from fpga-xc3s100e/mux2_oneout.v rename to fpga/mux2_oneout.v index 3cbc0fd6b..fa61205a2 100644 --- a/fpga-xc3s100e/mux2_oneout.v +++ b/fpga/mux2_oneout.v @@ -4,13 +4,14 @@ // kombi, 2020.05 //----------------------------------------------------------------------------- -module mux2_oneout(sel, y, x0, x1); - input [1:0] sel; - output x0, x1; - input y; - reg x0, x1; +module mux2_oneout( + input [1:0] sel, + input y, + output reg x0, + output reg x1 +); -always @(x0 or x1 or sel) +always @(*) begin case (sel) 1'b0: x1 = y; diff --git a/fpga-xc2s30/util.v b/fpga/mux8.v similarity index 68% rename from fpga-xc2s30/util.v rename to fpga/mux8.v index 66361ca59..d9118d243 100644 --- a/fpga-xc2s30/util.v +++ b/fpga/mux8.v @@ -17,23 +17,25 @@ // General-purpose miscellany. // -module mux8(sel, y, x0, x1, x2, x3, x4, x5, x6, x7); - input [2:0] sel; - input x0, x1, x2, x3, x4, x5, x6, x7; - output y; - reg y; +// 8 inputs to 1 output multiplexer +module mux8( + input [2:0] sel, + output reg y, + input x0, x1, x2, x3, x4, x5, x6, x7 +); -always @(x0 or x1 or x2 or x3 or x4 or x5 or x6 or x7 or sel) +always @(*) begin + // y = x[sel]; case (sel) - 3'b000: y = x0; - 3'b001: y = x1; - 3'b010: y = x2; - 3'b011: y = x3; - 3'b100: y = x4; - 3'b101: y = x5; - 3'b110: y = x6; - 3'b111: y = x7; + 3'd0: y = x0; + 3'd1: y = x1; + 3'd2: y = x2; + 3'd3: y = x3; + 3'd4: y = x4; + 3'd5: y = x5; + 3'd6: y = x6; + 3'd7: y = x7; endcase end diff --git a/fpga-xc2s30/tests/Makefile b/fpga/tests/Makefile similarity index 100% rename from fpga-xc2s30/tests/Makefile rename to fpga/tests/Makefile diff --git a/fpga-xc2s30/tests/plot_edgedetect.py b/fpga/tests/plot_edgedetect.py old mode 100755 new mode 100644 similarity index 100% rename from fpga-xc2s30/tests/plot_edgedetect.py rename to fpga/tests/plot_edgedetect.py diff --git a/fpga-xc2s30/sim.tcl b/fpga/tests/sim.tcl similarity index 100% rename from fpga-xc2s30/sim.tcl rename to fpga/tests/sim.tcl diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.filtered.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.filtered.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.filtered.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.filtered.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.high.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.high.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.high.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.high.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.highz.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.highz.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.highz.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.highz.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.in b/fpga/tests/tb_data/pcf7931_read_1MSA_data.in similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.in rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.in diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.low.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.low.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.low.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.low.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.lowz.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.lowz.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.lowz.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.lowz.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.max.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.max.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.max.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.max.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.min.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.min.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.min.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.min.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.state.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.state.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.state.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.state.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.time b/fpga/tests/tb_data/pcf7931_read_1MSA_data.time similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.time rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.time diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.toggle.gold b/fpga/tests/tb_data/pcf7931_read_1MSA_data.toggle.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_read_1MSA_data.toggle.gold rename to fpga/tests/tb_data/pcf7931_read_1MSA_data.toggle.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.filtered.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.filtered.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.filtered.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.filtered.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.high.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.high.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.high.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.high.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.highz.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.highz.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.highz.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.highz.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.in b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.in similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.in rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.in diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.low.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.low.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.low.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.low.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.lowz.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.lowz.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.lowz.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.lowz.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.max.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.max.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.max.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.max.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.min.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.min.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.min.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.min.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.state.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.state.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.state.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.state.gold diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.time b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.time similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.time rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.time diff --git a/fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.toggle.gold b/fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.toggle.gold similarity index 100% rename from fpga-xc2s30/tests/tb_data/pcf7931_write1byte_1MSA_data.toggle.gold rename to fpga/tests/tb_data/pcf7931_write1byte_1MSA_data.toggle.gold diff --git a/fpga-xc2s30/tests/tb_lf_edge_detect.v b/fpga/tests/tb_lf_edge_detect.v similarity index 100% rename from fpga-xc2s30/tests/tb_lf_edge_detect.v rename to fpga/tests/tb_lf_edge_detect.v diff --git a/fpga-xc2s30/tests/tb_lp20khz_1MSa_iir_filter.v b/fpga/tests/tb_lp20khz_1MSa_iir_filter.v similarity index 100% rename from fpga-xc2s30/tests/tb_lp20khz_1MSa_iir_filter.v rename to fpga/tests/tb_lp20khz_1MSa_iir_filter.v diff --git a/fpga-xc2s30/tests/tb_min_max_tracker.v b/fpga/tests/tb_min_max_tracker.v similarity index 100% rename from fpga-xc2s30/tests/tb_min_max_tracker.v rename to fpga/tests/tb_min_max_tracker.v diff --git a/fpga-xc2s30/testbed_fpga.v b/fpga/tests/testbed_fpga.v similarity index 100% rename from fpga-xc2s30/testbed_fpga.v rename to fpga/tests/testbed_fpga.v diff --git a/fpga-xc2s30/testbed_hi_read_tx.v b/fpga/tests/testbed_hi_read_tx.v similarity index 100% rename from fpga-xc2s30/testbed_hi_read_tx.v rename to fpga/tests/testbed_hi_read_tx.v diff --git a/fpga-xc2s30/testbed_hi_simulate.v b/fpga/tests/testbed_hi_simulate.v similarity index 100% rename from fpga-xc2s30/testbed_hi_simulate.v rename to fpga/tests/testbed_hi_simulate.v diff --git a/fpga-xc2s30/testbed_lo_read.v b/fpga/tests/testbed_lo_read.v similarity index 100% rename from fpga-xc2s30/testbed_lo_read.v rename to fpga/tests/testbed_lo_read.v diff --git a/fpga-xc2s30/testbed_lo_simulate.v b/fpga/tests/testbed_lo_simulate.v similarity index 100% rename from fpga-xc2s30/testbed_lo_simulate.v rename to fpga/tests/testbed_lo_simulate.v diff --git a/fpga/xc2s30-5-vq100.ucf b/fpga/xc2s30-5-vq100.ucf new file mode 100644 index 000000000..e42ce0d88 --- /dev/null +++ b/fpga/xc2s30-5-vq100.ucf @@ -0,0 +1,45 @@ +# 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_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" ; + +# definition of Clock nets: +NET "ck_1356meg" TNM_NET = "clk_net_1356" ; +NET "ck_1356megb" TNM_NET = "clk_net_1356b"; +NET "pck0" TNM_NET = "clk_net_pck0" ; +NET "spck" TNM_NET = "clk_net_spck" ; + +# Timing specs of clock nets: +TIMEGRP "clk_net_1356_all" = "clk_net_1356" "clk_net_1356b" ; +TIMESPEC "TS_1356MHz" = PERIOD "clk_net_1356_all" 74 ns HIGH 37 ns ; +TIMESPEC "TS_24MHz" = PERIOD "clk_net_pck0" 42 ns HIGH 21 ns ; +TIMESPEC "TS_4MHz" = PERIOD "clk_net_spck" 250 ns HIGH 125 ns ; + diff --git a/fpga/xc3s100e-4-vq100.ucf b/fpga/xc3s100e-4-vq100.ucf new file mode 100644 index 000000000..b259af2ed --- /dev/null +++ b/fpga/xc3s100e-4-vq100.ucf @@ -0,0 +1,48 @@ +# See the schematic for the pin assignment. + +NET "adc_d<0>" LOC = "P79" ; +NET "adc_d<1>" LOC = "P78" ; +NET "adc_d<2>" LOC = "P71" ; +NET "adc_d<3>" LOC = "P70" ; +NET "adc_d<4>" LOC = "P69" ; +NET "adc_d<5>" LOC = "P68" ; +NET "adc_d<6>" LOC = "P67" ; +NET "adc_d<7>" LOC = "P66" ; +#NET "cross_hi" LOC = "P88" ; +#NET "miso" LOC = "P40" ; +NET "adc_clk" LOC = "P65" ; +NET "adc_noe" LOC = "P62" ; +NET "ck_1356meg" LOC = "P88" ; +NET "ck_1356megb" LOC = "P89" ; +NET "cross_lo" LOC = "P90" ; +NET "dbg" LOC = "P22" ; +NET "mosi" LOC = "P43" ; +NET "ncs" LOC = "P40" ; +NET "pck0" LOC = "P36" ; +NET "pwr_hi" LOC = "P85" ; +NET "pwr_lo" LOC = "P83" ; +NET "pwr_oe1" LOC = "P84" ; +NET "pwr_oe2" LOC = "P91" ; +NET "pwr_oe3" LOC = "P92" ; +NET "pwr_oe4" LOC = "P86" ; +NET "spck" LOC = "P39" ; +NET "ssp_clk" LOC = "P33" ; +NET "ssp_din" LOC = "P32" ; +NET "ssp_dout" LOC = "P34" ; +NET "ssp_frame" LOC = "P27" ; +NET "FPGA_SWITCH" LOC = "P38" ; +NET "PWR_LO_EN" LOC = "P94" ; + +# definition of Clock nets: +NET "ck_1356meg" TNM_NET = "clk_net_1356" ; +NET "ck_1356megb" TNM_NET = "clk_net_1356b"; +NET "pck0" TNM_NET = "clk_net_pck0" ; +NET "spck" TNM_NET = "clk_net_spck" ; +NET "FPGA_SWITCH" CLOCK_DEDICATED_ROUTE = FALSE ; + +# Timing specs of clock nets: +TIMEGRP "clk_net_1356_all" = "clk_net_1356" "clk_net_1356b" ; +TIMESPEC "TS_1356MHz" = PERIOD "clk_net_1356_all" 74 ns HIGH 37 ns ; +TIMESPEC "TS_24MHz" = PERIOD "clk_net_pck0" 42 ns HIGH 21 ns ; +TIMESPEC "TS_4MHz" = PERIOD "clk_net_spck" 250 ns HIGH 125 ns ; + diff --git a/include/protocols.h b/include/protocols.h index 0183f9f0d..721dccaf5 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -191,12 +191,13 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_CMD_TRANSFER 0xB0 #define MIFARE_MAGIC_GDM_AUTH_KEY 0x80 +#define MIFARE_MAGIC_GDM_READBLOCK 0x38 #define MIFARE_MAGIC_GDM_WRITEBLOCK 0xA8 #define MIFARE_MAGIC_GDM_READ_CFG 0xE0 #define MIFARE_MAGIC_GDM_WRITE_CFG 0xE1 #define MIFARE_EV1_PERSONAL_UID 0x40 -#define MIFARE_EV1_SETMODE 0x43 +#define MIFARE_EV1_SETMOD 0x43 #define MIFARE_EV1_UIDF0 0x00 #define MIFARE_EV1_UIDF1 0x40 #define MIFARE_EV1_UIDF2 0x20 diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 58b3a2162..135125bfc 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -282,7 +282,8 @@ static int bitparse_find_section(FILE *infile, char section_name, unsigned int * /* Four byte length field */ for (int i = 0; i < 4; i++) { tmp = fgetc(infile); - if (tmp < 0) { + /* image length sanity check, should be under 300KB */ + if ((tmp < 0) || (tmp > 300 * 1024)) { break; } current_length += tmp << (24 - (i * 8)); @@ -292,7 +293,8 @@ static int bitparse_find_section(FILE *infile, char section_name, unsigned int * default: /* Fall through, two byte length field */ for (int i = 0; i < 2; i++) { tmp = fgetc(infile); - if (tmp < 0) { + /* if name, date or time fields are too long, we probably shouldn't parse them */ + if ((tmp < 0) || (tmp > 64)) { break; } current_length += tmp << (8 - (i * 8)); @@ -334,14 +336,16 @@ static int FpgaGatherVersion(FILE *infile, char *infile_name, char *dst, int len } } - if (!memcmp("fpga_lf", basename(infile_name), 7)) - strncat(dst, "LF", len - strlen(dst) - 1); - else if (!memcmp("fpga_hf_15", basename(infile_name), 10)) - strncat(dst, "HF 15", len - strlen(dst) - 1); - else if (!memcmp("fpga_hf.", basename(infile_name), 8)) - strncat(dst, "HF", len - strlen(dst) - 1); - else if (!memcmp("fpga_felica", basename(infile_name), 7)) - strncat(dst, "HF FeliCa", len - strlen(dst) - 1); + if (bitparse_find_section(infile, 'a', &fpga_info_len)) { + for (uint32_t i = 0; i < fpga_info_len; i++) { + char c = (char)fgetc(infile); + if (i < sizeof(tempstr)) { + tempstr[i] = c; + } + } + + strncat(dst, tempstr, len - strlen(dst) - 1); + } strncat(dst, " image ", len - strlen(dst) - 1); if (bitparse_find_section(infile, 'b', &fpga_info_len)) {