Add raw HF signal plotting (#786)
authorpwpiwi <pwpiwi@users.noreply.github.com>
Wed, 20 Feb 2019 18:18:12 +0000 (19:18 +0100)
committerGitHub <noreply@github.com>
Wed, 20 Feb 2019 18:18:12 +0000 (19:18 +0100)
* Add raw HF signal plotting
* new fpga module hi_get_trace.v - store A/D converter output to circular buffer on FPGA
* new command 'hf plot' - pull data from FPGA and display it in Graph Window

30 files changed:
CHANGELOG.md
armsrc/appmain.c
armsrc/apps.h
armsrc/fpgaloader.c
armsrc/fpgaloader.h
armsrc/hfsnoop.c
armsrc/hfsnoop.h [new file with mode: 0644]
armsrc/hitag2.c
armsrc/hitagS.c
armsrc/iclass.c
armsrc/iso14443a.c
armsrc/iso14443b.c
armsrc/iso15693.c
armsrc/legicrf.c
armsrc/legicrfsim.c
armsrc/lfops.c
armsrc/lfsampling.c
armsrc/mifarecmd.c
armsrc/mifaresniff.c
armsrc/pcf7931.c
client/cmdhf.c
client/cmdparser.h
client/comms.c
client/comms.h
common/fpga.h
fpga/Makefile
fpga/fpga_hf.bit
fpga/fpga_hf.v
fpga/hi_get_trace.v [new file with mode: 0644]
include/usb_cmd.h

index f2c285b4bfe8da98afbf3c677e96a8b98a9053d4..c2bf52c5fbf5e83fb6fba3db8b73fd0094e04e23 100644 (file)
@@ -13,7 +13,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 ### Fixed
 - AC-Mode decoding for HitagS
 - Wrong UID at HitagS simulation
-- 'hf 15 sim' now works as expected (piwi)
+- `hf 15 sim` now works as expected (piwi)
 
 ### Added
 - Support Standard Communication Mode in HITAG S
@@ -25,8 +25,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (Merlok)
 - Added `lf paradox clone` to clone a Paradox card
 - Added `emv` commmands working for both contactless and smart cards (Merlok)
-- Added 'hf 15 snoop' (piwi)
-
+- Added `hf 15 snoop` (piwi)
+- Added support for standard USB Smartcard Readers (piwi)
+- Added `hf plot` (piwi)
 
 ## [v3.1.0][2018-10-10]
 
index cdc784c089fa2f6e13d684cb3e03d68438e9bdd0..2a16f5f0e70b418b7014259a4b6fce9ff43c8ff2 100644 (file)
@@ -30,6 +30,8 @@
 #include "mifareutil.h"
 #include "pcf7931.h"
 #include "i2c.h"
+#include "hfsnoop.h"
+#include "fpgaloader.h"
 #ifdef WITH_LCD
  #include "LCD.h"
 #endif
@@ -1323,11 +1325,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes);
                        break;
 #endif
+
 #ifdef WITH_HFSNOOP
                case CMD_HF_SNIFFER:
                        HfSnoop(c->arg[0], c->arg[1]);
                        break;
+               case CMD_HF_PLOT:
+                       HfPlot();
+                       break;
 #endif
+
 #ifdef WITH_SMARTCARD
                case CMD_SMART_ATR: {
                        SmartCardAtr();
@@ -1377,7 +1384,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
 
                case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
-
                        LED_B_ON();
                        uint8_t *BigBuf = BigBuf_get_addr();
                        for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
index fad9e6eb7873ec6417be34be41cfb468d38121a4..aaa128ab54e3a28781ab6cc1ca203299d8b80f7a 100644 (file)
@@ -21,7 +21,6 @@
 #include "mifare.h"
 #include "../common/crc32.h"
 #include "BigBuf.h"
-#include "fpgaloader.h"
 
 extern const uint8_t OddByteParity[256];
 extern int rsamples;   // = 0;
@@ -174,13 +173,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data);
 void WritePageHitagS(hitag_function htf, hitag_data* htd,int page);
 void check_challenges_cmd(bool file_given, byte_t* data, uint64_t tagMode);
 
-
-
 // cmd.h
 bool cmd_receive(UsbCommand* cmd);
 bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);
 
-/// util.h
-void HfSnoop(int , int);
-
 #endif
index 45294d6008fbf47ed628d19b6a92c25778a758b9..d1d527c498826c79d3338b8933b0b176142e7273 100644 (file)
@@ -166,7 +166,7 @@ bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count)
        AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf;           // transfer to this memory address
        AT91C_BASE_PDC_SSC->PDC_RCR = sample_count;             // transfer this many samples
        AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf;          // next transfer to same memory address
