]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - fpga/lo_read.v
Initial commit for the firmware. Used the 20090306_ela version as baseline.
[proxmark3-svn] / fpga / lo_read.v
diff --git a/fpga/lo_read.v b/fpga/lo_read.v
new file mode 100644 (file)
index 0000000..9c3edb2
--- /dev/null
@@ -0,0 +1,102 @@
+//-----------------------------------------------------------------------------\r
+// The way that we connect things in low-frequency read mode. In this case\r
+// we are generating the 134 kHz or 125 kHz carrier, and running the \r
+// unmodulated carrier at that frequency. The A/D samples at that same rate,\r
+// and the result is serialized.\r
+//\r
+// Jonathan Westhues, April 2006\r
+//-----------------------------------------------------------------------------\r
+\r
+module lo_read(\r
+    pck0, ck_1356meg, ck_1356megb,\r
+    pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,\r
+    adc_d, adc_clk,\r
+    ssp_frame, ssp_din, ssp_dout, ssp_clk,\r
+    cross_hi, cross_lo,\r
+    dbg,\r
+    lo_is_125khz\r
+);\r
+    input pck0, ck_1356meg, ck_1356megb;\r
+    output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;\r
+    input [7:0] adc_d;\r
+    output adc_clk;\r
+    input ssp_dout;\r
+    output ssp_frame, ssp_din, ssp_clk;\r
+    input cross_hi, cross_lo;\r
+    output dbg;\r
+    input lo_is_125khz;\r
+\r
+// The low-frequency RFID stuff. This is relatively simple, because most\r
+// of the work happens on the ARM, and we just pass samples through. The\r
+// PCK0 must be divided down to generate the A/D clock, and from there by\r
+// a factor of 8 to generate the carrier (that we apply to the coil drivers).\r
+//\r
+// This is also where we decode the received synchronous serial port words,\r
+// to determine how to drive the output enables.\r
+\r
+// PCK0 will run at (PLL clock) / 4, or 24 MHz. That means that we can do\r
+// 125 kHz by dividing by a further factor of (8*12*2), or ~134 kHz by\r
+// dividing by a factor of (8*11*2) (for 136 kHz, ~2% error, tolerable).\r
+\r
+reg [3:0] pck_divider;\r
+reg clk_lo;\r
+\r
+always @(posedge pck0)\r
+begin\r
+    if(lo_is_125khz)\r
+    begin\r
+        if(pck_divider == 4'd11)\r
+        begin\r
+            pck_divider <= 4'd0;\r
+            clk_lo = !clk_lo;\r
+        end\r
+        else\r
+            pck_divider <= pck_divider + 1;\r
+    end\r
+    else\r
+    begin\r
+        if(pck_divider == 4'd10)\r
+        begin\r
+            pck_divider <= 4'd0;\r
+            clk_lo = !clk_lo;\r
+        end\r
+        else\r
+            pck_divider <= pck_divider + 1;\r
+    end\r
+end\r
+\r
+reg [2:0] carrier_divider_lo;\r
+\r
+always @(posedge clk_lo)\r
+begin\r
+    carrier_divider_lo <= carrier_divider_lo + 1;\r
+end\r
+\r
+assign pwr_lo = carrier_divider_lo[2];\r
+\r
+// This serializes the values returned from the A/D, and sends them out\r
+// over the SSP.\r
+\r
+reg [7:0] to_arm_shiftreg;\r
+\r
+always @(posedge clk_lo)\r
+begin\r
+    if(carrier_divider_lo == 3'b000)\r
+        to_arm_shiftreg <= adc_d;\r
+    else\r
+        to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0];\r
+end\r
+\r
+assign ssp_clk = clk_lo;\r
+assign ssp_frame = (carrier_divider_lo == 3'b001);\r
+assign ssp_din = to_arm_shiftreg[7];\r
+\r
+// The ADC converts on the falling edge, and our serializer loads when\r
+// carrier_divider_lo == 3'b000.\r
+assign adc_clk = ~carrier_divider_lo[2];\r
+\r
+assign pwr_hi = 1'b0;\r
+\r
+assign dbg = adc_clk;\r
+\r
+endmodule\r
Impressum, Datenschutz