X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/7cc204bff881ce1d1833d8e93469f6bbba80c70e..f004ba08d4e1bb3472f931924234c901a41d1ae1:/fpga/lo_edge_detect.v?ds=sidebyside

diff --git a/fpga/lo_edge_detect.v b/fpga/lo_edge_detect.v
index af600b83..dc97fc6f 100644
--- a/fpga/lo_edge_detect.v
+++ b/fpga/lo_edge_detect.v
@@ -1,20 +1,34 @@
 //-----------------------------------------------------------------------------
-// The way that we connect things in low-frequency simulation mode. In this
-// case just pass everything through to the ARM, which can bit-bang this
-// (because it is so slow).
+// Copyright (C) 2014 iZsh <izsh at fail0verflow.com>
 //
-// Jonathan Westhues, April 2006
+// 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.
 //-----------------------------------------------------------------------------
+//
+// There are two modes:
+// - lf_ed_toggle_mode == 0: the output is set low (resp. high) when a low
+//   (resp. high) edge/peak is detected, with hysteresis
+// - lf_ed_toggle_mode == 1: the output is toggling whenever an edge/peak
+//   is detected.
+//   That way you can detect two consecutive edges/peaks at the same level (L/H)
+//
+// Output:
+// - ssp_frame (wired to TIOA1 on the arm) for the edge detection/state
+// - ssp_clk: cross_lo
+`include "lp20khz_1MSa_iir_filter.v"
+`include "lf_edge_detect.v"
 
 module lo_edge_detect(
-	input pck0, input [7:0] pck_cnt, input pck_divclk,
-	output pwr_lo, output pwr_hi,
-	output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
-	input [7:0] adc_d, output adc_clk,
-	output ssp_frame, input ssp_dout, output ssp_clk,
-	input cross_lo,
-	output dbg,
-	input lf_field
+    input pck0, input pck_divclk,
+    output pwr_lo, output pwr_hi,
+    output pwr_oe1, output pwr_oe2, output pwr_oe3, output pwr_oe4,
+    input [7:0] adc_d, output adc_clk,
+    output ssp_frame, input ssp_dout, output ssp_clk,
+    input cross_lo,
+    output dbg,
+    input lf_field,
+    input lf_ed_toggle_mode, input [7:0] lf_ed_threshold
 );
 
 wire tag_modulation = ssp_dout & !lf_field;
@@ -28,34 +42,25 @@ assign pwr_oe4 = tag_modulation;
 assign ssp_clk = cross_lo;
 assign pwr_lo = reader_modulation;
 assign pwr_hi = 1'b0;
-assign dbg = ssp_frame;
-
-assign adc_clk = ~pck_divclk;
-
-// Toggle the output with hysteresis
-//  Set to high if the ADC value is above 200
-//  Set to low if the ADC value is below 64
-reg is_high;
-reg is_low;
-reg output_state;
-
-always @(posedge pck0)
-begin
-	if((pck_cnt == 8'd7) && !pck_divclk) begin
-		is_high = (adc_d >= 8'd190);
-		is_low = (adc_d <= 8'd70);
-	end
-end
-
-always @(posedge is_high or posedge is_low)
-begin
-	if(is_high)
-		output_state <= 1'd1;
-	else if(is_low)
-		output_state <= 1'd0;
-end
-
-assign ssp_frame = output_state;
+
+// filter the ADC values
+wire data_rdy;
+wire [7:0] adc_filtered;
+assign adc_clk = pck0;
+lp20khz_1MSa_iir_filter adc_filter(pck0, adc_d, data_rdy, adc_filtered);
+
+// detect edges
+wire [7:0] high_threshold, highz_threshold, lowz_threshold, low_threshold;
+wire [7:0] max, min;
+wire edge_state, edge_toggle;
+lf_edge_detect lf_ed(pck0, adc_filtered, lf_ed_threshold,
+	max, min,
+	high_threshold, highz_threshold, lowz_threshold, low_threshold,
+	edge_state, edge_toggle);
+
+assign dbg = lf_ed_toggle_mode ? edge_toggle : edge_state;
+
+assign ssp_frame = lf_ed_toggle_mode ? edge_toggle : edge_state;
 
 endmodule