-       AT91C_BASE_PDC_SSC->PDC_RNCR = sample_count;            // ... with same number of samples      AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;         // go!
+       AT91C_BASE_PDC_SSC->PDC_RNCR = sample_count;            // ... with same number of samples
        AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;         // go!
        return true;
 }
@@ -417,8 +417,10 @@ void FpgaDownloadAndGo(int bitstream_version)
        uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
        
        // check whether or not the bitstream is already loaded
-       if (downloaded_bitstream == bitstream_version)
+       if (downloaded_bitstream == bitstream_version) {
+               FpgaEnableTracing();
                return;
+       }
 
        // make sure that we have enough memory to decompress
        BigBuf_free(); BigBuf_Clear_ext(false); 
@@ -454,16 +456,30 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v)
        while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);              // wait for the transfer to complete
        AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v;         // send the data
 }
+
 //-----------------------------------------------------------------------------
 // Write the FPGA setup word (that determines what mode the logic is in, read
 // vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to
 // avoid changing this function's occurence everywhere in the source code.
 //-----------------------------------------------------------------------------
-void FpgaWriteConfWord(uint8_t v)
+void FpgaWriteConfWord(uint16_t v)
 {
        FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
 }
 
+//-----------------------------------------------------------------------------
+// enable/disable FPGA internal tracing
+//-----------------------------------------------------------------------------
+void FpgaEnableTracing(void)
+{
+       FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1);
+}
+
+void FpgaDisableTracing(void)
+{
+       FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0);
+}
+
 //-----------------------------------------------------------------------------
 // Set up the CMOS switches that mux the ADC: four switches, independently
 // closable, but should only close one at a time. Not an FPGA thing, but
index 0600067edd52c07d2aec566079d739a885fa49fc..006de8de1e2be0a6c94e880a18b163f8919e7097 100644 (file)
 #include <stdbool.h>
 
 void FpgaSendCommand(uint16_t cmd, uint16_t v);
-void FpgaWriteConfWord(uint8_t v);
+void FpgaWriteConfWord(uint16_t v);
 void FpgaDownloadAndGo(int bitstream_version);
 void FpgaSetupSsc(uint8_t mode);
 void SetupSpi(int mode);
 bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count);
 void Fpga_print_status();
 int FpgaGetCurrent();
+void FpgaEnableTracing(void);
+void FpgaDisableTracing(void);
 #define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
 #define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
 void SetAdcMuxFor(uint32_t whichGpio);
@@ -33,9 +35,14 @@ void SetAdcMuxFor(uint32_t whichGpio);
 #define FPGA_BITSTREAM_HF 2
 
 // Definitions for the FPGA commands.
+// BOTH
 #define FPGA_CMD_SET_CONFREG                        (1<<12)
+// LF
 #define FPGA_CMD_SET_DIVISOR                        (2<<12)
 #define FPGA_CMD_SET_USER_BYTE1                     (3<<12)
+// HF
+#define FPGA_CMD_TRACE_ENABLE                       (2<<12)
+
 // Definitions for the FPGA configuration word.
 // LF
 #define FPGA_MAJOR_MODE_LF_ADC                      (0<<5)
@@ -47,21 +54,27 @@ void SetAdcMuxFor(uint32_t whichGpio);
 #define FPGA_MAJOR_MODE_HF_SIMULATOR                (2<<5)
 #define FPGA_MAJOR_MODE_HF_ISO14443A                (3<<5)
 #define FPGA_MAJOR_MODE_HF_SNOOP                    (4<<5)
+#define FPGA_MAJOR_MODE_HF_GET_TRACE                (5<<5)
 // BOTH
 #define FPGA_MAJOR_MODE_OFF                         (7<<5)
+
 // Options for LF_ADC
 #define FPGA_LF_ADC_READER_FIELD                    (1<<0)
+
 // Options for LF_EDGE_DETECT
 #define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD          FPGA_CMD_SET_USER_BYTE1
 #define FPGA_LF_EDGE_DETECT_READER_FIELD            (1<<0)
 #define FPGA_LF_EDGE_DETECT_TOGGLE_MODE             (1<<1)
+
 // Options for the HF reader, tx to tag
 #define FPGA_HF_READER_TX_SHALLOW_MOD               (1<<0)
+
 // Options for the HF reader, correlating against rx from tag
 #define FPGA_HF_READER_RX_XCORR_848_KHZ             (1<<0)
 #define FPGA_HF_READER_RX_XCORR_SNOOP               (1<<1)
 #define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ        (1<<2)
 #define FPGA_HF_READER_RX_XCORR_AMPLITUDE           (1<<3)
+
 // Options for the HF simulated tag, how to modulate
 #define FPGA_HF_SIMULATOR_NO_MODULATION             (0<<0)
 #define FPGA_HF_SIMULATOR_MODULATE_BPSK             (1<<0)
