mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
ADD: FPGA code to support FeliCa / ISO 18092. Thanks to @satsuoni
This commit is contained in:
parent
ce5525bc16
commit
5c1f7686f6
5 changed files with 555 additions and 2 deletions
|
@ -1,14 +1,19 @@
|
|||
include ../common/Makefile.common
|
||||
|
||||
all: fpga_lf.bit fpga_hf.bit
|
||||
all: fpga_lf.bit fpga_hf.bit fpga_nfc.bit
|
||||
clean:
|
||||
$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp
|
||||
$(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst
|
||||
|
||||
fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v
|
||||
fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_flite.v
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr
|
||||
|
||||
fpga_nfc.ngc: fpga_nfc.v fpga.ucf xst_nfc.scr util.v hi_flite.v
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst_nfc.scr
|
||||
|
||||
|
||||
fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v lp20khz_1MSa_iir_filter.v min_max_tracker.v lf_edge_detect.v
|
||||
$(DELETE) $@
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr
|
||||
|
|
BIN
fpga/fpga_hf.bit
BIN
fpga/fpga_hf.bit
Binary file not shown.
BIN
fpga/fpga_lf.bit
BIN
fpga/fpga_lf.bit
Binary file not shown.
121
fpga/fpga_nfc.v
Normal file
121
fpga/fpga_nfc.v
Normal file
|
@ -0,0 +1,121 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// The FPGA is responsible for interfacing between the A/D, the coil drivers,
|
||||
// and the ARM. In the low-frequency modes it passes the data straight
|
||||
// through, so that the ARM gets raw A/D samples over the SSP. In the high-
|
||||
// frequency modes, the FPGA might perform some demodulation first, to
|
||||
// reduce the amount of data that we must send to the ARM.
|
||||
//
|
||||
// I am not really an FPGA/ASIC designer, so I am sure that a lot of this
|
||||
// could be improved.
|
||||
//
|
||||
// Jonathan Westhues, March 2006
|
||||
// Added ISO14443-A support by Gerhard de Koning Gans, April 2008
|
||||
// iZsh <izsh at fail0verflow.com>, June 2014
|
||||
// Satsuoni <>, October 2017 , added FeliCa support.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
`include "hi_flite.v"
|
||||
`include "util.v"
|
||||
|
||||
module fpga_nfc(
|
||||
input spck, output miso, input mosi, input ncs,
|
||||
input pck0, input ck_1356meg, input ck_1356megb,
|
||||
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 adc_noe,
|
||||
output ssp_frame, output ssp_din, input ssp_dout, output ssp_clk,
|
||||
input cross_hi, input cross_lo,
|
||||
output dbg
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The SPI receiver. This sets up the configuration word, which the rest of
|
||||
// the logic looks at to determine how to connect the A/D and the coil
|
||||
// drivers (i.e., which section gets it). Also assign some symbolic names
|
||||
// to the configuration bits, for use below.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
reg [15:0] shift_reg;
|
||||
reg [7:0] conf_word;
|
||||
|
||||
// We switch modes between transmitting to the 13.56 MHz tag and receiving
|
||||
// from it, which means that we must make sure that we can do so without
|
||||
// glitching, or else we will glitch the transmitted carrier.
|
||||
always @(posedge ncs)
|
||||
begin
|
||||
case(shift_reg[15:12])
|
||||
4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge spck)
|
||||
begin
|
||||
if(~ncs)
|
||||
begin
|
||||
shift_reg[15:1] <= shift_reg[14:0];
|
||||
shift_reg[0] <= mosi;
|
||||
end
|
||||
end
|
||||
|
||||
wire [2:0] major_mode;
|
||||
assign major_mode = conf_word[7:5];
|
||||
|
||||
// For the high-frequency transmit configuration: modulation depth, either
|
||||
// 100% (just quite driving antenna, steady LOW), or shallower (tri-state
|
||||
// some fraction of the buffers)
|
||||
//wire hi_read_tx_shallow_modulation = conf_word[0];
|
||||
|
||||
// For the high-frequency receive correlator: frequency against which to
|
||||
// correlate.
|
||||
//wire hi_read_rx_xcorr_848 = conf_word[0];
|
||||
// and whether to drive the coil (reader) or just short it (snooper)
|
||||
//wire hi_read_rx_xcorr_snoop = conf_word[1];
|
||||
// divide subcarrier frequency by 4
|
||||
//wire hi_read_rx_xcorr_quarter = conf_word[2];
|
||||
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// And then we instantiate the modules corresponding to each of the FPGA's
|
||||
// major modes, and use muxes to connect the outputs of the active mode to
|
||||
// the output pins.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
hi_flite hfl(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hfl_pwr_lo, hfl_pwr_hi, hfl_pwr_oe1, hfl_pwr_oe2, hfl_pwr_oe3, hfl_pwr_oe4,
|
||||
adc_d, hfl_adc_clk,
|
||||
hfl_ssp_frame, hfl_ssp_din, ssp_dout, hfl_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hfl_dbg,
|
||||
hi_simulate_mod_type
|
||||
);
|
||||
|
||||
// Major modes:
|
||||
// no major modes here for now, except NFC demod/sim. Maybe I should remove mux at some point, unless I can think of more modes
|
||||
// 000 --
|
||||
// 001 --
|
||||
// 010 --
|
||||
// 011 --
|
||||
// 100 --
|
||||
// 101 -- HF NFC demod, just to copy it for now
|
||||
// 111 -- everything off
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_ssp_clk, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_ssp_din, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_ssp_frame, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe1, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe2, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe3, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe4, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_lo, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_hi, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_adc_clk, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_dbg, 1'b0, 1'b0);
|
||||
|
||||
// In all modes, let the ADC's outputs be enabled.
|
||||
assign adc_noe = 1'b0;
|
||||
|
||||
endmodule
|
427
fpga/hi_flite.v
Normal file
427
fpga/hi_flite.v
Normal file
|
@ -0,0 +1,427 @@
|
|||
// Satsuoni, October 2017, Added FeliCa support
|
||||
//
|
||||
//this code demodulates and modulates signal as described in ISO/IEC 18092. That includes packets used for Felica, NFC Tag 3, etc. (which do overlap)
|
||||
//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave)
|
||||
// only 212 kbps (fc/64) for now 414 is relatively straightforward...
|
||||
// modulation waits for
|
||||
|
||||
//market sprocket -doesn't really mean anything ;)
|
||||
`define SNIFFER 3'b000
|
||||
`define TAGSIM_LISTEN 3'b001 //same as SNIFFER, really. demod does not distinguish tag from reader
|
||||
`define TAGSIM_MODULATE 3'b010
|
||||
`define TAGSIM_MOD_NODELAY 3'b011 //not implemented yet. for use with commands other than polling, which might require different timing, as per Felica standard
|
||||
|
||||
module hi_flite(
|
||||
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,
|
||||
mod_type // maybe used
|
||||
);
|
||||
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 [2:0] mod_type; // maybe used.
|
||||
assign dbg=0;
|
||||
|
||||
// Most off, oe4 for modulation; No reader emulation (would presumably just require switching power on, but I am not sure)
|
||||
assign pwr_hi = 1'b0;
|
||||
assign pwr_lo = 1'b0;
|
||||
assign pwr_oe1 = 1'b0;
|
||||
assign pwr_oe2 = 1'b0;
|
||||
assign pwr_oe3 = 1'b0;
|
||||
|
||||
|
||||
//512x64/fc -wait before ts0, 32768 ticks
|
||||
//tslot: 256*64/fc
|
||||
|
||||
assign adc_clk = ck_1356meg;
|
||||
|
||||
|
||||
///heuristic values for initial thresholds. seem to work OK
|
||||
`define imin 70//(13'd256)
|
||||
`define imax 180//(-13'd256)
|
||||
`define ithrmin 91//-13'd8
|
||||
`define ithrmax 160// 13'd8
|
||||
|
||||
|
||||
//minimum values and corresponding thresholds
|
||||
reg [8:0] curmin=`imin;
|
||||
|
||||
reg [8:0] curminthres=`ithrmin;
|
||||
|
||||
reg [8:0] curmaxthres=`ithrmax;
|
||||
reg [8:0] curmax=`imax;
|
||||
|
||||
|
||||
//signal state, 1-not modulated, 0 -modulated
|
||||
reg after_hysteresis = 1'b1;
|
||||
|
||||
//state machine for envelope tracking
|
||||
reg [1:0] state=1'd0;
|
||||
|
||||
|
||||
//lower edge detected, trying to detect first bit of SYNC (b24d, 1011001001001101)
|
||||
reg try_sync=1'b0;
|
||||
|
||||
//detected first sync bit, phase frozen
|
||||
reg did_sync=0;
|
||||
|
||||
|
||||
`define bithalf_212 32 //half-bit length for 212 kbit
|
||||
`define bitlen_212 64 //full-bit length for 212 kbit
|
||||
`define bitmlen_212 63 //bit transition edge
|
||||
`define bitmhalf_212 31 //mod flip
|
||||
|
||||
|
||||
//ssp clock and current values
|
||||
reg ssp_clk;
|
||||
reg ssp_frame;
|
||||
reg curbit=1'b0;
|
||||
|
||||
reg [7:0] fccount=8'd0; // in-bit tick counter. Counts carrier cycles from the first lower edge detected, reset on every manchester bit detected
|
||||
|
||||
reg [7:0] tsinceedge=8'd0;// ticks from last edge, desync if the valye is too large
|
||||
|
||||
reg zero=1'b0; // Manchester first halfbit low second high corresponds to this value. It has been known to change. SYNC is used to set it
|
||||
|
||||
//ssp counter for transfer and framing
|
||||
reg [8:0] ssp_cnt=9'd0;
|
||||
|
||||
always @(posedge adc_clk)
|
||||
ssp_cnt <= (ssp_cnt + 1);
|
||||
|
||||
|
||||
reg getting_arm_data=1'b0;
|
||||
|
||||
|
||||
reg [47:0] delayline=48'd0; //48-bit preamble delay line. Just push the data into it starting from first SYNC (1) bit coming from ARM Made this long to keep all ARM data received during preamble
|
||||
reg [5:0] delay_read_ptr=6'd0; // this is supposed to count ARM delay in the buffer.
|
||||
reg preamble=0; // whether we are sending preamble
|
||||
|
||||
|
||||
|
||||
always @(negedge adc_clk)
|
||||
begin
|
||||
//count fc/64 - transfer bits to ARM at the rate they are received
|
||||
if(ssp_cnt[5:0] == 6'b000000)
|
||||
begin
|
||||
ssp_clk <= 1'b1;
|
||||
ssp_din <= curbit;
|
||||
|
||||
//sample ssp_dout?
|
||||
if(mod_type==`TAGSIM_MODULATE||mod_type==`TAGSIM_MOD_NODELAY)
|
||||
begin
|
||||
delayline<={delayline[46:0],ssp_dout};
|
||||
if ((~getting_arm_data) && ssp_dout)
|
||||
begin
|
||||
getting_arm_data <=1'b1;
|
||||
delay_read_ptr<=delay_read_ptr+1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (getting_arm_data & preamble)
|
||||
begin
|
||||
delay_read_ptr<=delay_read_ptr+1;
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
getting_arm_data <=1'b0;
|
||||
delay_read_ptr<=6'd0;
|
||||
end
|
||||
|
||||
end
|
||||
if(ssp_cnt[5:0] == 6'b100000)
|
||||
ssp_clk <= 1'b0;
|
||||
//create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason
|
||||
// took me a day to figure THAT out.
|
||||
if(ssp_cnt[8:0] == 9'd31)
|
||||
begin
|
||||
ssp_frame <= 1'b1;
|
||||
end
|
||||
if(ssp_cnt[8:0] == 9'b1011111)
|
||||
begin
|
||||
ssp_frame <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
//send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise)
|
||||
reg ssp_din;
|
||||
|
||||
|
||||
|
||||
//previous signal value, mostly to detect SYNC
|
||||
reg prv =1'b1;
|
||||
|
||||
|
||||
reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry.
|
||||
|
||||
//modulated coil. set to 1 to modulate low, 0 to keep signal high
|
||||
reg mod_sig_coil=1'b0;
|
||||
|
||||
// set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...)
|
||||
// start sending over 1s on ssp->arm when we start sending preamble
|
||||
|
||||
reg counting_desync=1'b0; // are we counting bits since last frame?
|
||||
reg sending=1'b0; // are we actively modulating?
|
||||
reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes.
|
||||
|
||||
|
||||
always @(negedge adc_clk) //every data ping?
|
||||
begin
|
||||
//envelope follow code...
|
||||
////////////
|
||||
if ((mod_type==`SNIFFER )||(mod_type==`TAGSIM_LISTEN))
|
||||
begin
|
||||
if (adc_d>curmaxthres) //rising edge
|
||||
begin
|
||||
case (state)
|
||||
0: begin
|
||||
curmax <= adc_d>155? adc_d :155;
|
||||
state <= 2;
|
||||
end
|
||||
1: begin
|
||||
curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4)); //threshold: 0.1875 max + 0.8125 min
|
||||
curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4));
|
||||
curmax <= adc_d>155? adc_d :155; // to hopefully prevent overflow from spikes going up to 255
|
||||
state <= 2;
|
||||
end
|
||||
2: begin
|
||||
if (adc_d>curmax)
|
||||
curmax <= adc_d;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
end
|
||||
endcase
|
||||
after_hysteresis <=1'b1;
|
||||
if(try_sync)
|
||||
tsinceedge<=0;
|
||||
end
|
||||
else if (adc_d<curminthres) //falling edge
|
||||
begin
|
||||
case (state)
|
||||
0: begin
|
||||
curmin <=adc_d<96? adc_d :96;
|
||||
state <=1;
|
||||
end
|
||||
1: begin
|
||||
if (adc_d<curmin)
|
||||
curmin <= adc_d;
|
||||
end
|
||||
2: begin
|
||||
curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4));
|
||||
curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4));
|
||||
curmin <=adc_d<96? adc_d :96;
|
||||
state <=1;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
end
|
||||
endcase
|
||||
after_hysteresis <=0;
|
||||
if (~try_sync ) //begin modulation, lower edge...
|
||||
begin
|
||||
try_sync <=1;
|
||||
counting_desync<=1'b0;
|
||||
fccount <= 1;
|
||||
did_sync<=0;
|
||||
curbit<=0;
|
||||
mid <=8'd127;
|
||||
tsinceedge<=0;
|
||||
prv <=1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
tsinceedge<=0;
|
||||
end
|
||||
end
|
||||
else //stable state, low or high
|
||||
begin
|
||||
curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4));
|
||||
curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4));
|
||||
state <=0;
|
||||
|
||||
if (try_sync )
|
||||
begin
|
||||
if (tsinceedge>=(128))
|
||||
begin
|
||||
//we might need to start counting... assuming ARM wants to reply to the frame.
|
||||
counting_desync<=1'b1;
|
||||
bit_counts<=1;// i think? 128 is about 2 bits passed... but 1 also works
|
||||
try_sync<=0;
|
||||
did_sync<=0;//desync
|
||||
curmin <=`imin; //reset envelope
|
||||
curmax <=`imax;
|
||||
curminthres <=`ithrmin;
|
||||
curmaxthres <=`ithrmax;
|
||||
prv <=1;
|
||||
tsinceedge <=0;
|
||||
after_hysteresis <=1'b1;
|
||||
curbit <=0;
|
||||
mid <=8'd128;
|
||||
end
|
||||
else
|
||||
tsinceedge<=(tsinceedge+1);
|
||||
end
|
||||
end
|
||||
|
||||
//move the counter to the outside...
|
||||
if (adc_d>=curminthres||try_sync)
|
||||
if(fccount==`bitmlen_212)
|
||||
begin
|
||||
fccount<=0;
|
||||
if (counting_desync)
|
||||
begin
|
||||
|
||||
if(bit_counts>768) // should be over ts0 now, without ARM interference... stop counting...
|
||||
begin
|
||||
bit_counts<=0;
|
||||
counting_desync<=0;
|
||||
end
|
||||
else
|
||||
bit_counts<=bit_counts+1;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
fccount<=fccount+1;
|
||||
end
|
||||
|
||||
if (try_sync && tsinceedge<128)
|
||||
begin
|
||||
//detect bits in their middle ssp sampling is in sync, so it would sample all bits in order
|
||||
if (fccount==`bithalf_212)
|
||||
begin
|
||||
if ((~did_sync) && ((prv==1&&(mid>128))||(prv==0&&(mid<=128))))
|
||||
begin
|
||||
//sync the Zero, and set curbit roperly
|
||||
did_sync <=1'b1;
|
||||
zero <= ~prv;// 1-prv
|
||||
curbit <=1;
|
||||
end
|
||||
else
|
||||
curbit <= (mid>128) ? (~zero):zero;
|
||||
|
||||
prv <=(mid>128) ?1:0;
|
||||
|
||||
if(adc_d>curmaxthres)
|
||||
mid <=8'd129;
|
||||
else if (adc_d<curminthres)
|
||||
mid <=8'd127;
|
||||
else
|
||||
begin
|
||||
if (after_hysteresis)
|
||||
begin
|
||||
mid <=8'd129;
|
||||
end
|
||||
else
|
||||
begin
|
||||
mid<=8'd127;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (fccount==`bitmlen_212)
|
||||
begin
|
||||
// fccount <=0;
|
||||
prv <=(mid>128)?1:0;
|
||||
mid <=128;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// minimum-maximum calc
|
||||
if(adc_d>curmaxthres)
|
||||
mid <=mid+1;
|
||||
else if (adc_d<curminthres)
|
||||
mid <=mid-1;
|
||||
else
|
||||
begin
|
||||
if (after_hysteresis)
|
||||
begin
|
||||
mid <=mid+1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
mid<=mid-1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
end
|
||||
sending <=0;
|
||||
|
||||
end //listen mode end
|
||||
else
|
||||
begin //sim mode start
|
||||
//not sure how precise do the time slots have to be... is anything within Ts ok?
|
||||
//keep counting until 576, just in case
|
||||
if(fccount==`bitmlen_212)
|
||||
begin
|
||||
if (bit_counts==512) //
|
||||
curbit<=1;
|
||||
else
|
||||
begin
|
||||
if(bit_counts>512)
|
||||
curbit<=mod_sig_coil;//delayline[delay_read_ptr];//bit_counts[0];
|
||||
else
|
||||
curbit<=0;
|
||||
end
|
||||
|
||||
fccount<=0;
|
||||
if (bit_counts<=576) //we don't need to count after that...
|
||||
begin
|
||||
bit_counts<=bit_counts+1;
|
||||
if (bit_counts== 512) //should start sending from next tick... i think?
|
||||
begin
|
||||
sending <=1;
|
||||
mod_sig_coil <=1;//modulate... down?
|
||||
preamble<=1;
|
||||
end
|
||||
else
|
||||
if (bit_counts== 559)
|
||||
begin
|
||||
preamble<=0;
|
||||
end
|
||||
end
|
||||
if (sending)
|
||||
begin //need next bit
|
||||
if(preamble)
|
||||
mod_sig_coil<=1;
|
||||
else
|
||||
mod_sig_coil<=~delayline[delay_read_ptr];
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
fccount<=fccount+1;
|
||||
|
||||
if ((fccount==`bitmhalf_212)&&(sending)) //flip modulation mid-bit
|
||||
begin
|
||||
mod_sig_coil<=~mod_sig_coil;//flip
|
||||
end
|
||||
end
|
||||
end //sim mode end
|
||||
|
||||
end
|
||||
|
||||
assign pwr_oe4 = mod_sig_coil & (mod_type == `TAGSIM_MODULATE)&sending;
|
||||
|
||||
endmodule
|
Loading…
Add table
Add a link
Reference in a new issue