2 This code demodulates and modulates signal as described in ISO/IEC 18092.
3 That includes packets used for Felica, NFC Tag 3, etc. (which do overlap)
4 simple envelope following algorithm is used (modification of fail0verflow LF one)
5 is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave)
7 Speeds supported: only 212 kbps (fc/64) for now. Todo: 414 kbps
8 though for reader, the selection has to come from ARM. modulation waits for market sprocket -doesn't really mean anything
11 bit 2 : reader drive/power on/off
12 bit 1 : speed bit, 0 : 212, 1 :424
13 bit 0 : listen or modulate
18 pwr_lo
, pwr_hi
, pwr_oe1
, pwr_oe2
, pwr_oe3
, pwr_oe4
,
20 ssp_frame
, ssp_din
, ssp_dout
, ssp_clk
,
25 output pwr_lo
, pwr_hi
, pwr_oe1
, pwr_oe2
, pwr_oe3
, pwr_oe4
;
29 output ssp_frame
, ssp_din
, ssp_clk
;
35 wire power
= mod_type
[2];
36 wire speed
= mod_type
[1];
37 wire disabl
= mod_type
[0];
39 // Most off, oe4 for modulation;
40 // Trying reader emulation (would presumably just require switching power on, but I am not sure)
42 assign pwr_oe2
= 1'b0;
44 // 512x64/fc -wait before ts0, 32768 ticks
46 assign adc_clk
= ck_1356meg
;
48 ///heuristic values for initial thresholds. seem to work OK
49 `define imin 70 // (13'd256)
50 `define imax 180 // (-13'd256)
51 `define ithrmin 91 // -13'd8
52 `define ithrmax 160 // 13'd8
54 `define min_bitdelay_212 8
55 //minimum values and corresponding thresholds
56 reg [8:0] curmin
=`imin;
57 reg [8:0] curminthres
=`ithrmin;
58 reg [8:0] curmaxthres
=`ithrmax;
59 reg [8:0] curmax
=`imax;
61 //signal state, 1-not modulated, 0 -modulated
62 reg after_hysteresis
= 1'b1;
64 //state machine for envelope tracking
67 //lower edge detected, trying to detect first bit of SYNC (b24d, 1011001001001101)
70 //detected first sync bit, phase frozen
73 `define bithalf_212 32 // half-bit length for 212 kbit
74 `define bitmlen_212 63 // bit transition edge
76 `define bithalf_424 16 // half-bit length for 212 kbit
77 `define bitmlen_424 31 // bit transition edge
79 wire [7:0] bithalf
= speed ?
`bithalf_424 : `bithalf_212;
80 wire [7:0] bitmlen
= speed ?
`bitmlen_424 : `bitmlen_212;
83 //ssp clock and current values
88 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
90 reg [7:0] tsinceedge
= 8'd0;// ticks from last edge, desync if the valye is too large
92 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
94 //ssp counter for transfer and framing
95 reg [8:0] ssp_cnt
= 9'd0;
97 always @(posedge adc_clk
)
98 ssp_cnt
<= (ssp_cnt
+ 1);
100 //maybe change it so that ARM sends preamble as well.
101 //then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation
103 always @(negedge adc_clk
)
105 //count fc/64 - transfer bits to ARM at the rate they are received
106 if( ((~speed
) && (ssp_cnt
[5:0] == 6'b000000)) ||
(speed
&& (ssp_cnt
[4:0] == 5'b00000)))
111 if( ( (~speed
) && (ssp_cnt
[5:0] == 6'b100000)) ||
(speed
&& ssp_cnt
[4:0] == 5'b10000))
113 //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
114 // took me a day to figure THAT out.
115 if(( (~speed
) && (ssp_cnt
[8:0] == 9'd31)) ||
(speed
&& ssp_cnt
[7:0] == 8'd15))
119 if(( (~speed
) && (ssp_cnt
[8:0] == 9'b1011111)) ||
(speed
&&ssp_cnt
[7:0] == 8'b101111) )
125 //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise)
128 //previous signal value, mostly to detect SYNC
131 // 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.
132 reg[7:0] mid
= 8'd128;
134 // set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...)
135 // start sending over 1s on ssp->arm when we start sending preamble
136 // reg sending = 1'b0; // are we actively modulating?
137 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. might remove those?
140 //we need some way to flush bit_counts triggers on mod_type changes don't compile
142 always @(negedge adc_clk
) // every data ping?
144 //envelope follow code...
146 if (fccount
== bitmlen
)
148 if ((~try_sync
) && (adc_d
< curminthres
) && disabl
)
157 if (bit_counts
> 768) // should be over ts0 now, without ARM interference... stop counting...
165 bit_counts
<= bit_counts
+ 1;
169 if((~try_sync
) && (adc_d
< curminthres
) && disabl
)
175 fccount
<= fccount
+ 1;
180 if (adc_d
> curmaxthres
)
184 curmax
<= adc_d
> `imax? adc_d : `imax;
188 curminthres
<= ((curmin
>> 1) + (curmin
>> 2) + (curmin
>> 4) + (curmax
>> 3) + (curmax
>> 4)); //threshold: 0.1875 max + 0.8125 min
189 curmaxthres
<= ((curmax
>> 1) + (curmax
>> 2) + (curmax
>> 4) + (curmin
>> 3) + (curmin
>> 4));
190 curmax
<= adc_d
> 155 ? adc_d
: 155; // to hopefully prevent overflow from spikes going up to 255
201 after_hysteresis
<= 1'b1;
205 else if (adc_d
<curminthres
) //falling edge
209 curmin
<= adc_d
<`imin? adc_d :`imin;
217 curminthres
<= ( (curmin
>> 1) + (curmin
>> 2) + (curmin
>> 4) + (curmax
>> 3) + (curmax
>> 4));
218 curmaxthres
<= ( (curmax
>> 1) + (curmax
>> 2) + (curmax
>> 4) + (curmin
>> 3) + (curmin
>> 4));
219 curmin
<= adc_d
< `imin ? adc_d : `imin;
226 after_hysteresis
<= 0;
227 if (~try_sync
) //begin modulation, lower edge...
242 else //stable state, low or high
244 curminthres
<= ( (curmin
>> 1) + (curmin
>> 2) + (curmin
>> 4) + (curmax
>> 3) + (curmax
>> 4));
245 curmaxthres
<= ( (curmax
>> 1) + (curmax
>> 2) + (curmax
>> 4) + (curmin
>> 3) + (curmin
>> 4));
250 if (tsinceedge
>= (128))
252 //we might need to start counting... assuming ARM wants to reply to the frame.
253 bit_counts
<= 1;// i think? 128 is about 2 bits passed... but 1 also works
255 did_sync
<= 0;//desync
256 curmin
<= `imin; //reset envelope
258 curminthres
<= `ithrmin;
259 curmaxthres
<= `ithrmax;
262 after_hysteresis
<= 1'b1;
267 tsinceedge
<= (tsinceedge
+ 1);
272 if (try_sync
&& tsinceedge
< 128)
274 //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order
275 if (fccount
== bithalf
)
277 if ((~did_sync
) && ((prv
== 1 && (mid
> 128))||
(prv
== 0 && (mid
<= 128))))
279 //sync the Zero, and set curbit roperly
281 zero
<= ~prv
;// 1-prv
285 curbit
<= (mid
> 128) ?
(~zero
) : zero
;
287 prv
<= (mid
> 128) ?
1 : 0;
289 if (adc_d
> curmaxthres
)
291 else if (adc_d
< curminthres
)
295 if (after_hysteresis
)
308 if (fccount
==bitmlen
)
311 prv
<= (mid
> 128) ?
1 : 0;
316 // minimum-maximum calc
317 if(adc_d
> curmaxthres
)
319 else if (adc_d
< curminthres
)
323 if (after_hysteresis
)
340 //put modulation here to maintain the correct clock. Seems that some readers are sensitive to that
346 wire mod
= ((fccount
>= bithalf
) ^ dlay
) & (~disabl
);
348 always @(ck_1356meg
or ssp_dout
or power
or disabl
or mod
)
352 pwr_hi
<= ck_1356meg
;
353 pwr_oe1
<= 1'b0;//mod;
354 pwr_oe3
<= 1'b0;//mod;
355 pwr_oe4
<= mod
;//1'b0;