]> cvs.zerfleddert.de Git - proxmark3-svn/blame - fpga/hi_iso14443a.v
Change section_start pointer to char** to prevent aliasing warnings on old toolchain
[proxmark3-svn] / fpga / hi_iso14443a.v
CommitLineData
6658905f 1//-----------------------------------------------------------------------------
2// ISO14443-A support for the Proxmark III
3// Gerhard de Koning Gans, April 2008
4//-----------------------------------------------------------------------------
5
6module hi_iso14443a(
7 pck0, ck_1356meg, ck_1356megb,
8 pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
9 adc_d, adc_clk,
10 ssp_frame, ssp_din, ssp_dout, ssp_clk,
11 cross_hi, cross_lo,
12 dbg,
13 mod_type
14);
15 input pck0, ck_1356meg, ck_1356megb;
16 output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
17 input [7:0] adc_d;
18 output adc_clk;
19 input ssp_dout;
20 output ssp_frame, ssp_din, ssp_clk;
21 input cross_hi, cross_lo;
22 output dbg;
23 input [2:0] mod_type;
24
25reg ssp_clk;
26reg ssp_frame;
27
28reg fc_div_2;
29always @(posedge ck_1356meg)
30 fc_div_2 = ~fc_div_2;
31
32wire adc_clk;
33assign adc_clk = ck_1356meg;
34
35reg after_hysteresis, after_hysteresis_prev1, after_hysteresis_prev2, after_hysteresis_prev3;
36reg [11:0] has_been_low_for;
37reg [8:0] saw_deep_modulation;
38reg [2:0] deep_counter;
39reg deep_modulation;
40always @(negedge adc_clk)
41begin
42 if(& adc_d[7:6]) after_hysteresis <= 1'b1;
43 else if(~(| adc_d[7:4])) after_hysteresis <= 1'b0;
44
45 if(~(| adc_d[7:0]))
46 begin
47 if(deep_counter == 3'd7)
48 begin
49 deep_modulation <= 1'b1;
50 saw_deep_modulation <= 8'd0;
51 end
52 else
53 deep_counter <= deep_counter + 1;
54 end
55 else
56 begin
57 deep_counter <= 3'd0;
58 if(saw_deep_modulation == 8'd255)
59 deep_modulation <= 1'b0;
60 else
61 saw_deep_modulation <= saw_deep_modulation + 1;
62 end
63
64 if(after_hysteresis)
65 begin
66 has_been_low_for <= 7'b0;
67 end
68 else
69 begin
70 if(has_been_low_for == 12'd4095)
71 begin
72 has_been_low_for <= 12'd0;
73 after_hysteresis <= 1'b1;
74 end
75 else
76 has_been_low_for <= has_been_low_for + 1;
77 end
78end
79
80// Report every 4 subcarrier cycles
81// 64 periods of carrier frequency => 6-bit counter [negedge_cnt]
82reg [5:0] negedge_cnt;
83reg bit1, bit2, bit3;
84reg [3:0] count_ones;
85reg [3:0] count_zeros;
86wire [7:0] avg;
87reg [7:0] lavg;
88reg signed [12:0] step1;
89reg signed [12:0] step2;
90reg [7:0] stepsize;
91reg curbit;
92reg [12:0] average;
93wire signed [9:0] dif;
94
95// A register to send the results to the arm
96reg signed [7:0] to_arm;
97
98assign avg[7:0] = average[11:4];
99assign dif = lavg - avg;
100
101reg bit_to_arm;
102reg fdt_indicator, fdt_elapsed;
103reg [10:0] fdt_counter;
104reg [47:0] mod_sig_buf;
105wire mod_sig_buf_empty;
106reg [5:0] mod_sig_ptr;
107reg [3:0] mod_sig_flip;
108reg mod_sig, mod_sig_coil;
109reg temp_buffer_reset;
110reg sendbit;
111
112assign mod_sig_buf_empty = ~(|mod_sig_buf[47:0]);
113reg [2:0] ssp_frame_counter;
114
115// ADC data appears on the rising edge, so sample it on the falling edge
116always @(negedge adc_clk)
117begin
118
119 // last bit = 0 then fdt = 1172, in case of 0x26 (7-bit command, LSB first!)
120 // last bit = 1 then fdt = 1236, in case of 0x52 (7-bit command, LSB first!)
121 if(fdt_counter == 11'd740) fdt_indicator = 1'b1;
122
123 if(fdt_counter == 11'd1148)
124 begin
125 if(fdt_elapsed)
126 begin
127 if(negedge_cnt[3:0] == mod_sig_flip[3:0]) mod_sig_coil <= mod_sig;
128 end
129 else
130 begin
131 mod_sig_flip[3:0] <= negedge_cnt[3:0];
132 mod_sig_coil <= mod_sig;
133 fdt_elapsed = 1'b1;
134 fdt_indicator = 1'b0;
135
136 if(~(| mod_sig_ptr[5:0])) mod_sig_ptr <= 6'b001001;
137 else temp_buffer_reset = 1'b1; // fix position of the buffer pointer
138 end
139 end
140 else
141 begin
142 fdt_counter <= fdt_counter + 1;
143 end
144
145 if(& negedge_cnt[3:0])
146 begin
147 // When there is a dip in the signal and not in reader mode
148 if(~after_hysteresis && mod_sig_buf_empty && ~((mod_type == 3'b100) || (mod_type == 3'b011) || (mod_type == 3'b010))) // last condition to prevent reset
149 begin
150 fdt_counter <= 11'd0;
151 fdt_elapsed = 1'b0;
152 fdt_indicator = 1'b0;
153 temp_buffer_reset = 1'b0;
154 mod_sig_ptr <= 6'b000000;
155 end
156
157 lavg <= avg;
158
159 if(stepsize<16) stepsize = 8'd16;
160
161 if(dif>0)
162 begin
163 step1 = dif*3;
164 step2 = stepsize*2; // 3:2
165 if(step1>step2)
166 begin
167 curbit = 1'b0;
168 stepsize = dif;
169 end
170 end
171 else
172 begin
173 step1 = dif*3;
174 step1 = -step1;
175 step2 = stepsize*2;
176 if(step1>step2)
177 begin
178 curbit = 1'b1;
179 stepsize = -dif;
180 end
181 end
182
183 if(curbit)
184 begin
185 count_zeros <= 4'd0;
186 if(& count_ones[3:2])
187 begin
188 curbit = 1'b0; // suppressed signal
189 stepsize = 8'd24; // just a fine number
190 end
191 else
192 begin
193 count_ones <= count_ones + 1;
194 end
195 end
196 else
197 begin
198 count_ones <= 4'd0;
199 if(& count_zeros[3:0])
200 begin
201 stepsize = 8'd24;
202 end
203 else
204 begin
205 count_zeros <= count_zeros + 1;
206 end
207 end
208
209 // What do we communicate to the ARM
210 if(mod_type == 3'b001) sendbit = after_hysteresis;
211 else if(mod_type == 3'b010)
212 begin
213 if(fdt_counter > 11'd772) sendbit = mod_sig_coil;
214 else sendbit = fdt_indicator;
215 end
216 else if(mod_type == 3'b011) sendbit = curbit;
217 else sendbit = 1'b0;
218
219 end
220
221 if(~(| negedge_cnt[3:0])) average <= adc_d;
222 else average <= average + adc_d;
223
224 if(negedge_cnt == 7'd63)
225 begin
226 if(deep_modulation)
227 begin
228 to_arm <= {after_hysteresis_prev1,after_hysteresis_prev2,after_hysteresis_prev3,after_hysteresis,1'b0,1'b0,1'b0,1'b0};
229 end
230 else
231 begin
232 to_arm <= {after_hysteresis_prev1,after_hysteresis_prev2,after_hysteresis_prev3,after_hysteresis,bit1,bit2,bit3,curbit};
233 end
234
235 negedge_cnt <= 0;
236
237 end
238 else
239 begin
240 negedge_cnt <= negedge_cnt + 1;
241 end
242
243 if(negedge_cnt == 6'd15)
244 begin
245 after_hysteresis_prev1 <= after_hysteresis;
246 bit1 <= curbit;
247 end
248 if(negedge_cnt == 6'd31)
249 begin
250 after_hysteresis_prev2 <= after_hysteresis;
251 bit2 <= curbit;
252 end
253 if(negedge_cnt == 6'd47)
254 begin
255 after_hysteresis_prev3 <= after_hysteresis;
256 bit3 <= curbit;
257 end
258
259
260 if(mod_type != 3'b000)
261 begin
262 if(negedge_cnt[3:0] == 4'b1000)
263 begin
264 // The modulation signal of the tag
265 mod_sig_buf[47:0] <= {mod_sig_buf[46:1], ssp_dout, 1'b0};
266 if((ssp_dout || (| mod_sig_ptr[5:0])) && ~fdt_elapsed)
267 if(mod_sig_ptr == 6'b101110)
268 begin
269 mod_sig_ptr <= 6'b000000;
270 end
271 else mod_sig_ptr <= mod_sig_ptr + 1;
272 else if(fdt_elapsed && ~temp_buffer_reset)
273 begin
274 if(ssp_dout) temp_buffer_reset = 1'b1;
275 if(mod_sig_ptr == 6'b000010) mod_sig_ptr <= 6'b001001;
276 else mod_sig_ptr <= mod_sig_ptr - 1;
277 end
278 else
279 begin
280 // side effect: when ptr = 1 it will cancel the first 1 of every block of ones
281 if(~mod_sig_buf[mod_sig_ptr-1] && ~mod_sig_buf[mod_sig_ptr+1]) mod_sig = 1'b0;
282 else mod_sig = mod_sig_buf[mod_sig_ptr] & fdt_elapsed; // & fdt_elapsed was for direct relay to oe4
283 end
284 end
285 end
286
287 // SSP Clock and data
288 if(mod_type == 3'b000)
289 begin
290 if(negedge_cnt[2:0] == 3'b100)
291 ssp_clk <= 1'b0;
292
293 if(negedge_cnt[2:0] == 3'b000)
294 begin
295 ssp_clk <= 1'b1;
296 // Don't shift if we just loaded new data, obviously.
297 if(negedge_cnt != 7'd0)
298 begin
299 to_arm[7:1] <= to_arm[6:0];
300 end
301 end
302
303 if(negedge_cnt[5:4] == 2'b00)
304 ssp_frame = 1'b1;
305 else
306 ssp_frame = 1'b0;
307
308 bit_to_arm = to_arm[7];
309 end
310 else
311 begin
312 if(negedge_cnt[3:0] == 4'b1000) ssp_clk <= 1'b0;
313
314 if(negedge_cnt[3:0] == 4'b0111)
315 begin
316 if(ssp_frame_counter == 3'd7) ssp_frame_counter <= 3'd0;
317 else ssp_frame_counter <= ssp_frame_counter + 1;
318 end
319
320 if(negedge_cnt[3:0] == 4'b0000)
321 begin
322 ssp_clk <= 1'b1;
323 end
324
325 ssp_frame = (ssp_frame_counter == 3'd7);
326
327 bit_to_arm = sendbit;
328 end
329
330end
331
332assign ssp_din = bit_to_arm;
333
334// Modulating carrier frequency is fc/16
335wire modulating_carrier;
336assign modulating_carrier = (mod_sig_coil & negedge_cnt[3] & (mod_type == 3'b010));
337assign pwr_hi = (ck_1356megb & (((mod_type == 3'b100) & ~mod_sig_coil) || (mod_type == 3'b011)));
338
339// This one is all LF, so doesn't matter
340//assign pwr_oe2 = modulating_carrier;
341assign pwr_oe2 = 1'b0;
342
343// Toggle only one of these, since we are already producing much deeper
344// modulation than a real tag would.
345//assign pwr_oe1 = modulating_carrier;
346assign pwr_oe1 = 1'b0;
347assign pwr_oe4 = modulating_carrier;
348//assign pwr_oe4 = 1'b0;
349
350// This one is always on, so that we can watch the carrier.
351//assign pwr_oe3 = modulating_carrier;
352assign pwr_oe3 = 1'b0;
353
354
355assign dbg = negedge_cnt[3];
356
357// Unused.
358assign pwr_lo = 1'b0;
359
360endmodule
Impressum, Datenschutz