index e492c47472cab53ce5baff06a6ac0698cfeecd94..755ac0ccc79c3bb0ba27401873d40ab6caf9f149 100644 (file)
@@ -1,10 +1,22 @@
+//-----------------------------------------------------------------------------
+// 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.h"
-#include "apps.h"
 #include "BigBuf.h"
 #include "util.h"
+#include "apps.h"
 #include "usb_cdc.h"   // for usb_poll_validate_length
-
-static void RAMFUNC optimizedSnoop(void);
+#include "fpga.h"
+#include "fpgaloader.h"
 
 static void RAMFUNC optimizedSnoop(void)
 {
@@ -74,3 +86,33 @@ void HfSnoop(int samplesToSkip, int triggersToSkip)
        LED_D_OFF();
 }
 
+void HfPlot(void)
+{
+       uint8_t *buf = ToSend;
+       uint8_t *this_buf = buf;
+       
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_GET_TRACE);
+       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 = USB_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 += USB_CMD_DATA_SIZE) {
+               // prepare next DMA transfer:
+               uint8_t *next_buf = buf + ((i + USB_CMD_DATA_SIZE) % (2 * USB_CMD_DATA_SIZE));
+               AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf;
+               AT91C_BASE_PDC_SSC->PDC_RNCR = USB_CMD_DATA_SIZE;
+               size_t len = MIN(FPGA_TRACE_SIZE - i, USB_CMD_DATA_SIZE);
+               while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) ; // wait for DMA transfer to complete
+               cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, FPGA_TRACE_SIZE, this_buf, len);
+               this_buf = next_buf;
+       }
+       // Trigger a finish downloading signal with an ACK frame
+       cmd_send(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0);
+       LED_B_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+}
diff --git a/armsrc/hfsnoop.h b/armsrc/hfsnoop.h
new file mode 100644 (file)
index 0000000..8c45e17
--- /dev/null
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef HFSNOOP_H__
+#define HFSNOOP_H__
+
+void HfSnoop(int samplesToSkip, int triggersToSkip);
+void HfPlot(void);
+
+#endif
index 8e690a7b556d2cf11be72baff5202bf1afca2569..0fd8d7458ac5631e969e6935af96513098726ca8 100644 (file)
@@ -22,6 +22,7 @@
 #include "hitag2.h"
 #include "string.h"
 #include "BigBuf.h"
+#include "fpgaloader.h"
 
 static bool bQuiet;
 
index 3c247d552958e7da6656dc9812d04671bcc7acd9..8a451606a802a8f9b443b4c62bbd06619fe0d02a 100644 (file)
@@ -20,6 +20,7 @@
 #include "hitag2.h"
 #include "string.h"
 #include "BigBuf.h"
+#include "fpgaloader.h"
 
 #define CRC_PRESET 0xFF
 #define CRC_POLYNOM 0x1D
index d27fc1c6f70ff533fe94b70e0590aae541a8100f..be7da703c7399bf007799643af39c3bd3385804b 100644 (file)
@@ -51,6 +51,7 @@
 #include "protocols.h"
 #include "optimized_cipher.h"
 #include "usb_cdc.h" // for usb_poll_validate_length
+#include "fpgaloader.h"
 
 static int timeout = 4096;
 
index 50160798664d2f42c29e8e528cdd5af32d904220..2fffe8373cfee3f02112b022438f3edc31d7f371 100644 (file)
@@ -25,6 +25,7 @@
 #include "BigBuf.h"
 #include "protocols.h"
 #include "parity.h"
+#include "fpgaloader.h"
 
 typedef struct {
        enum {
@@ -1771,7 +1772,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                if (anticollision) {
                        // SELECT_ALL
                        ReaderTransmit(sel_all, sizeof(sel_all), NULL);
-                       if (!ReaderReceive(resp, resp_par)) return 0;
+                       if (!ReaderReceive(resp, resp_par)) {
+                               return 0;
+                       }
 
                        if (Demod.collisionPos) {                       // we had a collision and need to construct the UID bit by bit
                                memset(uid_resp, 0, 4);
@@ -1793,7 +1796,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                                        }
                                        collision_answer_offset = uid_resp_bits%8;
                                        ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
-                                       if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0;
+                                       if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) {
+                                               return 0;
+                                       }
                                }
                                // finally, add the last bits and BCC of the UID
                                for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
@@ -1827,7 +1832,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
 
                // Receive the SAK
-               if (!ReaderReceive(resp, resp_par)) return 0;
+               if (!ReaderReceive(resp, resp_par)) {
+                       return 0;
+               }
                sak = resp[0];
        
                // Test if more parts of the uid are coming
@@ -1862,7 +1869,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                AppendCrc14443a(rats, 2);
                ReaderTransmit(rats, sizeof(rats), NULL);
 
-               if (!(len = ReaderReceive(resp, resp_par))) return 0;
+               if (!(len = ReaderReceive(resp, resp_par))) {
+                       return 0;
+               }
 
                if(p_hi14a_card) {
                        memcpy(p_hi14a_card->ats, resp, len);
@@ -2044,7 +2053,7 @@ void ReaderIso14443a(UsbCommand *c)
                                // 1 - all is OK with ATS, 2 - without ATS
                                cantSELECT = true;
                        }
-                       
+                       FpgaDisableTracing();
                        LED_B_ON();
                        cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
                        LED_B_OFF();
@@ -2058,6 +2067,7 @@ void ReaderIso14443a(UsbCommand *c)
        if(param & ISO14A_APDU && !cantSELECT) {
                uint8_t res;
                arg0 = iso14_apdu(cmd, len, buf, &res);
+               FpgaDisableTracing();
                LED_B_ON();
                cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf));
                LED_B_OFF();
