R&Y: Added DAY RTA Tapp Card and Additional BKK BEM Stored Value Card AIDs to `aid_de...
[RRG-proxmark3.git] / fpga / hi_flite.v
blob8346e49f20719772ff8c19835c21e9a9d3dde9da
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
18 This code demodulates and modulates signal as described in ISO/IEC 18092.
19 That includes packets used for Felica, NFC Tag 3, etc. (which do overlap)
20 simple envelope following algorithm is used (modification of fail0verflow LF one)
21 is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave)
23 Speeds supported: only 212 kbps (fc/64) for now. Todo: 414 kbps
24 though for reader, the selection has to come from ARM. modulation waits for market sprocket -doesn't really mean anything
26 mod_type: bits 210:
27 bit 2 : reader drive/power on/off
28 bit 1 : speed bit, 0 : 212, 1 :424
29 bit 0 : listen or modulate
32 module hi_flite(
33 input ck_1356meg,
34 input [7:0] adc_d,
35 input [3:0] mod_type,
36 input ssp_dout,
38 output reg ssp_din,
39 output reg ssp_frame,
40 output reg ssp_clk,
41 output adc_clk,
42 output reg pwr_lo,
43 output reg pwr_hi,
44 output reg pwr_oe1,
45 output reg pwr_oe2,
46 output reg pwr_oe3,
47 output reg pwr_oe4,
48 output debug
51 assign debug = 0;
53 wire power = mod_type[2];
54 wire speed = mod_type[1];
55 wire disabl = mod_type[0];
57 // 512x64/fc -wait before ts0, 32768 ticks
58 // tslot: 256*64/fc
59 assign adc_clk = ck_1356meg;
61 ///heuristic values for initial thresholds. seem to work OK
62 `define imin 70 // (13'd256)
63 `define imax 180 // (-13'd256)
64 `define ithrmin 91 // -13'd8
65 `define ithrmax 160 // 13'd8
67 `define min_bitdelay_212 8
68 //minimum values and corresponding thresholds
69 reg [8:0] curmin=`imin;
70 reg [8:0] curminthres=`ithrmin;
71 reg [8:0] curmaxthres=`ithrmax;
72 reg [8:0] curmax=`imax;
74 //signal state, 1-not modulated, 0 -modulated
75 reg after_hysteresis = 1'b1;
77 //state machine for envelope tracking
78 reg [1:0] state = 1'd0;
80 //lower edge detected, trying to detect first bit of SYNC (b24d, 1011001001001101)
81 reg try_sync = 1'b0;
83 //detected first sync bit, phase frozen
84 reg did_sync=0;
86 `define bithalf_212 32 // half-bit length for 212 kbit
87 `define bitmlen_212 63 // bit transition edge
89 `define bithalf_424 16 // half-bit length for 212 kbit
90 `define bitmlen_424 31 // bit transition edge
92 wire [7:0] bithalf = speed ? `bithalf_424 : `bithalf_212;
93 wire [7:0] bitmlen = speed ? `bitmlen_424 : `bitmlen_212;
95 reg curbit = 1'b0;
97 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
99 reg [7:0] tsinceedge = 8'd0;// ticks from last edge, desync if the valye is too large
101 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
103 //ssp clock and current values
104 //ssp counter for transfer and framing
105 reg [8:0] ssp_cnt = 9'd0;
107 always @(posedge adc_clk)
108 ssp_cnt <= (ssp_cnt + 1);
110 //maybe change it so that ARM sends preamble as well.
111 //then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation
113 always @(negedge adc_clk)
114 begin
115 //count fc/64 - transfer bits to ARM at the rate they are received
116 if( ((~speed) && (ssp_cnt[5:0] == 6'b000000) ) || (speed && (ssp_cnt[4:0] == 5'b00000)) )
117 begin
118 ssp_clk <= 1'b1;
119 //send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise)
120 ssp_din <= curbit;
122 if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000))
123 ssp_clk <= 1'b0;
124 //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
125 // took me a day to figure THAT out.
126 if(( (~speed) && (ssp_cnt[8:0] == 9'd31)) || (speed && ssp_cnt[7:0] == 8'd15))
127 begin
128 ssp_frame <= 1'b1;
130 if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111)) || (speed &&ssp_cnt[7:0] == 8'b101111) )
131 begin
132 ssp_frame <= 1'b0;
136 //previous signal value, mostly to detect SYNC
137 reg prv = 1'b1;
139 // 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.
140 reg[7:0] mid = 8'd128;
142 // set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...)
143 // start sending over 1s on ssp->arm when we start sending preamble
144 // reg sending = 1'b0; // are we actively modulating?
145 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?
147 //we need some way to flush bit_counts triggers on mod_type changes don't compile
148 reg dlay;
149 always @(negedge adc_clk) // every data ping?
150 begin
151 //envelope follow code...
152 ////////////
153 if (fccount == bitmlen)
154 begin
155 if ((~try_sync) && (adc_d < curminthres) && disabl )
156 begin
157 fccount <= 1;
159 else
160 begin
161 fccount <= 0;
163 dlay <= ssp_dout;
164 if (bit_counts > 768) // should be over ts0 now, without ARM interference... stop counting...
165 begin
166 bit_counts <= 0;
168 else
169 if (power)
170 bit_counts <= 0;
171 else
172 bit_counts <= bit_counts + 1;
174 else
175 begin
176 if((~try_sync) && (adc_d < curminthres) && disabl)
177 begin
178 fccount <= 1;
180 else
181 begin
182 fccount <= fccount + 1;
186 // rising edge
187 if (adc_d > curmaxthres)
188 begin
189 case (state)
190 0: begin
191 curmax <= adc_d > `imax? adc_d : `imax;
192 state <= 2;
194 1: begin
195 curminthres <= ((curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4)); //threshold: 0.1875 max + 0.8125 min
196 curmaxthres <= ((curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4));
197 curmax <= adc_d > 155 ? adc_d : 155; // to hopefully prevent overflow from spikes going up to 255
198 state <= 2;
200 2: begin
201 if (adc_d > curmax)
202 curmax <= adc_d;
204 default:
205 begin
207 endcase
208 after_hysteresis <= 1'b1;
209 if(try_sync)
210 tsinceedge <= 0;
212 else if (adc_d<curminthres) //falling edge
213 begin
214 case (state)
215 0: begin
216 curmin <= adc_d<`imin? adc_d :`imin;
217 state <= 1;
219 1: begin
220 if (adc_d<curmin)
221 curmin <= adc_d;
223 2: begin
224 curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4));
225 curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4));
226 curmin <= adc_d < `imin ? adc_d : `imin;
227 state <= 1;
229 default:
230 begin
232 endcase
233 after_hysteresis <= 0;
234 if (~try_sync ) //begin modulation, lower edge...
235 begin
236 try_sync <= 1;
237 fccount <= 1;
238 did_sync <= 0;
239 curbit <= 0;
240 mid <= 8'd127;
241 tsinceedge <= 0;
242 prv <= 1;
244 else
245 begin
246 tsinceedge <= 0;
249 else //stable state, low or high
250 begin
251 curminthres <= ( (curmin >> 1) + (curmin >> 2) + (curmin >> 4) + (curmax >> 3) + (curmax >> 4));
252 curmaxthres <= ( (curmax >> 1) + (curmax >> 2) + (curmax >> 4) + (curmin >> 3) + (curmin >> 4));
253 state <= 0;
255 if (try_sync )
256 begin
257 if (tsinceedge >= (128))
258 begin
259 //we might need to start counting... assuming ARM wants to reply to the frame.
260 bit_counts <= 1;// i think? 128 is about 2 bits passed... but 1 also works
261 try_sync <= 0;
262 did_sync <= 0;//desync
263 curmin <= `imin; //reset envelope
264 curmax <= `imax;
265 curminthres <= `ithrmin;
266 curmaxthres <= `ithrmax;
267 prv <= 1;
268 tsinceedge <= 0;
269 after_hysteresis <= 1'b1;
270 curbit <= 0;
271 mid <= 8'd128;
273 else
274 tsinceedge <= (tsinceedge + 1);
278 if (try_sync && tsinceedge < 128)
279 begin
280 //detect bits in their middle ssp sampling is in sync, so it would sample all bits in order
281 if (fccount == bithalf)
282 begin
283 if ((~did_sync) && ((prv == 1 && (mid > 128))||(prv == 0 && (mid <= 128))))
284 begin
285 //sync the Zero, and set curbit roperly
286 did_sync <= 1'b1;
287 zero <= ~prv;// 1-prv
288 curbit <= 1;
290 else
291 curbit <= (mid > 128) ? (~zero) : zero;
293 prv <= (mid > 128) ? 1 : 0;
295 if (adc_d > curmaxthres)
296 mid <= 8'd129;
297 else if (adc_d < curminthres)
298 mid <= 8'd127;
299 else
300 begin
301 if (after_hysteresis)
302 begin
303 mid <= 8'd129;
305 else
306 begin
307 mid <= 8'd127;
311 else
312 begin
313 if (fccount==bitmlen)
314 begin
315 // fccount <= 0;
316 prv <= (mid > 128) ? 1 : 0;
317 mid <= 128;
319 else
320 begin
321 // minimum-maximum calc
322 if(adc_d > curmaxthres)
323 mid <= mid + 1;
324 else if (adc_d < curminthres)
325 mid <= mid - 1;
326 else
327 begin
328 if (after_hysteresis)
329 begin
330 mid <= mid + 1;
332 else
333 begin
334 mid <= mid - 1;
340 // sending <= 0;
343 //put modulation here to maintain the correct clock. Seems that some readers are sensitive to that
345 wire mod = ((fccount >= bithalf) ^ dlay) & (~disabl);
347 always @(ck_1356meg or ssp_dout or power or disabl or mod)
348 begin
349 if (power)
350 begin
351 pwr_hi <= ck_1356meg;
352 pwr_lo <= 1'b0;
353 pwr_oe1 <= 1'b0;//mod;
354 pwr_oe2 <= 1'b0;//mod;
355 pwr_oe3 <= 1'b0;//mod;
356 pwr_oe4 <= mod;//1'b0;
358 else
359 begin
360 pwr_hi <= 1'b0;
361 pwr_lo <= 1'b0;
362 pwr_oe1 <= 1'b0;
363 pwr_oe2 <= 1'b0;
364 pwr_oe3 <= 1'b0;
365 pwr_oe4 <= mod;
369 endmodule