]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso15693.c
The older gnuarm in the windows toolchain seems to need the glue_7t section
[proxmark3-svn] / armsrc / iso15693.c
CommitLineData
6658905f 1//-----------------------------------------------------------------------------\r
2// Routines to support ISO 15693. This includes both the reader software and\r
3// the `fake tag' modes, but at the moment I've implemented only the reader\r
4// stuff, and that barely.\r
5// Jonathan Westhues, split Nov 2006\r
6\r
7// Modified by Greg Jones, Jan 2009 to perform modulation onboard in arm rather than on PC\r
8// Also added additional reader commands (SELECT, READ etc.)\r
9\r
10//-----------------------------------------------------------------------------\r
11#include <proxmark3.h>\r
12#include "apps.h"\r
13#include <stdio.h>\r
14#include <stdlib.h>\r
15\r
16// FROM winsrc\prox.h //////////////////////////////////\r
17#define arraylen(x) (sizeof(x)/sizeof((x)[0]))\r
18\r
19//-----------------------------------------------------------------------------\r
20// Map a sequence of octets (~layer 2 command) into the set of bits to feed\r
21// to the FPGA, to transmit that command to the tag.\r
22//-----------------------------------------------------------------------------\r
23\r
6658905f 24 // The sampling rate is 106.353 ksps/s, for T = 18.8 us\r
25\r
f7c64b57 26 // SOF defined as\r
6658905f 27 // 1) Unmodulated time of 56.64us\r
28 // 2) 24 pulses of 423.75khz\r
29 // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)\r
30\r
31 static const int FrameSOF[] = {\r
32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r
33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r
34 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
35 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
36 -1, -1, -1, -1,\r
37 -1, -1, -1, -1,\r
38 1, 1, 1, 1,\r
39 1, 1, 1, 1\r
40 };\r
41 static const int Logic0[] = {\r
42 1, 1, 1, 1,\r
43 1, 1, 1, 1,\r
44 -1, -1, -1, -1,\r
45 -1, -1, -1, -1\r
46 };\r
47 static const int Logic1[] = {\r
48 -1, -1, -1, -1,\r
49 -1, -1, -1, -1,\r
50 1, 1, 1, 1,\r
51 1, 1, 1, 1\r
52 };\r
53\r
f7c64b57 54 // EOF defined as\r
6658905f 55 // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)\r
56 // 2) 24 pulses of 423.75khz\r
57 // 3) Unmodulated time of 56.64us\r
58\r
59 static const int FrameEOF[] = {\r
60 1, 1, 1, 1,\r
61 1, 1, 1, 1,\r
62 -1, -1, -1, -1,\r
63 -1, -1, -1, -1,\r
64 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
65 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
66 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r
67 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1\r
68 };\r
69\r
6658905f 70static void CodeIso15693AsReader(BYTE *cmd, int n)\r
71{\r
72 int i, j;\r
73\r
74 ToSendReset();\r
75\r
76 // Give it a bit of slack at the beginning\r
77 for(i = 0; i < 24; i++) {\r
78 ToSendStuffBit(1);\r
79 }\r
80\r
81 ToSendStuffBit(0);\r
82 ToSendStuffBit(1);\r
83 ToSendStuffBit(1);\r
84 ToSendStuffBit(1);\r
85 ToSendStuffBit(1);\r
86 ToSendStuffBit(0);\r
87 ToSendStuffBit(1);\r
88 ToSendStuffBit(1);\r
89 for(i = 0; i < n; i++) {\r
90 for(j = 0; j < 8; j += 2) {\r
91 int these = (cmd[i] >> j) & 3;\r
92 switch(these) {\r
93 case 0:\r
94 ToSendStuffBit(1);\r
95 ToSendStuffBit(0);\r
96 ToSendStuffBit(1);\r
97 ToSendStuffBit(1);\r
98 ToSendStuffBit(1);\r
99 ToSendStuffBit(1);\r
100 ToSendStuffBit(1);\r
101 ToSendStuffBit(1);\r
102 break;\r
103 case 1:\r
104 ToSendStuffBit(1);\r
105 ToSendStuffBit(1);\r
106 ToSendStuffBit(1);\r
107 ToSendStuffBit(0);\r
108 ToSendStuffBit(1);\r
109 ToSendStuffBit(1);\r
110 ToSendStuffBit(1);\r
111 ToSendStuffBit(1);\r
112 break;\r
113 case 2:\r
114 ToSendStuffBit(1);\r
115 ToSendStuffBit(1);\r
116 ToSendStuffBit(1);\r
117 ToSendStuffBit(1);\r
118 ToSendStuffBit(1);\r
119 ToSendStuffBit(0);\r
120 ToSendStuffBit(1);\r
121 ToSendStuffBit(1);\r
122 break;\r
123 case 3:\r
124 ToSendStuffBit(1);\r
125 ToSendStuffBit(1);\r
126 ToSendStuffBit(1);\r
127 ToSendStuffBit(1);\r
128 ToSendStuffBit(1);\r
129 ToSendStuffBit(1);\r
130 ToSendStuffBit(1);\r
131 ToSendStuffBit(0);\r
132 break;\r
133 }\r
134 }\r
135 }\r
136 ToSendStuffBit(1);\r
137 ToSendStuffBit(1);\r
138 ToSendStuffBit(0);\r
139 ToSendStuffBit(1);\r
140\r
141 // And slack at the end, too.\r
142 for(i = 0; i < 24; i++) {\r
143 ToSendStuffBit(1);\r
144 }\r
145}\r
146\r
147//-----------------------------------------------------------------------------\r
148// The CRC used by ISO 15693.\r
149//-----------------------------------------------------------------------------\r
150static WORD Crc(BYTE *v, int n)\r
151{\r
152 DWORD reg;\r
153 int i, j;\r
154\r
155 reg = 0xffff;\r
156 for(i = 0; i < n; i++) {\r
157 reg = reg ^ ((DWORD)v[i]);\r
158 for (j = 0; j < 8; j++) {\r
159 if (reg & 0x0001) {\r
160 reg = (reg >> 1) ^ 0x8408;\r
161 } else {\r
162 reg = (reg >> 1);\r
163 }\r
164 }\r
165 }\r
166\r
167 return ~reg;\r
168}\r
169\r
f7c64b57 170char *strcat(char *dest, const char *src)\r
171{\r
172 size_t dest_len = strlen(dest);\r
173 size_t i;\r
174 \r
175 for (i = 0 ; src[i] != '\0' ; i++)\r
176 dest[dest_len + i] = src[i];\r
177 dest[dest_len + i] = '\0';\r
6658905f 178 \r
f7c64b57 179 return dest;\r
180}\r
6658905f 181\r
f7c64b57 182////////////////////////////////////////// code to do 'itoa'\r
6658905f 183\r
184/* reverse: reverse string s in place */\r
185void reverse(char s[])\r
186{\r
187 int c, i, j;\r
188\r
189 for (i = 0, j = strlen(s)-1; i<j; i++, j--) {\r
190 c = s[i];\r
191 s[i] = s[j];\r
192 s[j] = c;\r
193 }\r
194}\r
195\r
196/* itoa: convert n to characters in s */\r
197void itoa(int n, char s[])\r
198{\r
199 int i, sign;\r
200\r
201 if ((sign = n) < 0) /* record sign */\r
202 n = -n; /* make n positive */\r
203 i = 0;\r
204 do { /* generate digits in reverse order */\r
205 s[i++] = n % 10 + '0'; /* get next digit */\r
206 } while ((n /= 10) > 0); /* delete it */\r
207 if (sign < 0)\r
208 s[i++] = '-';\r
209 s[i] = '\0';\r
210 reverse(s);\r
f7c64b57 211}\r
6658905f 212\r
213//////////////////////////////////////// END 'itoa' CODE\r
214\r
6658905f 215//-----------------------------------------------------------------------------\r
216// Encode (into the ToSend buffers) an identify request, which is the first\r
217// thing that you must send to a tag to get a response.\r
218//-----------------------------------------------------------------------------\r
219static void BuildIdentifyRequest(void)\r
220{\r
221 BYTE cmd[5];\r
222\r
223 WORD crc;\r
224 // one sub-carrier, inventory, 1 slot, fast rate\r
225 // AFI is at bit 5 (1<<4) when doing an INVENTORY\r
f7c64b57 226 cmd[0] = (1 << 2) | (1 << 5) | (1 << 1);\r
6658905f 227 // inventory command code\r
228 cmd[1] = 0x01;\r
229 // no mask\r
230 cmd[2] = 0x00;\r
231 //Now the CRC\r
232 crc = Crc(cmd, 3);\r
233 cmd[3] = crc & 0xff;\r
234 cmd[4] = crc >> 8;\r
235\r
236 CodeIso15693AsReader(cmd, sizeof(cmd));\r
237}\r
238\r
239static void BuildSysInfoRequest(BYTE *uid)\r
240{\r
241 BYTE cmd[12];\r
242\r
243 WORD crc;\r
244 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block\r
245 // followed by teh block data\r
246 // one sub-carrier, inventory, 1 slot, fast rate\r
247 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit\r
248 // System Information command code\r
249 cmd[1] = 0x2B;\r
250 // UID may be optionally specified here\r
251 // 64-bit UID\r
252 cmd[2] = 0x32;\r
253 cmd[3]= 0x4b;\r
254 cmd[4] = 0x03;\r
255 cmd[5] = 0x01;\r
256 cmd[6] = 0x00;\r
257 cmd[7] = 0x10;\r
f7c64b57 258 cmd[8] = 0x05;\r
259 cmd[9]= 0xe0; // always e0 (not exactly unique)\r
6658905f 260 //Now the CRC\r
f7c64b57 261 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes\r
6658905f 262 cmd[10] = crc & 0xff;\r
263 cmd[11] = crc >> 8;\r
264\r
265 CodeIso15693AsReader(cmd, sizeof(cmd));\r
266}\r
267\r
268static void BuildSelectRequest( BYTE uid[])\r
269{\r
f7c64b57 270\r
6658905f 271// uid[6]=0x31; // this is getting ignored - the uid array is not happening...\r
272 BYTE cmd[12];\r
273\r
274 WORD crc;\r
275 // one sub-carrier, inventory, 1 slot, fast rate\r
276 //cmd[0] = (1 << 2) | (1 << 5) | (1 << 1); // INVENTROY FLAGS\r
277 cmd[0] = (1 << 4) | (1 << 5) | (1 << 1); // Select and addressed FLAGS\r
278 // SELECT command code\r
279 cmd[1] = 0x25;\r
280 // 64-bit UID\r
281// cmd[2] = uid[0];//0x32;\r
282// cmd[3]= uid[1];//0x4b;\r
283// cmd[4] = uid[2];//0x03;\r
284// cmd[5] = uid[3];//0x01;\r
285// cmd[6] = uid[4];//0x00;\r
286// cmd[7] = uid[5];//0x10;\r
f7c64b57 287// cmd[8] = uid[6];//0x05;\r
6658905f 288 cmd[2] = 0x32;//\r
f7c64b57 289 cmd[3] = 0x4b;\r
6658905f 290 cmd[4] = 0x03;\r
291 cmd[5] = 0x01;\r
292 cmd[6] = 0x00;\r
293 cmd[7] = 0x10;\r
294 cmd[8] = 0x05; // infineon?\r
295\r
f7c64b57 296 cmd[9]= 0xe0; // always e0 (not exactly unique)\r
6658905f 297\r
298// DbpIntegers(cmd[8],cmd[7],cmd[6]);\r
299 // Now the CRC\r
f7c64b57 300 crc = Crc(cmd, 10); // the crc needs to be calculated over 10 bytes\r
6658905f 301 cmd[10] = crc & 0xff;\r
302 cmd[11] = crc >> 8;\r
303\r
304 CodeIso15693AsReader(cmd, sizeof(cmd));\r
305}\r
306\r
307static void BuildReadBlockRequest(BYTE *uid, BYTE blockNumber )\r
308{\r
309 BYTE cmd[13];\r
310\r
311 WORD crc;\r
312 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block\r
313 // followed by teh block data\r
314 // one sub-carrier, inventory, 1 slot, fast rate\r
315 cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit\r
316 // READ BLOCK command code\r
317 cmd[1] = 0x20;\r
318 // UID may be optionally specified here\r
319 // 64-bit UID\r
320 cmd[2] = 0x32;\r
321 cmd[3]= 0x4b;\r
322 cmd[4] = 0x03;\r
323 cmd[5] = 0x01;\r
324 cmd[6] = 0x00;\r
325 cmd[7] = 0x10;\r
f7c64b57 326 cmd[8] = 0x05;\r
327 cmd[9]= 0xe0; // always e0 (not exactly unique)\r
6658905f 328 // Block number to read\r
329 cmd[10] = blockNumber;//0x00;\r
330 //Now the CRC\r
f7c64b57 331 crc = Crc(cmd, 11); // the crc needs to be calculated over 2 bytes\r
6658905f 332 cmd[11] = crc & 0xff;\r
333 cmd[12] = crc >> 8;\r
334\r
335 CodeIso15693AsReader(cmd, sizeof(cmd));\r
336}\r
337\r
6658905f 338static void BuildReadMultiBlockRequest(BYTE *uid)\r
339{\r
340 BYTE cmd[14];\r
341\r
342 WORD crc;\r
343 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block\r
344 // followed by teh block data\r
345 // one sub-carrier, inventory, 1 slot, fast rate\r
346 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit\r
347 // READ Multi BLOCK command code\r
348 cmd[1] = 0x23;\r
349 // UID may be optionally specified here\r
350 // 64-bit UID\r
351 cmd[2] = 0x32;\r
352 cmd[3]= 0x4b;\r
353 cmd[4] = 0x03;\r
354 cmd[5] = 0x01;\r
355 cmd[6] = 0x00;\r
356 cmd[7] = 0x10;\r
f7c64b57 357 cmd[8] = 0x05;\r
358 cmd[9]= 0xe0; // always e0 (not exactly unique)\r
6658905f 359 // First Block number to read\r
360 cmd[10] = 0x00;\r
361 // Number of Blocks to read\r
362 cmd[11] = 0x2f; // read quite a few\r
363 //Now the CRC\r
f7c64b57 364 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes\r
6658905f 365 cmd[12] = crc & 0xff;\r
366 cmd[13] = crc >> 8;\r
367\r
368 CodeIso15693AsReader(cmd, sizeof(cmd));\r
369}\r
370\r
371static void BuildArbitraryRequest(BYTE *uid,BYTE CmdCode)\r
372{\r
373 BYTE cmd[14];\r
374\r
375 WORD crc;\r
376 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block\r
377 // followed by teh block data\r
378 // one sub-carrier, inventory, 1 slot, fast rate\r
379 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit\r
380 // READ BLOCK command code\r
381 cmd[1] = CmdCode;\r
382 // UID may be optionally specified here\r
383 // 64-bit UID\r
384 cmd[2] = 0x32;\r
385 cmd[3]= 0x4b;\r
386 cmd[4] = 0x03;\r
387 cmd[5] = 0x01;\r
388 cmd[6] = 0x00;\r
389 cmd[7] = 0x10;\r
f7c64b57 390 cmd[8] = 0x05;\r
391 cmd[9]= 0xe0; // always e0 (not exactly unique)\r
6658905f 392 // Parameter\r
393 cmd[10] = 0x00;\r
394 cmd[11] = 0x0a;\r
395\r
396// cmd[12] = 0x00;\r
397// cmd[13] = 0x00; //Now the CRC\r
f7c64b57 398 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes\r
6658905f 399 cmd[12] = crc & 0xff;\r
400 cmd[13] = crc >> 8;\r
401\r
402 CodeIso15693AsReader(cmd, sizeof(cmd));\r
403}\r
404\r
f7c64b57 405static void BuildArbitraryCustomRequest(BYTE uid[], BYTE CmdCode)\r
6658905f 406{\r
407 BYTE cmd[14];\r
408\r
409 WORD crc;\r
410 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block\r
411 // followed by teh block data\r
412 // one sub-carrier, inventory, 1 slot, fast rate\r
413 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit\r
414 // READ BLOCK command code\r
415 cmd[1] = CmdCode;\r
416 // UID may be optionally specified here\r
417 // 64-bit UID\r
418 cmd[2] = 0x32;\r
419 cmd[3]= 0x4b;\r
420 cmd[4] = 0x03;\r
421 cmd[5] = 0x01;\r
422 cmd[6] = 0x00;\r
423 cmd[7] = 0x10;\r
f7c64b57 424 cmd[8] = 0x05;\r
425 cmd[9]= 0xe0; // always e0 (not exactly unique)\r
6658905f 426 // Parameter\r
427 cmd[10] = 0x05; // for custom codes this must be manufcturer code\r
428 cmd[11] = 0x00;\r
429\r
430// cmd[12] = 0x00;\r
431// cmd[13] = 0x00; //Now the CRC\r
f7c64b57 432 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes\r
6658905f 433 cmd[12] = crc & 0xff;\r
434 cmd[13] = crc >> 8;\r
435\r
436 CodeIso15693AsReader(cmd, sizeof(cmd));\r
437}\r
438\r
439/////////////////////////////////////////////////////////////////////////\r
440// Now the VICC>VCD responses when we are simulating a tag\r
441////////////////////////////////////////////////////////////////////\r
442\r
443 static void BuildInventoryResponse(void)\r
444{\r
445 BYTE cmd[12];\r
446\r
447 WORD crc;\r
448 // one sub-carrier, inventory, 1 slot, fast rate\r
449 // AFI is at bit 5 (1<<4) when doing an INVENTORY\r
f7c64b57 450 cmd[0] = 0; //(1 << 2) | (1 << 5) | (1 << 1);\r
6658905f 451 cmd[1] = 0;\r
452 // 64-bit UID\r
453 cmd[2] = 0x32;\r
454 cmd[3]= 0x4b;\r
455 cmd[4] = 0x03;\r
456 cmd[5] = 0x01;\r
457 cmd[6] = 0x00;\r
458 cmd[7] = 0x10;\r
f7c64b57 459 cmd[8] = 0x05;\r
6658905f 460 cmd[9]= 0xe0;\r
461 //Now the CRC\r
462 crc = Crc(cmd, 10);\r
463 cmd[10] = crc & 0xff;\r
464 cmd[11] = crc >> 8;\r
465\r
466 CodeIso15693AsReader(cmd, sizeof(cmd));\r
467}\r
468\r
6658905f 469//-----------------------------------------------------------------------------\r
470// Transmit the command (to the tag) that was placed in ToSend[].\r
471//-----------------------------------------------------------------------------\r
472static void TransmitTo15693Tag(const BYTE *cmd, int len, int *samples, int *wait)\r
473{\r
474 int c;\r
475\r
476// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
477 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);\r
478 if(*wait < 10) { *wait = 10; }\r
479\r
480// for(c = 0; c < *wait;) {\r
481// if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
482// SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!\r
483// c++;\r
484// }\r
485// if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
486// volatile DWORD r = SSC_RECEIVE_HOLDING;\r
487// (void)r;\r
488// }\r
489// WDT_HIT();\r
490// }\r
491\r
492 c = 0;\r
493 for(;;) {\r
494 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
495 SSC_TRANSMIT_HOLDING = cmd[c];\r
496 c++;\r
497 if(c >= len) {\r
498 break;\r
499 }\r
500 }\r
501 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
502 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
503 (void)r;\r
504 }\r
505 WDT_HIT();\r
506 }\r
507 *samples = (c + *wait) << 3;\r
508}\r
509\r
6658905f 510//-----------------------------------------------------------------------------\r
511// Transmit the command (to the reader) that was placed in ToSend[].\r
512//-----------------------------------------------------------------------------\r
513static void TransmitTo15693Reader(const BYTE *cmd, int len, int *samples, int *wait)\r
514{\r
515 int c;\r
516\r
517// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);\r
518 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR); // No requirement to energise my coils\r
519 if(*wait < 10) { *wait = 10; }\r
520\r
521 c = 0;\r
522 for(;;) {\r
523 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
524 SSC_TRANSMIT_HOLDING = cmd[c];\r
525 c++;\r
526 if(c >= len) {\r
527 break;\r
528 }\r
529 }\r
530 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
531 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
532 (void)r;\r
533 }\r
534 WDT_HIT();\r
535 }\r
536 *samples = (c + *wait) << 3;\r
537}\r
538\r
f7c64b57 539static int GetIso15693AnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed)\r
6658905f 540{\r
541 int c = 0;\r
542 BYTE *dest = (BYTE *)BigBuf;\r
543 int getNext = 0;\r
544\r
6658905f 545 SBYTE prev = 0;\r
546\r
547// NOW READ RESPONSE\r
548 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);\r
549 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads\r
550 c = 0;\r
551 getNext = FALSE;\r
552 for(;;) {\r
553 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
554 SSC_TRANSMIT_HOLDING = 0x43;\r
555 }\r
556 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
557 SBYTE b;\r
558 b = (SBYTE)SSC_RECEIVE_HOLDING;\r
559\r
560 // The samples are correlations against I and Q versions of the\r
561 // tone that the tag AM-modulates, so every other sample is I,\r
562 // every other is Q. We just want power, so abs(I) + abs(Q) is\r
563 // close to what we want.\r
564 if(getNext) {\r
565 SBYTE r;\r
566\r
567 if(b < 0) {\r
568 r = -b;\r
569 } else {\r
570 r = b;\r
571 }\r
572 if(prev < 0) {\r
573 r -= prev;\r
574 } else {\r
575 r += prev;\r
576 }\r
577\r
578 dest[c++] = (BYTE)r;\r
579\r
580 if(c >= 2000) {\r
581 break;\r
582 }\r
583 } else {\r
584 prev = b;\r
585 }\r
586\r
587 getNext = !getNext;\r
588 }\r
589 }\r
590\r
591//////////////////////////////////////////\r
592/////////// DEMODULATE ///////////////////\r
593//////////////////////////////////////////\r
594\r
595 int i, j;\r
f7c64b57 596 int max = 0, maxPos=0;\r
6658905f 597\r
598 int skip = 4;\r
599\r
6658905f 600// if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL\r
601\r
602 // First, correlate for SOF\r
603 for(i = 0; i < 100; i++) {\r
604 int corr = 0;\r
605 for(j = 0; j < arraylen(FrameSOF); j += skip) {\r
606 corr += FrameSOF[j]*dest[i+(j/skip)];\r
607 }\r
608 if(corr > max) {\r
609 max = corr;\r
610 maxPos = i;\r
611 }\r
612 }\r
613// DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));\r
614\r
615 int k = 0; // this will be our return value\r
616\r
617 // greg - If correlation is less than 1 then there's little point in continuing\r
f7c64b57 618 if ((max/(arraylen(FrameSOF)/skip)) >= 1)\r
6658905f 619 {\r
620\r
621 i = maxPos + arraylen(FrameSOF)/skip;\r
f7c64b57 622\r
6658905f 623 BYTE outBuf[20];\r
624 memset(outBuf, 0, sizeof(outBuf));\r
625 BYTE mask = 0x01;\r
626 for(;;) {\r
627 int corr0 = 0, corr1 = 0, corrEOF = 0;\r
628 for(j = 0; j < arraylen(Logic0); j += skip) {\r
629 corr0 += Logic0[j]*dest[i+(j/skip)];\r
630 }\r
631 for(j = 0; j < arraylen(Logic1); j += skip) {\r
632 corr1 += Logic1[j]*dest[i+(j/skip)];\r
633 }\r
634 for(j = 0; j < arraylen(FrameEOF); j += skip) {\r
635 corrEOF += FrameEOF[j]*dest[i+(j/skip)];\r
636 }\r
637 // Even things out by the length of the target waveform.\r
638 corr0 *= 4;\r
639 corr1 *= 4;\r
640\r
641 if(corrEOF > corr1 && corrEOF > corr0) {\r
642// DbpString("EOF at %d", i);\r
643 break;\r
644 } else if(corr1 > corr0) {\r
645 i += arraylen(Logic1)/skip;\r
646 outBuf[k] |= mask;\r
647 } else {\r
648 i += arraylen(Logic0)/skip;\r
649 }\r
650 mask <<= 1;\r
651 if(mask == 0) {\r
652 k++;\r
653 mask = 0x01;\r
654 }\r
655 if((i+(int)arraylen(FrameEOF)) >= 2000) {\r
656 DbpString("ran off end!");\r
657 break;\r
658 }\r
659 }\r
660 if(mask != 0x01) {\r
661 DbpString("error, uneven octet! (discard extra bits!)");\r
662/// DbpString(" mask=%02x", mask);\r
663 }\r
664// BYTE str1 [8];\r
665// itoa(k,str1);\r
666// strcat(str1," octets read");\r
667\r
668// DbpString( str1); // DbpString("%d octets", k);\r
669\r
670// for(i = 0; i < k; i+=3) {\r
671// //DbpString("# %2d: %02x ", i, outBuf[i]);\r
672// DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);\r
673// }\r
674\r
675 for(i = 0; i < k; i++) {\r
676 receivedResponse[i] = outBuf[i];\r
f7c64b57 677 }\r
6658905f 678 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))\r
679 return k; // return the number of bytes demodulated\r
680\r
681/// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));\r
682\r
6658905f 683}\r
684\r
685// Now the GetISO15693 message from sniffing command\r
f7c64b57 686static int GetIso15693AnswerFromSniff(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed)\r
6658905f 687{\r
688 int c = 0;\r
689 BYTE *dest = (BYTE *)BigBuf;\r
690 int getNext = 0;\r
691\r
6658905f 692 SBYTE prev = 0;\r
693\r
694// NOW READ RESPONSE\r
695 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);\r
696 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads\r
697 c = 0;\r
698 getNext = FALSE;\r
699 for(;;) {\r
700 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
701 SSC_TRANSMIT_HOLDING = 0x43;\r
702 }\r
703 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
704 SBYTE b;\r
705 b = (SBYTE)SSC_RECEIVE_HOLDING;\r
706\r
707 // The samples are correlations against I and Q versions of the\r
708 // tone that the tag AM-modulates, so every other sample is I,\r
709 // every other is Q. We just want power, so abs(I) + abs(Q) is\r
710 // close to what we want.\r
711 if(getNext) {\r
712 SBYTE r;\r
713\r
714 if(b < 0) {\r
715 r = -b;\r
716 } else {\r
717 r = b;\r
718 }\r
719 if(prev < 0) {\r
720 r -= prev;\r
721 } else {\r
722 r += prev;\r
723 }\r
724\r
725 dest[c++] = (BYTE)r;\r
726\r
727 if(c >= 20000) {\r
728 break;\r
729 }\r
730 } else {\r
731 prev = b;\r
732 }\r
733\r
734 getNext = !getNext;\r
735 }\r
736 }\r
737\r
738//////////////////////////////////////////\r
739/////////// DEMODULATE ///////////////////\r
740//////////////////////////////////////////\r
741\r
742 int i, j;\r
f7c64b57 743 int max = 0, maxPos=0;\r
6658905f 744\r
745 int skip = 4;\r
746\r
6658905f 747// if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL\r
748\r
749 // First, correlate for SOF\r
750 for(i = 0; i < 19000; i++) {\r
751 int corr = 0;\r
752 for(j = 0; j < arraylen(FrameSOF); j += skip) {\r
753 corr += FrameSOF[j]*dest[i+(j/skip)];\r
754 }\r
755 if(corr > max) {\r
756 max = corr;\r
757 maxPos = i;\r
758 }\r
759 }\r
760// DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));\r
761\r
762 int k = 0; // this will be our return value\r
763\r
764 // greg - If correlation is less than 1 then there's little point in continuing\r
f7c64b57 765 if ((max/(arraylen(FrameSOF)/skip)) >= 1) // THIS SHOULD BE 1\r
6658905f 766 {\r
767\r
768 i = maxPos + arraylen(FrameSOF)/skip;\r
f7c64b57 769\r
6658905f 770 BYTE outBuf[20];\r
771 memset(outBuf, 0, sizeof(outBuf));\r
772 BYTE mask = 0x01;\r
773 for(;;) {\r
774 int corr0 = 0, corr1 = 0, corrEOF = 0;\r
775 for(j = 0; j < arraylen(Logic0); j += skip) {\r
776 corr0 += Logic0[j]*dest[i+(j/skip)];\r
777 }\r
778 for(j = 0; j < arraylen(Logic1); j += skip) {\r
779 corr1 += Logic1[j]*dest[i+(j/skip)];\r
780 }\r
781 for(j = 0; j < arraylen(FrameEOF); j += skip) {\r
782 corrEOF += FrameEOF[j]*dest[i+(j/skip)];\r
783 }\r
784 // Even things out by the length of the target waveform.\r
785 corr0 *= 4;\r
786 corr1 *= 4;\r
787\r
788 if(corrEOF > corr1 && corrEOF > corr0) {\r
789// DbpString("EOF at %d", i);\r
790 break;\r
791 } else if(corr1 > corr0) {\r
792 i += arraylen(Logic1)/skip;\r
793 outBuf[k] |= mask;\r
794 } else {\r
795 i += arraylen(Logic0)/skip;\r
796 }\r
797 mask <<= 1;\r
798 if(mask == 0) {\r
799 k++;\r
800 mask = 0x01;\r
801 }\r
802 if((i+(int)arraylen(FrameEOF)) >= 2000) {\r
803 DbpString("ran off end!");\r
804 break;\r
805 }\r
806 }\r
807 if(mask != 0x01) {\r
808 DbpString("error, uneven octet! (discard extra bits!)");\r
809/// DbpString(" mask=%02x", mask);\r
810 }\r
811// BYTE str1 [8];\r
812// itoa(k,str1);\r
813// strcat(str1," octets read");\r
814\r
815// DbpString( str1); // DbpString("%d octets", k);\r
816\r
817// for(i = 0; i < k; i+=3) {\r
818// //DbpString("# %2d: %02x ", i, outBuf[i]);\r
819// DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);\r
820// }\r
821\r
822 for(i = 0; i < k; i++) {\r
823 receivedResponse[i] = outBuf[i];\r
f7c64b57 824 }\r
6658905f 825 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))\r
826 return k; // return the number of bytes demodulated\r
827\r
828/// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));\r
6658905f 829}\r
830\r
6658905f 831//-----------------------------------------------------------------------------\r
832// Start to read an ISO 15693 tag. We send an identify request, then wait\r
833// for the response. The response is not demodulated, just left in the buffer\r
834// so that it can be downloaded to a PC and processed there.\r
835//-----------------------------------------------------------------------------\r
836void AcquireRawAdcSamplesIso15693(void)\r
837{\r
838 int c = 0;\r
839 BYTE *dest = (BYTE *)BigBuf;\r
840 int getNext = 0;\r
841\r
842 SBYTE prev = 0;\r
843\r
844 BuildIdentifyRequest();\r
845\r
846 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
847\r
848 // Give the tags time to energize\r
849 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);\r
850 SpinDelay(100);\r
851\r
852 // Now send the command\r
853 FpgaSetupSsc();\r
854 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);\r
855\r
856 c = 0;\r
857 for(;;) {\r
858 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
859 SSC_TRANSMIT_HOLDING = ToSend[c];\r
860 c++;\r
861 if(c == ToSendMax+3) {\r
862 break;\r
863 }\r
864 }\r
865 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
866 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
867 (void)r;\r
868 }\r
869 WDT_HIT();\r
870 }\r
871\r
872 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);\r
873\r
874 c = 0;\r
875 getNext = FALSE;\r
876 for(;;) {\r
877 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
878 SSC_TRANSMIT_HOLDING = 0x43;\r
879 }\r
880 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
881 SBYTE b;\r
882 b = (SBYTE)SSC_RECEIVE_HOLDING;\r
883\r
884 // The samples are correlations against I and Q versions of the\r
885 // tone that the tag AM-modulates, so every other sample is I,\r
886 // every other is Q. We just want power, so abs(I) + abs(Q) is\r
887 // close to what we want.\r
888 if(getNext) {\r
889 SBYTE r;\r
890\r
891 if(b < 0) {\r
892 r = -b;\r
893 } else {\r
894 r = b;\r
895 }\r
896 if(prev < 0) {\r
897 r -= prev;\r
898 } else {\r
899 r += prev;\r
900 }\r
901\r
902 dest[c++] = (BYTE)r;\r
903\r
904 if(c >= 2000) {\r
905 break;\r
906 }\r
907 } else {\r
908 prev = b;\r
909 }\r
910\r
911 getNext = !getNext;\r
912 }\r
913 }\r
914}\r
915\r
6658905f 916//-----------------------------------------------------------------------------\r
917// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector\r
918// all demodulation performed in arm rather than host. - greg\r
919//-----------------------------------------------------------------------------\r
920void ReaderIso15693(DWORD parameter)\r
921{\r
922 LED_A_ON();\r
923 LED_B_ON();\r
924 LED_C_OFF();\r
925 LED_D_OFF();\r
926\r
6658905f 927//DbpString(parameter);\r
928\r
929 BYTE *receivedAnswer0 = (((BYTE *)BigBuf) + 3560); // allow 100 bytes per reponse (way too much)\r
f7c64b57 930 BYTE *receivedAnswer1 = (((BYTE *)BigBuf) + 3660); //\r
6658905f 931 BYTE *receivedAnswer2 = (((BYTE *)BigBuf) + 3760);\r
932 BYTE *receivedAnswer3 = (((BYTE *)BigBuf) + 3860);\r
f7c64b57 933 //BYTE *TagUID= (((BYTE *)BigBuf) + 3960); // where we hold the uid for hi15reader\r
934// int responseLen0 = 0;\r
6658905f 935 int responseLen1 = 0;\r
936 int responseLen2 = 0;\r
937 int responseLen3 = 0;\r
938\r
939 // Blank arrays\r
940 int j;\r
941 for(j = 0; j < 100; j++) {\r
942 receivedAnswer3[j] = 0;\r
943 receivedAnswer2[j] =0;\r
944 receivedAnswer1[j] = 0;\r
945 receivedAnswer0[j] = 0;\r
946 }\r
947\r
948 // Setup SSC\r
949 FpgaSetupSsc();\r
950\r
951 // Start from off (no field generated)\r
952 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
953 SpinDelay(200);\r
954\r
955 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
956 FpgaSetupSsc();\r
957\r
958 // Give the tags time to energize\r
959 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);\r
960 SpinDelay(200);\r
961\r
962 LED_A_ON();\r
963 LED_B_OFF();\r
964 LED_C_OFF();\r
965 LED_D_OFF();\r
966\r
967 int samples = 0;\r
968 int tsamples = 0;\r
969 int wait = 0;\r
970 int elapsed = 0;\r
971\r
972 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID\r
973 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME\r
f7c64b57 974 BYTE TagUID[7]; // where we hold the uid for hi15reader\r
6658905f 975\r
976// BuildIdentifyRequest();\r
f7c64b57 977// //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);\r
6658905f 978// TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3\r
979// // Now wait for a response\r
f7c64b57 980// responseLen0 = GetIso15693AnswerFromTag(receivedAnswer0, 100, &samples, &elapsed) ;\r
6658905f 981// if (responseLen0 >=12) // we should do a better check than this\r
982// {\r
983// // really we should check it is a valid mesg\r
984// // but for now just grab what we think is the uid\r
985// TagUID[0] = receivedAnswer0[2];\r
986// TagUID[1] = receivedAnswer0[3];\r
987// TagUID[2] = receivedAnswer0[4];\r
988// TagUID[3] = receivedAnswer0[5];\r
989// TagUID[4] = receivedAnswer0[6];\r
990// TagUID[5] = receivedAnswer0[7];\r
991// TagUID[6] = receivedAnswer0[8]; // IC Manufacturer code\r
f7c64b57 992// DbpIntegers(TagUID[6],TagUID[5],TagUID[4]);\r
6658905f 993//}\r
994\r
995 // Now send the IDENTIFY command\r
996 BuildIdentifyRequest();\r
f7c64b57 997 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);\r
6658905f 998 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3\r
999 // Now wait for a response\r
1000 responseLen1 = GetIso15693AnswerFromTag(receivedAnswer1, 100, &samples, &elapsed) ;\r
f7c64b57 1001\r
6658905f 1002 if (responseLen1 >=12) // we should do a better check than this\r
1003 {\r
f7c64b57 1004\r
6658905f 1005 TagUID[0] = receivedAnswer1[2];\r
1006 TagUID[1] = receivedAnswer1[3];\r
1007 TagUID[2] = receivedAnswer1[4];\r
1008 TagUID[3] = receivedAnswer1[5];\r
1009 TagUID[4] = receivedAnswer1[6];\r
1010 TagUID[5] = receivedAnswer1[7];\r
1011 TagUID[6] = receivedAnswer1[8]; // IC Manufacturer code\r
f7c64b57 1012\r
6658905f 1013 // Now send the SELECT command\r
f7c64b57 1014 BuildSelectRequest(TagUID);\r
6658905f 1015 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3\r
1016 // Now wait for a response\r
f7c64b57 1017 responseLen2 = GetIso15693AnswerFromTag(receivedAnswer2, 100, &samples, &elapsed);\r
6658905f 1018\r
1019 // Now send the MULTI READ command\r
1020// BuildArbitraryRequest(*TagUID,parameter);\r
f7c64b57 1021 BuildArbitraryCustomRequest(TagUID,parameter);\r
6658905f 1022// BuildReadBlockRequest(*TagUID,parameter);\r
1023// BuildSysInfoRequest(*TagUID);\r
f7c64b57 1024 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);\r
1025 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3\r
6658905f 1026 // Now wait for a response\r
1027 responseLen3 = GetIso15693AnswerFromTag(receivedAnswer3, 100, &samples, &elapsed) ;\r
1028\r
1029 }\r
1030\r
f7c64b57 1031 char str1 [4];\r
6658905f 1032 //char str2 [200];\r
1033 int i;\r
1034\r
1035 itoa(responseLen1,str1);\r
1036 strcat(str1," octets read from IDENTIFY request");\r
1037 DbpString(str1);\r
1038 for(i = 0; i < responseLen1; i+=3) {\r
1039 DbpIntegers(receivedAnswer1[i],receivedAnswer1[i+1],receivedAnswer1[i+2]);\r
1040 }\r
1041\r
1042 itoa(responseLen2,str1);\r
1043 strcat(str1," octets read from SELECT request");\r
1044 DbpString(str1);\r
1045 for(i = 0; i < responseLen2; i+=3) {\r
1046 DbpIntegers(receivedAnswer2[i],receivedAnswer2[i+1],receivedAnswer2[i+2]);\r
1047 }\r
1048\r
1049 itoa(responseLen3,str1);\r
1050 strcat(str1," octets read from XXX request");\r
1051 DbpString(str1);\r
1052 for(i = 0; i < responseLen3; i+=3) {\r
1053 DbpIntegers(receivedAnswer3[i],receivedAnswer3[i+1],receivedAnswer3[i+2]);\r
1054 }\r
6658905f 1055\r
1056// str2[0]=0;\r
1057// for(i = 0; i < responseLen3; i++) {\r
1058// itoa(str1,receivedAnswer3[i]);\r
1059// strcat(str2,str1);\r
1060// }\r
f7c64b57 1061// DbpString(str2);\r
6658905f 1062\r
1063 LED_A_OFF();\r
1064 LED_B_OFF();\r
1065 LED_C_OFF();\r
1066 LED_D_OFF();\r
6658905f 1067}\r
1068\r
6658905f 1069//-----------------------------------------------------------------------------\r
1070// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands\r
1071// all demodulation performed in arm rather than host. - greg\r
1072//-----------------------------------------------------------------------------\r
1073void SimTagIso15693(DWORD parameter)\r
1074{\r
1075 LED_A_ON();\r
1076 LED_B_ON();\r
1077 LED_C_OFF();\r
1078 LED_D_OFF();\r
1079\r
6658905f 1080//DbpString(parameter);\r
1081\r
1082 BYTE *receivedAnswer0 = (((BYTE *)BigBuf) + 3560); // allow 100 bytes per reponse (way too much)\r
f7c64b57 1083 BYTE *receivedAnswer1 = (((BYTE *)BigBuf) + 3660); //\r
6658905f 1084 BYTE *receivedAnswer2 = (((BYTE *)BigBuf) + 3760);\r
1085 BYTE *receivedAnswer3 = (((BYTE *)BigBuf) + 3860);\r
f7c64b57 1086 //BYTE *TagUID= (((BYTE *)BigBuf) + 3960); // where we hold the uid for hi15reader\r
1087// int responseLen0 = 0;\r
6658905f 1088 int responseLen1 = 0;\r
f7c64b57 1089// int responseLen2 = 0;\r
1090// int responseLen3 = 0;\r
6658905f 1091\r
1092 // Blank arrays\r
1093 int j;\r
1094 for(j = 0; j < 100; j++) {\r
1095 receivedAnswer3[j] = 0;\r
1096 receivedAnswer2[j] =0;\r
1097 receivedAnswer1[j] = 0;\r
1098 receivedAnswer0[j] = 0;\r
1099 }\r
1100\r
1101 // Setup SSC\r
1102 FpgaSetupSsc();\r
1103\r
1104 // Start from off (no field generated)\r
1105 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1106 SpinDelay(200);\r
1107\r
1108 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1109 FpgaSetupSsc();\r
1110\r
1111 // Give the tags time to energize\r
1112// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); // NO GOOD FOR SIM TAG!!!!\r
1113 SpinDelay(200);\r
1114\r
1115 LED_A_OFF();\r
1116 LED_B_OFF();\r
1117 LED_C_ON();\r
1118 LED_D_OFF();\r
1119\r
1120 int samples = 0;\r
1121 int tsamples = 0;\r
1122 int wait = 0;\r
1123 int elapsed = 0;\r
1124\r
1125 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID\r
1126 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME\r
f7c64b57 1127 // BYTE TagUID[7]; // where we hold the uid for hi15reader\r
6658905f 1128\r
1129 // Now send the IDENTIFY command\r
f7c64b57 1130 // BuildIdentifyRequest();\r
1131 // TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3\r
6658905f 1132\r
1133 // Now wait for a command from the reader\r
1134 responseLen1=0;\r
f7c64b57 1135 // while(responseLen1=0) {\r
1136 // if(BUTTON_PRESS()) break;\r
6658905f 1137 responseLen1 = GetIso15693AnswerFromSniff(receivedAnswer1, 100, &samples, &elapsed) ;\r
f7c64b57 1138 // }\r
6658905f 1139\r
6658905f 1140 if (responseLen1 >=1) // we should do a better check than this\r
1141 {\r
1142 // Build a suitable reponse to the reader INVENTORY cocmmand\r
f7c64b57 1143 BuildInventoryResponse();\r
6658905f 1144 TransmitTo15693Reader(ToSend,ToSendMax,&tsamples, &wait);\r
1145\r
1146 // Now wait for a command from the reader\r
f7c64b57 1147// responseLen2 = GetIso15693AnswerFromTag(receivedAnswer2, 100, &samples, &elapsed);\r
6658905f 1148\r
6658905f 1149 // Now wait for a command from the reader\r
1150// responseLen3 = GetIso15693AnswerFromTag(receivedAnswer3, 100, &samples, &elapsed) ;\r
1151\r
1152 }\r
1153\r
f7c64b57 1154 char str1 [4];\r
6658905f 1155 //char str2 [200];\r
1156 int i;\r
1157\r
1158 itoa(responseLen1,str1);\r
1159 strcat(str1," octets read from reader command");\r
1160 DbpString(str1);\r
1161 for(i = 0; i < responseLen1; i+=3) {\r
1162 DbpIntegers(receivedAnswer1[i],receivedAnswer1[i+1],receivedAnswer1[i+2]);\r
1163 }\r
1164\r
1165// itoa(responseLen2,str1);\r
1166// strcat(str1," octets read from SELECT request");\r
1167// DbpString(str1);\r
1168// for(i = 0; i < responseLen2; i+=3) {\r
1169// DbpIntegers(receivedAnswer2[i],receivedAnswer2[i+1],receivedAnswer2[i+2]);\r
1170// }\r
1171//\r
1172// itoa(responseLen3,str1);\r
1173// strcat(str1," octets read from XXX request");\r
1174// DbpString(str1);\r
1175// for(i = 0; i < responseLen3; i+=3) {\r
1176// DbpIntegers(receivedAnswer3[i],receivedAnswer3[i+1],receivedAnswer3[i+2]);\r
1177// }\r
6658905f 1178\r
1179// str2[0]=0;\r
1180// for(i = 0; i < responseLen3; i++) {\r
1181// itoa(str1,receivedAnswer3[i]);\r
1182// strcat(str2,str1);\r
1183// }\r
f7c64b57 1184// DbpString(str2);\r
6658905f 1185\r
1186 LED_A_OFF();\r
1187 LED_B_OFF();\r
1188 LED_C_OFF();\r
1189 LED_D_OFF();\r
f7c64b57 1190}\r
Impressum, Datenschutz