X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/db09cb3adbe715b058a64357184e4963a8b6d78e..d19929cbe8d681b60496ca6d9d9cbd806822e163:/fpga/lo_edge_detect.v diff --git a/fpga/lo_edge_detect.v b/fpga/lo_edge_detect.v new file mode 100644 index 00000000..8458ee69 --- /dev/null +++ b/fpga/lo_edge_detect.v @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// 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). +// +// Jonathan Westhues, April 2006 +//----------------------------------------------------------------------------- + +module lo_edge_detect( + pck0, ck_1356meg, ck_1356megb, + pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, + adc_d, adc_clk, + ssp_frame, ssp_din, ssp_dout, ssp_clk, + cross_hi, cross_lo, + dbg, + divisor, + lf_field +); + input pck0, ck_1356meg, ck_1356megb; + output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; + input [7:0] adc_d; + output adc_clk; + input ssp_dout; + output ssp_frame, ssp_din, ssp_clk; + input cross_hi, cross_lo; + output dbg; + input [7:0] divisor; + input lf_field; + +// Divide the clock to be used for the ADC +reg [7:0] pck_divider; +reg clk_state; + +wire tag_modulation; +assign tag_modulation = ssp_dout & !lf_field; +wire reader_modulation; +assign reader_modulation = !ssp_dout & lf_field & clk_state; + +// No logic, straight through. +assign pwr_oe1 = 1'b0; // not used in LF mode +assign pwr_oe2 = tag_modulation; +assign pwr_oe3 = tag_modulation; +assign pwr_oe4 = tag_modulation; +assign ssp_clk = cross_lo; +assign pwr_lo = reader_modulation; +assign pwr_hi = 1'b0; +assign dbg = ssp_frame; + +always @(posedge pck0) +begin + if(pck_divider == divisor[7:0]) + begin + pck_divider <= 8'd0; + clk_state = !clk_state; + end + else + begin + pck_divider <= pck_divider + 1; + end +end + +assign adc_clk = ~clk_state; + +// 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_divider == 8'd7) && !clk_state) 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; + +endmodule +