]>
Commit | Line | Data |
---|---|---|
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 | |
e691fc45 | 42 | if(& adc_d[7:6]) after_hysteresis <= 1'b1; // if adc_d >= 196 |
43 | else if(~(| adc_d[7:4])) after_hysteresis <= 1'b0; // if adc_d <= 15 | |
6658905f | 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; | |
e691fc45 | 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 [7:0] rx_mod_edge_threshold; | |
6658905f | 92 | reg curbit; |
e691fc45 | 93 | // reg [12:0] average; |
94 | // wire signed [9:0] dif; | |
95 | ||
96 | // storage for two previous samples: | |
97 | reg [7:0] adc_d_1; | |
98 | reg [7:0] adc_d_2; | |
99 | reg [7:0] adc_d_3; | |
100 | reg [7:0] adc_d_4; | |
101 | ||
102 | // the filtered signal (filter performs noise reduction and edge detection) | |
103 | // (gaussian derivative) | |
104 | wire signed [10:0] adc_d_filtered; | |
105 | assign adc_d_filtered = (adc_d_4 << 1) + adc_d_3 - adc_d_1 - (adc_d << 1); | |
106 | ||
107 | // Registers to store steepest edges detected: | |
108 | reg [7:0] rx_mod_falling_edge_max; | |
109 | reg [7:0] rx_mod_rising_edge_max; | |
6658905f | 110 | |
111 | // A register to send the results to the arm | |
112 | reg signed [7:0] to_arm; | |
113 | ||
6658905f | 114 | |
115 | reg bit_to_arm; | |
116 | reg fdt_indicator, fdt_elapsed; | |
117 | reg [10:0] fdt_counter; | |
118 | reg [47:0] mod_sig_buf; | |
119 | wire mod_sig_buf_empty; | |
120 | reg [5:0] mod_sig_ptr; | |
121 | reg [3:0] mod_sig_flip; | |
122 | reg mod_sig, mod_sig_coil; | |
123 | reg temp_buffer_reset; | |
124 | reg sendbit; | |
125 | ||
126 | assign mod_sig_buf_empty = ~(|mod_sig_buf[47:0]); | |
127 | reg [2:0] ssp_frame_counter; | |
128 | ||
129 | // ADC data appears on the rising edge, so sample it on the falling edge | |
130 | always @(negedge adc_clk) | |
131 | begin | |
e691fc45 | 132 | // ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
133 | // relevant for TAGSIM_MOD only. Timing of Tag's answer to a command received from a reader | |
134 | // ISO14443-3 specifies: | |
135 | // fdt = 1172, if last bit was 0. | |
136 | // fdt = 1236, if last bit was 1. | |
137 | // the FPGA takes care for the 1172 delay. To achieve the additional 1236-1172=64 ticks delay, the ARM must send an additional correction bit (before the start bit). | |
138 | // The correction bit will be coded as 00010000, i.e. it adds 4 bits to the transmission stream, causing the required delay. | |
139 | if(fdt_counter == 11'd740) fdt_indicator = 1'b1; // fdt_indicator is true for 740 <= fdt_counter <= 1148. Ready to buffer data. (?) | |
140 | // Shouldn' this be 1236 - 720 = 516? (The mod_sig_buf can buffer 46 data bits, | |
141 | // i.e. a maximum delay of 46 * 16 = 720 adc_clk ticks) | |
6658905f | 142 | |
e691fc45 | 143 | if(fdt_counter == 11'd1148) // additional 16 (+ eventual n*128) adc_clk_ticks delay will be added by the mod_sig_buf below |
144 | // the remaining 8 ticks delay comes from the 8 ticks timing difference between reseting fdt_counter and the mod_sig_buf clock. | |
6658905f | 145 | begin |
146 | if(fdt_elapsed) | |
147 | begin | |
e691fc45 | 148 | if(negedge_cnt[3:0] == mod_sig_flip[3:0]) mod_sig_coil <= mod_sig; // start modulating (if mod_sig is already set) |
6658905f | 149 | end |
150 | else | |
151 | begin | |
e691fc45 | 152 | mod_sig_flip[3:0] <= negedge_cnt[3:0]; // exact timing of modulation |
153 | mod_sig_coil <= mod_sig; // modulate (if mod_sig is already set) | |
6658905f | 154 | fdt_elapsed = 1'b1; |
155 | fdt_indicator = 1'b0; | |
156 | ||
e691fc45 | 157 | if(~(| mod_sig_ptr[5:0])) mod_sig_ptr <= 6'b001001; // didn't receive a 1 yet. Delay next 1 by n*128 ticks. |
158 | else temp_buffer_reset = 1'b1; // else fix the buffer size at current position | |
6658905f | 159 | end |
160 | end | |
161 | else | |
162 | begin | |
e691fc45 | 163 | fdt_counter <= fdt_counter + 1; // Count until 1148 |
6658905f | 164 | end |
165 | ||
e691fc45 | 166 | |
167 | //------------------------------------------------------------------------------------------------------------------------------------------- | |
168 | // Relevant for READER_LISTEN only | |
169 | // look for steepest falling and rising edges: | |
170 | if (adc_d_filtered > 0) | |
171 | begin | |
172 | if (adc_d_filtered > rx_mod_falling_edge_max) | |
173 | rx_mod_falling_edge_max <= adc_d_filtered; | |
174 | end | |
175 | else | |
176 | begin | |
177 | if (-adc_d_filtered > rx_mod_rising_edge_max) | |
178 | rx_mod_rising_edge_max <= -adc_d_filtered; | |
179 | end | |
180 | ||
181 | // store previous samples for filtering and edge detection: | |
182 | adc_d_4 <= adc_d_3; | |
183 | adc_d_3 <= adc_d_2; | |
184 | adc_d_2 <= adc_d_1; | |
185 | adc_d_1 <= adc_d; | |
186 | ||
187 | ||
188 | ||
189 | if(& negedge_cnt[3:0]) // == 0xf == 15 | |
6658905f | 190 | begin |
e691fc45 | 191 | // Relevant for TAGSIM_MOD only (timing Tag's answer. See above) |
192 | // When there is a dip in the signal and not in (READER_MOD, READER_LISTEN, TAGSIM_MOD) | |
6658905f | 193 | if(~after_hysteresis && mod_sig_buf_empty && ~((mod_type == 3'b100) || (mod_type == 3'b011) || (mod_type == 3'b010))) // last condition to prevent reset |
194 | begin | |
195 | fdt_counter <= 11'd0; | |
196 | fdt_elapsed = 1'b0; | |
197 | fdt_indicator = 1'b0; | |
198 | temp_buffer_reset = 1'b0; | |
199 | mod_sig_ptr <= 6'b000000; | |
200 | end | |
201 | ||
e691fc45 | 202 | // Relevant for READER_LISTEN only |
203 | // detect modulation signal: if modulating, there must be a falling and a rising edge ... and vice versa | |
204 | if (rx_mod_falling_edge_max > 6 && rx_mod_rising_edge_max > 6) | |
205 | curbit = 1'b1; // modulation | |
6658905f | 206 | else |
e691fc45 | 207 | curbit = 1'b0; // no modulation |
208 | ||
209 | // prepare next edge detection: | |
210 | rx_mod_rising_edge_max <= 0; | |
211 | rx_mod_falling_edge_max <= 0; | |
212 | ||
213 | ||
6658905f | 214 | // What do we communicate to the ARM |
e691fc45 | 215 | if(mod_type == 3'b001) sendbit = after_hysteresis; // TAGSIM_LISTEN |
216 | else if(mod_type == 3'b010) // TAGSIM_MOD | |
6658905f | 217 | begin |
218 | if(fdt_counter > 11'd772) sendbit = mod_sig_coil; | |
219 | else sendbit = fdt_indicator; | |
220 | end | |
e691fc45 | 221 | else if(mod_type == 3'b011) sendbit = curbit; // READER_LISTEN |
222 | else sendbit = 1'b0; // READER_MOD, SNIFFER | |
6658905f | 223 | |
224 | end | |
225 | ||
e691fc45 | 226 | //------------------------------------------------------------------------------------------------------------------------------------------ |
227 | // Relevant for SNIFFER mode only. Prepare communication to ARM. | |
228 | if(negedge_cnt == 7'd63) | |
6658905f | 229 | begin |
230 | if(deep_modulation) | |
231 | begin | |
232 | to_arm <= {after_hysteresis_prev1,after_hysteresis_prev2,after_hysteresis_prev3,after_hysteresis,1'b0,1'b0,1'b0,1'b0}; | |
233 | end | |
234 | else | |
235 | begin | |
236 | to_arm <= {after_hysteresis_prev1,after_hysteresis_prev2,after_hysteresis_prev3,after_hysteresis,bit1,bit2,bit3,curbit}; | |
237 | end | |
238 | ||
239 | negedge_cnt <= 0; | |
240 | ||
e691fc45 | 241 | end |
6658905f | 242 | else |
243 | begin | |
244 | negedge_cnt <= negedge_cnt + 1; | |
245 | end | |
246 | ||
247 | if(negedge_cnt == 6'd15) | |
248 | begin | |
249 | after_hysteresis_prev1 <= after_hysteresis; | |
250 | bit1 <= curbit; | |
251 | end | |
252 | if(negedge_cnt == 6'd31) | |
253 | begin | |
254 | after_hysteresis_prev2 <= after_hysteresis; | |
255 | bit2 <= curbit; | |
256 | end | |
257 | if(negedge_cnt == 6'd47) | |
258 | begin | |
259 | after_hysteresis_prev3 <= after_hysteresis; | |
260 | bit3 <= curbit; | |
261 | end | |
262 | ||
e691fc45 | 263 | //-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
264 | // Relevant in TAGSIM_MOD only. Delay-Line to buffer data and send it at the correct time | |
265 | // Note: Data in READER_MOD is fed through this delay line as well. | |
266 | if(mod_type != 3'b000) // != SNIFFER | |
6658905f | 267 | begin |
e691fc45 | 268 | if(negedge_cnt[3:0] == 4'b1000) // == 0x8 |
6658905f | 269 | begin |
e691fc45 | 270 | // The modulation signal of the tag. The delay line is only relevant for TAGSIM_MOD, but used in other modes as well. |
271 | // Note: this means that even in READER_MOD, there will be an arbitrary delay depending on the time of a previous reset of fdt_counter and the time and | |
272 | // content of the next bit to be transmitted. | |
273 | mod_sig_buf[47:0] <= {mod_sig_buf[46:1], ssp_dout, 1'b0}; // shift in new data starting at mod_sig_buf[1]. mod_sig_buf[0] = 0 always. | |
274 | if((ssp_dout || (| mod_sig_ptr[5:0])) && ~fdt_elapsed) // buffer a 1 (and all subsequent data) until fdt_counter = 1148 adc_clk ticks. | |
275 | if(mod_sig_ptr == 6'b101110) // buffer overflow at 46 - this would mean data loss | |
6658905f | 276 | begin |
277 | mod_sig_ptr <= 6'b000000; | |
278 | end | |
e691fc45 | 279 | else mod_sig_ptr <= mod_sig_ptr + 1; // increase buffer (= increase delay by 16 adc_clk ticks). ptr always points to first 1. |
280 | else if(fdt_elapsed && ~temp_buffer_reset) | |
281 | // fdt_elapsed. If we didn't receive a 1 yet, ptr will be at 9 and not yet fixed. Otherwise temp_buffer_reset will be 1 already. | |
6658905f | 282 | begin |
e691fc45 | 283 | // wait for the next 1 after fdt_elapsed before fixing the delay and starting modulation. This ensures that the response can only happen |
284 | // at intervals of 8 * 16 = 128 adc_clk ticks intervals (as defined in ISO14443-3) | |
285 | if(ssp_dout) temp_buffer_reset = 1'b1; | |
286 | if(mod_sig_ptr == 6'b000010) mod_sig_ptr <= 6'b001001; // still nothing received, need to go for the next interval | |
287 | else mod_sig_ptr <= mod_sig_ptr - 1; // decrease buffer. | |
6658905f | 288 | end |
289 | else | |
e691fc45 | 290 | // mod_sig_ptr and therefore the delay is now fixed until fdt_counter is reset (this can happen in SNIFFER and TAGSIM_LISTEN mode only. Note that SNIFFER |
291 | // mode (3'b000) is the default and is active in FPGA_MAJOR_MODE_OFF if no other minor mode is explicitly requested. | |
6658905f | 292 | begin |
e691fc45 | 293 | // don't modulate with the correction bit (which is sent as 00010000, all other bits will come with at least 2 consecutive 1s) |
294 | // side effect: when ptr = 1 it will cancel the first 1 of every block of ones. Note: this would only be the case if we received a 1 just before fdt_elapsed. | |
6658905f | 295 | if(~mod_sig_buf[mod_sig_ptr-1] && ~mod_sig_buf[mod_sig_ptr+1]) mod_sig = 1'b0; |
e691fc45 | 296 | // finally, do the modulation: |
297 | else mod_sig = mod_sig_buf[mod_sig_ptr] & fdt_elapsed; | |
6658905f | 298 | end |
299 | end | |
300 | end | |
301 | ||
e691fc45 | 302 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
303 | // Communication to ARM (SSP Clock and data) | |
304 | // SNIFFER mode (ssp_clk = adc_clk / 8, ssp_frame clock = adc_clk / 64)): | |
6658905f | 305 | if(mod_type == 3'b000) |
306 | begin | |
307 | if(negedge_cnt[2:0] == 3'b100) | |
308 | ssp_clk <= 1'b0; | |
309 | ||
310 | if(negedge_cnt[2:0] == 3'b000) | |
311 | begin | |
312 | ssp_clk <= 1'b1; | |
313 | // Don't shift if we just loaded new data, obviously. | |
314 | if(negedge_cnt != 7'd0) | |
315 | begin | |
316 | to_arm[7:1] <= to_arm[6:0]; | |
317 | end | |
318 | end | |
319 | ||
320 | if(negedge_cnt[5:4] == 2'b00) | |
321 | ssp_frame = 1'b1; | |
322 | else | |
323 | ssp_frame = 1'b0; | |
324 | ||
325 | bit_to_arm = to_arm[7]; | |
326 | end | |
327 | else | |
e691fc45 | 328 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
329 | // Communication to ARM (SSP Clock and data) | |
330 | // all other modes (ssp_clk = adc_clk / 16, ssp_frame clock = adc_clk / 128): | |
6658905f | 331 | begin |
332 | if(negedge_cnt[3:0] == 4'b1000) ssp_clk <= 1'b0; | |
333 | ||
334 | if(negedge_cnt[3:0] == 4'b0111) | |
335 | begin | |
336 | if(ssp_frame_counter == 3'd7) ssp_frame_counter <= 3'd0; | |
337 | else ssp_frame_counter <= ssp_frame_counter + 1; | |
338 | end | |
339 | ||
340 | if(negedge_cnt[3:0] == 4'b0000) | |
341 | begin | |
342 | ssp_clk <= 1'b1; | |
343 | end | |
344 | ||
345 | ssp_frame = (ssp_frame_counter == 3'd7); | |
346 | ||
347 | bit_to_arm = sendbit; | |
348 | end | |
349 | ||
350 | end | |
351 | ||
352 | assign ssp_din = bit_to_arm; | |
353 | ||
e691fc45 | 354 | |
355 | // Modulating carrier (adc_clk/16, for TAGSIM_MOD only). Will be 0 for other modes. | |
6658905f | 356 | wire modulating_carrier; |
e691fc45 | 357 | assign modulating_carrier = (mod_sig_coil & negedge_cnt[3] & (mod_type == 3'b010)); // in TAGSIM_MOD only. Otherwise always 0. |
358 | ||
359 | // for READER_MOD only: drop carrier for mod_sig_coil==1 (pause), READER_LISTEN: carrier always on, others: carrier always off | |
360 | assign pwr_hi = (ck_1356megb & (((mod_type == 3'b100) & ~mod_sig_coil) || (mod_type == 3'b011))); | |
6658905f | 361 | |
6658905f | 362 | |
e691fc45 | 363 | // Enable HF antenna drivers: |
6658905f | 364 | assign pwr_oe1 = 1'b0; |
e691fc45 | 365 | assign pwr_oe3 = 1'b0; |
366 | ||
367 | // TAGSIM_MOD: short circuit antenna with different resistances (modulated by modulating_carrier) | |
368 | // for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms | |
369 | // for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms | |
6658905f | 370 | assign pwr_oe4 = modulating_carrier; |
6658905f | 371 | |
e691fc45 | 372 | // This is all LF, so doesn't matter. |
373 | assign pwr_oe2 = 1'b0; | |
374 | assign pwr_lo = 1'b0; | |
6658905f | 375 | |
376 | ||
377 | assign dbg = negedge_cnt[3]; | |
378 | ||
6658905f | 379 | endmodule |