diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b6519146e..57c36490a 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1560,6 +1560,18 @@ static void PacketReceived(PacketCommandNG *packet) { setHf14aConfig(&c); break; } + case CMD_HF_ISO14443A_SET_THRESHOLDS: { + struct p { + uint8_t threshold; + uint8_t threshold_high; + uint8_t legic_threshold; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaSendCommand(FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, (payload->threshold & 0x3f) | ((payload->threshold_high & 0x3f) << 6)); + LegicRfSetThreshold((uint32_t)payload->legic_threshold); + break; + } case CMD_HF_ISO14443A_SNIFF: { SniffIso14443a(packet->data.asBytes[0]); reply_ng(CMD_HF_ISO14443A_SNIFF, PM3_SUCCESS, NULL, 0); diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 42d511875..6239f27cb 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -64,7 +64,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ #define LEGIC_CARD_MEMSIZE 1024 /* The largest Legic Prime card is 1k */ #define WRITE_LOWERLIMIT 4 /* UID and MCC are not writable */ -#define INPUT_THRESHOLD 8 /* heuristically determined, lower values */ +static uint32_t input_threshold = 8; /* heuristically determined, lower values */ /* lead to detecting false ack during write */ //----------------------------------------------------------------------------- @@ -129,7 +129,7 @@ static bool rx_bit(void) { int32_t power = (MAX(ABS(sum_ci), ABS(sum_cq)) + (MIN(ABS(sum_ci), ABS(sum_cq)) >> 1)); // compare average (power / 8) to threshold - return ((power >> 3) > INPUT_THRESHOLD); + return ((power >> 3) > input_threshold); } //----------------------------------------------------------------------------- @@ -566,3 +566,7 @@ OUT: switch_off(); StopTicks(); } + +void LegicRfSetThreshold(uint32_t threshold) { + input_threshold = threshold; +} diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 02f20b536..5932c450e 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -26,6 +26,7 @@ void LegicRfInfo(void); int LegicRfReaderEx(uint16_t offset, uint16_t len, uint8_t iv); void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, const uint8_t *data); +void LegicRfSetThreshold(uint32_t threshold); legic_card_select_t *getLegicCardInfo(void); #endif /* __LEGICRF_H */ diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 58bce9532..767935a77 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -743,6 +743,45 @@ static int CmdSetDivisor(const char *Cmd) { return PM3_SUCCESS; } +static int CmdSetHFThreshold(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hw sethfthresh", + "Set thresholds in HF/14a and Legic mode.", + "hw sethfthresh -t 7 -i 20 -l 8" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("t", "thresh", "", "threshold, used in 14a reader mode (def 7)"), + arg_int0("i", "high", "", "high threshold, used in 14a sniff mode (def 20)"), + arg_int0("l", "legic", "", "threshold used in Legic mode (def 8)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t threshold; + uint8_t threshold_high; + uint8_t legic_threshold; + } PACKED params; + + params.threshold = arg_get_int_def(ctx, 1, 7); + params.threshold_high = arg_get_int_def(ctx, 2, 20); + params.legic_threshold = arg_get_int_def(ctx, 3, 8); + CLIParserFree(ctx); + + if ((params.threshold < 1) || (params.threshold > 63) || (params.threshold_high < 1) || (params.threshold_high > 63)) { + PrintAndLogEx(ERR, "Thresholds must be between " _YELLOW_("1") " and " _YELLOW_("63")); + return PM3_EINVARG; + } + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443A_SET_THRESHOLDS, (uint8_t *)¶ms, sizeof(params)); + PrintAndLogEx(SUCCESS, "Thresholds set."); + return PM3_SUCCESS; +} + static int CmdSetMux(const char *Cmd) { CLIParserContext *ctx; @@ -1195,6 +1234,7 @@ static command_t CommandTable[] = { {"readmem", CmdReadmem, IfPm3Present, "Read from processor flash"}, {"reset", CmdReset, IfPm3Present, "Reset the Proxmark3"}, {"setlfdivisor", CmdSetDivisor, IfPm3Present, "Drive LF antenna at 12MHz / (divisor + 1)"}, + {"sethfthresh", CmdSetHFThreshold, IfPm3Present, "Set thresholds in HF/14a mode"}, {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"}, {"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"}, {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, diff --git a/doc/commands.json b/doc/commands.json index 8dfcf7ce4..44884e6e6 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -7940,6 +7940,21 @@ ], "usage": "hw reset [-h]" }, + "hw sethfthresh": { + "command": "hw sethfthresh", + "description": "Set thresholds in HF/14a and Legic mode.", + "notes": [ + "hw sethfthresh -t 7 -i 20 -l 8" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-t, --thresh threshold, used in 14a reader mode (def 7)", + "-i, --high high threshold, used in 14a sniff mode (def 20)", + "-l, --legic threshold used in Legic mode (def 8)" + ], + "usage": "hw sethfthresh [-h] [-t ] [-i ] [-l ]" + }, "hw setlfdivisor": { "command": "hw setlfdivisor", "description": "Drive LF antenna at 12 MHz / (divisor + 1).", diff --git a/doc/commands.md b/doc/commands.md index eeaebfe1a..1bbd7c01f 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -804,6 +804,7 @@ Check column "offline" for their availability. |`hw readmem `|N |`Read from processor flash` |`hw reset `|N |`Reset the Proxmark3` |`hw setlfdivisor `|N |`Drive LF antenna at 12MHz / (divisor + 1)` +|`hw sethfthresh `|N |`Set thresholds in HF/14a mode` |`hw setmux `|N |`Set the ADC mux to a specific value` |`hw standalone `|N |`Jump to the standalone mode` |`hw status `|N |`Show runtime status information about the connected Proxmark3` diff --git a/fpga/define.v b/fpga/define.v index 05cbd6d7e..b7267a545 100644 --- a/fpga/define.v +++ b/fpga/define.v @@ -39,7 +39,8 @@ +-------------------------------------------------+ | 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 T T T T T T T T | C = FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, T = threshold (in LF mode) +| C C C C H H H H H H T T T T T T | C = FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, H = threshold_high, T = threshold (in HF/14a mode) | C C C C E | C = FPGA_CMD_TRACE_ENABLE, E=0 off, E=1 on +-------------------------------------------------+ diff --git a/fpga/fpga_icopyx_hf.bit b/fpga/fpga_icopyx_hf.bit index b142f3abe..0bd761f40 100644 Binary files a/fpga/fpga_icopyx_hf.bit and b/fpga/fpga_icopyx_hf.bit differ diff --git a/fpga/fpga_icopyx_hf.v b/fpga/fpga_icopyx_hf.v index 233c1aeab..492265607 100644 --- a/fpga/fpga_icopyx_hf.v +++ b/fpga/fpga_icopyx_hf.v @@ -127,6 +127,10 @@ hi_simulate hs( ); // 2 - HF ISO14443-A + +`define EDGE_DETECT_THRESHOLD 3 +`define EDGE_DETECT_THRESHOLDHIGH 20 + hi_iso14443a hisn( .ck_1356meg (ck_1356meg), .pwr_lo (hisn_pwr_lo), @@ -142,7 +146,9 @@ hi_iso14443a hisn( .ssp_dout (ssp_dout), .ssp_clk (hisn_ssp_clk), .debug (hisn_debug), - .mod_type (minor_mode) + .mod_type (minor_mode), + .edge_detect_threshold (`EDGE_DETECT_THRESHOLD), + .edge_detect_threshold_high (`EDGE_DETECT_THRESHOLDHIGH) ); // 3 - HF sniff diff --git a/fpga/fpga_pm3_felica.bit b/fpga/fpga_pm3_felica.bit index b2a808633..6c3b02e8b 100644 Binary files a/fpga/fpga_pm3_felica.bit and b/fpga/fpga_pm3_felica.bit differ diff --git a/fpga/fpga_pm3_hf.bit b/fpga/fpga_pm3_hf.bit index ff2184270..f59d788fa 100644 Binary files a/fpga/fpga_pm3_hf.bit and b/fpga/fpga_pm3_hf.bit differ diff --git a/fpga/fpga_pm3_hf_15.bit b/fpga/fpga_pm3_hf_15.bit index 38ffbbc96..03c3b6b94 100644 Binary files a/fpga/fpga_pm3_hf_15.bit and b/fpga/fpga_pm3_hf_15.bit differ diff --git a/fpga/fpga_pm3_lf.bit b/fpga/fpga_pm3_lf.bit index 4430f391c..701dfbd55 100644 Binary files a/fpga/fpga_pm3_lf.bit and b/fpga/fpga_pm3_lf.bit differ diff --git a/fpga/fpga_pm3_top.v b/fpga/fpga_pm3_top.v index 89b03d3ad..a36cd3e6d 100644 --- a/fpga/fpga_pm3_top.v +++ b/fpga/fpga_pm3_top.v @@ -111,6 +111,8 @@ always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi}; reg trace_enable; reg [7:0] lf_ed_threshold; +reg [5:0] hf_edge_detect_threshold; +reg [5:0] hf_edge_detect_threshold_high; // adjustable frequency clock wire [7:0] pck_cnt; @@ -124,6 +126,12 @@ reg [11:0] conf_word; reg [8:0] conf_word; `endif +initial +begin + hf_edge_detect_threshold <= 7; + hf_edge_detect_threshold_high <= 20; +end + // 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. @@ -147,6 +155,11 @@ begin `else `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; + `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: + begin + hf_edge_detect_threshold <= shift_reg[5:0]; + hf_edge_detect_threshold_high <= shift_reg[11:6]; + end `endif endcase end @@ -321,7 +334,9 @@ hi_iso14443a hisn( .pwr_oe2 (mux2_pwr_oe2), .pwr_oe3 (mux2_pwr_oe3), .pwr_oe4 (mux2_pwr_oe4), - .debug (mux2_debug) + .debug (mux2_debug), + .edge_detect_threshold (hf_edge_detect_threshold), + .edge_detect_threshold_high (hf_edge_detect_threshold_high) ); `endif // WITH_HF2 diff --git a/fpga/hi_iso14443a.v b/fpga/hi_iso14443a.v index 771950ac2..bbc20bee7 100644 --- a/fpga/hi_iso14443a.v +++ b/fpga/hi_iso14443a.v @@ -19,6 +19,8 @@ module hi_iso14443a( input ck_1356meg, input [7:0] adc_d, input [3:0] mod_type, + input [10:0] edge_detect_threshold, + input [10:0] edge_detect_threshold_high, input ssp_dout, output ssp_din, @@ -212,13 +214,6 @@ 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 7 -`endif -`define EDGE_DETECT_THRESHOLDHIGH 20 - always @(negedge adc_clk) begin if(negedge_cnt[3:0] == mod_detect_reset_time) @@ -226,7 +221,7 @@ 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)) + if ((rx_mod_falling_edge_max > edge_detect_threshold_high) && (rx_mod_rising_edge_max < -edge_detect_threshold_high)) curbit <= 1'b1; // modulation else curbit <= 1'b0; // no modulation @@ -234,7 +229,7 @@ begin 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)) + 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 diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index fc26fb233..06cc63b55 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -640,6 +640,8 @@ typedef struct { #define CMD_HF_ISO14443A_GET_CONFIG 0x03B1 #define CMD_HF_ISO14443A_SET_CONFIG 0x03B2 +#define CMD_HF_ISO14443A_SET_THRESHOLDS 0x03B8 + // For measurements of the antenna tuning #define CMD_MEASURE_ANTENNA_TUNING 0x0400 #define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401