]> git.zerfleddert.de Git - proxmark3-svn/blame - fpga/lo_read.v
Initial commit for the firmware. Used the 20090306_ela version as baseline.
[proxmark3-svn] / fpga / lo_read.v
CommitLineData
6658905f 1//-----------------------------------------------------------------------------\r
2// The way that we connect things in low-frequency read mode. In this case\r
3// we are generating the 134 kHz or 125 kHz carrier, and running the \r
4// unmodulated carrier at that frequency. The A/D samples at that same rate,\r
5// and the result is serialized.\r
6//\r
7// Jonathan Westhues, April 2006\r
8//-----------------------------------------------------------------------------\r
9\r
10module lo_read(\r
11 pck0, ck_1356meg, ck_1356megb,\r
12 pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,\r
13 adc_d, adc_clk,\r
14 ssp_frame, ssp_din, ssp_dout, ssp_clk,\r
15 cross_hi, cross_lo,\r
16 dbg,\r
17 lo_is_125khz\r
18);\r
19 input pck0, ck_1356meg, ck_1356megb;\r
20 output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;\r
21 input [7:0] adc_d;\r
22 output adc_clk;\r
23 input ssp_dout;\r
24 output ssp_frame, ssp_din, ssp_clk;\r
25 input cross_hi, cross_lo;\r
26 output dbg;\r
27 input lo_is_125khz;\r
28\r
29// The low-frequency RFID stuff. This is relatively simple, because most\r
30// of the work happens on the ARM, and we just pass samples through. The\r
31// PCK0 must be divided down to generate the A/D clock, and from there by\r
32// a factor of 8 to generate the carrier (that we apply to the coil drivers).\r
33//\r
34// This is also where we decode the received synchronous serial port words,\r
35// to determine how to drive the output enables.\r
36\r
37// PCK0 will run at (PLL clock) / 4, or 24 MHz. That means that we can do\r
38// 125 kHz by dividing by a further factor of (8*12*2), or ~134 kHz by\r
39// dividing by a factor of (8*11*2) (for 136 kHz, ~2% error, tolerable).\r
40\r
41reg [3:0] pck_divider;\r
42reg clk_lo;\r
43\r
44always @(posedge pck0)\r
45begin\r
46 if(lo_is_125khz)\r
47 begin\r
48 if(pck_divider == 4'd11)\r
49 begin\r
50 pck_divider <= 4'd0;\r
51 clk_lo = !clk_lo;\r
52 end\r
53 else\r
54 pck_divider <= pck_divider + 1;\r
55 end\r
56 else\r
57 begin\r
58 if(pck_divider == 4'd10)\r
59 begin\r
60 pck_divider <= 4'd0;\r
61 clk_lo = !clk_lo;\r
62 end\r
63 else\r
64 pck_divider <= pck_divider + 1;\r
65 end\r
66end\r
67\r
68reg [2:0] carrier_divider_lo;\r
69\r
70always @(posedge clk_lo)\r
71begin\r
72 carrier_divider_lo <= carrier_divider_lo + 1;\r
73end\r
74\r
75assign pwr_lo = carrier_divider_lo[2];\r
76\r
77// This serializes the values returned from the A/D, and sends them out\r
78// over the SSP.\r
79\r
80reg [7:0] to_arm_shiftreg;\r
81\r
82always @(posedge clk_lo)\r
83begin\r
84 if(carrier_divider_lo == 3'b000)\r
85 to_arm_shiftreg <= adc_d;\r
86 else\r
87 to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];\r
88end\r
89\r
90assign ssp_clk = clk_lo;\r
91assign ssp_frame = (carrier_divider_lo == 3'b001);\r
92assign ssp_din = to_arm_shiftreg[7];\r
93\r
94// The ADC converts on the falling edge, and our serializer loads when\r
95// carrier_divider_lo == 3'b000.\r
96assign adc_clk = ~carrier_divider_lo[2];\r
97\r
98assign pwr_hi = 1'b0;\r
99\r
100assign dbg = adc_clk;\r
101\r
102endmodule\r
Impressum, Datenschutz