diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 56cfec1de..bbc4eecf9 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -206,8 +206,9 @@ void MeasureAntennaTuning(void) { LEDsoff(); } +// Measure HF in miliVolt uint16_t MeasureAntennaTuningHfData(void) { - uint16_t volt = 0; // in mV + uint16_t volt = 0; uint16_t avg = AvgAdc(ADC_CHAN_HF); volt = (MAX_ADC_HF_VOLTAGE * avg) >> 10; bool use_high = (volt > MAX_ADC_HF_VOLTAGE - 300); @@ -219,6 +220,11 @@ uint16_t MeasureAntennaTuningHfData(void) { return volt; } +// Measure LF in miliVolt +uint32_t MeasureAntennaTuningLfData(void) { + return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; +} + void ReadMem(int addr) { const uint8_t *data = ((uint8_t *)addr); @@ -1415,6 +1421,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_MEASURE_ANTENNA_TUNING_HF: { if (packet->length != 1) reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EINVARG, NULL, 0); + switch (packet->data.asBytes[0]) { case 1: // MEASURE_ANTENNA_TUNING_HF_START // Let the FPGA drive the high-frequency antenna around 13.56 MHz. @@ -1438,6 +1445,35 @@ static void PacketReceived(PacketCommandNG *packet) { } break; } + case CMD_MEASURE_ANTENNA_TUNING_LF: { + if (packet->length != 1) + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0); + + switch (packet->data.asBytes[0]) { + case 1: // MEASURE_ANTENNA_TUNING_LF_START + // Let the FPGA drive the low-frequency antenna around 125Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); + break; + case 2: + if (button_status == BUTTON_SINGLE_CLICK) + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EOPABORTED, NULL, 0); + + uint32_t volt = MeasureAntennaTuningLfData(); + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, (uint8_t *)&volt, sizeof(volt)); + break; + case 3: + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); + break; + default: + reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0); + break; + } + break; + } case CMD_LISTEN_READER_FIELD: { if (packet->length != sizeof(uint8_t)) break; diff --git a/client/cmdlf.c b/client/cmdlf.c index 366f2ed0e..002a596fe 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -190,6 +190,61 @@ static int usage_lf_find(void) { PrintAndLogEx(NORMAL, " lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); return PM3_SUCCESS; } +static int usage_lf_tune(void) { + PrintAndLogEx(NORMAL, "Continuously measure LF antenna tuning."); + PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); + PrintAndLogEx(NORMAL, "Usage: lf tune [h] <0|1>"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " <> "); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf tune = "); + return PM3_SUCCESS; +} + +int CmdLFTune(const char *Cmd) { + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_lf_tune(); + int iter = param_get32ex(Cmd, 0, 0, 10); + + PrintAndLogEx(SUCCESS, "Measuring LF antenna, click button or press Enter to exit"); + + uint8_t mode[] = {1}; + PacketResponseNG resp; + + clearCommandBuffer(); + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF initialization, aborting"); + return PM3_ETIMEOUT; + } + mode[0] = 2; + // loop forever (till button pressed) if iter = 0 (default) + for (uint8_t i = 0; iter == 0 || i < iter; i++) { + if (kbd_enter_pressed()) { // abort by keyboard press + break; + } + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF measure, aborting"); + return PM3_ETIMEOUT; + } + if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint32_t))) + break; + uint32_t volt = resp.data.asDwords[0] & 0xFFFF; + PrintAndLogEx(INPLACE, "%u mV / %5u V", volt, (uint32_t)(volt / 1000)); + } + mode[0] = 3; + SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_LF, mode, sizeof(mode)); + if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_LF, &resp, 1000)) { + PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark LF shutdown, aborting"); + return PM3_ETIMEOUT; + } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Done."); + return PM3_SUCCESS; +} /* send a LF command before reading */ @@ -1166,6 +1221,7 @@ static command_t CommandTable[] = { {"simpsk", CmdLFpskSim, IfPm3Lf, "[1|2|3] [c ] [i] [r ] [d ] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"}, {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, + {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 13995a429..1628c558d 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -442,6 +442,7 @@ typedef struct { // For measurements of the antenna tuning #define CMD_MEASURE_ANTENNA_TUNING 0x0400 #define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401 +#define CMD_MEASURE_ANTENNA_TUNING_LF 0x0402 #define CMD_LISTEN_READER_FIELD 0x0420 #define CMD_HF_DROPFIELD 0x0430