]>
Commit | Line | Data |
---|---|---|
1 | //----------------------------------------------------------------------------- | |
2 | // ISO14443-A support for the Proxmark III | |
3 | // Gerhard de Koning Gans, April 2008 | |
4 | //----------------------------------------------------------------------------- | |
5 | ||
6 | module 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 | ||
25 | reg ssp_clk; | |
26 | reg ssp_frame; | |
27 | ||
28 | reg fc_div_2; | |
29 | always @(posedge ck_1356meg) | |
30 | fc_div_2 = ~fc_div_2; | |
31 | ||
32 | wire adc_clk; | |
33 | assign adc_clk = ck_1356meg; | |
34 | ||
35 | reg after_hysteresis, after_hysteresis_prev1, after_hysteresis_prev2, after_hysteresis_prev3; | |
36 | reg [11:0] has_been_low_for; | |
37 | reg [8:0] saw_deep_modulation; | |
38 | reg [2:0] deep_counter; | |
39 | reg deep_modulation; | |
40 | always @(negedge adc_clk) | |
41 | begin | |
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 | |
78 | end | |
79 | ||
80 | // Report every 4 subcarrier cycles | |
81 | // 64 periods of carrier frequency => 6-bit counter [negedge_cnt] | |
82 | reg [5:0] negedge_cnt; | |
83 | reg bit1, bit2, bit3; | |
84 | reg [3:0] count_ones; | |
85 | reg [3:0] count_zeros; | |
86 | wire [7:0] avg; | |
87 | reg [7:0] lavg; | |
88 | reg signed [12:0] step1; | |
89 | reg signed [12:0] step2; | |
90 | reg [7:0] stepsize; | |
91 | reg curbit; | |
92 | reg [12:0] average; | |
93 | wire signed [9:0] dif; | |
94 | ||
95 | // A register to send the results to the arm | |
96 | reg signed [7:0] to_arm; | |
97 | ||
98 | assign avg[7:0] = average[11:4]; | |
99 | assign dif = lavg - avg; | |
100 | ||
101 | reg bit_to_arm; | |
102 | reg fdt_indicator, fdt_elapsed; | |
103 | reg [10:0] fdt_counter; | |
104 | reg [47:0] mod_sig_buf; | |
105 | wire mod_sig_buf_empty; | |
106 | reg [5:0] mod_sig_ptr; | |
107 | reg [3:0] mod_sig_flip; | |
108 | reg mod_sig, mod_sig_coil; | |
109 | reg temp_buffer_reset; | |
110 | reg sendbit; | |
111 | ||
112 | assign mod_sig_buf_empty = ~(|mod_sig_buf[47:0]); | |
113 | reg [2:0] ssp_frame_counter; | |
114 | ||
115 | // ADC data appears on the rising edge, so sample it on the falling edge | |
116 | always @(negedge adc_clk) | |
117 | begin | |
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 | ||
330 | end | |
331 | ||
332 | assign ssp_din = bit_to_arm; | |
333 | ||
334 | // Modulating carrier frequency is fc/16 | |
335 | wire modulating_carrier; | |
336 | assign modulating_carrier = (mod_sig_coil & negedge_cnt[3] & (mod_type == 3'b010)); | |
337 | assign 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; | |
341 | assign 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; | |
346 | assign pwr_oe1 = 1'b0; | |
347 | assign 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; | |
352 | assign pwr_oe3 = 1'b0; | |
353 | ||
354 | ||
355 | assign dbg = negedge_cnt[3]; | |
356 | ||
357 | // Unused. | |
358 | assign pwr_lo = 1'b0; | |
359 | ||
360 | endmodule |