]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso15693.c
Merge branch 'master' into fix_iclass_sim
[proxmark3-svn] / armsrc / iso15693.c
CommitLineData
15c4dc5a 1//-----------------------------------------------------------------------------
bd20f8f4 2// Jonathan Westhues, split Nov 2006
3// Modified by Greg Jones, Jan 2009
e6304bca 4// Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
a66f26da 5// Modified by piwi, Oct 2018
bd20f8f4 6//
7// This code is licensed to you under the terms of the GNU GPL, version 2 or,
8// at your option, any later version. See the LICENSE.txt file for the text of
9// the license.
10//-----------------------------------------------------------------------------
15c4dc5a 11// Routines to support ISO 15693. This includes both the reader software and
8c6cca0b 12// the `fake tag' modes.
15c4dc5a 13//-----------------------------------------------------------------------------
8c6cca0b 14
15// The ISO 15693 describes two transmission modes from reader to tag, and four
16// transmission modes from tag to reader. As of Oct 2018 this code supports
17// both reader modes and the high speed variant with one subcarrier from card to reader.
18// As long as the card fully support ISO 15693 this is no problem, since the
a66f26da 19// reader chooses both data rates, but some non-standard tags do not.
8c6cca0b 20// For card simulation, the code supports both high and low speed modes with one subcarrier.
9455b51c 21//
22// VCD (reader) -> VICC (tag)
23// 1 out of 256:
a66f26da 24// data rate: 1,66 kbit/s (fc/8192)
25// used for long range
9455b51c 26// 1 out of 4:
a66f26da 27// data rate: 26,48 kbit/s (fc/512)
28// used for short range, high speed
8c6cca0b 29//
9455b51c 30// VICC (tag) -> VCD (reader)
31// Modulation:
a66f26da 32// ASK / one subcarrier (423,75 khz)
33// FSK / two subcarriers (423,75 khz && 484,28 khz)
9455b51c 34// Data Rates / Modes:
a66f26da 35// low ASK: 6,62 kbit/s
36// low FSK: 6.67 kbit/s
37// high ASK: 26,48 kbit/s
38// high FSK: 26,69 kbit/s
9455b51c 39//-----------------------------------------------------------------------------
9455b51c 40
41
42// Random Remarks:
43// *) UID is always used "transmission order" (LSB), which is reverse to display order
44
45// TODO / BUGS / ISSUES:
8c6cca0b 46// *) signal decoding is unable to detect collisions.
47// *) add anti-collision support for inventory-commands
e6304bca 48// *) read security status of a block
8c6cca0b 49// *) sniffing and simulation do not support two subcarrier modes.
d9de20fa 50// *) remove or refactor code under "deprecated"
9455b51c 51// *) document all the functions
52
d9de20fa 53#include "iso15693.h"
bd20f8f4 54
e30c654b 55#include "proxmark3.h"
f7e3ed82 56#include "util.h"
15c4dc5a 57#include "apps.h"
9ab7a6c7 58#include "string.h"
9455b51c 59#include "iso15693tools.h"
8c6cca0b 60#include "protocols.h"
902cb3c0 61#include "cmd.h"
d9de20fa 62#include "BigBuf.h"
fc52fbd4 63#include "fpgaloader.h"
15c4dc5a 64
15c4dc5a 65#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
66
70b2fc0a 67static int DEBUG = 0;
68
9455b51c 69///////////////////////////////////////////////////////////////////////
70// ISO 15693 Part 2 - Air Interface
3d2c9c9b 71// This section basically contains transmission and receiving of bits
9455b51c 72///////////////////////////////////////////////////////////////////////
73
8c6cca0b 74// buffers
3d2c9c9b 75#define ISO15693_DMA_BUFFER_SIZE 2048 // must be a power of 2
d9de20fa 76#define ISO15693_MAX_RESPONSE_LENGTH 36 // allows read single block with the maximum block size of 256bits. Read multiple blocks not supported yet
77#define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet
8c6cca0b 78
9455b51c 79// ---------------------------
8c6cca0b 80// Signal Processing
9455b51c 81// ---------------------------
82
83// prepare data using "1 out of 4" code for later transmission
8c6cca0b 84// resulting data rate is 26.48 kbit/s (fc/512)
9455b51c 85// cmd ... data
86// n ... length of data
f7e3ed82 87static void CodeIso15693AsReader(uint8_t *cmd, int n)
15c4dc5a 88{
89 int i, j;
90
91 ToSendReset();
92
93 // Give it a bit of slack at the beginning
94 for(i = 0; i < 24; i++) {
95 ToSendStuffBit(1);
96 }
97
9455b51c 98 // SOF for 1of4
15c4dc5a 99 ToSendStuffBit(0);
100 ToSendStuffBit(1);
101 ToSendStuffBit(1);
102 ToSendStuffBit(1);
103 ToSendStuffBit(1);
104 ToSendStuffBit(0);
105 ToSendStuffBit(1);
106 ToSendStuffBit(1);
107 for(i = 0; i < n; i++) {
108 for(j = 0; j < 8; j += 2) {
109 int these = (cmd[i] >> j) & 3;
110 switch(these) {
111 case 0:
112 ToSendStuffBit(1);
113 ToSendStuffBit(0);
114 ToSendStuffBit(1);
115 ToSendStuffBit(1);
116 ToSendStuffBit(1);
117 ToSendStuffBit(1);
118 ToSendStuffBit(1);
119 ToSendStuffBit(1);
120 break;
121 case 1:
122 ToSendStuffBit(1);
123 ToSendStuffBit(1);
124 ToSendStuffBit(1);
125 ToSendStuffBit(0);
126 ToSendStuffBit(1);
127 ToSendStuffBit(1);
128 ToSendStuffBit(1);
129 ToSendStuffBit(1);
130 break;
131 case 2:
132 ToSendStuffBit(1);
133 ToSendStuffBit(1);
134 ToSendStuffBit(1);
135 ToSendStuffBit(1);
136 ToSendStuffBit(1);
137 ToSendStuffBit(0);
138 ToSendStuffBit(1);
139 ToSendStuffBit(1);
140 break;
141 case 3:
142 ToSendStuffBit(1);
143 ToSendStuffBit(1);
144 ToSendStuffBit(1);
145 ToSendStuffBit(1);
146 ToSendStuffBit(1);
147 ToSendStuffBit(1);
148 ToSendStuffBit(1);
149 ToSendStuffBit(0);
150 break;
151 }
152 }
153 }
9455b51c 154 // EOF
15c4dc5a 155 ToSendStuffBit(1);
156 ToSendStuffBit(1);
157 ToSendStuffBit(0);
158 ToSendStuffBit(1);
159
70b2fc0a 160 // Fill remainder of last byte with 1
161 for(i = 0; i < 4; i++) {
15c4dc5a 162 ToSendStuffBit(1);
163 }
a66f26da 164
bdf96aae 165 ToSendMax++;
15c4dc5a 166}
167
70b2fc0a 168// encode data using "1 out of 256" scheme
8c6cca0b 169// data rate is 1,66 kbit/s (fc/8192)
9455b51c 170// is designed for more robust communication over longer distances
171static void CodeIso15693AsReader256(uint8_t *cmd, int n)
15c4dc5a 172{
15c4dc5a 173 int i, j;
174
9455b51c 175 ToSendReset();
176
177 // Give it a bit of slack at the beginning
178 for(i = 0; i < 24; i++) {
179 ToSendStuffBit(1);
180 }
181
182 // SOF for 1of256
183 ToSendStuffBit(0);
184 ToSendStuffBit(1);
185 ToSendStuffBit(1);
186 ToSendStuffBit(1);
187 ToSendStuffBit(1);
188 ToSendStuffBit(1);
189 ToSendStuffBit(1);
190 ToSendStuffBit(0);
8c6cca0b 191
15c4dc5a 192 for(i = 0; i < n; i++) {
9455b51c 193 for (j = 0; j<=255; j++) {
194 if (cmd[i]==j) {
195 ToSendStuffBit(1);
196 ToSendStuffBit(0);
15c4dc5a 197 } else {
9455b51c 198 ToSendStuffBit(1);
199 ToSendStuffBit(1);
8c6cca0b 200 }
201 }
15c4dc5a 202 }
9455b51c 203 // EOF
204 ToSendStuffBit(1);
205 ToSendStuffBit(1);
206 ToSendStuffBit(0);
207 ToSendStuffBit(1);
15c4dc5a 208
8c6cca0b 209 // Fill remainder of last byte with 1
210 for(i = 0; i < 4; i++) {
9455b51c 211 ToSendStuffBit(1);
212 }
8c6cca0b 213
214 ToSendMax++;
215}
216
217
3d2c9c9b 218// static uint8_t encode4Bits(const uint8_t b) {
219 // uint8_t c = b & 0xF;
220 // // OTA, the least significant bits first
221 // // The columns are
222 // // 1 - Bit value to send
223 // // 2 - Reversed (big-endian)
224 // // 3 - Manchester Encoded
225 // // 4 - Hex values
226
227 // switch(c){
228 // // 1 2 3 4
229 // case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55
230 // case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95
231 // case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65
232 // case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5
233 // case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59
234 // case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99
235 // case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69
236 // case 8: return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9
237 // case 7: return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56
238 // case 6: return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96
239 // case 5: return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66
240 // case 4: return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6
241 // case 3: return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a
242 // case 2: return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a
243 // case 1: return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a
244 // default: return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
245
246 // }
247// }
248
249void CodeIso15693AsTag(uint8_t *cmd, size_t len) {
250 /*
251 * SOF comprises 3 parts;
252 * * An unmodulated time of 56.64 us
253 * * 24 pulses of 423.75 kHz (fc/32)
254 * * A logic 1, which starts with an unmodulated time of 18.88us
255 * followed by 8 pulses of 423.75kHz (fc/32)
256 *
257 * EOF comprises 3 parts:
258 * - A logic 0 (which starts with 8 pulses of fc/32 followed by an unmodulated
259 * time of 18.88us.
260 * - 24 pulses of fc/32
261 * - An unmodulated time of 56.64 us
262 *
263 * A logic 0 starts with 8 pulses of fc/32
264 * followed by an unmodulated time of 256/fc (~18,88us).
265 *
266 * A logic 0 starts with unmodulated time of 256/fc (~18,88us) followed by
267 * 8 pulses of fc/32 (also 18.88us)
268 *
269 * A bit here becomes 8 pulses of fc/32. Therefore:
270 * The SOF can be written as 00011101 = 0x1D
271 * The EOF can be written as 10111000 = 0xb8
272 * A logic 1 is 01
273 * A logic 0 is 10
274 *
275 * */
276
8c6cca0b 277 ToSendReset();
278
279 // SOF
3d2c9c9b 280 ToSend[++ToSendMax] = 0x1D; // 00011101
8c6cca0b 281
282 // data
3d2c9c9b 283 for(int i = 0; i < len; i++) {
8c6cca0b 284 for(int j = 0; j < 8; j++) {
285 if ((cmd[i] >> j) & 0x01) {
286 ToSendStuffBit(0);
287 ToSendStuffBit(1);
288 } else {
289 ToSendStuffBit(1);
290 ToSendStuffBit(0);
291 }
292 }
293 }
294
295 // EOF
3d2c9c9b 296 ToSend[++ToSendMax] = 0xB8; // 10111000
8c6cca0b 297
298 ToSendMax++;
15c4dc5a 299}
300
9455b51c 301
70b2fc0a 302// Transmit the command (to the tag) that was placed in cmd[].
d9de20fa 303static void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t start_time)
15c4dc5a 304{
5ea2a248 305 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_FULL_MOD);
306 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
15c4dc5a 307
5ea2a248 308 while (GetCountSspClk() < start_time) ;
d9de20fa 309
70b2fc0a 310 LED_B_ON();
5ea2a248 311 for(int c = 0; c < len; c++) {
312 uint8_t data = cmd[c];
313 for (int i = 0; i < 8; i++) {
314 uint16_t send_word = (data & 0x80) ? 0x0000 : 0xffff;
315 while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
316 AT91C_BASE_SSC->SSC_THR = send_word;
317 while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
318 AT91C_BASE_SSC->SSC_THR = send_word;
319 data <<= 1;
320 }
321 WDT_HIT();
322 }
70b2fc0a 323 LED_B_OFF();
15c4dc5a 324}
325
5ea2a248 326
15c4dc5a 327//-----------------------------------------------------------------------------
8c6cca0b 328// Transmit the tag response (to the reader) that was placed in cmd[].
15c4dc5a 329//-----------------------------------------------------------------------------
3d2c9c9b 330void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t start_time, bool slow) {
8c6cca0b 331 // don't use the FPGA_HF_SIMULATOR_MODULATE_424K_8BIT minor mode. It would spoil GetCountSspClk()
70b2fc0a 332 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K);
15c4dc5a 333
8c6cca0b 334 uint8_t shift_delay = start_time & 0x00000007;
8c6cca0b 335
336 while (GetCountSspClk() < (start_time & 0xfffffff8)) ;
d9de20fa 337
70b2fc0a 338 LED_C_ON();
8c6cca0b 339 uint8_t bits_to_shift = 0x00;
3d2c9c9b 340 uint8_t bits_to_send = 0x00;
a66f26da 341 for(size_t c = 0; c < len; c++) {
8c6cca0b 342 for (int i = 7; i >= 0; i--) {
3d2c9c9b 343 uint8_t cmd_bits = ((cmd[c] >> i) & 0x01) ? 0xff : 0x00;
8c6cca0b 344 for (int j = 0; j < (slow?4:1); ) {
345 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
a66f26da 346 bits_to_send = bits_to_shift << (8 - shift_delay) | cmd_bits >> shift_delay;
3d2c9c9b 347 AT91C_BASE_SSC->SSC_THR = bits_to_send;
a66f26da 348 bits_to_shift = cmd_bits;
8c6cca0b 349 j++;
350 }
8c6cca0b 351 }
a66f26da 352 }
3d2c9c9b 353 WDT_HIT();
a66f26da 354 }
3d2c9c9b 355 // send the remaining bits, padded with 0:
356 bits_to_send = bits_to_shift << (8 - shift_delay);
357 for ( ; ; ) {
358 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
359 AT91C_BASE_SSC->SSC_THR = bits_to_send;
360 break;
361 }
362 }
70b2fc0a 363 LED_C_OFF();
3d2c9c9b 364
15c4dc5a 365}
366
9455b51c 367
70b2fc0a 368//=============================================================================
8c6cca0b 369// An ISO 15693 decoder for tag responses (one subcarrier only).
d9de20fa 370// Uses cross correlation to identify each bit and EOF.
70b2fc0a 371// This function is called 8 times per bit (every 2 subcarrier cycles).
8c6cca0b 372// Subcarrier frequency fs is 424kHz, 1/fs = 2,36us,
70b2fc0a 373// i.e. function is called every 4,72us
374// LED handling:
375// LED C -> ON once we have received the SOF and are expecting the rest.
376// LED C -> OFF once we have received EOF or are unsynced
377//
378// Returns: true if we received a EOF
379// false if we are still waiting for some more
380//=============================================================================
381
c0e7527d 382#define NOISE_THRESHOLD 160 // don't try to correlate noise
70b2fc0a 383
8c6cca0b 384typedef struct DecodeTag {
70b2fc0a 385 enum {
d9de20fa 386 STATE_TAG_SOF_LOW,
387 STATE_TAG_SOF_HIGH,
388 STATE_TAG_SOF_HIGH_END,
8c6cca0b 389 STATE_TAG_RECEIVING_DATA,
d9de20fa 390 STATE_TAG_EOF
70b2fc0a 391 } state;
392 int bitCount;
393 int posCount;
394 enum {
395 LOGIC0,
396 LOGIC1,
397 SOF_PART1,
398 SOF_PART2
399 } lastBit;
400 uint16_t shiftReg;
d9de20fa 401 uint16_t max_len;
70b2fc0a 402 uint8_t *output;
403 int len;
404 int sum1, sum2;
8c6cca0b 405} DecodeTag_t;
70b2fc0a 406
d9de20fa 407
408static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag)
15c4dc5a 409{
8c6cca0b 410 switch(DecodeTag->state) {
a66f26da 411 case STATE_TAG_SOF_LOW:
d9de20fa 412 // waiting for 12 times low (11 times low is accepted as well)
413 if (amplitude < NOISE_THRESHOLD) {
8c6cca0b 414 DecodeTag->posCount++;
70b2fc0a 415 } else {
d9de20fa 416 if (DecodeTag->posCount > 10) {
417 DecodeTag->posCount = 1;
418 DecodeTag->sum1 = 0;
419 DecodeTag->state = STATE_TAG_SOF_HIGH;
420 } else {
421 DecodeTag->posCount = 0;
422 }
15c4dc5a 423 }
d9de20fa 424 break;
a66f26da 425
d9de20fa 426 case STATE_TAG_SOF_HIGH:
427 // waiting for 10 times high. Take average over the last 8
428 if (amplitude > NOISE_THRESHOLD) {
429 DecodeTag->posCount++;
430 if (DecodeTag->posCount > 2) {
431 DecodeTag->sum1 += amplitude; // keep track of average high value
432 }
433 if (DecodeTag->posCount == 10) {
434 DecodeTag->sum1 >>= 4; // calculate half of average high value (8 samples)
435 DecodeTag->state = STATE_TAG_SOF_HIGH_END;
436 }
437 } else { // high phase was too short
438 DecodeTag->posCount = 1;
439 DecodeTag->state = STATE_TAG_SOF_LOW;
70b2fc0a 440 }
70b2fc0a 441 break;
442
d9de20fa 443 case STATE_TAG_SOF_HIGH_END:
444 // waiting for a falling edge
445 if (amplitude < DecodeTag->sum1) { // signal drops below 50% average high: a falling edge
446 DecodeTag->lastBit = SOF_PART1; // detected 1st part of SOF (12 samples low and 12 samples high)
447 DecodeTag->shiftReg = 0;
448 DecodeTag->bitCount = 0;
449 DecodeTag->len = 0;
450 DecodeTag->sum1 = amplitude;
8c6cca0b 451 DecodeTag->sum2 = 0;
452 DecodeTag->posCount = 2;
453 DecodeTag->state = STATE_TAG_RECEIVING_DATA;
70b2fc0a 454 LED_C_ON();
d9de20fa 455 } else {
456 DecodeTag->posCount++;
457 if (DecodeTag->posCount > 13) { // high phase too long
458 DecodeTag->posCount = 0;
459 DecodeTag->state = STATE_TAG_SOF_LOW;
460 LED_C_OFF();
461 }
70b2fc0a 462 }
70b2fc0a 463 break;
15c4dc5a 464
8c6cca0b 465 case STATE_TAG_RECEIVING_DATA:
466 if (DecodeTag->posCount == 1) {
467 DecodeTag->sum1 = 0;
468 DecodeTag->sum2 = 0;
70b2fc0a 469 }
8c6cca0b 470 if (DecodeTag->posCount <= 4) {
d9de20fa 471 DecodeTag->sum1 += amplitude;
70b2fc0a 472 } else {
d9de20fa 473 DecodeTag->sum2 += amplitude;
70b2fc0a 474 }
8c6cca0b 475 if (DecodeTag->posCount == 8) {
d9de20fa 476 int32_t corr_1 = DecodeTag->sum2 - DecodeTag->sum1;
477 int32_t corr_0 = -corr_1;
478 int32_t corr_EOF = (DecodeTag->sum1 + DecodeTag->sum2) / 2;
70b2fc0a 479 if (corr_EOF > corr_0 && corr_EOF > corr_1) {
d9de20fa 480 if (DecodeTag->lastBit == LOGIC0) { // this was already part of EOF
481 DecodeTag->state = STATE_TAG_EOF;
482 } else {
483 DecodeTag->posCount = 0;
484 DecodeTag->state = STATE_TAG_SOF_LOW;
485 LED_C_OFF();
486 }
70b2fc0a 487 } else if (corr_1 > corr_0) {
488 // logic 1
8c6cca0b 489 if (DecodeTag->lastBit == SOF_PART1) { // still part of SOF
d9de20fa 490 DecodeTag->lastBit = SOF_PART2; // SOF completed
70b2fc0a 491 } else {
8c6cca0b 492 DecodeTag->lastBit = LOGIC1;
493 DecodeTag->shiftReg >>= 1;
494 DecodeTag->shiftReg |= 0x80;
495 DecodeTag->bitCount++;
496 if (DecodeTag->bitCount == 8) {
497 DecodeTag->output[DecodeTag->len] = DecodeTag->shiftReg;
498 DecodeTag->len++;
d9de20fa 499 if (DecodeTag->len > DecodeTag->max_len) {
500 // buffer overflow, give up
501 DecodeTag->posCount = 0;
502 DecodeTag->state = STATE_TAG_SOF_LOW;
503 LED_C_OFF();
504 }
8c6cca0b 505 DecodeTag->bitCount = 0;
506 DecodeTag->shiftReg = 0;
70b2fc0a 507 }
508 }
509 } else {
510 // logic 0
8c6cca0b 511 if (DecodeTag->lastBit == SOF_PART1) { // incomplete SOF
d9de20fa 512 DecodeTag->posCount = 0;
513 DecodeTag->state = STATE_TAG_SOF_LOW;
70b2fc0a 514 LED_C_OFF();
515 } else {
8c6cca0b 516 DecodeTag->lastBit = LOGIC0;
517 DecodeTag->shiftReg >>= 1;
518 DecodeTag->bitCount++;
519 if (DecodeTag->bitCount == 8) {
520 DecodeTag->output[DecodeTag->len] = DecodeTag->shiftReg;
521 DecodeTag->len++;
d9de20fa 522 if (DecodeTag->len > DecodeTag->max_len) {
523 // buffer overflow, give up
524 DecodeTag->posCount = 0;
525 DecodeTag->state = STATE_TAG_SOF_LOW;
526 LED_C_OFF();
527 }
8c6cca0b 528 DecodeTag->bitCount = 0;
529 DecodeTag->shiftReg = 0;
70b2fc0a 530 }
531 }
532 }
8c6cca0b 533 DecodeTag->posCount = 0;
70b2fc0a 534 }
8c6cca0b 535 DecodeTag->posCount++;
70b2fc0a 536 break;
8c6cca0b 537
d9de20fa 538 case STATE_TAG_EOF:
539 if (DecodeTag->posCount == 1) {
540 DecodeTag->sum1 = 0;
541 DecodeTag->sum2 = 0;
542 }
543 if (DecodeTag->posCount <= 4) {
544 DecodeTag->sum1 += amplitude;
70b2fc0a 545 } else {
d9de20fa 546 DecodeTag->sum2 += amplitude;
70b2fc0a 547 }
d9de20fa 548 if (DecodeTag->posCount == 8) {
549 int32_t corr_1 = DecodeTag->sum2 - DecodeTag->sum1;
550 int32_t corr_0 = -corr_1;
551 int32_t corr_EOF = (DecodeTag->sum1 + DecodeTag->sum2) / 2;
552 if (corr_EOF > corr_0 || corr_1 > corr_0) {
553 DecodeTag->posCount = 0;
554 DecodeTag->state = STATE_TAG_SOF_LOW;
555 LED_C_OFF();
556 } else {
557 LED_C_OFF();
558 return true;
559 }
560 }
561 DecodeTag->posCount++;
70b2fc0a 562 break;
563
15c4dc5a 564 }
15c4dc5a 565
70b2fc0a 566 return false;
567}
15c4dc5a 568
15c4dc5a 569
d9de20fa 570static void DecodeTagInit(DecodeTag_t *DecodeTag, uint8_t *data, uint16_t max_len)
70b2fc0a 571{
d9de20fa 572 DecodeTag->posCount = 0;
573 DecodeTag->state = STATE_TAG_SOF_LOW;
8c6cca0b 574 DecodeTag->output = data;
d9de20fa 575 DecodeTag->max_len = max_len;
576}
577
578
579static void DecodeTagReset(DecodeTag_t *DecodeTag)
580{
581 DecodeTag->posCount = 0;
582 DecodeTag->state = STATE_TAG_SOF_LOW;
70b2fc0a 583}
584
d9de20fa 585
70b2fc0a 586/*
8c6cca0b 587 * Receive and decode the tag response, also log to tracebuffer
70b2fc0a 588 */
d9de20fa 589static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int timeout)
70b2fc0a 590{
d9de20fa 591 int samples = 0;
70b2fc0a 592 bool gotFrame = false;
70b2fc0a 593
d9de20fa 594 uint16_t *dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
a66f26da 595
8c6cca0b 596 // the Decoder data structure
d9de20fa 597 DecodeTag_t DecodeTag = { 0 };
598 DecodeTagInit(&DecodeTag, response, max_len);
70b2fc0a 599
600 // wait for last transfer to complete
601 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
602
603 // And put the FPGA in the appropriate mode
5ea2a248 604 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE);
70b2fc0a 605
606 // Setup and start DMA.
5ea2a248 607 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
70b2fc0a 608 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
70b2fc0a 609 uint16_t *upTo = dmaBuf;
70b2fc0a 610
611 for(;;) {
d9de20fa 612 uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
70b2fc0a 613
d9de20fa 614 if (behindBy == 0) continue;
8c6cca0b 615
d9de20fa 616 uint16_t tagdata = *upTo++;
70b2fc0a 617
70b2fc0a 618 if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
619 upTo = dmaBuf; // start reading the circular buffer from the beginning
d9de20fa 620 if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
621 Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);
622 break;
623 }
15c4dc5a 624 }
70b2fc0a 625 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
626 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
627 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
15c4dc5a 628 }
d9de20fa 629
70b2fc0a 630 samples++;
15c4dc5a 631
d9de20fa 632 if (Handle15693SamplesFromTag(tagdata, &DecodeTag)) {
70b2fc0a 633 gotFrame = true;
634 break;
635 }
15c4dc5a 636
d9de20fa 637 if (samples > timeout && DecodeTag.state < STATE_TAG_RECEIVING_DATA) {
8c6cca0b 638 DecodeTag.len = 0;
70b2fc0a 639 break;
640 }
8c6cca0b 641
70b2fc0a 642 }
643
644 FpgaDisableSscDma();
d9de20fa 645 BigBuf_free();
a66f26da 646
d9de20fa 647 if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
a66f26da 648 samples, gotFrame, DecodeTag.state, DecodeTag.len, DecodeTag.bitCount, DecodeTag.posCount);
70b2fc0a 649
d9de20fa 650 if (DecodeTag.len > 0) {
8c6cca0b 651 LogTrace(DecodeTag.output, DecodeTag.len, 0, 0, NULL, false);
70b2fc0a 652 }
653
8c6cca0b 654 return DecodeTag.len;
15c4dc5a 655}
656
9455b51c 657
8c6cca0b 658//=============================================================================
659// An ISO15693 decoder for reader commands.
660//
661// This function is called 4 times per bit (every 2 subcarrier cycles).
662// Subcarrier frequency fs is 848kHz, 1/fs = 1,18us, i.e. function is called every 2,36us
663// LED handling:
664// LED B -> ON once we have received the SOF and are expecting the rest.
665// LED B -> OFF once we have received EOF or are in error state or unsynced
666//
667// Returns: true if we received a EOF
668// false if we are still waiting for some more
669//=============================================================================
670
671typedef struct DecodeReader {
672 enum {
673 STATE_READER_UNSYNCD,
5b12974a 674 STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF,
8c6cca0b 675 STATE_READER_AWAIT_1ST_RISING_EDGE_OF_SOF,
676 STATE_READER_AWAIT_2ND_FALLING_EDGE_OF_SOF,
677 STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF,
678 STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4,
679 STATE_READER_RECEIVE_DATA_1_OUT_OF_4,
680 STATE_READER_RECEIVE_DATA_1_OUT_OF_256
681 } state;
682 enum {
683 CODING_1_OUT_OF_4,
684 CODING_1_OUT_OF_256
685 } Coding;
686 uint8_t shiftReg;
687 uint8_t bitCount;
688 int byteCount;
689 int byteCountMax;
690 int posCount;
a66f26da 691 int sum1, sum2;
8c6cca0b 692 uint8_t *output;
693} DecodeReader_t;
694
695
d9de20fa 696static void DecodeReaderInit(DecodeReader_t* DecodeReader, uint8_t *data, uint16_t max_len)
697{
698 DecodeReader->output = data;
699 DecodeReader->byteCountMax = max_len;
700 DecodeReader->state = STATE_READER_UNSYNCD;
701 DecodeReader->byteCount = 0;
702 DecodeReader->bitCount = 0;
703 DecodeReader->posCount = 1;
704 DecodeReader->shiftReg = 0;
705}
706
707
708static void DecodeReaderReset(DecodeReader_t* DecodeReader)
709{
710 DecodeReader->state = STATE_READER_UNSYNCD;
711}
712
713
714static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uint8_t bit, DecodeReader_t *restrict DecodeReader)
15c4dc5a 715{
3d2c9c9b 716 switch (DecodeReader->state) {
8c6cca0b 717 case STATE_READER_UNSYNCD:
5b12974a 718 // wait for unmodulated carrier
719 if (bit) {
720 DecodeReader->state = STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF;
721 }
722 break;
723
724 case STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF:
3d2c9c9b 725 if (!bit) {
8c6cca0b 726 // we went low, so this could be the beginning of a SOF
8c6cca0b 727 DecodeReader->posCount = 1;
d9de20fa 728 DecodeReader->state = STATE_READER_AWAIT_1ST_RISING_EDGE_OF_SOF;
8c6cca0b 729 }
730 break;
15c4dc5a 731
8c6cca0b 732 case STATE_READER_AWAIT_1ST_RISING_EDGE_OF_SOF:
733 DecodeReader->posCount++;
3d2c9c9b 734 if (bit) { // detected rising edge
735 if (DecodeReader->posCount < 4) { // rising edge too early (nominally expected at 5)
5b12974a 736 DecodeReader->state = STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF;
8c6cca0b 737 } else { // SOF
738 DecodeReader->state = STATE_READER_AWAIT_2ND_FALLING_EDGE_OF_SOF;
739 }
740 } else {
3d2c9c9b 741 if (DecodeReader->posCount > 5) { // stayed low for too long
d9de20fa 742 DecodeReaderReset(DecodeReader);
8c6cca0b 743 } else {
744 // do nothing, keep waiting
745 }
746 }
747 break;
748
749 case STATE_READER_AWAIT_2ND_FALLING_EDGE_OF_SOF:
750 DecodeReader->posCount++;
3d2c9c9b 751 if (!bit) { // detected a falling edge
8c6cca0b 752 if (DecodeReader->posCount < 20) { // falling edge too early (nominally expected at 21 earliest)
d9de20fa 753 DecodeReaderReset(DecodeReader);
8c6cca0b 754 } else if (DecodeReader->posCount < 23) { // SOF for 1 out of 4 coding
755 DecodeReader->Coding = CODING_1_OUT_OF_4;
756 DecodeReader->state = STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF;
757 } else if (DecodeReader->posCount < 28) { // falling edge too early (nominally expected at 29 latest)
d9de20fa 758 DecodeReaderReset(DecodeReader);
5b12974a 759 } else { // SOF for 1 out of 256 coding
8c6cca0b 760 DecodeReader->Coding = CODING_1_OUT_OF_256;
761 DecodeReader->state = STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF;
762 }
763 } else {
3d2c9c9b 764 if (DecodeReader->posCount > 29) { // stayed high for too long
5b12974a 765 DecodeReader->state = STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF;
8c6cca0b 766 } else {
767 // do nothing, keep waiting
768 }
769 }
770 break;
771
772 case STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF:
773 DecodeReader->posCount++;
774 if (bit) { // detected rising edge
775 if (DecodeReader->Coding == CODING_1_OUT_OF_256) {
776 if (DecodeReader->posCount < 32) { // rising edge too early (nominally expected at 33)
5b12974a 777 DecodeReader->state = STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF;
8c6cca0b 778 } else {
779 DecodeReader->posCount = 1;
780 DecodeReader->bitCount = 0;
781 DecodeReader->byteCount = 0;
782 DecodeReader->sum1 = 1;
783 DecodeReader->state = STATE_READER_RECEIVE_DATA_1_OUT_OF_256;
784 LED_B_ON();
785 }
786 } else { // CODING_1_OUT_OF_4
787 if (DecodeReader->posCount < 24) { // rising edge too early (nominally expected at 25)
5b12974a 788 DecodeReader->state = STATE_READER_AWAIT_1ST_FALLING_EDGE_OF_SOF;
8c6cca0b 789 } else {
5b12974a 790 DecodeReader->posCount = 1;
8c6cca0b 791 DecodeReader->state = STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4;
792 }
793 }
794 } else {
795 if (DecodeReader->Coding == CODING_1_OUT_OF_256) {
796 if (DecodeReader->posCount > 34) { // signal stayed low for too long
5b12974a 797 DecodeReaderReset(DecodeReader);
8c6cca0b 798 } else {
799 // do nothing, keep waiting
800 }
801 } else { // CODING_1_OUT_OF_4
802 if (DecodeReader->posCount > 26) { // signal stayed low for too long
5b12974a 803 DecodeReaderReset(DecodeReader);
8c6cca0b 804 } else {
805 // do nothing, keep waiting
806 }
807 }
808 }
809 break;
810
811 case STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4:
812 DecodeReader->posCount++;
813 if (bit) {
5b12974a 814 if (DecodeReader->posCount == 9) {
8c6cca0b 815 DecodeReader->posCount = 1;
816 DecodeReader->bitCount = 0;
817 DecodeReader->byteCount = 0;
818 DecodeReader->sum1 = 1;
819 DecodeReader->state = STATE_READER_RECEIVE_DATA_1_OUT_OF_4;
820 LED_B_ON();
821 } else {
822 // do nothing, keep waiting
823 }
824 } else { // unexpected falling edge
d9de20fa 825 DecodeReaderReset(DecodeReader);
8c6cca0b 826 }
827 break;
828
829 case STATE_READER_RECEIVE_DATA_1_OUT_OF_4:
830 DecodeReader->posCount++;
831 if (DecodeReader->posCount == 1) {
832 DecodeReader->sum1 = bit;
833 } else if (DecodeReader->posCount <= 4) {
834 DecodeReader->sum1 += bit;
835 } else if (DecodeReader->posCount == 5) {
836 DecodeReader->sum2 = bit;
837 } else {
838 DecodeReader->sum2 += bit;
839 }
840 if (DecodeReader->posCount == 8) {
841 DecodeReader->posCount = 0;
842 int corr10 = DecodeReader->sum1 - DecodeReader->sum2;
843 int corr01 = DecodeReader->sum2 - DecodeReader->sum1;
844 int corr11 = (DecodeReader->sum1 + DecodeReader->sum2) / 2;
845 if (corr01 > corr11 && corr01 > corr10) { // EOF
846 LED_B_OFF(); // Finished receiving
d9de20fa 847 DecodeReaderReset(DecodeReader);
8c6cca0b 848 if (DecodeReader->byteCount != 0) {
849 return true;
850 }
851 }
852 if (corr10 > corr11) { // detected a 2bit position
853 DecodeReader->shiftReg >>= 2;
854 DecodeReader->shiftReg |= (DecodeReader->bitCount << 6);
855 }
856 if (DecodeReader->bitCount == 15) { // we have a full byte
857 DecodeReader->output[DecodeReader->byteCount++] = DecodeReader->shiftReg;
858 if (DecodeReader->byteCount > DecodeReader->byteCountMax) {
859 // buffer overflow, give up
860 LED_B_OFF();
d9de20fa 861 DecodeReaderReset(DecodeReader);
8c6cca0b 862 }
863 DecodeReader->bitCount = 0;
d9de20fa 864 DecodeReader->shiftReg = 0;
8c6cca0b 865 } else {
866 DecodeReader->bitCount++;
867 }
868 }
869 break;
870
871 case STATE_READER_RECEIVE_DATA_1_OUT_OF_256:
872 DecodeReader->posCount++;
873 if (DecodeReader->posCount == 1) {
874 DecodeReader->sum1 = bit;
875 } else if (DecodeReader->posCount <= 4) {
876 DecodeReader->sum1 += bit;
877 } else if (DecodeReader->posCount == 5) {
878 DecodeReader->sum2 = bit;
879 } else {
880 DecodeReader->sum2 += bit;
881 }
882 if (DecodeReader->posCount == 8) {
883 DecodeReader->posCount = 0;
884 int corr10 = DecodeReader->sum1 - DecodeReader->sum2;
885 int corr01 = DecodeReader->sum2 - DecodeReader->sum1;
886 int corr11 = (DecodeReader->sum1 + DecodeReader->sum2) / 2;
887 if (corr01 > corr11 && corr01 > corr10) { // EOF
888 LED_B_OFF(); // Finished receiving
d9de20fa 889 DecodeReaderReset(DecodeReader);
8c6cca0b 890 if (DecodeReader->byteCount != 0) {
891 return true;
892 }
893 }
894 if (corr10 > corr11) { // detected the bit position
895 DecodeReader->shiftReg = DecodeReader->bitCount;
896 }
897 if (DecodeReader->bitCount == 255) { // we have a full byte
898 DecodeReader->output[DecodeReader->byteCount++] = DecodeReader->shiftReg;
899 if (DecodeReader->byteCount > DecodeReader->byteCountMax) {
900 // buffer overflow, give up
901 LED_B_OFF();
d9de20fa 902 DecodeReaderReset(DecodeReader);
8c6cca0b 903 }
904 }
905 DecodeReader->bitCount++;
906 }
907 break;
908
909 default:
910 LED_B_OFF();
d9de20fa 911 DecodeReaderReset(DecodeReader);
8c6cca0b 912 break;
15c4dc5a 913 }
8c6cca0b 914
915 return false;
916}
917
918
8c6cca0b 919//-----------------------------------------------------------------------------
920// Receive a command (from the reader to us, where we are the simulated tag),
921// and store it in the given buffer, up to the given maximum length. Keeps
922// spinning, waiting for a well-framed command, until either we get one
3d2c9c9b 923// (returns len) or someone presses the pushbutton on the board (returns -1).
8c6cca0b 924//
925// Assume that we're called with the SSC (to the FPGA) and ADC path set
926// correctly.
927//-----------------------------------------------------------------------------
928
3d2c9c9b 929int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time) {
d9de20fa 930 int samples = 0;
8c6cca0b 931 bool gotFrame = false;
932 uint8_t b;
933
3d2c9c9b 934 uint8_t dmaBuf[ISO15693_DMA_BUFFER_SIZE];
8c6cca0b 935
936 // the decoder data structure
6eeb5f1c 937 DecodeReader_t DecodeReader = {0};
d9de20fa 938 DecodeReaderInit(&DecodeReader, received, max_len);
8c6cca0b 939
940 // wait for last transfer to complete
941 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
942
70b2fc0a 943 LED_D_OFF();
8c6cca0b 944 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
15c4dc5a 945
8c6cca0b 946 // clear receive register and wait for next transfer
947 uint32_t temp = AT91C_BASE_SSC->SSC_RHR;
948 (void) temp;
949 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) ;
15c4dc5a 950
3d2c9c9b 951 uint32_t dma_start_time = GetCountSspClk() & 0xfffffff8;
15c4dc5a 952
8c6cca0b 953 // Setup and start DMA.
954 FpgaSetupSscDma(dmaBuf, ISO15693_DMA_BUFFER_SIZE);
955 uint8_t *upTo = dmaBuf;
15c4dc5a 956
3d2c9c9b 957 for (;;) {
d9de20fa 958 uint16_t behindBy = ((uint8_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
70b2fc0a 959
d9de20fa 960 if (behindBy == 0) continue;
15c4dc5a 961
8c6cca0b 962 b = *upTo++;
3d2c9c9b 963 if (upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
8c6cca0b 964 upTo = dmaBuf; // start reading the circular buffer from the beginning
3d2c9c9b 965 if (behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
d9de20fa 966 Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);
967 break;
968 }
8c6cca0b 969 }
970 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
971 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
972 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
973 }
15c4dc5a 974
8c6cca0b 975 for (int i = 7; i >= 0; i--) {
976 if (Handle15693SampleFromReader((b >> i) & 0x01, &DecodeReader)) {
3d2c9c9b 977 *eof_time = dma_start_time + samples - DELAY_READER_TO_ARM_SIM; // end of EOF
8c6cca0b 978 gotFrame = true;
9455b51c 979 break;
980 }
8c6cca0b 981 samples++;
15c4dc5a 982 }
8c6cca0b 983
984 if (gotFrame) {
985 break;
15c4dc5a 986 }
8c6cca0b 987
988 if (BUTTON_PRESS()) {
3d2c9c9b 989 DecodeReader.byteCount = -1;
8c6cca0b 990 break;
15c4dc5a 991 }
15c4dc5a 992
8c6cca0b 993 WDT_HIT();
994 }
995
8c6cca0b 996 FpgaDisableSscDma();
a66f26da 997
d9de20fa 998 if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
a66f26da 999 samples, gotFrame, DecodeReader.state, DecodeReader.byteCount, DecodeReader.bitCount, DecodeReader.posCount);
8c6cca0b 1000
d9de20fa 1001 if (DecodeReader.byteCount > 0) {
a66f26da 1002 uint32_t sof_time = *eof_time
3d2c9c9b 1003 - DecodeReader.byteCount * (DecodeReader.Coding==CODING_1_OUT_OF_4?128:2048) // time for byte transfers
1004 - 32 // time for SOF transfer
1005 - 16; // time for EOF transfer
1006 LogTrace(DecodeReader.output, DecodeReader.byteCount, sof_time, *eof_time, NULL, true);
8c6cca0b 1007 }
1008
1009 return DecodeReader.byteCount;
15c4dc5a 1010}
1011
9455b51c 1012
d9de20fa 1013// Encode (into the ToSend buffers) an identify request, which is the first
1014// thing that you must send to a tag to get a response.
1015static void BuildIdentifyRequest(void)
1016{
1017 uint8_t cmd[5];
1018
1019 uint16_t crc;
1020 // one sub-carrier, inventory, 1 slot, fast rate
1021 // AFI is at bit 5 (1<<4) when doing an INVENTORY
1022 cmd[0] = (1 << 2) | (1 << 5) | (1 << 1);
1023 // inventory command code
1024 cmd[1] = 0x01;
1025 // no mask
1026 cmd[2] = 0x00;
1027 //Now the CRC
3d2c9c9b 1028 crc = Iso15693Crc(cmd, 3);
d9de20fa 1029 cmd[3] = crc & 0xff;
1030 cmd[4] = crc >> 8;
1031
1032 CodeIso15693AsReader(cmd, sizeof(cmd));
1033}
1034
1035
15c4dc5a 1036//-----------------------------------------------------------------------------
1037// Start to read an ISO 15693 tag. We send an identify request, then wait
1038// for the response. The response is not demodulated, just left in the buffer
1039// so that it can be downloaded to a PC and processed there.
1040//-----------------------------------------------------------------------------
1041void AcquireRawAdcSamplesIso15693(void)
1042{
70b2fc0a 1043 LEDsoff();
1044 LED_A_ON();
8c6cca0b 1045
117d9ec2 1046 uint8_t *dest = BigBuf_get_addr();
15c4dc5a 1047
7cc204bf 1048 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
5ea2a248 1049 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
1050 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
15c4dc5a 1051 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1052
5ea2a248 1053 BuildIdentifyRequest();
1054
15c4dc5a 1055 // Give the tags time to energize
70b2fc0a 1056 LED_D_ON();
15c4dc5a 1057 SpinDelay(100);
1058
1059 // Now send the command
5ea2a248 1060 TransmitTo15693Tag(ToSend, ToSendMax, 0);
70b2fc0a 1061
1062 // wait for last transfer to complete
5ea2a248 1063 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) ;
15c4dc5a 1064
5ea2a248 1065 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE);
15c4dc5a 1066
70b2fc0a 1067 for(int c = 0; c < 4000; ) {
15c4dc5a 1068 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
d9de20fa 1069 uint16_t r = AT91C_BASE_SSC->SSC_RHR;
1070 dest[c++] = r >> 5;
9455b51c 1071 }
1072 }
70b2fc0a 1073
1074 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1075 LEDsoff();
9455b51c 1076}
1077
1078
d9de20fa 1079void SnoopIso15693(void)
9455b51c 1080{
1523527f 1081 LED_A_ON();
d9de20fa 1082 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1083 BigBuf_free();
8c6cca0b 1084
d9de20fa 1085 clear_trace();
1086 set_tracing(true);
3fe4ff4f 1087
d9de20fa 1088 // The DMA buffer, used to stream samples from the FPGA
1089 uint16_t* dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
1090 uint16_t *upTo;
1091
1092 // Count of samples received so far, so that we can include timing
1093 // information in the trace buffer.
1094 int samples = 0;
1095
1096 DecodeTag_t DecodeTag = {0};
1097 uint8_t response[ISO15693_MAX_RESPONSE_LENGTH];
1098 DecodeTagInit(&DecodeTag, response, sizeof(response));
9455b51c 1099
d9de20fa 1100 DecodeReader_t DecodeReader = {0};;
1101 uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
1102 DecodeReaderInit(&DecodeReader, cmd, sizeof(cmd));
1103
1104 // Print some debug information about the buffer sizes
1105 if (DEBUG) {
1106 Dbprintf("Snooping buffers initialized:");
1107 Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
1108 Dbprintf(" Reader -> tag: %i bytes", ISO15693_MAX_COMMAND_LENGTH);
1109 Dbprintf(" tag -> Reader: %i bytes", ISO15693_MAX_RESPONSE_LENGTH);
1110 Dbprintf(" DMA: %i bytes", ISO15693_DMA_BUFFER_SIZE * sizeof(uint16_t));
1111 }
5ea2a248 1112 Dbprintf("Snoop started. Press PM3 Button to stop.");
a66f26da 1113
5ea2a248 1114 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNOOP_AMPLITUDE);
9455b51c 1115 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1116
d9de20fa 1117 // Setup for the DMA.
5ea2a248 1118 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
d9de20fa 1119 upTo = dmaBuf;
1120 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
9455b51c 1121
d9de20fa 1122 bool TagIsActive = false;
1123 bool ReaderIsActive = false;
1124 bool ExpectTagAnswer = false;
9455b51c 1125
d9de20fa 1126 // And now we loop, receiving samples.
1127 for(;;) {
1128 uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
1129
1130 if (behindBy == 0) continue;
1131
1132 uint16_t snoopdata = *upTo++;
1133
1134 if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
1135 upTo = dmaBuf; // start reading the circular buffer from the beginning
1136 if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
1137 Dbprintf("About to blow circular buffer - aborted! behindBy=%d, samples=%d", behindBy, samples);
1138 break;
1139 }
1140 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
1141 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
1142 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
1143 WDT_HIT();
1144 if(BUTTON_PRESS()) {
1145 DbpString("Snoop stopped.");
1146 break;
1147 }
1148 }
1149 }
1150 samples++;
a66f26da 1151
d9de20fa 1152 if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
1153 if (Handle15693SampleFromReader(snoopdata & 0x02, &DecodeReader)) {
1154 FpgaDisableSscDma();
1155 ExpectTagAnswer = true;
1156 LogTrace(DecodeReader.output, DecodeReader.byteCount, samples, samples, NULL, true);
1157 /* And ready to receive another command. */
1158 DecodeReaderReset(&DecodeReader);
1159 /* And also reset the demod code, which might have been */
1160 /* false-triggered by the commands from the reader. */
1161 DecodeTagReset(&DecodeTag);
1162 upTo = dmaBuf;
1163 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
1164 }
1165 if (Handle15693SampleFromReader(snoopdata & 0x01, &DecodeReader)) {
1166 FpgaDisableSscDma();
1167 ExpectTagAnswer = true;
1168 LogTrace(DecodeReader.output, DecodeReader.byteCount, samples, samples, NULL, true);
1169 /* And ready to receive another command. */
1170 DecodeReaderReset(&DecodeReader);
1171 /* And also reset the demod code, which might have been */
1172 /* false-triggered by the commands from the reader. */
1173 DecodeTagReset(&DecodeTag);
1174 upTo = dmaBuf;
1175 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
1176 }
1177 ReaderIsActive = (DecodeReader.state >= STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF);
9455b51c 1178 }
d9de20fa 1179
a66f26da 1180 if (!ReaderIsActive && ExpectTagAnswer) { // no need to try decoding tag data if the reader is currently sending or no answer expected yet
d9de20fa 1181 if (Handle15693SamplesFromTag(snoopdata >> 2, &DecodeTag)) {
1182 FpgaDisableSscDma();
1183 //Use samples as a time measurement
1184 LogTrace(DecodeTag.output, DecodeTag.len, samples, samples, NULL, false);
1185 // And ready to receive another response.
1186 DecodeTagReset(&DecodeTag);
1187 DecodeReaderReset(&DecodeReader);
1188 ExpectTagAnswer = false;
1189 upTo = dmaBuf;
1190 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
1191 }
1192 TagIsActive = (DecodeTag.state >= STATE_TAG_RECEIVING_DATA);
1193 }
1194
9455b51c 1195 }
70b2fc0a 1196
d9de20fa 1197 FpgaDisableSscDma();
1198 BigBuf_free();
a66f26da 1199
d9de20fa 1200 LEDsoff();
1201
1202 DbpString("Snoop statistics:");
1203 Dbprintf(" ExpectTagAnswer: %d", ExpectTagAnswer);
1204 Dbprintf(" DecodeTag State: %d", DecodeTag.state);
1205 Dbprintf(" DecodeTag byteCnt: %d", DecodeTag.len);
1206 Dbprintf(" DecodeReader State: %d", DecodeReader.state);
1207 Dbprintf(" DecodeReader byteCnt: %d", DecodeReader.byteCount);
1208 Dbprintf(" Trace length: %d", BigBuf_get_traceLen());
9455b51c 1209}
1210
1211
8c6cca0b 1212// Initialize the proxmark as iso15k reader
70b2fc0a 1213static void Iso15693InitReader() {
7cc204bf 1214 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
9455b51c 1215 // Setup SSC
e6304bca 1216 // FpgaSetupSsc();
9455b51c 1217
1218 // Start from off (no field generated)
70b2fc0a 1219 LED_D_OFF();
9455b51c 1220 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
e6304bca 1221 SpinDelay(10);
9455b51c 1222
1223 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
5ea2a248 1224 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
9455b51c 1225
1226 // Give the tags time to energize
70b2fc0a 1227 LED_D_ON();
5ea2a248 1228 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
e6304bca 1229 SpinDelay(250);
9455b51c 1230}
1231
1232///////////////////////////////////////////////////////////////////////
1233// ISO 15693 Part 3 - Air Interface
70b2fc0a 1234// This section basically contains transmission and receiving of bits
9455b51c 1235///////////////////////////////////////////////////////////////////////
1236
9455b51c 1237
1238// uid is in transmission order (which is reverse of display order)
1239static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
1240{
1241 uint8_t cmd[13];
1242
1243 uint16_t crc;
d9de20fa 1244 // If we set the Option_Flag in this request, the VICC will respond with the security status of the block
1245 // followed by the block data
a66f26da 1246 cmd[0] = ISO15693_REQ_OPTION | ISO15693_REQ_ADDRESS | ISO15693_REQ_DATARATE_HIGH;
9455b51c 1247 // READ BLOCK command code
d9de20fa 1248 cmd[1] = ISO15693_READBLOCK;
9455b51c 1249 // UID may be optionally specified here
1250 // 64-bit UID
1251 cmd[2] = uid[0];
1252 cmd[3] = uid[1];
1253 cmd[4] = uid[2];
1254 cmd[5] = uid[3];
1255 cmd[6] = uid[4];
1256 cmd[7] = uid[5];
1257 cmd[8] = uid[6];
1258 cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique)
1259 // Block number to read
d9de20fa 1260 cmd[10] = blockNumber;
9455b51c 1261 //Now the CRC
3d2c9c9b 1262 crc = Iso15693Crc(cmd, 11); // the crc needs to be calculated over 11 bytes
9455b51c 1263 cmd[11] = crc & 0xff;
1264 cmd[12] = crc >> 8;
1265
1266 CodeIso15693AsReader(cmd, sizeof(cmd));
1267}
1268
70b2fc0a 1269
9455b51c 1270// Now the VICC>VCD responses when we are simulating a tag
8c6cca0b 1271static void BuildInventoryResponse(uint8_t *uid)
9455b51c 1272{
1273 uint8_t cmd[12];
1274
1275 uint16_t crc;
8c6cca0b 1276
1277 cmd[0] = 0; // No error, no protocol format extension
3fe4ff4f 1278 cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
9455b51c 1279 // 64-bit UID
3fe4ff4f 1280 cmd[2] = uid[7]; //0x32;
1281 cmd[3] = uid[6]; //0x4b;
1282 cmd[4] = uid[5]; //0x03;
1283 cmd[5] = uid[4]; //0x01;
1284 cmd[6] = uid[3]; //0x00;
1285 cmd[7] = uid[2]; //0x10;
1286 cmd[8] = uid[1]; //0x05;
1287 cmd[9] = uid[0]; //0xe0;
9455b51c 1288 //Now the CRC
3d2c9c9b 1289 crc = Iso15693Crc(cmd, 10);
9455b51c 1290 cmd[10] = crc & 0xff;
1291 cmd[11] = crc >> 8;
1292
8c6cca0b 1293 CodeIso15693AsTag(cmd, sizeof(cmd));
9455b51c 1294}
1295
e6304bca 1296// Universal Method for sending to and recv bytes from a tag
a66f26da 1297// init ... should we initialize the reader?
1298// speed ... 0 low speed, 1 hi speed
1299// *recv will contain the tag's answer
1300// return: lenght of received data
d9de20fa 1301int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time) {
9455b51c 1302
9455b51c 1303 LED_A_ON();
70b2fc0a 1304 LED_B_OFF();
9455b51c 1305 LED_C_OFF();
8c6cca0b 1306
09ffd16e 1307 if (init) Iso15693InitReader();
1308
9455b51c 1309 int answerLen=0;
9455b51c 1310
9455b51c 1311 if (!speed) {
1312 // low speed (1 out of 256)
1313 CodeIso15693AsReader256(send, sendlen);
1314 } else {
1315 // high speed (1 out of 4)
1316 CodeIso15693AsReader(send, sendlen);
1317 }
8c6cca0b 1318
d9de20fa 1319 TransmitTo15693Tag(ToSend, ToSendMax, start_time);
1320
9455b51c 1321 // Now wait for a response
d9de20fa 1322 if (recv != NULL) {
5ea2a248 1323 answerLen = GetIso15693AnswerFromTag(recv, max_recv_len, DELAY_ISO15693_VCD_TO_VICC_READER * 2);
9455b51c 1324 }
1325
1326 LED_A_OFF();
8c6cca0b 1327
9455b51c 1328 return answerLen;
1329}
15c4dc5a 1330
15c4dc5a 1331
9455b51c 1332// --------------------------------------------------------------------
8c6cca0b 1333// Debug Functions
9455b51c 1334// --------------------------------------------------------------------
15c4dc5a 1335
9455b51c 1336// Decodes a message from a tag and displays its metadata and content
1337#define DBD15STATLEN 48
1338void DbdecodeIso15693Answer(int len, uint8_t *d) {
1339 char status[DBD15STATLEN+1]={0};
1340 uint16_t crc;
1341
d9de20fa 1342 if (len > 3) {
1343 if (d[0] & ISO15693_RES_EXT)
1344 strncat(status,"ProtExt ", DBD15STATLEN);
1345 if (d[0] & ISO15693_RES_ERROR) {
9455b51c 1346 // error
d9de20fa 1347 strncat(status,"Error ", DBD15STATLEN);
9455b51c 1348 switch (d[1]) {
8c6cca0b 1349 case 0x01:
d9de20fa 1350 strncat(status,"01:notSupp", DBD15STATLEN);
15c4dc5a 1351 break;
8c6cca0b 1352 case 0x02:
d9de20fa 1353 strncat(status,"02:notRecog", DBD15STATLEN);
9455b51c 1354 break;
8c6cca0b 1355 case 0x03:
d9de20fa 1356 strncat(status,"03:optNotSupp", DBD15STATLEN);
9455b51c 1357 break;
8c6cca0b 1358 case 0x0f:
d9de20fa 1359 strncat(status,"0f:noInfo", DBD15STATLEN);
9455b51c 1360 break;
8c6cca0b 1361 case 0x10:
d9de20fa 1362 strncat(status,"10:doesn'tExist", DBD15STATLEN);
9455b51c 1363 break;
8c6cca0b 1364 case 0x11:
d9de20fa 1365 strncat(status,"11:lockAgain", DBD15STATLEN);
9455b51c 1366 break;
8c6cca0b 1367 case 0x12:
d9de20fa 1368 strncat(status,"12:locked", DBD15STATLEN);
9455b51c 1369 break;
8c6cca0b 1370 case 0x13:
d9de20fa 1371 strncat(status,"13:progErr", DBD15STATLEN);
9455b51c 1372 break;
8c6cca0b 1373 case 0x14:
d9de20fa 1374 strncat(status,"14:lockErr", DBD15STATLEN);
9455b51c 1375 break;
1376 default:
d9de20fa 1377 strncat(status,"unknownErr", DBD15STATLEN);
15c4dc5a 1378 }
d9de20fa 1379 strncat(status," ", DBD15STATLEN);
9455b51c 1380 } else {
d9de20fa 1381 strncat(status,"NoErr ", DBD15STATLEN);
15c4dc5a 1382 }
8c6cca0b 1383
3d2c9c9b 1384 crc=Iso15693Crc(d,len-2);
8c6cca0b 1385 if ( (( crc & 0xff ) == d[len-2]) && (( crc >> 8 ) == d[len-1]) )
9455b51c 1386 strncat(status,"CrcOK",DBD15STATLEN);
1387 else
8c6cca0b 1388 strncat(status,"CrcFail!",DBD15STATLEN);
9455b51c 1389
1390 Dbprintf("%s",status);
15c4dc5a 1391 }
1392}
1393
9455b51c 1394
1395
1396///////////////////////////////////////////////////////////////////////
1397// Functions called via USB/Client
1398///////////////////////////////////////////////////////////////////////
1399
1400void SetDebugIso15693(uint32_t debug) {
1401 DEBUG=debug;
1402 Dbprintf("Iso15693 Debug is now %s",DEBUG?"on":"off");
1403 return;
1404}
1405
d9de20fa 1406
5ea2a248 1407//---------------------------------------------------------------------------------------
1408// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector.
15c4dc5a 1409// all demodulation performed in arm rather than host. - greg
5ea2a248 1410//---------------------------------------------------------------------------------------
f7e3ed82 1411void ReaderIso15693(uint32_t parameter)
15c4dc5a 1412{
70b2fc0a 1413 LEDsoff();
15c4dc5a 1414 LED_A_ON();
15c4dc5a 1415
d9de20fa 1416 set_tracing(true);
a66f26da 1417
d9de20fa 1418 int answerLen = 0;
3fe4ff4f 1419 uint8_t TagUID[8] = {0x00};
1420
09ffd16e 1421 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1422
d9de20fa 1423 uint8_t answer[ISO15693_MAX_RESPONSE_LENGTH];
15c4dc5a 1424
3fe4ff4f 1425 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
15c4dc5a 1426 // Setup SSC
5ea2a248 1427 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
15c4dc5a 1428
1429 // Start from off (no field generated)
a66f26da 1430 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1431 SpinDelay(200);
15c4dc5a 1432
15c4dc5a 1433 // Give the tags time to energize
70b2fc0a 1434 LED_D_ON();
5ea2a248 1435 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
15c4dc5a 1436 SpinDelay(200);
d9de20fa 1437 StartCountSspClk();
1438
15c4dc5a 1439
15c4dc5a 1440 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1441 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
15c4dc5a 1442
1443 // Now send the IDENTIFY command
1444 BuildIdentifyRequest();
d9de20fa 1445 TransmitTo15693Tag(ToSend, ToSendMax, 0);
a66f26da 1446
15c4dc5a 1447 // Now wait for a response
5ea2a248 1448 answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC_READER * 2) ;
1449 uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER;
15c4dc5a 1450
d9de20fa 1451 if (answerLen >=12) // we should do a better check than this
15c4dc5a 1452 {
d9de20fa 1453 TagUID[0] = answer[2];
1454 TagUID[1] = answer[3];
1455 TagUID[2] = answer[4];
1456 TagUID[3] = answer[5];
1457 TagUID[4] = answer[6];
1458 TagUID[5] = answer[7];
1459 TagUID[6] = answer[8]; // IC Manufacturer code
1460 TagUID[7] = answer[9]; // always E0
15c4dc5a 1461
15c4dc5a 1462 }
1463
d9de20fa 1464 Dbprintf("%d octets read from IDENTIFY request:", answerLen);
1465 DbdecodeIso15693Answer(answerLen, answer);
1466 Dbhexdump(answerLen, answer, false);
9455b51c 1467
1468 // UID is reverse
d9de20fa 1469 if (answerLen >= 12)
3fe4ff4f 1470 Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
1471 TagUID[7],TagUID[6],TagUID[5],TagUID[4],
1472 TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
9455b51c 1473
1474
315e18e6 1475 // Dbprintf("%d octets read from SELECT request:", answerLen2);
1476 // DbdecodeIso15693Answer(answerLen2,answer2);
1477 // Dbhexdump(answerLen2,answer2,true);
9455b51c 1478
315e18e6 1479 // Dbprintf("%d octets read from XXX request:", answerLen3);
1480 // DbdecodeIso15693Answer(answerLen3,answer3);
1481 // Dbhexdump(answerLen3,answer3,true);
9455b51c 1482
9455b51c 1483 // read all pages
d9de20fa 1484 if (answerLen >= 12 && DEBUG) {
5ea2a248 1485 for (int i = 0; i < 32; i++) { // sanity check, assume max 32 pages
8c6cca0b 1486 BuildReadBlockRequest(TagUID, i);
d9de20fa 1487 TransmitTo15693Tag(ToSend, ToSendMax, start_time);
5ea2a248 1488 int answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC_READER * 2);
1489 start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER;
d9de20fa 1490 if (answerLen > 0) {
1491 Dbprintf("READ SINGLE BLOCK %d returned %d octets:", i, answerLen);
1492 DbdecodeIso15693Answer(answerLen, answer);
1493 Dbhexdump(answerLen, answer, false);
1494 if ( *((uint32_t*) answer) == 0x07160101 ) break; // exit on NoPageErr
8c6cca0b 1495 }
8c6cca0b 1496 }
9455b51c 1497 }
15c4dc5a 1498
8c6cca0b 1499 // for the time being, switch field off to protect rdv4.0
70b2fc0a 1500 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
a66f26da 1501 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
15c4dc5a 1502 LED_D_OFF();
8c6cca0b 1503
70b2fc0a 1504 LED_A_OFF();
15c4dc5a 1505}
1506
8c6cca0b 1507
1508// Simulate an ISO15693 TAG.
1509// For Inventory command: print command and send Inventory Response with given UID
1510// TODO: interpret other reader commands and send appropriate response
3fe4ff4f 1511void SimTagIso15693(uint32_t parameter, uint8_t *uid)
15c4dc5a 1512{
70b2fc0a 1513 LEDsoff();
15c4dc5a 1514 LED_A_ON();
15c4dc5a 1515
7cc204bf 1516 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1517 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
a66f26da 1518 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
8c6cca0b 1519 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
15c4dc5a 1520
8c6cca0b 1521 StartCountSspClk();
15c4dc5a 1522
8c6cca0b 1523 uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
15c4dc5a 1524
8c6cca0b 1525 // Build a suitable response to the reader INVENTORY command
1526 BuildInventoryResponse(uid);
15c4dc5a 1527
8c6cca0b 1528 // Listen to reader
1529 while (!BUTTON_PRESS()) {
1530 uint32_t eof_time = 0, start_time = 0;
1531 int cmd_len = GetIso15693CommandFromReader(cmd, sizeof(cmd), &eof_time);
1532
1533 if ((cmd_len >= 5) && (cmd[0] & ISO15693_REQ_INVENTORY) && (cmd[1] == ISO15693_INVENTORY)) { // TODO: check more flags
1534 bool slow = !(cmd[0] & ISO15693_REQ_DATARATE_HIGH);
5ea2a248 1535 start_time = eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM - DELAY_ARM_TO_READER_SIM;
8c6cca0b 1536 TransmitTo15693Reader(ToSend, ToSendMax, start_time, slow);
1537 }
3fe4ff4f 1538
8c6cca0b 1539 Dbprintf("%d bytes read from reader:", cmd_len);
1540 Dbhexdump(cmd_len, cmd, false);
1541 }
15c4dc5a 1542
a66f26da 1543 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
70b2fc0a 1544 LEDsoff();
15c4dc5a 1545}
9455b51c 1546
1547
1548// Since there is no standardized way of reading the AFI out of a tag, we will brute force it
1549// (some manufactures offer a way to read the AFI, though)
8c6cca0b 1550void BruteforceIso15693Afi(uint32_t speed)
1551{
70b2fc0a 1552 LEDsoff();
1553 LED_A_ON();
8c6cca0b 1554
d9de20fa 1555 uint8_t data[6];
1556 uint8_t recv[ISO15693_MAX_RESPONSE_LENGTH];
a66f26da 1557
9455b51c 1558 int datalen=0, recvlen=0;
8c6cca0b 1559
9455b51c 1560 Iso15693InitReader();
d9de20fa 1561 StartCountSspClk();
a66f26da 1562
9455b51c 1563 // first without AFI
8c6cca0b 1564 // Tags should respond without AFI and with AFI=0 even when AFI is active
1565
1566 data[0] = ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_SLOT1;
1567 data[1] = ISO15693_INVENTORY;
1568 data[2] = 0; // mask length
3d2c9c9b 1569 datalen = Iso15693AddCrc(data,3);
d9de20fa 1570 recvlen = SendDataTag(data, datalen, false, speed, recv, sizeof(recv), 0);
5ea2a248 1571 uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER;
9455b51c 1572 WDT_HIT();
1573 if (recvlen>=12) {
3d2c9c9b 1574 Dbprintf("NoAFI UID=%s", Iso15693sprintUID(NULL, &recv[2]));
9455b51c 1575 }
8c6cca0b 1576
9455b51c 1577 // now with AFI
8c6cca0b 1578
1579 data[0] = ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_AFI | ISO15693_REQINV_SLOT1;
1580 data[1] = ISO15693_INVENTORY;
1581 data[2] = 0; // AFI
1582 data[3] = 0; // mask length
1583
d9de20fa 1584 for (int i = 0; i < 256; i++) {
1585 data[2] = i & 0xFF;
3d2c9c9b 1586 datalen = Iso15693AddCrc(data,4);
d9de20fa 1587 recvlen = SendDataTag(data, datalen, false, speed, recv, sizeof(recv), start_time);
5ea2a248 1588 start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD_READER;
9455b51c 1589 WDT_HIT();
d9de20fa 1590 if (recvlen >= 12) {
3d2c9c9b 1591 Dbprintf("AFI=%i UID=%s", i, Iso15693sprintUID(NULL, &recv[2]));
9455b51c 1592 }
8c6cca0b 1593 }
9455b51c 1594 Dbprintf("AFI Bruteforcing done.");
8c6cca0b 1595
a66f26da 1596 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
70b2fc0a 1597 LEDsoff();
9455b51c 1598}
1599
1600// Allows to directly send commands to the tag via the client
70b2fc0a 1601void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]) {
9455b51c 1602
d9de20fa 1603 int recvlen = 0;
1604 uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
8c6cca0b 1605
70b2fc0a 1606 LED_A_ON();
8c6cca0b 1607
9455b51c 1608 if (DEBUG) {
d9de20fa 1609 Dbprintf("SEND:");
8c6cca0b 1610 Dbhexdump(datalen, data, false);
9455b51c 1611 }
8c6cca0b 1612
d9de20fa 1613 recvlen = SendDataTag(data, datalen, true, speed, (recv?recvbuf:NULL), sizeof(recvbuf), 0);
9455b51c 1614
8c6cca0b 1615 if (recv) {
9455b51c 1616 if (DEBUG) {
d9de20fa 1617 Dbprintf("RECV:");
8c6cca0b 1618 Dbhexdump(recvlen, recvbuf, false);
d9de20fa 1619 DbdecodeIso15693Answer(recvlen, recvbuf);
9455b51c 1620 }
d9de20fa 1621
1622 cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
1623
9455b51c 1624 }
1625
8c6cca0b 1626 // for the time being, switch field off to protect rdv4.0
70b2fc0a 1627 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
a66f26da 1628 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
70b2fc0a 1629 LED_D_OFF();
8c6cca0b 1630
70b2fc0a 1631 LED_A_OFF();
9455b51c 1632}
1633
096dee17 1634//-----------------------------------------------------------------------------
1635// Work with "magic Chinese" card.
1636//
1637//-----------------------------------------------------------------------------
1638
1639// Set the UID to the tag (based on Iceman work).
1640void SetTag15693Uid(uint8_t *uid)
1641{
a66f26da 1642 uint8_t cmd[4][9] = {0x00};
1643
1644 uint16_t crc;
1645
1646 int recvlen = 0;
1647 uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
1648
1649 LED_A_ON();
1650
1651 // Command 1 : 02213E00000000
1652 cmd[0][0] = 0x02;
1653 cmd[0][1] = 0x21;
1654 cmd[0][2] = 0x3e;
1655 cmd[0][3] = 0x00;
1656 cmd[0][4] = 0x00;
1657 cmd[0][5] = 0x00;
1658 cmd[0][6] = 0x00;
1659
1660 // Command 2 : 02213F69960000
1661 cmd[1][0] = 0x02;
1662 cmd[1][1] = 0x21;
1663 cmd[1][2] = 0x3f;
1664 cmd[1][3] = 0x69;
1665 cmd[1][4] = 0x96;
1666 cmd[1][5] = 0x00;
1667 cmd[1][6] = 0x00;
1668
1669 // Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
1670 cmd[2][0] = 0x02;
1671 cmd[2][1] = 0x21;
1672 cmd[2][2] = 0x38;
1673 cmd[2][3] = uid[7];
1674 cmd[2][4] = uid[6];
1675 cmd[2][5] = uid[5];
1676 cmd[2][6] = uid[4];
1677
1678 // Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
1679 cmd[3][0] = 0x02;
1680 cmd[3][1] = 0x21;
1681 cmd[3][2] = 0x39;
1682 cmd[3][3] = uid[3];
1683 cmd[3][4] = uid[2];
1684 cmd[3][5] = uid[1];
1685 cmd[3][6] = uid[0];
1686
1687 for (int i=0; i<4; i++) {
1688 // Add the CRC
1689 crc = Iso15693Crc(cmd[i], 7);
1690 cmd[i][7] = crc & 0xff;
1691 cmd[i][8] = crc >> 8;
1692
1693 if (DEBUG) {
1694 Dbprintf("SEND:");
1695 Dbhexdump(sizeof(cmd[i]), cmd[i], false);
1696 }
1697
1698 recvlen = SendDataTag(cmd[i], sizeof(cmd[i]), true, 1, recvbuf, sizeof(recvbuf), 0);
1699
1700 if (DEBUG) {
1701 Dbprintf("RECV:");
1702 Dbhexdump(recvlen, recvbuf, false);
1703 DbdecodeIso15693Answer(recvlen, recvbuf);
1704 }
1705
1706 cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
1707 }
1708
1709 LED_D_OFF();
1710
1711 LED_A_OFF();
096dee17 1712}
9455b51c 1713
1714
1715
1716// --------------------------------------------------------------------
1717// -- Misc & deprecated functions
1718// --------------------------------------------------------------------
1719
e6304bca 1720/*
9455b51c 1721
1722// do not use; has a fix UID
1723static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
1724{
1725 uint8_t cmd[12];
1726
1727 uint16_t crc;
5ea2a248 1728 // If we set the Option_Flag in this request, the VICC will respond with the security status of the block
1729 // followed by the block data
9455b51c 1730 // one sub-carrier, inventory, 1 slot, fast rate
1731 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1732 // System Information command code
1733 cmd[1] = 0x2B;
1734 // UID may be optionally specified here
1735 // 64-bit UID
1736 cmd[2] = 0x32;
1737 cmd[3]= 0x4b;
1738 cmd[4] = 0x03;
1739 cmd[5] = 0x01;
1740 cmd[6] = 0x00;
1741 cmd[7] = 0x10;
1742 cmd[8] = 0x05;
1743 cmd[9]= 0xe0; // always e0 (not exactly unique)
1744 //Now the CRC
3d2c9c9b 1745 crc = Iso15693Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
9455b51c 1746 cmd[10] = crc & 0xff;
1747 cmd[11] = crc >> 8;
1748
1749 CodeIso15693AsReader(cmd, sizeof(cmd));
1750}
1751
9455b51c 1752
1753// do not use; has a fix UID
1754static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
1755{
1756 uint8_t cmd[14];
1757
1758 uint16_t crc;
5ea2a248 1759 // If we set the Option_Flag in this request, the VICC will respond with the security status of the block
1760 // followed by the block data
9455b51c 1761 // one sub-carrier, inventory, 1 slot, fast rate
1762 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1763 // READ Multi BLOCK command code
1764 cmd[1] = 0x23;
1765 // UID may be optionally specified here
1766 // 64-bit UID
1767 cmd[2] = 0x32;
1768 cmd[3]= 0x4b;
1769 cmd[4] = 0x03;
1770 cmd[5] = 0x01;
1771 cmd[6] = 0x00;
1772 cmd[7] = 0x10;
1773 cmd[8] = 0x05;
1774 cmd[9]= 0xe0; // always e0 (not exactly unique)
1775 // First Block number to read
1776 cmd[10] = 0x00;
1777 // Number of Blocks to read
1778 cmd[11] = 0x2f; // read quite a few
1779 //Now the CRC
3d2c9c9b 1780 crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
9455b51c 1781 cmd[12] = crc & 0xff;
1782 cmd[13] = crc >> 8;
1783
1784 CodeIso15693AsReader(cmd, sizeof(cmd));
1785}
1786
1787// do not use; has a fix UID
1788static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
1789{
1790 uint8_t cmd[14];
1791
1792 uint16_t crc;
5ea2a248 1793 // If we set the Option_Flag in this request, the VICC will respond with the security status of the block
1794 // followed by the block data
9455b51c 1795 // one sub-carrier, inventory, 1 slot, fast rate
1796 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1797 // READ BLOCK command code
1798 cmd[1] = CmdCode;
1799 // UID may be optionally specified here
1800 // 64-bit UID
1801 cmd[2] = 0x32;
1802 cmd[3]= 0x4b;
1803 cmd[4] = 0x03;
1804 cmd[5] = 0x01;
1805 cmd[6] = 0x00;
1806 cmd[7] = 0x10;
1807 cmd[8] = 0x05;
1808 cmd[9]= 0xe0; // always e0 (not exactly unique)
1809 // Parameter
1810 cmd[10] = 0x00;
1811 cmd[11] = 0x0a;
1812
a66f26da 1813// cmd[12] = 0x00;
1814// cmd[13] = 0x00; //Now the CRC
3d2c9c9b 1815 crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
9455b51c 1816 cmd[12] = crc & 0xff;
1817 cmd[13] = crc >> 8;
1818
1819 CodeIso15693AsReader(cmd, sizeof(cmd));
1820}
1821
1822// do not use; has a fix UID
1823static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
1824{
1825 uint8_t cmd[14];
1826
1827 uint16_t crc;
5ea2a248 1828 // If we set the Option_Flag in this request, the VICC will respond with the security status of the block
1829 // followed by the block data
9455b51c 1830 // one sub-carrier, inventory, 1 slot, fast rate
1831 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1832 // READ BLOCK command code
1833 cmd[1] = CmdCode;
1834 // UID may be optionally specified here
1835 // 64-bit UID
1836 cmd[2] = 0x32;
1837 cmd[3]= 0x4b;
1838 cmd[4] = 0x03;
1839 cmd[5] = 0x01;
1840 cmd[6] = 0x00;
1841 cmd[7] = 0x10;
1842 cmd[8] = 0x05;
1843 cmd[9]= 0xe0; // always e0 (not exactly unique)
1844 // Parameter
5ea2a248 1845 cmd[10] = 0x05; // for custom codes this must be manufacturer code
9455b51c 1846 cmd[11] = 0x00;
1847
a66f26da 1848// cmd[12] = 0x00;
1849// cmd[13] = 0x00; //Now the CRC
3d2c9c9b 1850 crc = Iso15693Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
9455b51c 1851 cmd[12] = crc & 0xff;
1852 cmd[13] = crc >> 8;
1853
1854 CodeIso15693AsReader(cmd, sizeof(cmd));
1855}
1856
1857
1858
1859
e6304bca 1860*/
9455b51c 1861
1862
Impressum, Datenschutz