Make detection threshold for ISO14443A configurable

This adds a new command "hw sethfthresh" to configure the thresholds
used inside the FPGA while demodulating ISO14443A. The thresholds
need to be increased on particularly noisy hardware, such as certain
Chinese PM3 Easy clones.
This commit is contained in:
Christian Zietz 2024-02-01 17:48:06 +01:00
parent a7da3f2a45
commit dbfd8b7a6d
12 changed files with 68 additions and 12 deletions

View file

@ -1560,6 +1560,11 @@ static void PacketReceived(PacketCommandNG *packet) {
setHf14aConfig(&c); setHf14aConfig(&c);
break; break;
} }
case CMD_HF_ISO14443A_SET_THRESHOLDS: {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaSendCommand(FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, (packet->data.asBytes[0] & 0x3f) | ((packet->data.asBytes[1] & 0x3f) << 6));
break;
}
case CMD_HF_ISO14443A_SNIFF: { case CMD_HF_ISO14443A_SNIFF: {
SniffIso14443a(packet->data.asBytes[0]); SniffIso14443a(packet->data.asBytes[0]);
reply_ng(CMD_HF_ISO14443A_SNIFF, PM3_SUCCESS, NULL, 0); reply_ng(CMD_HF_ISO14443A_SNIFF, PM3_SUCCESS, NULL, 0);

View file

@ -743,6 +743,37 @@ static int CmdSetDivisor(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int CmdSetHFThreshold(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hw sethfthresh",
"Set thresholds in HF/14a mode.",
"hw sethfthresh -i 20 -t 7"
);
void *argtable[] = {
arg_param_begin,
arg_int0("i", "high", "<dec>", "high threshold, used in sniff mode (def 20)"),
arg_int0("t", "thresh", "<dec>", "threshold, used in reader mode (def 7)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t params[2];
params[1] = arg_get_int_def(ctx, 1, 20);
params[0] = arg_get_int_def(ctx, 2, 7);
CLIParserFree(ctx);
if ((params[0]<1) || (params[0]>63) || (params[1]<1) || (params[1]>63)) {
PrintAndLogEx(ERR, "Thresholds must be between " _YELLOW_("1") " and " _YELLOW_("63"));
return PM3_EINVARG;
}
clearCommandBuffer();
SendCommandNG(CMD_HF_ISO14443A_SET_THRESHOLDS, (uint8_t *)&params, sizeof(params));
PrintAndLogEx(SUCCESS, "Thresholds set.");
return PM3_SUCCESS;
}
static int CmdSetMux(const char *Cmd) { static int CmdSetMux(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
@ -1195,6 +1226,7 @@ static command_t CommandTable[] = {
{"readmem", CmdReadmem, IfPm3Present, "Read from processor flash"}, {"readmem", CmdReadmem, IfPm3Present, "Read from processor flash"},
{"reset", CmdReset, IfPm3Present, "Reset the Proxmark3"}, {"reset", CmdReset, IfPm3Present, "Reset the Proxmark3"},
{"setlfdivisor", CmdSetDivisor, IfPm3Present, "Drive LF antenna at 12MHz / (divisor + 1)"}, {"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"}, {"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"},
{"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"}, {"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"},
{"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"}, {"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"},

View file

@ -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 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 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 | C C C C E | C = FPGA_CMD_TRACE_ENABLE, E=0 off, E=1 on
+-------------------------------------------------+ +-------------------------------------------------+

Binary file not shown.

View file

@ -127,6 +127,10 @@ hi_simulate hs(
); );
// 2 - HF ISO14443-A // 2 - HF ISO14443-A
`define EDGE_DETECT_THRESHOLD 3
`define EDGE_DETECT_THRESHOLDHIGH 20
hi_iso14443a hisn( hi_iso14443a hisn(
.ck_1356meg (ck_1356meg), .ck_1356meg (ck_1356meg),
.pwr_lo (hisn_pwr_lo), .pwr_lo (hisn_pwr_lo),
@ -142,7 +146,9 @@ hi_iso14443a hisn(
.ssp_dout (ssp_dout), .ssp_dout (ssp_dout),
.ssp_clk (hisn_ssp_clk), .ssp_clk (hisn_ssp_clk),
.debug (hisn_debug), .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 // 3 - HF sniff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -111,6 +111,8 @@ always @(posedge spck) if (~ncs) shift_reg <= {shift_reg[14:0], mosi};
reg trace_enable; reg trace_enable;
reg [7:0] lf_ed_threshold; reg [7:0] lf_ed_threshold;
reg [10:0] hf_edge_detect_threshold;
reg [10:0] hf_edge_detect_threshold_high;
// adjustable frequency clock // adjustable frequency clock
wire [7:0] pck_cnt; wire [7:0] pck_cnt;
@ -124,6 +126,12 @@ reg [11:0] conf_word;
reg [8:0] conf_word; reg [8:0] conf_word;
`endif `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 // 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 // from it, which means that we must make sure that we can do so without
// glitching, or else we will glitch the transmitted carrier. // glitching, or else we will glitch the transmitted carrier.
@ -147,6 +155,11 @@ begin
`else `else
`FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0]; `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0];
`FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0]; `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0];
`FPGA_CMD_SET_EDGE_DETECT_THRESHOLD:
begin
hf_edge_detect_threshold <= {6'b0, shift_reg[5:0]};
hf_edge_detect_threshold_high <= {6'b0, shift_reg[11:6]};
end
`endif `endif
endcase endcase
end end
@ -321,7 +334,9 @@ hi_iso14443a hisn(
.pwr_oe2 (mux2_pwr_oe2), .pwr_oe2 (mux2_pwr_oe2),
.pwr_oe3 (mux2_pwr_oe3), .pwr_oe3 (mux2_pwr_oe3),
.pwr_oe4 (mux2_pwr_oe4), .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 `endif // WITH_HF2

View file

@ -19,6 +19,8 @@ module hi_iso14443a(
input ck_1356meg, input ck_1356meg,
input [7:0] adc_d, input [7:0] adc_d,
input [3:0] mod_type, input [3:0] mod_type,
input [10:0] edge_detect_threshold,
input [10:0] edge_detect_threshold_high,
input ssp_dout, input ssp_dout,
output ssp_din, 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 signed [10:0] rx_mod_rising_edge_max;
reg curbit; 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) always @(negedge adc_clk)
begin begin
if(negedge_cnt[3:0] == mod_detect_reset_time) if(negedge_cnt[3:0] == mod_detect_reset_time)
@ -226,7 +221,7 @@ begin
if (mod_type == `FPGA_HF_ISO14443A_SNIFFER) if (mod_type == `FPGA_HF_ISO14443A_SNIFFER)
begin begin
// detect modulation signal: if modulating, there must have been a falling AND a rising edge // 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 curbit <= 1'b1; // modulation
else else
curbit <= 1'b0; // no modulation curbit <= 1'b0; // no modulation
@ -234,7 +229,7 @@ begin
else else
begin begin
// detect modulation signal: if modulating, there must have been a falling AND a rising edge // 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 curbit <= 1'b1; // modulation
else else
curbit <= 1'b0; // no modulation curbit <= 1'b0; // no modulation

View file

@ -640,6 +640,8 @@ typedef struct {
#define CMD_HF_ISO14443A_GET_CONFIG 0x03B1 #define CMD_HF_ISO14443A_GET_CONFIG 0x03B1
#define CMD_HF_ISO14443A_SET_CONFIG 0x03B2 #define CMD_HF_ISO14443A_SET_CONFIG 0x03B2
#define CMD_HF_ISO14443A_SET_THRESHOLDS 0x03B8
// For measurements of the antenna tuning // For measurements of the antenna tuning
#define CMD_MEASURE_ANTENNA_TUNING 0x0400 #define CMD_MEASURE_ANTENNA_TUNING 0x0400
#define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401 #define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401