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