diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 471dbc6be..cc66b37f4 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -17,6 +17,7 @@ #include "dbprint.h" #include "pmflash.h" #include "fpga.h" +#include "fpga.h" #include "fpgaloader.h" #include "string.h" #include "legicrf.h" @@ -440,6 +441,11 @@ void SendCapabilities(void) { #else capabilities.compiled_with_hfsniff = false; #endif +#ifdef WITH_HFPLOT + capabilities.compiled_with_hfplot = true; +#else + capabilities.compiled_with_hfplot = false; +#endif #ifdef WITH_ISO14443a capabilities.compiled_with_iso14443a = true; #else @@ -924,7 +930,7 @@ static void PacketReceived(PacketCommandNG *packet) { #ifdef WITH_HITAG case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type - SniffHitag(); + SniffHitag(packet->oldarg[0]); break; } case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content @@ -1358,6 +1364,13 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif +#ifdef WITH_HFPLOT + case CMD_FPGAMEM_DOWNLOAD: { + HfPlotDownload(); + break; + } +#endif + #ifdef WITH_SMARTCARD case CMD_SMART_ATR: { SmartCardAtr(); @@ -1637,7 +1650,7 @@ static void PacketReceived(PacketCommandNG *packet) { Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); } // Trigger a finish downloading signal with an ACK frame - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1698,7 +1711,7 @@ static void PacketReceived(PacketCommandNG *packet) { Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); } // Trigger a finish downloading signal with an ACK frame - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1780,7 +1793,7 @@ static void PacketReceived(PacketCommandNG *packet) { } else { rdv40_spiffs_append((char *) filename, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE); } - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1822,7 +1835,7 @@ static void PacketReceived(PacketCommandNG *packet) { res = Flash_Write(startidx, data, len); isok = (res == len) ? 1 : 0; - reply_old(CMD_ACK, isok, 0, 0, 0, 0); + reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1833,14 +1846,14 @@ static void PacketReceived(PacketCommandNG *packet) { bool isok = false; if (initalwipe) { isok = Flash_WipeMemory(); - reply_old(CMD_ACK, isok, 0, 0, 0, 0); + reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); break; } if (page < 3) isok = Flash_WipeMemoryPage(page); - reply_old(CMD_ACK, isok, 0, 0, 0, 0); + reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1871,7 +1884,7 @@ static void PacketReceived(PacketCommandNG *packet) { } FlashStop(); - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); BigBuf_free(); LED_B_OFF(); break; diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 9b7e83470..a441163e1 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -124,8 +124,8 @@ void SetupSpi(int mode) { } //----------------------------------------------------------------------------- -// Set up the synchronous serial port, with the one set of options that we -// always use when we are talking to the FPGA. Both RX and TX are enabled. +// Set up the synchronous serial port with the set of options that fits +// the FPGA mode. Both RX and TX are always enabled. //----------------------------------------------------------------------------- void FpgaSetupSsc(void) { // First configure the GPIOs, and get ourselves a clock. @@ -141,16 +141,16 @@ void FpgaSetupSsc(void) { // Now set up the SSC proper, starting from a known state. AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - // RX clock comes from TX clock, RX starts when TX starts, data changes - // on RX clock rising edge, sampled on falling edge + // RX clock comes from TX clock, RX starts on Transmit Start, + // data and frame signal is sampled on falling edge of RK AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); // 8 bits per transfer, no loopback, MSB first, 1 transfer per sync // pulse, no output sync AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - // clock comes from TK pin, no clock output, outputs change on falling - // edge of TK, sample on rising edge of TK, start on positive-going edge of sync + // TX clock comes from TK pin, no clock output, outputs change on falling + // edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); // tx framing is the same as the rx framing diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 2c96ec218..4ab03cd22 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -1,3 +1,12 @@ +//----------------------------------------------------------------------------- +// piwi, 2019 +// +// 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. +//----------------------------------------------------------------------------- +// Routines to get sample data from FPGA. +//----------------------------------------------------------------------------- #include "hfsnoop.h" #include "proxmark3_arm.h" #include "BigBuf.h" @@ -5,8 +14,9 @@ #include "ticks.h" #include "dbprint.h" #include "util.h" - -static void RAMFUNC optimizedSniff(void); +#include "fpga.h" +#include "appmain.h" +#include "cmd.h" static void RAMFUNC optimizedSniff(void) { int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory @@ -79,3 +89,42 @@ void HfSniff(int samplesToSkip, int triggersToSkip) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); } + +void HfPlotDownload(void) { + uint8_t *buf = ToSend; + uint8_t *this_buf = buf; + + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + + FpgaSetupSsc(); + + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address + AT91C_BASE_PDC_SSC->PDC_RCR = PM3_CMD_DATA_SIZE; // transfer this many samples + buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer + + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM + + LED_B_ON(); + for(size_t i = 0; i < FPGA_TRACE_SIZE; i += PM3_CMD_DATA_SIZE) { + // prepare next DMA transfer: + uint8_t *next_buf = buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE)); + + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf; + AT91C_BASE_PDC_SSC->PDC_RNCR = PM3_CMD_DATA_SIZE; + + size_t len = MIN(FPGA_TRACE_SIZE - i, PM3_CMD_DATA_SIZE); + + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) {}; // wait for DMA transfer to complete + + reply_old(CMD_FPGAMEM_DOWNLOADED, i, len, FPGA_TRACE_SIZE, this_buf, len); + this_buf = next_buf; + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + // Trigger a finish downloading signal with an ACK frame + reply_mix(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0); + LED_B_OFF(); +} diff --git a/armsrc/hfsnoop.h b/armsrc/hfsnoop.h index b6fac7eb7..049536940 100644 --- a/armsrc/hfsnoop.h +++ b/armsrc/hfsnoop.h @@ -1,6 +1,7 @@ //----------------------------------------------------------------------------- // Jonathan Westhues, Aug 2005 // Gerhard de Koning Gans, April 2008, May 2011 +// Piwi, Feb 2019 // // 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 @@ -12,5 +13,5 @@ #define __HFSNOOP_H void HfSniff(int, int); - +void HfPlotDownload(void); #endif diff --git a/client/cmdhf.c b/client/cmdhf.c index 7f6c7facf..347e4de46 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -3,6 +3,7 @@ // Merlok - 2017 // Doegox - 2019 // Iceman - 2019 +// Piwi - 2019 // // 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 @@ -12,11 +13,11 @@ //----------------------------------------------------------------------------- #include "cmdhf.h" -#include // tolower - -#include "cmdparser.h" // command_t -#include "comms.h" // clearCommandBuffer +#include // tolower +#include "cmdparser.h" // command_t +#include "cliparser/cliparser.h" // parse +#include "comms.h" // clearCommandBuffer #include "cmdhf14a.h" // ISO14443-A #include "cmdhf14b.h" // ISO14443-B #include "cmdhf15.h" // ISO15693 @@ -34,6 +35,9 @@ #include "cmdhflto.h" // LTO-CM #include "cmdtrace.h" // trace list #include "ui.h" +#include "cmddata.h" +#include "graph.h" +#include "../common_fpga/fpga.h" static int CmdHelp(const char *Cmd); @@ -224,6 +228,35 @@ int CmdHFSniff(const char *Cmd) { return PM3_SUCCESS; } +int CmdHFPlot(const char *Cmd) { + CLIParserInit("hf plot", + "Plots HF signal after RF signal path and A/D conversion.", + "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n" + "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n"); + void* argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + uint8_t buf[FPGA_TRACE_SIZE]; + + PacketResponseNG response; + if (!GetFromDevice(FPGA_MEM, buf, FPGA_TRACE_SIZE, 0, NULL, 0, &response, 4000, true)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + for (size_t i = 0; i < FPGA_TRACE_SIZE; i++) { + GraphBuffer[i] = (int)buf[i] - 128; + } + + GraphTraceLen = FPGA_TRACE_SIZE; + ShowGraphWindow(); + RepaintGraphWindow(); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"14a", CmdHF14A, AlwaysAvailable, "{ ISO14443A RFIDs... }"}, @@ -241,6 +274,7 @@ static command_t CommandTable[] = { {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, + {"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"}, {"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"}, {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags"}, {"sniff", CmdHFSniff, IfPm3Hfsniff, " Generic HF Sniff"}, diff --git a/client/cmdhf.h b/client/cmdhf.h index 14ded8e0e..09af16d5e 100644 --- a/client/cmdhf.h +++ b/client/cmdhf.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh -// +// Piwi, Feb 2019 // 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. @@ -17,5 +17,6 @@ int CmdHF(const char *Cmd); int CmdHFTune(const char *Cmd); int CmdHFSearch(const char *Cmd); int CmdHFSniff(const char *Cmd); +int CmdHFPlot(const char *Cmd); #endif diff --git a/client/cmdparser.c b/client/cmdparser.c index fca6fb772..ab9fd3732 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -95,6 +95,12 @@ bool IfPm3Hfsniff(void) { return pm3_capabilities.compiled_with_hfsniff; } +bool IfPm3Hfplot(void) { + if (!IfPm3Present()) + return false; + return pm3_capabilities.compiled_with_hfplot; +} + bool IfPm3Iso14443a(void) { if (!IfPm3Present()) return false; diff --git a/client/cmdparser.h b/client/cmdparser.h index b98aef9d4..1105f63ae 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -34,6 +34,7 @@ bool IfPm3FpcUsartFromUsb(void); bool IfPm3Lf(void); bool IfPm3Hitag(void); bool IfPm3Hfsniff(void); +bool IfPm3Hfplot(void); bool IfPm3Iso14443a(void); bool IfPm3Iso14443b(void); bool IfPm3Iso14443(void); diff --git a/client/comms.c b/client/comms.c index cbabe3354..9b031eb9e 100644 --- a/client/comms.c +++ b/client/comms.c @@ -797,6 +797,10 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 //return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM); return false; } + case FPGA_MEM: { + SendCommandMIX(CMD_FPGAMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); + return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_FPGAMEM_DOWNLOADED); + } } return false; } diff --git a/client/comms.h b/client/comms.h index b49ff6d11..eaf9a16c0 100644 --- a/client/comms.h +++ b/client/comms.h @@ -40,7 +40,8 @@ typedef enum { BIG_BUF_EML, FLASH_MEM, SIM_MEM, - SPIFFS + SPIFFS, + FPGA_MEM, } DeviceMemType_t; typedef struct { diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 22ae385c3..8fe070582 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -92,7 +92,8 @@ PLATFORM_DEFS += \ -DWITH_ICLASS \ -DWITH_FELICA \ -DWITH_NFCBARCODE \ - -DWITH_HFSNIFF + -DWITH_HFSNIFF \ + -DWITH_HFPLOT # Standalone mode diff --git a/common_fpga/fpga.h b/common_fpga/fpga.h index 5ab015f57..31580d8c9 100644 --- a/common_fpga/fpga.h +++ b/common_fpga/fpga.h @@ -14,6 +14,8 @@ #define FPGA_INTERLEAVE_SIZE 288 #define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE +#define FPGA_TRACE_SIZE 3072 + static const uint8_t bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; extern const int fpga_bitstream_num; extern const char *const fpga_version_information[]; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 9100348bc..ac397ff61 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -174,6 +174,7 @@ typedef struct { bool compiled_with_hitag : 1; // hf bool compiled_with_hfsniff : 1; + bool compiled_with_hfplot : 1; bool compiled_with_iso14443a : 1; bool compiled_with_iso14443b : 1; bool compiled_with_iso15693 : 1; @@ -188,7 +189,7 @@ typedef struct { bool hw_available_flash : 1; bool hw_available_smartcard : 1; } PACKED capabilities_t; -#define CAPABILITIES_VERSION 3 +#define CAPABILITIES_VERSION 4 extern capabilities_t pm3_capabilities; // For CMD_LF_T55XX_WRITEBL @@ -522,6 +523,11 @@ typedef struct { #define CMD_HF_MFU_OTP_TEAROFF 0x0740 #define CMD_HF_SNIFF 0x0800 +#define CMD_HF_PLOT 0x0801 + +// Fpga plot download +#define CMD_FPGAMEM_DOWNLOAD 0x0802 +#define CMD_FPGAMEM_DOWNLOADED 0x0803 // For ThinFilm Kovio #define CMD_HF_THINFILM_READ 0x0810