mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-20 23:06:25 +08:00
Added LF frequency adjustments from d18c7db, cleaned up code,
typo fixes in iso14443a code, added the missing "tools" directory, added initial elements for online/offline detection for commands.
This commit is contained in:
parent
974ba9a205
commit
30f2a7d38f
|
@ -87,8 +87,10 @@ void AcquireRawAdcSamples125k(BOOL at134khz)
|
|||
memset(dest,0,n);
|
||||
|
||||
if(at134khz) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
|
||||
} else {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
|
||||
}
|
||||
|
||||
|
@ -121,7 +123,7 @@ void AcquireRawAdcSamples125k(BOOL at134khz)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read an ADC channel and block till it completes, then return the result
|
||||
// in ADC units (0 to 1023). Also a routine to average sixteen samples and
|
||||
// in ADC units (0 to 1023). Also a routine to average 32 samples and
|
||||
// return that.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ReadAdc(int ch)
|
||||
|
@ -152,6 +154,29 @@ static int AvgAdc(int ch)
|
|||
|
||||
return (a + 15) >> 5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sweeps the useful LF range of the proxmark from
|
||||
* 46.8kHz (divisor=255) to 600kHz (divisor=19) and
|
||||
* reads the voltage in the antenna: the result is a graph
|
||||
* which should clearly show the resonating frequency of your
|
||||
* LF antenna ( hopefully around 90 if it is tuned to 125kHz!)
|
||||
*/
|
||||
void SweepLFrange()
|
||||
{
|
||||
BYTE *dest = (BYTE *)BigBuf;
|
||||
int i;
|
||||
|
||||
// clear buffer
|
||||
memset(BigBuf,0,sizeof(BigBuf));
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
|
||||
for (i=255; i>19; i--) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
||||
SpinDelay(20);
|
||||
dest[i] = (137500 * AvgAdc(4)) >> 18;
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureAntennaTuning(void)
|
||||
{
|
||||
|
@ -164,6 +189,7 @@ void MeasureAntennaTuning(void)
|
|||
UsbCommand c;
|
||||
|
||||
// Let the FPGA drive the low-frequency antenna around 125 kHz.
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
|
||||
SpinDelay(20);
|
||||
vLf125 = AvgAdc(4);
|
||||
|
@ -172,6 +198,7 @@ void MeasureAntennaTuning(void)
|
|||
vLf125 = (137500 * vLf125) >> 10;
|
||||
|
||||
// Let the FPGA drive the low-frequency antenna around 134 kHz.
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
|
||||
SpinDelay(20);
|
||||
vLf134 = AvgAdc(4);
|
||||
|
@ -207,7 +234,7 @@ void SimulateTagLowFrequency(int period)
|
|||
PIO_OUTPUT_DISABLE = (1 << GPIO_SSC_CLK);
|
||||
|
||||
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
|
||||
i = 0;
|
||||
for(;;) {
|
||||
|
@ -345,6 +372,7 @@ static void CmdHIDdemodFSK(void)
|
|||
int m=0, n=0, i=0, idx=0, found=0, lastval=0;
|
||||
DWORD hi=0, lo=0;
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
|
||||
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
|
@ -448,7 +476,7 @@ static void CmdHIDdemodFSK(void)
|
|||
dest[i++]=dest[idx-1];
|
||||
dest[i++]=dest[idx-1];
|
||||
break;
|
||||
// When a logic 0 is immediately followed by the start of the next transmisson
|
||||
// When a logic 0 is immediately followed by the start of the next transmisson
|
||||
// (special pattern) a pattern of 4 bit duration lengths is created.
|
||||
case 4:
|
||||
dest[i++]=dest[idx-1];
|
||||
|
@ -573,20 +601,19 @@ void UsbPacketReceived(BYTE *packet, int len)
|
|||
break;
|
||||
|
||||
case CMD_READER_ISO_15693:
|
||||
ReaderIso15693(c->ext1);
|
||||
ReaderIso15693(c->ext1);
|
||||
break;
|
||||
|
||||
case CMD_SIMTAG_ISO_15693:
|
||||
SimTagIso15693(c->ext1);
|
||||
SimTagIso15693(c->ext1);
|
||||
break;
|
||||
|
||||
|
||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
|
||||
AcquireRawAdcSamplesIso14443(c->ext1);
|
||||
break;
|
||||
|
||||
case CMD_READER_ISO_14443a:
|
||||
ReaderIso14443a(c->ext1);
|
||||
ReaderIso14443a(c->ext1);
|
||||
break;
|
||||
|
||||
case CMD_SNOOP_ISO_14443:
|
||||
|
@ -656,6 +683,14 @@ void UsbPacketReceived(BYTE *packet, int len)
|
|||
LCDReset();
|
||||
break;
|
||||
|
||||
case CMD_SWEEP_LF:
|
||||
SweepLFrange();
|
||||
break;
|
||||
|
||||
case CMD_SET_LF_DIVISOR:
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
|
||||
break;
|
||||
|
||||
case CMD_LCD:
|
||||
LCDSend(c->ext1);
|
||||
break;
|
||||
|
|
|
@ -19,6 +19,7 @@ extern BYTE ToSend[];
|
|||
extern DWORD BigBuf[];
|
||||
|
||||
/// fpga.c
|
||||
void FpgaSendCommand(WORD cmd, WORD v);
|
||||
void FpgaWriteConfWord(BYTE v);
|
||||
void FpgaDownloadAndGo(void);
|
||||
void FpgaSetupSsc(void);
|
||||
|
@ -26,6 +27,9 @@ void SetupSpi(int mode);
|
|||
void FpgaSetupSscDma(BYTE *buf, int len);
|
||||
void SetAdcMuxFor(int whichGpio);
|
||||
|
||||
// Definitions for the FPGA commands.
|
||||
#define FPGA_CMD_SET_CONFREG (1<<12)
|
||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||
// Definitions for the FPGA configuration word.
|
||||
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_SIMULATOR (1<<5)
|
||||
|
|
|
@ -53,7 +53,7 @@ void SetupSpi(int mode)
|
|||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||
( 0 << 4) | // Bits per Transfer (8 bits)
|
||||
( 8 << 4) | // Bits per Transfer (16 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
|
@ -185,15 +185,25 @@ void FpgaDownloadAndGo(void)
|
|||
LED_D_OFF();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send a 16 bit command/data pair to the FPGA.
|
||||
// The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
|
||||
// where C is the 4 bit command and D is the 12 bit data
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaSendCommand(WORD cmd, WORD v)
|
||||
{
|
||||
SetupSpi(SPI_FPGA_MODE);
|
||||
while ((SPI_STATUS & SPI_STATUS_TX_EMPTY) == 0); // wait for the transfer to complete
|
||||
SPI_TX_DATA = SPI_CONTROL_LAST_TRANSFER | cmd | v; // send the data
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Write the FPGA setup word (that determines what mode the logic is in, read
|
||||
// vs. clone vs. etc.).
|
||||
// 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(BYTE v)
|
||||
{
|
||||
SetupSpi(SPI_FPGA_MODE);
|
||||
while ((SPI_STATUS & SPI_STATUS_TX_EMPTY) == 0); // wait for the transfer to complete
|
||||
SPI_TX_DATA = SPI_CONTROL_LAST_TRANSFER | v; // send the data
|
||||
FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
10541
armsrc/fpgaimg.c
10541
armsrc/fpgaimg.c
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include <proxmark3.h>
|
||||
#include "apps.h"
|
||||
#include "..\common\iso14443_crc.c"
|
||||
#include "../common/iso14443_crc.c"
|
||||
|
||||
|
||||
//static void GetSamplesFor14443(BOOL weTx, int n);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include <proxmark3.h>
|
||||
#include "apps.h"
|
||||
#include "..\common\iso14443_crc.c"
|
||||
#include "../common/iso14443_crc.c"
|
||||
|
||||
typedef enum {
|
||||
SEC_D = 1,
|
||||
|
@ -1686,7 +1686,7 @@ void ReaderIso14443a(DWORD parameter)
|
|||
|
||||
// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in
|
||||
// which case we need to make a cascade 2 request and select - this is a long UID
|
||||
if (receivedAnswer[0] = 0x88)
|
||||
if (receivedAnswer[0] == 0x88)
|
||||
{
|
||||
// Do cascade level 2 stuff
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
################
|
||||
## 2009/04/09 ##
|
||||
################
|
||||
winsrc/gui.cpp
|
||||
Changes to PaintGraph to create X axis labels that are snapped to a power of two (useful when analysing low freq tags
|
||||
with cycle times that are a power of two). Also small changes to keep the X axis labels fixed within the graph window
|
||||
as the width of the graph window is resized.
|
||||
armsrc/apps.h
|
||||
New defines for FPGA commands FPGA_CMD_SET_CONFREG, FPGA_CMD_SET_DIVISOR_REG
|
||||
armsrc/appmain.c
|
||||
|
||||
armsrc/fpga.c
|
||||
FpgaWriteConfWord(data) is now a special case of FpgaSendCommand(FPGA_CMD_SET_CONFREG, data) to avoid changing every
|
||||
source file containing FpgaWriteConfWord()
|
||||
fpga/fpga.v
|
||||
Changes to the serial conf word, now takes a 4 bit command and 12 bit data code
|
||||
fpga/lo_read.v
|
||||
Significant changes to lo_read, it now can be configured with a divisor value to produce a configurable drive clock
|
||||
for the antenna.
|
||||
Recompiled FPGA code
|
||||
|
||||
################
|
||||
## 2009/04/09 ##
|
||||
################
|
||||
|
|
25
fpga/fpga.v
25
fpga/fpga.v
|
@ -21,7 +21,7 @@
|
|||
`include "util.v"
|
||||
|
||||
module fpga(
|
||||
spck, miso, mosi, ncs,
|
||||
spcki, miso, mosi, ncs,
|
||||
pck0i, ck_1356meg, ck_1356megb,
|
||||
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||
adc_d, adc_clk, adc_noe,
|
||||
|
@ -29,7 +29,7 @@ module fpga(
|
|||
cross_hi, cross_lo,
|
||||
dbg
|
||||
);
|
||||
input spck, mosi, ncs;
|
||||
input spcki, mosi, ncs;
|
||||
output miso;
|
||||
input pck0i, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
|
@ -40,11 +40,16 @@ module fpga(
|
|||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
|
||||
//assign pck0 = pck0i;
|
||||
IBUFG #(.IOSTANDARD("DEFAULT") ) pck0b(
|
||||
.O(pck0),
|
||||
.I(pck0i)
|
||||
);
|
||||
//assign pck0 = pck0i;
|
||||
//assign spck = spcki;
|
||||
IBUFG #(.IOSTANDARD("DEFAULT") ) spckb(
|
||||
.O(spck),
|
||||
.I(spcki)
|
||||
);
|
||||
//-----------------------------------------------------------------------------
|
||||
// The SPI receiver. This sets up the configuration word, which the rest of
|
||||
// the logic looks at to determine how to connect the A/D and the coil
|
||||
|
@ -52,7 +57,8 @@ module fpga(
|
|||
// to the configuration bits, for use below.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
reg [7:0] conf_word_shift;
|
||||
reg [15:0] shift_reg;
|
||||
reg [7:0] divisor;
|
||||
reg [7:0] conf_word;
|
||||
|
||||
// We switch modes between transmitting to the 13.56 MHz tag and receiving
|
||||
|
@ -60,15 +66,18 @@ reg [7:0] conf_word;
|
|||
// glitching, or else we will glitch the transmitted carrier.
|
||||
always @(posedge ncs)
|
||||
begin
|
||||
conf_word <= conf_word_shift;
|
||||
case(shift_reg[15:12])
|
||||
4'b0001: conf_word <= shift_reg[7:0];
|
||||
4'b0010: divisor <= shift_reg[7:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge spck)
|
||||
begin
|
||||
if(~ncs)
|
||||
begin
|
||||
conf_word_shift[7:1] <= conf_word_shift[6:0];
|
||||
conf_word_shift[0] <= mosi;
|
||||
shift_reg[15:1] <= shift_reg[14:0];
|
||||
shift_reg[0] <= mosi;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -110,7 +119,7 @@ lo_read lr(
|
|||
lr_ssp_frame, lr_ssp_din, ssp_dout, lr_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
lr_dbg,
|
||||
lo_is_125khz
|
||||
lo_is_125khz, divisor
|
||||
);
|
||||
|
||||
lo_simulate ls(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// The way that we connect things in low-frequency read mode. In this case
|
||||
// we are generating the 134 kHz or 125 kHz carrier, and running the
|
||||
// we are generating the 134 kHz or 125 kHz carrier, and running the
|
||||
// unmodulated carrier at that frequency. The A/D samples at that same rate,
|
||||
// and the result is serialized.
|
||||
//
|
||||
|
@ -14,7 +14,7 @@ module lo_read(
|
|||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
lo_is_125khz
|
||||
lo_is_125khz, divisor
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
|
@ -25,6 +25,7 @@ module lo_read(
|
|||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input lo_is_125khz;
|
||||
input [7:0] divisor;
|
||||
|
||||
// The low-frequency RFID stuff. This is relatively simple, because most
|
||||
// of the work happens on the ARM, and we just pass samples through. The
|
||||
|
@ -38,65 +39,39 @@ module lo_read(
|
|||
// 125 kHz by dividing by a further factor of (8*12*2), or ~134 kHz by
|
||||
// dividing by a factor of (8*11*2) (for 136 kHz, ~2% error, tolerable).
|
||||
|
||||
reg [3:0] pck_divider;
|
||||
reg clk_lo;
|
||||
reg [7:0] to_arm_shiftreg;
|
||||
reg [7:0] pck_divider;
|
||||
reg [6:0] ssp_divider;
|
||||
reg ant_lo;
|
||||
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if(lo_is_125khz)
|
||||
begin
|
||||
if(pck_divider == 4'd11)
|
||||
begin
|
||||
pck_divider <= 4'd0;
|
||||
clk_lo = !clk_lo;
|
||||
end
|
||||
else
|
||||
pck_divider <= pck_divider + 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(pck_divider == 4'd10)
|
||||
begin
|
||||
pck_divider <= 4'd0;
|
||||
clk_lo = !clk_lo;
|
||||
end
|
||||
else
|
||||
pck_divider <= pck_divider + 1;
|
||||
end
|
||||
if(pck_divider == 8'd0)
|
||||
begin
|
||||
pck_divider <= divisor[7:0];
|
||||
ant_lo = !ant_lo;
|
||||
if(ant_lo == 1'b0)
|
||||
begin
|
||||
ssp_divider <= 7'b0011111;
|
||||
to_arm_shiftreg <= adc_d;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
pck_divider <= pck_divider - 1;
|
||||
if(ssp_divider[6] == 1'b0)
|
||||
begin
|
||||
if (ssp_divider[1:0] == 1'b11) to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];
|
||||
ssp_divider <= ssp_divider - 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [2:0] carrier_divider_lo;
|
||||
|
||||
always @(posedge clk_lo)
|
||||
begin
|
||||
carrier_divider_lo <= carrier_divider_lo + 1;
|
||||
end
|
||||
|
||||
assign pwr_lo = carrier_divider_lo[2];
|
||||
|
||||
// This serializes the values returned from the A/D, and sends them out
|
||||
// over the SSP.
|
||||
|
||||
reg [7:0] to_arm_shiftreg;
|
||||
|
||||
always @(posedge clk_lo)
|
||||
begin
|
||||
if(carrier_divider_lo == 3'b000)
|
||||
to_arm_shiftreg <= adc_d;
|
||||
else
|
||||
to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];
|
||||
end
|
||||
|
||||
assign ssp_clk = clk_lo;
|
||||
assign ssp_frame = (carrier_divider_lo == 3'b001);
|
||||
assign ssp_din = to_arm_shiftreg[7];
|
||||
|
||||
// The ADC converts on the falling edge, and our serializer loads when
|
||||
// carrier_divider_lo == 3'b000.
|
||||
assign adc_clk = ~carrier_divider_lo[2];
|
||||
|
||||
assign ssp_clk = pck_divider[1];
|
||||
assign ssp_frame = ~ssp_divider[5];
|
||||
assign pwr_hi = 1'b0;
|
||||
|
||||
assign pwr_lo = ant_lo;
|
||||
assign adc_clk = ~ant_lo;
|
||||
assign dbg = adc_clk;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
`include "lo_read_org.v"
|
||||
`include "lo_read.v"
|
||||
|
||||
/*
|
||||
pck0 - input main 24Mhz clock (PLL / 4)
|
||||
[7:0] adc_d - input data from A/D converter
|
||||
|
@ -29,6 +29,7 @@ module testbed_lo_read;
|
|||
reg pck0;
|
||||
reg [7:0] adc_d;
|
||||
reg lo_is_125khz;
|
||||
reg [15:0] divisor;
|
||||
|
||||
wire pwr_lo;
|
||||
wire adc_clk;
|
||||
|
@ -47,38 +48,61 @@ module testbed_lo_read;
|
|||
wire cross_hi;
|
||||
wire dbg;
|
||||
|
||||
lo_read #(5,200) dut(
|
||||
lo_read_org #(5,10) dut1(
|
||||
.pck0(pck0),
|
||||
.ck_1356meg(ck_1356meg),
|
||||
.ck_1356megb(ck_1356megb),
|
||||
.pwr_lo(pwr_lo),
|
||||
.pwr_hi(pwr_hi),
|
||||
.pwr_oe1(pwr_oe1),
|
||||
.pwr_oe2(pwr_oe2),
|
||||
.pwr_oe3(pwr_oe3),
|
||||
.pwr_oe4(pwr_oe4),
|
||||
.ck_1356meg(ack_1356meg),
|
||||
.ck_1356megb(ack_1356megb),
|
||||
.pwr_lo(apwr_lo),
|
||||
.pwr_hi(apwr_hi),
|
||||
.pwr_oe1(apwr_oe1),
|
||||
.pwr_oe2(apwr_oe2),
|
||||
.pwr_oe3(apwr_oe3),
|
||||
.pwr_oe4(apwr_oe4),
|
||||
.adc_d(adc_d),
|
||||
.adc_clk(adc_clk),
|
||||
.ssp_frame(ssp_frame),
|
||||
.ssp_din(ssp_din),
|
||||
.ssp_dout(ssp_dout),
|
||||
.ssp_clk(ssp_clk),
|
||||
.cross_hi(cross_hi),
|
||||
.cross_lo(cross_lo),
|
||||
.dbg(dbg),
|
||||
.ssp_frame(assp_frame),
|
||||
.ssp_din(assp_din),
|
||||
.ssp_dout(assp_dout),
|
||||
.ssp_clk(assp_clk),
|
||||
.cross_hi(across_hi),
|
||||
.cross_lo(across_lo),
|
||||
.dbg(adbg),
|
||||
.lo_is_125khz(lo_is_125khz)
|
||||
);
|
||||
|
||||
integer idx, i;
|
||||
lo_read #(5,10) dut2(
|
||||
.pck0(pck0),
|
||||
.ck_1356meg(bck_1356meg),
|
||||
.ck_1356megb(bck_1356megb),
|
||||
.pwr_lo(bpwr_lo),
|
||||
.pwr_hi(bpwr_hi),
|
||||
.pwr_oe1(bpwr_oe1),
|
||||
.pwr_oe2(bpwr_oe2),
|
||||
.pwr_oe3(bpwr_oe3),
|
||||
.pwr_oe4(bpwr_oe4),
|
||||
.adc_d(adc_d),
|
||||
.adc_clk(badc_clk),
|
||||
.ssp_frame(bssp_frame),
|
||||
.ssp_din(bssp_din),
|
||||
.ssp_dout(bssp_dout),
|
||||
.ssp_clk(bssp_clk),
|
||||
.cross_hi(bcross_hi),
|
||||
.cross_lo(bcross_lo),
|
||||
.dbg(bdbg),
|
||||
.lo_is_125khz(lo_is_125khz),
|
||||
.divisor(divisor)
|
||||
);
|
||||
|
||||
integer idx, i, adc_val=8;
|
||||
|
||||
// main clock
|
||||
always #5 pck0 = !pck0;
|
||||
|
||||
//new A/D value available from ADC on positive edge
|
||||
task crank_dut;
|
||||
begin
|
||||
@(posedge adc_clk) ;
|
||||
adc_d = $random;
|
||||
adc_d = adc_val;
|
||||
adc_val = (adc_val *2) + 53;
|
||||
end
|
||||
endtask
|
||||
|
||||
|
@ -87,19 +111,13 @@ module testbed_lo_read;
|
|||
// init inputs
|
||||
pck0 = 0;
|
||||
adc_d = 0;
|
||||
|
||||
// simulate 4 A/D cycles at 134Khz
|
||||
lo_is_125khz=0;
|
||||
for (i = 0 ; i < 4 ; i = i + 1) begin
|
||||
crank_dut;
|
||||
end
|
||||
lo_is_125khz = 1;
|
||||
divisor=255; //min 19, 95=125Khz, max 255
|
||||
|
||||
// simulate 4 A/D cycles at 125Khz
|
||||
lo_is_125khz=1;
|
||||
for (i = 0 ; i < 4 ; i = i + 1) begin
|
||||
for (i = 0 ; i < 8 ; i = i + 1) begin
|
||||
crank_dut;
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // main
|
||||
|
|
|
@ -44,6 +44,8 @@ typedef struct {
|
|||
#define CMD_SIMULATE_TAG_125K 0x0207
|
||||
#define CMD_HID_DEMOD_FSK 0x0208 // ## New command: demodulate HID tag ID
|
||||
#define CMD_HID_SIM_TAG 0x0209 // ## New command: simulate HID tag by ID
|
||||
#define CMD_SET_LF_DIVISOR 0x020A
|
||||
#define CMD_SWEEP_LF 0x020B
|
||||
|
||||
// For the 13.56 MHz tags
|
||||
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
|
||||
|
@ -58,7 +60,6 @@ typedef struct {
|
|||
#define CMD_SNOOP_ISO_14443a 0x0383 // ## New snoop command
|
||||
#define CMD_SIMULATE_TAG_ISO_14443a 0x0384 // ## New command: Simulate tag 14443a
|
||||
#define CMD_READER_ISO_14443a 0x0385 // ## New command to act like a 14443a reader
|
||||
|
||||
#define CMD_SIMULATE_MIFARE_CARD 0x0386
|
||||
|
||||
// For measurements of the antenna tuning
|
||||
|
@ -67,5 +68,6 @@ typedef struct {
|
|||
|
||||
// For direct FPGA control
|
||||
#define CMD_FPGA_MAJOR_MODE_OFF 0x0500 // ## FPGA Control
|
||||
#define CMD_TEST 0x0501
|
||||
|
||||
#endif
|
||||
|
|
18
tools/merge-srec.pl
Normal file
18
tools/merge-srec.pl
Normal file
|
@ -0,0 +1,18 @@
|
|||
# merge the code that initially executes out of flash with the RAM image
|
||||
|
||||
($flashFile, $ramFile) = @ARGV;
|
||||
|
||||
open(FLASH, $flashFile) or die "$flashFile: $!\n";
|
||||
|
||||
while(<FLASH>) {
|
||||
print if /^S3/;
|
||||
}
|
||||
|
||||
open(RAM, $ramFile) or die "$ramFile: $!\n";
|
||||
|
||||
while(<RAM>) {
|
||||
if(/^S3(..)(........)(.*)/) {
|
||||
$addr = sprintf('%08X', hex($2) - 0x00200000 + 0x200);
|
||||
print "S3$1$addr$3\n";
|
||||
}
|
||||
}
|
39
tools/rbt2c.pl
Normal file
39
tools/rbt2c.pl
Normal file
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# This tool converts a Xilinx xxx.rbt FPGA bitstream to a table that will
|
||||
# compile as C source code. The output format is DWORDs, MSB first.
|
||||
|
||||
print "// Generated by rbt2c.pl, do not edit!\n\n";
|
||||
|
||||
for(1..7) {
|
||||
chomp($_ = <>);
|
||||
print "//// $_\n";
|
||||
}
|
||||
|
||||
print <<EOT;
|
||||
|
||||
#include <proxmark3.h>
|
||||
|
||||
const DWORD FpgaImage[] = {
|
||||
EOT
|
||||
|
||||
while(<>) {
|
||||
chomp;
|
||||
$v = 0;
|
||||
for $b (split(//, $_)) {
|
||||
$v <<= 1;
|
||||
if($b eq '1') {
|
||||
$v |= 1;
|
||||
} elsif($b ne '0') {
|
||||
die;
|
||||
}
|
||||
}
|
||||
printf("\t0x%08x,\n", $v);
|
||||
}
|
||||
|
||||
print <<EOT;
|
||||
};
|
||||
|
||||
const DWORD FpgaImageLen = sizeof(FpgaImage) / sizeof(FpgaImage[0]);
|
||||
|
||||
EOT
|
35
tools/srecswap.pl
Normal file
35
tools/srecswap.pl
Normal file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# endian-swap S records; we need this because the JTAG tools we're using
|
||||
# expect the memory image in byte-swapped format
|
||||
#
|
||||
# Jonathan Westhues, April 2004
|
||||
|
||||
if(@ARGV == 0) {
|
||||
die "usage: $0 file-to-endian-swap.s19 > out.s19\n";
|
||||
}
|
||||
|
||||
while(<>) {
|
||||
chomp;
|
||||
|
||||
if(/^S0/) {
|
||||
next;
|
||||
}
|
||||
if(/^S7/) {
|
||||
print "$_\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if(not /^S3(..)(........)(.*)(..)$/) {
|
||||
die "bad S record at line $.\n";
|
||||
}
|
||||
|
||||
$data = $3;
|
||||
$checksum = $4;
|
||||
|
||||
print "S3$1$2";
|
||||
while($data =~ m#(..)(..)(..)(..)#g) {
|
||||
print "$4$3$2$1";
|
||||
}
|
||||
print "$checksum\n";
|
||||
}
|
|
@ -1598,6 +1598,7 @@ static void Cmdaskdemod(char *str) {
|
|||
* routine, feel free to improve...
|
||||
*
|
||||
* 1st argument: clock rate (as number of samples per clock rate)
|
||||
* Typical values can be 64, 32, 128...
|
||||
*/
|
||||
static void Cmdmanchesterdemod(char *str) {
|
||||
int i;
|
||||
|
@ -1605,18 +1606,23 @@ static void Cmdmanchesterdemod(char *str) {
|
|||
int lastval;
|
||||
int lc = 0;
|
||||
int bitidx = 0;
|
||||
int bitidx2;
|
||||
int bit2idx = 0;
|
||||
|
||||
|
||||
sscanf(str, "%i", &clock);
|
||||
|
||||
int tolerance = clock/4;
|
||||
/* Holds the decoded bitstream. */
|
||||
int BitStream[MAX_GRAPH_TRACE_LEN*2];
|
||||
int BitStream2[MAX_GRAPH_TRACE_LEN];
|
||||
/* Holds the decoded bitstream: each clock period contains 2 bits */
|
||||
/* later simplified to 1 bit after manchester decoding. */
|
||||
/* Add 10 bits to allow for noisy / uncertain traces without aborting */
|
||||
/* int BitStream[GraphTraceLen*2/clock+10]; */
|
||||
|
||||
/* But it does not work if compiling on WIndows: therefore we just allocate a */
|
||||
/* large array */
|
||||
int BitStream[MAX_GRAPH_TRACE_LEN];
|
||||
|
||||
/* Detect first transition */
|
||||
/* Lo-Hi (arbitrary) */
|
||||
/* Lo-Hi (arbitrary) */
|
||||
for(i=1;i<GraphTraceLen;i++) {
|
||||
if (GraphBuffer[i-1]<GraphBuffer[i]) {
|
||||
lastval = i;
|
||||
|
@ -1626,18 +1632,24 @@ static void Cmdmanchesterdemod(char *str) {
|
|||
}
|
||||
|
||||
/* Then detect duration between 2 successive transitions */
|
||||
/* At this stage, GraphTrace is either 0 or 1 */
|
||||
for(bitidx = 1 ;i<GraphTraceLen;i++) {
|
||||
if (GraphBuffer[i-1] != GraphBuffer[i]) {
|
||||
lc = i-lastval;
|
||||
lastval = i;
|
||||
// Error check: if bitidx becomes too large, we do not
|
||||
// have a Manchester encoded bitstream or the clock is really
|
||||
// wrong!
|
||||
if (bitidx > (GraphTraceLen*2/clock+8) ) {
|
||||
PrintToScrollback("Error: the clock you gave is probably wrong, aborting.");
|
||||
return;
|
||||
}
|
||||
// Then switch depending on lc length:
|
||||
// Tolerance is 1/4 of clock rate (arbitrary)
|
||||
if ((lc-clock/2) < tolerance) {
|
||||
// Short pulse
|
||||
if (abs(lc-clock/2) < tolerance) {
|
||||
// Short pulse : either "1" or "0"
|
||||
BitStream[bitidx++]=GraphBuffer[i-1];
|
||||
} else if ((lc-clock) < tolerance) {
|
||||
// Long pulse
|
||||
} else if (abs(lc-clock) < tolerance) {
|
||||
// Long pulse: either "11" or "00"
|
||||
BitStream[bitidx++]=GraphBuffer[i-1];
|
||||
BitStream[bitidx++]=GraphBuffer[i-1];
|
||||
} else {
|
||||
|
@ -1649,39 +1661,41 @@ static void Cmdmanchesterdemod(char *str) {
|
|||
}
|
||||
|
||||
// At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
|
||||
for (bitidx2 = 0; bitidx2<bitidx; bitidx2 += 2) {
|
||||
if ((BitStream[bitidx2] == 0) && (BitStream[bitidx2+1] == 1)) {
|
||||
BitStream2[bitidx2/2] = 1;
|
||||
} else if ((BitStream[bitidx2] == 1) && (BitStream[bitidx2+1] == 0)) {
|
||||
BitStream2[bitidx2/2] = 0;
|
||||
// Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
|
||||
// to stop output at the final bitidx2 value, not bitidx
|
||||
for (i = 0; i < bitidx; i += 2) {
|
||||
if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
|
||||
BitStream[bit2idx++] = 1;
|
||||
} else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
|
||||
BitStream[bit2idx++] = 0;
|
||||
} else {
|
||||
// We cannot end up in this state, this means we are unsynchronized,
|
||||
// move up 1 bit:
|
||||
bitidx2++;
|
||||
i++;
|
||||
PrintToScrollback("Unsynchronized, resync...");
|
||||
PrintToScrollback("(too many of those messages mean the stream is not Manchester encoded)");
|
||||
}
|
||||
}
|
||||
PrintToScrollback("Manchester decoded bitstream \n---------");
|
||||
// Now output the bitstream to the scrollback by line of 16 bits
|
||||
for (i = 0; i<bitidx/2; i+=16) {
|
||||
for (i = 0; i < (bit2idx-16); i+=16) {
|
||||
PrintToScrollback("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
|
||||
BitStream2[i],
|
||||
BitStream2[i+1],
|
||||
BitStream2[i+2],
|
||||
BitStream2[i+3],
|
||||
BitStream2[i+4],
|
||||
BitStream2[i+5],
|
||||
BitStream2[i+6],
|
||||
BitStream2[i+7],
|
||||
BitStream2[i+8],
|
||||
BitStream2[i+9],
|
||||
BitStream2[i+10],
|
||||
BitStream2[i+11],
|
||||
BitStream2[i+12],
|
||||
BitStream2[i+13],
|
||||
BitStream2[i+14],
|
||||
BitStream2[i+15]);
|
||||
BitStream[i],
|
||||
BitStream[i+1],
|
||||
BitStream[i+2],
|
||||
BitStream[i+3],
|
||||
BitStream[i+4],
|
||||
BitStream[i+5],
|
||||
BitStream[i+6],
|
||||
BitStream[i+7],
|
||||
BitStream[i+8],
|
||||
BitStream[i+9],
|
||||
BitStream[i+10],
|
||||
BitStream[i+11],
|
||||
BitStream[i+12],
|
||||
BitStream[i+13],
|
||||
BitStream[i+14],
|
||||
BitStream[i+15]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1805,6 +1819,32 @@ static void CmdLcd(char *str)
|
|||
static void CmdTest(char *str)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the divisor for LF frequency clock: lets the user choose any LF frequency below
|
||||
* 600kHz.
|
||||
*/
|
||||
static void CmdSetDivisor(char *str)
|
||||
{
|
||||
UsbCommand c;
|
||||
c.cmd = CMD_SET_LF_DIVISOR;
|
||||
c.ext1 = atoi(str);
|
||||
if (( c.ext1<0) || (c.ext1>255)) {
|
||||
PrintToScrollback("divisor must be between 19 and 255");
|
||||
} else {
|
||||
SendCommand(&c, FALSE);
|
||||
PrintToScrollback("Divisor set, expected freq=%dHz", 12000000/(c.ext1+1));
|
||||
}
|
||||
}
|
||||
|
||||
static void CmdSweepLF(char *str)
|
||||
{
|
||||
UsbCommand c;
|
||||
c.cmd = CMD_SWEEP_LF;
|
||||
SendCommand(&c, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef void HandlerFunction(char *cmdline);
|
||||
|
||||
|
@ -1863,6 +1903,8 @@ static struct {
|
|||
"lcdreset", CmdLcdReset, "Hardware reset LCD",
|
||||
"lcd", CmdLcd, "Send command/data to LCD",
|
||||
"test", CmdTest, "Placeholder command for testing new code",
|
||||
"setlfdivisor", CmdSetDivisor, "Drive LF antenna at 12Mhz/(divisor+1)",
|
||||
"sweeplf", CmdSweepLF, "Sweep through LF freq range and store results in buffer",
|
||||
"quit", CmdQuit, "quit program"
|
||||
};
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ void ExecCmd(char *cmd)
|
|||
|
||||
}
|
||||
int CommandFinished;
|
||||
int offset = 64;
|
||||
|
||||
static void ResizeCommandWindow(void)
|
||||
{
|
||||
|
@ -122,8 +123,8 @@ static void PaintGraph(HDC hdc)
|
|||
|
||||
SelectObject(hdc, WhitePen);
|
||||
|
||||
MoveToEx(hdc, r.left + 40, r.top, NULL);
|
||||
LineTo(hdc, r.left + 40, r.bottom);
|
||||
MoveToEx(hdc, r.left + offset, r.top, NULL);
|
||||
LineTo(hdc, r.left + offset, r.bottom);
|
||||
|
||||
int zeroHeight = r.top + (r.bottom - r.top) / 2;
|
||||
SelectObject(hdc, GreyPen);
|
||||
|
@ -131,7 +132,7 @@ static void PaintGraph(HDC hdc)
|
|||
LineTo(hdc, r.right, zeroHeight);
|
||||
|
||||
int startMax =
|
||||
(GraphTraceLen - (int)((r.right - r.left - 40) / GraphPixelsPerPoint));
|
||||
(GraphTraceLen - (int)((r.right - r.left - offset) / GraphPixelsPerPoint));
|
||||
if(startMax < 0) {
|
||||
startMax = 0;
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ static void PaintGraph(HDC hdc)
|
|||
if(fabs((double)GraphBuffer[i]) > absYMax) {
|
||||
absYMax = (int)fabs((double)GraphBuffer[i]);
|
||||
}
|
||||
int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
|
||||
int x = offset + (int)((i - GraphStart)*GraphPixelsPerPoint);
|
||||
if(x > r.right) {
|
||||
break;
|
||||
}
|
||||
|
@ -163,12 +164,15 @@ static void PaintGraph(HDC hdc)
|
|||
SetBkColor(hdc, RGB(0, 0, 0));
|
||||
|
||||
// number of points that will be plotted
|
||||
int span = (int)((r.right - r.left) / GraphPixelsPerPoint);
|
||||
// one label every 100 pixels, let us say
|
||||
int labels = (r.right - r.left - 40) / 100;
|
||||
double span = (int)((r.right - r.left) / GraphPixelsPerPoint);
|
||||
|
||||
// one label every offset pixels, let us say
|
||||
int labels = (r.right - r.left - offset) / offset;
|
||||
if(labels <= 0) labels = 1;
|
||||
int pointsPerLabel = span / labels;
|
||||
// round to nearest power of 2
|
||||
int pointsPerLabel = (int)(log(span / labels)/log(2.0));
|
||||
if(pointsPerLabel <= 0) pointsPerLabel = 1;
|
||||
pointsPerLabel = (int)pow(2.0,pointsPerLabel);
|
||||
|
||||
int yMin = INT_MAX;
|
||||
int yMax = INT_MIN;
|
||||
|
@ -179,7 +183,7 @@ static void PaintGraph(HDC hdc)
|
|||
if(i >= GraphTraceLen) {
|
||||
break;
|
||||
}
|
||||
int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
|
||||
int x = offset + (int)((i - GraphStart)*GraphPixelsPerPoint);
|
||||
if(x > r.right + GraphPixelsPerPoint) {
|
||||
break;
|
||||
}
|
||||
|
@ -212,8 +216,8 @@ static void PaintGraph(HDC hdc)
|
|||
|
||||
if(((i - GraphStart) % pointsPerLabel == 0) && i != GraphStart) {
|
||||
SelectObject(hdc, WhitePen);
|
||||
MoveToEx(hdc, x, zeroHeight - 3, NULL);
|
||||
LineTo(hdc, x, zeroHeight + 3);
|
||||
MoveToEx(hdc, x, zeroHeight - 8, NULL);
|
||||
LineTo(hdc, x, zeroHeight + 8);
|
||||
|
||||
char str[100];
|
||||
sprintf(str, "+%d", (i - GraphStart));
|
||||
|
@ -244,9 +248,9 @@ static void PaintGraph(HDC hdc)
|
|||
}
|
||||
|
||||
char str[100];
|
||||
sprintf(str, "@%d max=%d min=%d mean=%d n=%d/%d dt=%d [%.3f]",
|
||||
sprintf(str, "@%d max=%d min=%d mean=%d n=%d/%d dt=%d [%.3f] zoom=%.3f",
|
||||
GraphStart, yMax, yMin, yMean, n, GraphTraceLen,
|
||||
CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor);
|
||||
CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor, GraphPixelsPerPoint);
|
||||
TextOut(hdc, 50, r.bottom - 20, str, strlen(str));
|
||||
}
|
||||
|
||||
|
@ -277,28 +281,28 @@ static LRESULT CALLBACK
|
|||
case WM_KEYDOWN:
|
||||
switch(wParam) {
|
||||
case VK_DOWN:
|
||||
if(GraphPixelsPerPoint <= 50) {
|
||||
if(GraphPixelsPerPoint <= 8) {
|
||||
GraphPixelsPerPoint *= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_UP:
|
||||
if(GraphPixelsPerPoint >= 0.02) {
|
||||
if(GraphPixelsPerPoint >= 0.01) {
|
||||
GraphPixelsPerPoint /= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_RIGHT:
|
||||
if(GraphPixelsPerPoint < 20) {
|
||||
GraphStart += (int)(20 / GraphPixelsPerPoint);
|
||||
if(GraphPixelsPerPoint < 16) {
|
||||
GraphStart += (int)(16 / GraphPixelsPerPoint);
|
||||
} else {
|
||||
GraphStart++;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_LEFT:
|
||||
if(GraphPixelsPerPoint < 20) {
|
||||
GraphStart -= (int)(20 / GraphPixelsPerPoint);
|
||||
if(GraphPixelsPerPoint < 16) {
|
||||
GraphStart -= (int)(16 / GraphPixelsPerPoint);
|
||||
} else {
|
||||
GraphStart--;
|
||||
}
|
||||
|
@ -314,7 +318,7 @@ nopaint:
|
|||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN: {
|
||||
int x = LOWORD(lParam);
|
||||
x -= 40;
|
||||
x -= offset;
|
||||
x = (int)(x / GraphPixelsPerPoint);
|
||||
x += GraphStart;
|
||||
if(msg == WM_LBUTTONDOWN) {
|
||||
|
|
Loading…
Reference in a new issue