@@ -2099,6 +2109,7 @@ void ReaderIso14443a(UsbCommand *c)
                        }
                }
                arg0 = ReaderReceive(buf, par);
+               FpgaDisableTracing();
 
                LED_B_ON();
                cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
@@ -2415,6 +2426,8 @@ void ReaderMifare(bool first_try)
                }
        }
        
+       FpgaDisableTracing();
+
        uint8_t buf[32];
        memcpy(buf + 0,  uid, 4);
        num_to_bytes(nt, 4, buf + 4);
@@ -2587,6 +2600,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
        DbpString("COMMAND FINISHED.");
 
        FpgaDisableSscDma();
+       FpgaDisableTracing();
        MfSniffEnd();
        
        Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len);
index 76d7a0753845f3453de413fe6c0a5ff7e96c5edd..3ebaa5393a27c8a7f818407bc5ddb42f7a0b206a 100644 (file)
 // the `fake tag' modes.
 //-----------------------------------------------------------------------------
 
+#include "iso14443b.h"
+
 #include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
 #include "string.h"
-
 #include "iso14443crc.h"
+#include "fpgaloader.h"
 
 #define RECEIVE_SAMPLES_TIMEOUT 1000 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA. 1000 seems to be much too high?
 #define ISO14443B_DMA_BUFFER_SIZE 128
index 9dc4bf187ee60c3c56aa261bcd5672acc866eb43..13b8a174a567d2201b4fe9ff552ca02a22498c92 100644 (file)
@@ -60,6 +60,7 @@
 #include "protocols.h"
 #include "cmd.h"
 #include "BigBuf.h"
+#include "fpgaloader.h"
 
 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
 
index d3fd35d104e0ba590801a6442eb96d9dcefd022e..947d6cd5f855050bc59f645c9dfdf6165e1d179e 100644 (file)
 // LEGIC RF simulation code
 //-----------------------------------------------------------------------------
 
+#include "legicrf.h"
+
 #include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
 #include "string.h"
-
-#include "legicrf.h"
 #include "legic_prng.h"
 #include "legic.h"
 #include "crc.h"
+#include "fpgaloader.h"
 
 static legic_card_select_t card;/* metadata of currently selected card */
 static crc_t legic_crc;
index 1411fbea6d85e7326127e4c5cc32da58863d6322..409235af6bc58bfd27ab967490d4ae26581d38c3 100644 (file)
 // LEGIC RF simulation code
 //-----------------------------------------------------------------------------
 
+#include "legicrfsim.h"
+
 #include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
 #include "string.h"
-
-#include "legicrfsim.h"
 #include "legic_prng.h"
 #include "legic.h"
 #include "crc.h"
 #include "usb_cdc.h"  // for usb_poll_validate_length
+#include "fpgaloader.h"
 
 static uint8_t* legic_mem;      /* card memory, used for sim */
 static legic_card_select_t card;/* metadata of currently selected card */
index 1816bdcaf600f8f7e398a2108377b7083b2dc579..81fdd7a66c5cb8c1169af608624f0d45ab23d66d 100644 (file)
@@ -18,6 +18,7 @@
 #include "lfsampling.h"
 #include "protocols.h"
 #include "usb_cdc.h" // for usb_poll_validate_length
