1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
17 // The FPGA is responsible for interfacing between the A/D, the coil drivers,
18 // and the ARM. In the low-frequency modes it passes the data straight
19 // through, so that the ARM gets raw A/D samples over the SSP. In the high-
20 // frequency modes, the FPGA might perform some demodulation first, to
21 // reduce the amount of data that we must send to the ARM.
22 //-----------------------------------------------------------------------------
24 // These defines are for reference only, they are passed by the Makefile so do not uncomment them here
25 // Proxmark3 RDV4 target
27 // Proxmark3 generic target
29 // iCopy-X with XC3S100E
32 // Pass desired defines to compiler to enable required modules
33 // WITH_LF enables Low Frequency mode when defined else HF is enabled
35 // WITH_LF0 enables module reader
37 // WITH_LF1 enables module edge detect
39 // WITH_LF2 enables module passthrough
41 // WITH_LF3 enables module ADC
44 // WITH_HF0 enables module HF reader
46 // WITH_HF1 enables module simulated tag
48 // WITH_HF2 enables module ISO14443-A
50 // WITH_HF3 enables module sniff
52 // WITH_HF4 enables module ISO18092 FeliCa
54 // WITH_HF5 enables module get trace
57 //`ifdef WITH_LF `include "clk_divider.v" `endif
58 //`ifdef WITH_LF0 `include "lo_read.v" `endif
59 //`ifdef WITH_LF1 `include "lo_edge_detect.v" `endif
60 //`ifdef WITH_LF2 `include "lo_passthru.v" `endif
61 //`ifdef WITH_LF3 `include "lo_adc.v" `endif
63 //`ifdef WITH_HF0 `include "hi_reader.v" `endif
64 //`ifdef WITH_HF1 `include "hi_simulate.v" `endif
65 //`ifdef WITH_HF2 `include "hi_iso14443a.v" `endif
66 //`ifdef WITH_HF3 `include "hi_sniffer.v" `endif
67 //`ifdef WITH_HF4 `include "hi_flite.v" `endif
68 //`ifdef WITH_HF5 `include "hi_get_trace.v" `endif
97 // In all modes, let the ADC's outputs be enabled.
98 assign adc_noe
= 1'b0;
100 //-----------------------------------------------------------------------------
101 // The SPI receiver. This sets up the configuration word, which the rest of
102 // the logic looks at to determine how to connect the A/D and the coil
103 // drivers (i.e., which section gets it). Also assign some symbolic names
104 // to the configuration bits, for use below.
105 //-----------------------------------------------------------------------------
107 // Receive 16bits of data from ARM here.
108 reg [15:0] shift_reg
;
109 always @(posedge spck
) if (~ncs
) shift_reg
<= {shift_reg
[14:0], mosi
};
113 reg [7:0] lf_ed_threshold
;
114 reg [5:0] hf_edge_detect_threshold
;
115 reg [5:0] hf_edge_detect_threshold_high
;
117 // adjustable frequency clock
121 clk_divider
div_clk(pck0
, divisor
, pck_cnt
, pck_divclk
);
124 reg [11:0] conf_word
;
131 hf_edge_detect_threshold
<= 7;
132 hf_edge_detect_threshold_high
<= 20;
135 // We switch modes between transmitting to the 13.56 MHz tag and receiving
136 // from it, which means that we must make sure that we can do so without
137 // glitching, or else we will glitch the transmitted carrier.
138 always @(posedge ncs
)
141 case (shift_reg
[15:12])
143 `FPGA_CMD_SET_CONFREG:
146 conf_word
<= shift_reg
[11:0];
147 if (shift_reg
[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) lf_ed_threshold <= 127; // default threshold
150 `FPGA_CMD_SET_DIVISOR:
151 divisor
<= shift_reg
[7:0]; // 8bits
153 `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD:
154 lf_ed_threshold
<= shift_reg
[7:0]; // 8 bits
156 `FPGA_CMD_SET_CONFREG: conf_word <= shift_reg[8:0];
157 `FPGA_CMD_TRACE_ENABLE: trace_enable <= shift_reg[0];
158 `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD:
160 hf_edge_detect_threshold
<= shift_reg
[5:0];
161 hf_edge_detect_threshold_high
<= shift_reg
[11:6];
167 //-----------------------------------------------------------------------------
168 // And then we instantiate the modules corresponding to each of the FPGA's
169 // major modes, and use muxes to connect the outputs of the active mode to
171 //-----------------------------------------------------------------------------
173 // ############################################################################
174 // # Enable Low Frequency Modules
177 // LF reader (generic)
181 .
pck_divclk (pck_divclk
),
184 .
lf_field (conf_word
[0]),
186 .
ssp_din (mux0_ssp_din
),
187 .
ssp_frame (mux0_ssp_frame
),
188 .
ssp_clk (mux0_ssp_clk
),
189 .
adc_clk (mux0_adc_clk
),
190 .
pwr_lo (mux0_pwr_lo
),
191 .
pwr_hi (mux0_pwr_hi
),
192 .
pwr_oe1 (mux0_pwr_oe1
),
193 .
pwr_oe2 (mux0_pwr_oe2
),
194 .
pwr_oe3 (mux0_pwr_oe3
),
195 .
pwr_oe4 (mux0_pwr_oe4
),
200 // LF edge detect (generic)
204 .
pck_divclk (pck_divclk
),
206 .
cross_lo (cross_lo
),
207 .
lf_field (conf_word
[0]),
208 .
lf_ed_toggle_mode (conf_word
[1]),
209 .
lf_ed_threshold (lf_ed_threshold
),
210 .
ssp_dout (ssp_dout
),
212 .
ssp_frame (mux1_ssp_frame
),
213 .
ssp_clk (mux1_ssp_clk
),
214 .
adc_clk (mux1_adc_clk
),
215 .
pwr_lo (mux1_pwr_lo
),
216 .
pwr_hi (mux1_pwr_hi
),
217 .
pwr_oe1 (mux1_pwr_oe1
),
218 .
pwr_oe2 (mux1_pwr_oe2
),
219 .
pwr_oe3 (mux1_pwr_oe3
),
220 .
pwr_oe4 (mux1_pwr_oe4
),
228 .
pck_divclk (pck_divclk
),
229 .
cross_lo (cross_lo
),
230 .
ssp_dout (ssp_dout
),
232 .
ssp_din (mux2_ssp_din
),
233 .
adc_clk (mux2_adc_clk
),
234 .
pwr_lo (mux2_pwr_lo
),
235 .
pwr_hi (mux2_pwr_hi
),
236 .
pwr_oe1 (mux2_pwr_oe1
),
237 .
pwr_oe2 (mux2_pwr_oe2
),
238 .
pwr_oe3 (mux2_pwr_oe3
),
239 .
pwr_oe4 (mux2_pwr_oe4
),
244 // LF ADC (read/write)
250 .
lf_field (conf_word
[0]),
251 .
ssp_dout (ssp_dout
),
253 .
ssp_din (mux3_ssp_din
),
254 .
ssp_frame (mux3_ssp_frame
),
255 .
ssp_clk (mux3_ssp_clk
),
256 .
adc_clk (mux3_adc_clk
),
257 .
pwr_lo (mux3_pwr_lo
),
258 .
pwr_hi (mux3_pwr_hi
),
259 .
pwr_oe1 (mux3_pwr_oe1
),
260 .
pwr_oe2 (mux3_pwr_oe2
),
261 .
pwr_oe3 (mux3_pwr_oe3
),
262 .
pwr_oe4 (mux3_pwr_oe4
),
267 assign mux6_pwr_lo
= 1'b1;
270 `else // if WITH_LF not defined
271 // ############################################################################
272 // # Enable High Frequency Modules
277 .
ck_1356meg (ck_1356megb
),
279 .
subcarrier_frequency (conf_word
[5:4]),
280 .
minor_mode (conf_word
[3:0]),
281 .
ssp_dout (ssp_dout
),
283 .
ssp_din (mux0_ssp_din
),
284 .
ssp_frame (mux0_ssp_frame
),
285 .
ssp_clk (mux0_ssp_clk
),
286 .
adc_clk (mux0_adc_clk
),
287 .
pwr_lo (mux0_pwr_lo
),
288 .
pwr_hi (mux0_pwr_hi
),
289 .
pwr_oe1 (mux0_pwr_oe1
),
290 .
pwr_oe2 (mux0_pwr_oe2
),
291 .
pwr_oe3 (mux0_pwr_oe3
),
292 .
pwr_oe4 (mux0_pwr_oe4
),
300 .
ck_1356meg (ck_1356meg
),
302 .
mod_type (conf_word
[3:0]),
303 .
ssp_dout (ssp_dout
),
305 .
ssp_din (mux1_ssp_din
),
306 .
ssp_frame (mux1_ssp_frame
),
307 .
ssp_clk (mux1_ssp_clk
),
308 .
adc_clk (mux1_adc_clk
),
309 .
pwr_lo (mux1_pwr_lo
),
310 .
pwr_hi (mux1_pwr_hi
),
311 .
pwr_oe1 (mux1_pwr_oe1
),
312 .
pwr_oe2 (mux1_pwr_oe2
),
313 .
pwr_oe3 (mux1_pwr_oe3
),
314 .
pwr_oe4 (mux1_pwr_oe4
),
322 .
ck_1356meg (ck_1356meg
),
324 .
mod_type (conf_word
[3:0]),
325 .
ssp_dout (ssp_dout
),
327 .
ssp_din (mux2_ssp_din
),
328 .
ssp_frame (mux2_ssp_frame
),
329 .
ssp_clk (mux2_ssp_clk
),
330 .
adc_clk (mux2_adc_clk
),
331 .
pwr_lo (mux2_pwr_lo
),
332 .
pwr_hi (mux2_pwr_hi
),
333 .
pwr_oe1 (mux2_pwr_oe1
),
334 .
pwr_oe2 (mux2_pwr_oe2
),
335 .
pwr_oe3 (mux2_pwr_oe3
),
336 .
pwr_oe4 (mux2_pwr_oe4
),
338 .
edge_detect_threshold (hf_edge_detect_threshold
),
339 .
edge_detect_threshold_high (hf_edge_detect_threshold_high
)
346 .
ck_1356meg (ck_1356megb
),
349 .
ssp_din (mux3_ssp_din
),
350 .
ssp_frame (mux3_ssp_frame
),
351 .
ssp_clk (mux3_ssp_clk
),
352 .
adc_clk (mux3_adc_clk
),
353 .
pwr_lo (mux3_pwr_lo
),
354 .
pwr_hi (mux3_pwr_hi
),
355 .
pwr_oe1 (mux3_pwr_oe1
),
356 .
pwr_oe2 (mux3_pwr_oe2
),
357 .
pwr_oe3 (mux3_pwr_oe3
),
358 .
pwr_oe4 (mux3_pwr_oe4
)
362 // HF ISO18092 FeliCa
365 .
ck_1356meg (ck_1356megb
),
367 .
mod_type (conf_word
[3:0]),
368 .
ssp_dout (ssp_dout
),
370 .
ssp_din (mux4_ssp_din
),
371 .
ssp_frame (mux4_ssp_frame
),
372 .
ssp_clk (mux4_ssp_clk
),
373 .
adc_clk (mux4_adc_clk
),
374 .
pwr_lo (mux4_pwr_lo
),
375 .
pwr_hi (mux4_pwr_hi
),
376 .
pwr_oe1 (mux4_pwr_oe1
),
377 .
pwr_oe2 (mux4_pwr_oe2
),
378 .
pwr_oe3 (mux4_pwr_oe3
),
379 .
pwr_oe4 (mux4_pwr_oe4
),
387 .
ck_1356megb (ck_1356megb
),
389 .
trace_enable (trace_enable
),
390 .
major_mode (conf_word
[8:6]),
391 .
ssp_din (mux5_ssp_din
),
392 .
ssp_frame (mux5_ssp_frame
),
393 .
ssp_clk (mux5_ssp_clk
)
399 // These assignments must agree with the defines in fpgaloader.h
400 // Major modes Low Frequency
401 // mux0 = LF reader (generic)
402 // mux1 = LF edge detect (generic)
403 // mux2 = LF passthrough
404 // mux3 = LF ADC (read/write)
408 // mux7 = FPGA_MAJOR_MODE_OFF
410 // Major modes High Frequency
412 // mux1 = HF simulated tag
413 // mux2 = HF ISO14443-A
415 // mux4 = HF ISO18092 FeliCa
416 // mux5 = HF get trace
418 // mux7 = FPGA_MAJOR_MODE_OFF
420 mux8
mux_ssp_clk (.
sel(conf_word
[8:6]), .
y(ssp_clk
), .
x0(mux0_ssp_clk
), .
x1(mux1_ssp_clk
), .
x2(mux2_ssp_clk
), .
x3(mux3_ssp_clk
), .
x4(mux4_ssp_clk
), .
x5(mux5_ssp_clk
), .
x6(mux6_ssp_clk
), .
x7(mux7_ssp_clk
) );
421 mux8
mux_ssp_din (.
sel(conf_word
[8:6]), .
y(ssp_din
), .
x0(mux0_ssp_din
), .
x1(mux1_ssp_din
), .
x2(mux2_ssp_din
), .
x3(mux3_ssp_din
), .
x4(mux4_ssp_din
), .
x5(mux5_ssp_din
), .
x6(mux6_ssp_din
), .
x7(mux7_ssp_din
) );
422 mux8
mux_ssp_frame (.
sel(conf_word
[8:6]), .
y(ssp_frame
), .
x0(mux0_ssp_frame
), .
x1(mux1_ssp_frame
), .
x2(mux2_ssp_frame
), .
x3(mux3_ssp_frame
), .
x4(mux4_ssp_frame
), .
x5(mux5_ssp_frame
), .
x6(mux6_ssp_frame
), .
x7(mux7_ssp_frame
) );
423 mux8
mux_pwr_oe1 (.
sel(conf_word
[8:6]), .
y(pwr_oe1
), .
x0(mux0_pwr_oe1
), .
x1(mux1_pwr_oe1
), .
x2(mux2_pwr_oe1
), .
x3(mux3_pwr_oe1
), .
x4(mux4_pwr_oe1
), .
x5(mux5_pwr_oe1
), .
x6(mux6_pwr_oe1
), .
x7(mux7_pwr_oe1
) );
424 mux8
mux_pwr_oe2 (.
sel(conf_word
[8:6]), .
y(pwr_oe2
), .
x0(mux0_pwr_oe2
), .
x1(mux1_pwr_oe2
), .
x2(mux2_pwr_oe2
), .
x3(mux3_pwr_oe2
), .
x4(mux4_pwr_oe2
), .
x5(mux5_pwr_oe2
), .
x6(mux6_pwr_oe2
), .
x7(mux7_pwr_oe2
) );
425 mux8
mux_pwr_oe3 (.
sel(conf_word
[8:6]), .
y(pwr_oe3
), .
x0(mux0_pwr_oe3
), .
x1(mux1_pwr_oe3
), .
x2(mux2_pwr_oe3
), .
x3(mux3_pwr_oe3
), .
x4(mux4_pwr_oe3
), .
x5(mux5_pwr_oe3
), .
x6(mux6_pwr_oe3
), .
x7(mux7_pwr_oe3
) );
426 mux8
mux_pwr_oe4 (.
sel(conf_word
[8:6]), .
y(pwr_oe4
), .
x0(mux0_pwr_oe4
), .
x1(mux1_pwr_oe4
), .
x2(mux2_pwr_oe4
), .
x3(mux3_pwr_oe4
), .
x4(mux4_pwr_oe4
), .
x5(mux5_pwr_oe4
), .
x6(mux6_pwr_oe4
), .
x7(mux7_pwr_oe4
) );
427 mux8
mux_pwr_lo (.
sel(conf_word
[8:6]), .
y(pwr_lo
), .
x0(mux0_pwr_lo
), .
x1(mux1_pwr_lo
), .
x2(mux2_pwr_lo
), .
x3(mux3_pwr_lo
), .
x4(mux4_pwr_lo
), .
x5(mux5_pwr_lo
), .
x6(mux6_pwr_lo
), .
x7(mux7_pwr_lo
) );
428 mux8
mux_pwr_hi (.
sel(conf_word
[8:6]), .
y(pwr_hi
), .
x0(mux0_pwr_hi
), .
x1(mux1_pwr_hi
), .
x2(mux2_pwr_hi
), .
x3(mux3_pwr_hi
), .
x4(mux4_pwr_hi
), .
x5(mux5_pwr_hi
), .
x6(mux6_pwr_hi
), .
x7(mux7_pwr_hi
) );
429 mux8
mux_adc_clk (.
sel(conf_word
[8:6]), .
y(adc_clk
), .
x0(mux0_adc_clk
), .
x1(mux1_adc_clk
), .
x2(mux2_adc_clk
), .
x3(mux3_adc_clk
), .
x4(mux4_adc_clk
), .
x5(mux5_adc_clk
), .
x6(mux6_adc_clk
), .
x7(mux7_adc_clk
) );
430 mux8
mux_dbg (.
sel(conf_word
[8:6]), .
y(dbg
), .
x0(mux0_debug
), .
x1(mux1_debug
), .
x2(mux2_debug
), .
x3(mux3_debug
), .
x4(mux4_debug
), .
x5(mux5_debug
), .
x6(mux6_debug
), .
x7(mux7_debug
) );