6658905f |
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 |