+#include "fpgaloader.h"
 
 /**
  * Function to do a modulation and then get samples.
index ffbc0da875ebe11e683fe9426b9c0630e39335ee..03bccf41a7bbd151fac373b593ec7b24934c0740 100644 (file)
@@ -12,7 +12,7 @@
 #include "string.h"
 #include "lfsampling.h"
 #include "usb_cdc.h"   // for usb_poll_validate_length
-//#include "ticks.h"           // for StartTicks
+#include "fpgaloader.h"
 
 sample_config config = { 1, 8, 1, 95, 0 } ;
 
index ca513cec953c897b00833595ce07781a402085e0..14ce1bcc2bf8699a5ce4488aae8a2cccb3e94575 100644 (file)
 \r
 #include "mifarecmd.h"\r
 \r
-#include "apps.h"\r
 #include "util.h"\r
 #include "parity.h"\r
 #include "crc.h"\r
+#include "fpgaloader.h"\r
 \r
 #define HARDNESTED_AUTHENTICATION_TIMEOUT 848                  // card times out 1ms after wrong authentication (according to NXP documentation)\r
 #define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400             // some (non standard) cards need a pause after select before they are ready for first authentication \r
index 5391e5f9af1c35f0bc2e8b44d600955610fa52c0..4dbcd90434cefabc8cbf579d2e21a9d62e09a6e2 100644 (file)
@@ -9,7 +9,7 @@
 //-----------------------------------------------------------------------------
 
 #include "mifaresniff.h"
-#include "apps.h"
+
 #include "proxmark3.h"
 #include "util.h"
 #include "string.h"
@@ -18,6 +18,9 @@
 #include "crapto1/crapto1.h"
 #include "mifareutil.h"
 #include "common.h"
+#include "cmd.h"
+#include "BigBuf.h"
+#include "fpgaloader.h"
 
 
 static int sniffState = SNF_INIT;
index 16b7912dbc672a9e407441cf81b8f503615ca88f..9aa0d9bea7e9e5d56ec86dc3bab2d2667feed766 100644 (file)
@@ -4,6 +4,7 @@
 #include "pcf7931.h"
 #include "util.h"
 #include "string.h"
+#include "fpgaloader.h"
 
 #define T0_PCF 8 //period for the pcf7931 in us
 #define ALLOC 16
index f11c5b651aee2d8da34658f7152d012190cc34e4..73b0bc76f4a4bead86536ec3eb389e170698d567 100644 (file)
 
 #include "cmdhf.h"
 
+#include <math.h>
 #include "usb_cmd.h"
 #include "comms.h"
 #include "ui.h"
 #include "cmdparser.h"
+#include "cliparser/cliparser.h"
 #include "cmdhf14a.h"
 #include "cmdhf14b.h"
 #include "cmdhf15.h"
@@ -27,6 +29,9 @@
 #include "cmdhftopaz.h"
 #include "cmdhflist.h"
 #include "cmdhffido.h"
+#include "cmddata.h"
+#include "graph.h"
+#include "fpga.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -73,31 +78,83 @@ int CmdHFSnoop(const char *Cmd)
        return 0;
 }
 
-static command_t CommandTable[] = 
+
+// static void InterpolateShannon(int *source, size_t source_len, int *dest, size_t dest_len)
+// {
+       // int *buf = (int*)malloc(source_len * sizeof(int));
+       // memcpy(buf, source, source_len * sizeof(int));
+       // for (int i = 0; i < source_len; i++) {
+               // buf[i] += 128;
+       // }
+       // for (int i = 0; i < dest_len; i++) {
+               // float value = 0.0;
+               // for (int j = 0; j < source_len; j++) {
+                       // if (i * source_len == j * dest_len) { // sin(0) / 0 = 1
+                               // value += (float)buf[j];
+                       // } else {
+                               // value += (float)buf[j] * sin(((float)i*source_len/dest_len-j)*3.1415) / (((float)i*source_len/dest_len-j)*3.1415);
+                       // }
+               // }
+               // dest[i] = value - 128;
+       // }
+       // free(buf);
+// }
+
+
+static 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];
+
+       if (GetFromFpgaRAM(buf, FPGA_TRACE_SIZE)) {
+               for (size_t i = 0; i < FPGA_TRACE_SIZE; i++) {
+                       GraphBuffer[i] = (int)buf[i] - 128;
+               }
+               GraphTraceLen = FPGA_TRACE_SIZE;
+               // InterpolateShannon(GraphBuffer, FPGA_TRACE_SIZE, GraphBuffer, FPGA_TRACE_SIZE*8/7);
+               // GraphTraceLen = FPGA_TRACE_SIZE*8/7;
+               ShowGraphWindow();
+               RepaintGraphWindow();
+       }
+       return 0;
+}
+
+
+static command_t CommandTable[] =
 {
-       {"help",        CmdHelp,                1, "This help"},
-       {"14a",         CmdHF14A,               1, "{ ISO14443A RFIDs... }"},
-       {"14b",         CmdHF14B,               1, "{ ISO14443B RFIDs... }"},
-       {"15",          CmdHF15,                1, "{ ISO15693 RFIDs... }"},
-       {"epa",         CmdHFEPA,               1, "{ German Identification Card... }"},
-       {"legic",       CmdHFLegic,             0, "{ LEGIC RFIDs... }"},
-       {"iclass",      CmdHFiClass,    1, "{ ICLASS RFIDs... }"},
-       {"mf",          CmdHFMF,                1, "{ MIFARE RFIDs... }"},
-       {"mfu",         CmdHFMFUltra,   1, "{ MIFARE Ultralight RFIDs... }"},
-       {"mfp",         CmdHFMFP,               1, "{ MIFARE Plus RFIDs... }"},
-       {"topaz",       CmdHFTopaz,             1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
-       {"fido",        CmdHFFido,              1, "{ FIDO and FIDO2 authenticators... }"},
-       {"tune",        CmdHFTune,              0, "Continuously measure HF antenna tuning"},
-       {"list",        CmdHFList,              1, "List protocol data in trace buffer"},
-       {"search",      CmdHFSearch,    1, "Search for known HF tags [preliminary]"},
+       {"help",    CmdHelp,        1, "This help"},
+       {"14a",     CmdHF14A,       0, "{ ISO14443A RFIDs... }"},
+       {"14b",     CmdHF14B,       0, "{ ISO14443B RFIDs... }"},
+       {"15",      CmdHF15,        1, "{ ISO15693 RFIDs... }"},
+       {"epa",     CmdHFEPA,       0, "{ German Identification Card... }"},
+       {"legic",   CmdHFLegic,     0, "{ LEGIC RFIDs... }"},
+       {"iclass",  CmdHFiClass,    1, "{ ICLASS RFIDs... }"},
+       {"mf",      CmdHFMF,        1, "{ MIFARE RFIDs... }"},
+       {"mfu",     CmdHFMFUltra,   1, "{ MIFARE Ultralight RFIDs... }"},
+       {"mfp",     CmdHFMFP,       0, "{ MIFARE Plus RFIDs... }"},
+       {"topaz",   CmdHFTopaz,     0, "{ TOPAZ (NFC Type 1) RFIDs... }"},
+       {"fido",    CmdHFFido,      0, "{ FIDO and FIDO2 authenticators... }"},
+       {"tune",    CmdHFTune,      0, "Continuously measure HF antenna tuning"},
+       {"list",    CmdHFList,      1, "List protocol data in trace buffer"},
+       {"plot",    CmdHFPlot,      0, "Plot signal"},
+       {"search",  CmdHFSearch,    0, "Search for known HF tags [preliminary]"},
        {"snoop",   CmdHFSnoop,     0, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Snoop"},
-       {NULL,          NULL,                   0, NULL}
+       {NULL,      NULL,           0, NULL}
 };
 
 int CmdHF(const char *Cmd)
 {
   CmdsParse(CommandTable, Cmd);
-  return 0; 
+  return 0;
 }
 
 int CmdHelp(const char *Cmd)
index 5217d04b692282e87e810bfbf82b218eb06d3042..cd4d1625736ff796932d9ae7ed2788fa6f4026ac 100644 (file)
@@ -9,7 +9,7 @@
 //-----------------------------------------------------------------------------
 
 #ifndef CMDPARSER_H__
-#define CMDPARSER_H__ 
+#define CMDPARSER_H__
 
 typedef struct command_s
 {
index 190b911093d598b6d859542a6b891ec2d69199d4..5af53715e9fa27470ca934dae87e968553ae0a2a 100644 (file)
@@ -301,6 +301,39 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon
 }
 
        
+bool GetFromFpgaRAM(uint8_t *dest, int bytes)
+{
+       UsbCommand c = {CMD_HF_PLOT, {0, 0, 0}};
+       SendCommand(&c);
+
+       uint64_t start_time = msclock();
+
+       UsbCommand response;
+       
+       int bytes_completed = 0;
+       bool show_warning = true;
+       while(true) {
+               if (getCommand(&response)) {
+                       if (response.cmd == CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {
+                               int copy_bytes = MIN(bytes - bytes_completed, response.arg[1]);
+                               memcpy(dest + response.arg[0], response.d.asBytes, copy_bytes);
+                               bytes_completed += copy_bytes;
+                       } else if (response.cmd == CMD_ACK) {
+                               return true;
+                       }
+               }
+
+               if (msclock() - start_time > 2000 && show_warning) {
+                       PrintAndLog("Waiting for a response from the proxmark...");
+                       PrintAndLog("You can cancel this operation by pressing the pm3 button");
+                       show_warning = false;
+               }
+       }
+
+       return false;
+}
+
+
 bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
        char *portname = (char *)port;
        if (!wait_for_port) {
index 689811658429a4503c614a5cfcfe01eb5bbc4409..65294695bf500a95a2ec2602ccb1b6585adf472e 100644 (file)
@@ -35,5 +35,6 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo
 bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
 bool WaitForResponse(uint32_t cmd, UsbCommand* response);
 bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
+bool GetFromFpgaRAM(uint8_t *dest, int bytes);
 
 #endif // COMMS_H_
index b99a75935ef4b6e4b4fb42e52ccb92d854dfb80a..65268ecfa6334fdf7c3d02c7b41edb53c41f66d8 100644 (file)
@@ -10,6 +10,7 @@
 #define FPGA_BITSTREAM_FIXED_HEADER_SIZE    sizeof(bitparse_fixed_header)
 #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;
index 2f93e741d7f9bbfd4564e5cd2a391b5f736de646..70b0b5fe906d6dd589351bdb21dc4c727ea3165c 100644 (file)
@@ -5,7 +5,7 @@ clean:
        $(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp
        $(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst
 
-fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v
+fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_get_trace.v
        $(DELETE) $@
        $(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr
 
index f16fd0614fbd2614e713a29da5f47a29094953e5..2ea2c24e76d0e4b64f173d48cf67dc299283e53d 100644 (file)
Binary files a/fpga/fpga_hf.bit and b/fpga/fpga_hf.bit differ
index 5d55cb89e6e696f3ff55588a81f080dd35e2aa39..ef93526016efefb468a64b3d41714fdd20511cc9 100644 (file)
@@ -18,6 +18,7 @@
 `include "hi_simulate.v"
 `include "hi_iso14443a.v"
 `include "hi_sniffer.v"
+`include "hi_get_trace.v"
 `include "util.v"
 
 module fpga_hf(
@@ -40,6 +41,7 @@ module fpga_hf(
 
 reg [15:0] shift_reg;
 reg [7: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
@@ -48,6 +50,7 @@ always @(posedge ncs)
 begin
        case(shift_reg[15:12])
                4'b0001: conf_word <= shift_reg[7:0];           // FPGA_CMD_SET_CONFREG
+               4'b0010: trace_enable <= shift_reg[0];          // FPGA_CMD_TRACE_ENABLE
        endcase
 end
 
@@ -129,7 +132,7 @@ hi_iso14443a hisn(
 
 hi_sniffer he(
        pck0, ck_1356meg, ck_1356megb,
-       he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3,       he_pwr_oe4,
+       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, ssp_dout, he_ssp_clk,
        cross_hi, cross_lo,
@@ -137,6 +140,12 @@ hi_sniffer he(
        hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
 );
 
+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, transmitting to tag; modulation depth selectable
@@ -144,19 +153,20 @@ hi_sniffer he(
 //   010 --  HF simulated tag
 //   011 --  HF ISO14443-A
 //   100 --  HF Snoop
+//   101 --  HF get trace
 //   111 --  everything off
 
-mux8 mux_ssp_clk               (major_mode, ssp_clk,   ht_ssp_clk,   hrxc_ssp_clk,   hs_ssp_clk,   hisn_ssp_clk,   he_ssp_clk, 1'b0, 1'b0, 1'b0);
-mux8 mux_ssp_din               (major_mode, ssp_din,   ht_ssp_din,   hrxc_ssp_din,   hs_ssp_din,   hisn_ssp_din,   he_ssp_din, 1'b0, 1'b0, 1'b0);
-mux8 mux_ssp_frame             (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe1               (major_mode, pwr_oe1,   ht_pwr_oe1,   hrxc_pwr_oe1,   hs_pwr_oe1,   hisn_pwr_oe1,   he_pwr_oe1, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe2               (major_mode, pwr_oe2,   ht_pwr_oe2,   hrxc_pwr_oe2,   hs_pwr_oe2,   hisn_pwr_oe2,   he_pwr_oe2, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe3               (major_mode, pwr_oe3,   ht_pwr_oe3,   hrxc_pwr_oe3,   hs_pwr_oe3,   hisn_pwr_oe3,   he_pwr_oe3, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe4               (major_mode, pwr_oe4,   ht_pwr_oe4,   hrxc_pwr_oe4,   hs_pwr_oe4,   hisn_pwr_oe4,   he_pwr_oe4, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_lo                        (major_mode, pwr_lo,    ht_pwr_lo,    hrxc_pwr_lo,    hs_pwr_lo,    hisn_pwr_lo,    he_pwr_lo, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_hi                        (major_mode, pwr_hi,    ht_pwr_hi,    hrxc_pwr_hi,    hs_pwr_hi,    hisn_pwr_hi,    he_pwr_hi, 1'b0, 1'b0, 1'b0);
-mux8 mux_adc_clk               (major_mode, adc_clk,   ht_adc_clk,   hrxc_adc_clk,   hs_adc_clk,   hisn_adc_clk,   he_adc_clk, 1'b0, 1'b0, 1'b0);
-mux8 mux_dbg                   (major_mode, dbg,       ht_dbg,       hrxc_dbg,       hs_dbg,       hisn_dbg,       he_dbg, 1'b0, 1'b0, 1'b0);
+mux8 mux_ssp_clk               (major_mode, ssp_clk,   ht_ssp_clk,   hrxc_ssp_clk,   hs_ssp_clk,   hisn_ssp_clk,   he_ssp_clk,   gt_ssp_clk,   1'b0, 1'b0);
+mux8 mux_ssp_din               (major_mode, ssp_din,   ht_ssp_din,   hrxc_ssp_din,   hs_ssp_din,   hisn_ssp_din,   he_ssp_din,   gt_ssp_din,   1'b0, 1'b0);
+mux8 mux_ssp_frame             (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, gt_ssp_frame, 1'b0, 1'b0);
+mux8 mux_pwr_oe1               (major_mode, pwr_oe1,   ht_pwr_oe1,   hrxc_pwr_oe1,   hs_pwr_oe1,   hisn_pwr_oe1,   he_pwr_oe1,   1'b0,         1'b0, 1'b0);
+mux8 mux_pwr_oe2               (major_mode, pwr_oe2,   ht_pwr_oe2,   hrxc_pwr_oe2,   hs_pwr_oe2,   hisn_pwr_oe2,   he_pwr_oe2,   1'b0,         1'b0, 1'b0);
+mux8 mux_pwr_oe3               (major_mode, pwr_oe3,   ht_pwr_oe3,   hrxc_pwr_oe3,   hs_pwr_oe3,   hisn_pwr_oe3,   he_pwr_oe3,   1'b0,         1'b0, 1'b0);
+mux8 mux_pwr_oe4               (major_mode, pwr_oe4,   ht_pwr_oe4,   hrxc_pwr_oe4,   hs_pwr_oe4,   hisn_pwr_oe4,   he_pwr_oe4,   1'b0,         1'b0, 1'b0);
+mux8 mux_pwr_lo                        (major_mode, pwr_lo,    ht_pwr_lo,    hrxc_pwr_lo,    hs_pwr_lo,    hisn_pwr_lo,    he_pwr_lo,    1'b0,         1'b0, 1'b0);
+mux8 mux_pwr_hi                        (major_mode, pwr_hi,    ht_pwr_hi,    hrxc_pwr_hi,    hs_pwr_hi,    hisn_pwr_hi,    he_pwr_hi,    1'b0,         1'b0, 1'b0);
+mux8 mux_adc_clk               (major_mode, adc_clk,   ht_adc_clk,   hrxc_adc_clk,   hs_adc_clk,   hisn_adc_clk,   he_adc_clk,   1'b0,         1'b0, 1'b0);
+mux8 mux_dbg                   (major_mode, dbg,       ht_dbg,       hrxc_dbg,       hs_dbg,       hisn_dbg,       he_dbg,       1'b0,         1'b0, 1'b0);
 
 // In all modes, let the ADC's outputs be enabled.
 assign adc_noe = 1'b0;
diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v
new file mode 100644 (file)
index 0000000..7acecf8
--- /dev/null
@@ -0,0 +1,160 @@
+//-----------------------------------------------------------------------------
+//
+// piwi, Feb 2019
+//-----------------------------------------------------------------------------
+
+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;
+
+// constants for some major_modes:
+`define OFF        3'b111
+`define GET_TRACE  3'b101
+
+
+// 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'd3)
+               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 == `GET_TRACE)
+       begin
+               write_enable1 <= 1'b0;
+               write_enable2 <= 1'b0;
+               if (previous_major_mode != `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 != `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
+                                       addr <= addr + 1;
+                       end
+               end
+               else
+               begin
+                       write_enable1 <= 1'b0;
+                       write_enable2 <= 1'b0;
+                       start_addr <= addr;
+               end
+       end
+       else // major_mode == `OFF
+       begin
+               write_enable1 <= 1'b0;
+               write_enable2 <= 1'b0;
+               if (previous_major_mode != `OFF && previous_major_mode != `GET_TRACE) // just switched off
+                       start_addr <= addr;
+       end
+end
+
+
+// (2+1)k RAM
+reg [7:0] D_out1, D_out2;
+reg [7:0] ram1 [2047:0];
+reg [7:0] ram2 [1023:0];
+
+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                          // or shift left
+            shift_out[7:1] <= shift_out[6:0];
+       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
index 4c27ac85e4b4283fdd04b5f38670555ec31062da..ef282256cc23b6b7145d8c2250bd883d940e40d3 100644 (file)
@@ -220,6 +220,7 @@ typedef struct{
 #define CMD_MIFARE_DESFIRE                                                0x072e
 
 #define CMD_HF_SNIFFER                                                    0x0800
+#define CMD_HF_PLOT                                                       0x0801
 
 #define CMD_UNKNOWN                                                       0xFFFF
 
Impressum, Datenschutz