1 //-----------------------------------------------------------------------------
2 // Routines to support ISO 15693. This includes both the reader software and
3 // the `fake tag' modes, but at the moment I've implemented only the reader
4 // stuff, and that barely.
5 // Jonathan Westhues, split Nov 2006
7 // Modified by Greg Jones, Jan 2009 to perform modulation onboard in arm rather than on PC
8 // Also added additional reader commands (SELECT, READ etc.)
10 //-----------------------------------------------------------------------------
11 #include <proxmark3.h>
16 // FROM winsrc\prox.h //////////////////////////////////
17 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
19 //-----------------------------------------------------------------------------
20 // Map a sequence of octets (~layer 2 command) into the set of bits to feed
21 // to the FPGA, to transmit that command to the tag.
22 //-----------------------------------------------------------------------------
27 // The sampling rate is 106.353 ksps/s, for T = 18.8 us
30 // 1) Unmodulated time of 56.64us
31 // 2) 24 pulses of 423.75khz
32 // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
34 static const int FrameSOF
[] = {
35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
38 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
44 static const int Logic0
[] = {
50 static const int Logic1
[] = {
58 // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
59 // 2) 24 pulses of 423.75khz
60 // 3) Unmodulated time of 56.64us
62 static const int FrameEOF
[] = {
67 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
68 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
76 static void CodeIso15693AsReader(BYTE
*cmd
, int n
)
82 // Give it a bit of slack at the beginning
83 for(i
= 0; i
< 24; i
++) {
95 for(i
= 0; i
< n
; i
++) {
96 for(j
= 0; j
< 8; j
+= 2) {
97 int these
= (cmd
[i
] >> j
) & 3;
147 // And slack at the end, too.
148 for(i
= 0; i
< 24; i
++) {
153 //-----------------------------------------------------------------------------
154 // The CRC used by ISO 15693.
155 //-----------------------------------------------------------------------------
156 static WORD
Crc(BYTE
*v
, int n
)
162 for(i
= 0; i
< n
; i
++) {
163 reg
= reg
^ ((DWORD
)v
[i
]);
164 for (j
= 0; j
< 8; j
++) {
166 reg
= (reg
>> 1) ^ 0x8408;
176 ////////////////////////////////////////// code to do 'itoa'
180 /* reverse: reverse string s in place */
181 void reverse(char s
[])
185 for (i
= 0, j
= strlen(s
)-1; i
<j
; i
++, j
--) {
192 /* itoa: convert n to characters in s */
193 void itoa(int n
, char s
[])
197 if ((sign
= n
) < 0) /* record sign */
198 n
= -n
; /* make n positive */
200 do { /* generate digits in reverse order */
201 s
[i
++] = n
% 10 + '0'; /* get next digit */
202 } while ((n
/= 10) > 0); /* delete it */
209 //////////////////////////////////////// END 'itoa' CODE
212 //-----------------------------------------------------------------------------
213 // Encode (into the ToSend buffers) an identify request, which is the first
214 // thing that you must send to a tag to get a response.
215 //-----------------------------------------------------------------------------
216 static void BuildIdentifyRequest(void)
221 // one sub-carrier, inventory, 1 slot, fast rate
222 // AFI is at bit 5 (1<<4) when doing an INVENTORY
223 cmd
[0] = (1 << 2) | (1 << 5) | (1 << 1);
224 // inventory command code
233 CodeIso15693AsReader(cmd
, sizeof(cmd
));
236 static void BuildSysInfoRequest(BYTE
*uid
)
241 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
242 // followed by teh block data
243 // one sub-carrier, inventory, 1 slot, fast rate
244 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
245 // System Information command code
247 // UID may be optionally specified here
256 cmd
[9]= 0xe0; // always e0 (not exactly unique)
258 crc
= Crc(cmd
, 10); // the crc needs to be calculated over 2 bytes
259 cmd
[10] = crc
& 0xff;
262 CodeIso15693AsReader(cmd
, sizeof(cmd
));
265 static void BuildSelectRequest( BYTE uid
[])
268 // uid[6]=0x31; // this is getting ignored - the uid array is not happening...
272 // one sub-carrier, inventory, 1 slot, fast rate
273 //cmd[0] = (1 << 2) | (1 << 5) | (1 << 1); // INVENTROY FLAGS
274 cmd
[0] = (1 << 4) | (1 << 5) | (1 << 1); // Select and addressed FLAGS
275 // SELECT command code
278 // cmd[2] = uid[0];//0x32;
279 // cmd[3]= uid[1];//0x4b;
280 // cmd[4] = uid[2];//0x03;
281 // cmd[5] = uid[3];//0x01;
282 // cmd[6] = uid[4];//0x00;
283 // cmd[7] = uid[5];//0x10;
284 // cmd[8] = uid[6];//0x05;
291 cmd
[8] = 0x05; // infineon?
293 cmd
[9]= 0xe0; // always e0 (not exactly unique)
295 // DbpIntegers(cmd[8],cmd[7],cmd[6]);
297 crc
= Crc(cmd
, 10); // the crc needs to be calculated over 10 bytes
298 cmd
[10] = crc
& 0xff;
301 CodeIso15693AsReader(cmd
, sizeof(cmd
));
304 static void BuildReadBlockRequest(BYTE
*uid
, BYTE blockNumber
)
309 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
310 // followed by teh block data
311 // one sub-carrier, inventory, 1 slot, fast rate
312 cmd
[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit
313 // READ BLOCK command code
315 // UID may be optionally specified here
324 cmd
[9]= 0xe0; // always e0 (not exactly unique)
325 // Block number to read
326 cmd
[10] = blockNumber
;//0x00;
328 crc
= Crc(cmd
, 11); // the crc needs to be calculated over 2 bytes
329 cmd
[11] = crc
& 0xff;
332 CodeIso15693AsReader(cmd
, sizeof(cmd
));
336 static void BuildReadMultiBlockRequest(BYTE
*uid
)
341 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
342 // followed by teh block data
343 // one sub-carrier, inventory, 1 slot, fast rate
344 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
345 // READ Multi BLOCK command code
347 // UID may be optionally specified here
356 cmd
[9]= 0xe0; // always e0 (not exactly unique)
357 // First Block number to read
359 // Number of Blocks to read
360 cmd
[11] = 0x2f; // read quite a few
362 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
363 cmd
[12] = crc
& 0xff;
366 CodeIso15693AsReader(cmd
, sizeof(cmd
));
369 static void BuildArbitraryRequest(BYTE
*uid
,BYTE CmdCode
)
374 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
375 // followed by teh block data
376 // one sub-carrier, inventory, 1 slot, fast rate
377 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
378 // READ BLOCK command code
380 // UID may be optionally specified here
389 cmd
[9]= 0xe0; // always e0 (not exactly unique)
395 // cmd[13] = 0x00; //Now the CRC
396 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
397 cmd
[12] = crc
& 0xff;
400 CodeIso15693AsReader(cmd
, sizeof(cmd
));
403 static void BuildArbitraryCustomRequest(BYTE
*uid
,BYTE CmdCode
)
408 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
409 // followed by teh block data
410 // one sub-carrier, inventory, 1 slot, fast rate
411 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
412 // READ BLOCK command code
414 // UID may be optionally specified here
423 cmd
[9]= 0xe0; // always e0 (not exactly unique)
425 cmd
[10] = 0x05; // for custom codes this must be manufcturer code
429 // cmd[13] = 0x00; //Now the CRC
430 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
431 cmd
[12] = crc
& 0xff;
434 CodeIso15693AsReader(cmd
, sizeof(cmd
));
437 /////////////////////////////////////////////////////////////////////////
438 // Now the VICC>VCD responses when we are simulating a tag
439 ////////////////////////////////////////////////////////////////////
441 static void BuildInventoryResponse(void)
446 // one sub-carrier, inventory, 1 slot, fast rate
447 // AFI is at bit 5 (1<<4) when doing an INVENTORY
448 cmd
[0] = 0; //(1 << 2) | (1 << 5) | (1 << 1);
461 cmd
[10] = crc
& 0xff;
464 CodeIso15693AsReader(cmd
, sizeof(cmd
));
468 //-----------------------------------------------------------------------------
469 // Transmit the command (to the tag) that was placed in ToSend[].
470 //-----------------------------------------------------------------------------
471 static void TransmitTo15693Tag(const BYTE
*cmd
, int len
, int *samples
, int *wait
)
475 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
476 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
477 if(*wait
< 10) { *wait
= 10; }
479 // for(c = 0; c < *wait;) {
480 // if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
481 // SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!
484 // if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
485 // volatile DWORD r = SSC_RECEIVE_HOLDING;
493 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
494 SSC_TRANSMIT_HOLDING
= cmd
[c
];
500 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
501 volatile DWORD r
= SSC_RECEIVE_HOLDING
;
506 *samples
= (c
+ *wait
) << 3;
510 //-----------------------------------------------------------------------------
511 // Transmit the command (to the reader) that was placed in ToSend[].
512 //-----------------------------------------------------------------------------
513 static void TransmitTo15693Reader(const BYTE
*cmd
, int len
, int *samples
, int *wait
)
517 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
518 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
); // No requirement to energise my coils
519 if(*wait
< 10) { *wait
= 10; }
523 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
524 SSC_TRANSMIT_HOLDING
= cmd
[c
];
530 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
531 volatile DWORD r
= SSC_RECEIVE_HOLDING
;
536 *samples
= (c
+ *wait
) << 3;
544 static int GetIso15693AnswerFromTag(BYTE
*receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
547 BYTE
*dest
= (BYTE
*)BigBuf
;
554 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
555 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
559 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
560 SSC_TRANSMIT_HOLDING
= 0x43;
562 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
564 b
= (SBYTE
)SSC_RECEIVE_HOLDING
;
566 // The samples are correlations against I and Q versions of the
567 // tone that the tag AM-modulates, so every other sample is I,
568 // every other is Q. We just want power, so abs(I) + abs(Q) is
569 // close to what we want.
597 //////////////////////////////////////////
598 /////////// DEMODULATE ///////////////////
599 //////////////////////////////////////////
607 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
609 // First, correlate for SOF
610 for(i
= 0; i
< 100; i
++) {
612 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
613 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
620 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
622 int k
= 0; // this will be our return value
624 // greg - If correlation is less than 1 then there's little point in continuing
625 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1)
628 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
631 memset(outBuf
, 0, sizeof(outBuf
));
634 int corr0
= 0, corr1
= 0, corrEOF
= 0;
635 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
636 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
638 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
639 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
641 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
642 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
644 // Even things out by the length of the target waveform.
648 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
649 // DbpString("EOF at %d", i);
651 } else if(corr1
> corr0
) {
652 i
+= arraylen(Logic1
)/skip
;
655 i
+= arraylen(Logic0
)/skip
;
662 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
663 DbpString("ran off end!");
668 DbpString("error, uneven octet! (discard extra bits!)");
669 /// DbpString(" mask=%02x", mask);
673 // strcat(str1," octets read");
675 // DbpString( str1); // DbpString("%d octets", k);
677 // for(i = 0; i < k; i+=3) {
678 // //DbpString("# %2d: %02x ", i, outBuf[i]);
679 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
682 for(i
= 0; i
< k
; i
++) {
683 receivedResponse
[i
] = outBuf
[i
];
685 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
686 return k
; // return the number of bytes demodulated
688 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
693 // Now the GetISO15693 message from sniffing command
694 static int GetIso15693AnswerFromSniff(BYTE
*receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
697 BYTE
*dest
= (BYTE
*)BigBuf
;
704 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
705 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
709 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
710 SSC_TRANSMIT_HOLDING
= 0x43;
712 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
714 b
= (SBYTE
)SSC_RECEIVE_HOLDING
;
716 // The samples are correlations against I and Q versions of the
717 // tone that the tag AM-modulates, so every other sample is I,
718 // every other is Q. We just want power, so abs(I) + abs(Q) is
719 // close to what we want.
747 //////////////////////////////////////////
748 /////////// DEMODULATE ///////////////////
749 //////////////////////////////////////////
757 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
759 // First, correlate for SOF
760 for(i
= 0; i
< 19000; i
++) {
762 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
763 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
770 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
772 int k
= 0; // this will be our return value
774 // greg - If correlation is less than 1 then there's little point in continuing
775 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1) // THIS SHOULD BE 1
778 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
781 memset(outBuf
, 0, sizeof(outBuf
));
784 int corr0
= 0, corr1
= 0, corrEOF
= 0;
785 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
786 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
788 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
789 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
791 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
792 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
794 // Even things out by the length of the target waveform.
798 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
799 // DbpString("EOF at %d", i);
801 } else if(corr1
> corr0
) {
802 i
+= arraylen(Logic1
)/skip
;
805 i
+= arraylen(Logic0
)/skip
;
812 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
813 DbpString("ran off end!");
818 DbpString("error, uneven octet! (discard extra bits!)");
819 /// DbpString(" mask=%02x", mask);
823 // strcat(str1," octets read");
825 // DbpString( str1); // DbpString("%d octets", k);
827 // for(i = 0; i < k; i+=3) {
828 // //DbpString("# %2d: %02x ", i, outBuf[i]);
829 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
832 for(i
= 0; i
< k
; i
++) {
833 receivedResponse
[i
] = outBuf
[i
];
835 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
836 return k
; // return the number of bytes demodulated
838 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
845 //-----------------------------------------------------------------------------
846 // Start to read an ISO 15693 tag. We send an identify request, then wait
847 // for the response. The response is not demodulated, just left in the buffer
848 // so that it can be downloaded to a PC and processed there.
849 //-----------------------------------------------------------------------------
850 void AcquireRawAdcSamplesIso15693(void)
853 BYTE
*dest
= (BYTE
*)BigBuf
;
858 BuildIdentifyRequest();
860 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
862 // Give the tags time to energize
863 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
866 // Now send the command
868 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
872 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
873 SSC_TRANSMIT_HOLDING
= ToSend
[c
];
875 if(c
== ToSendMax
+3) {
879 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
880 volatile DWORD r
= SSC_RECEIVE_HOLDING
;
886 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
891 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
892 SSC_TRANSMIT_HOLDING
= 0x43;
894 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
896 b
= (SBYTE
)SSC_RECEIVE_HOLDING
;
898 // The samples are correlations against I and Q versions of the
899 // tone that the tag AM-modulates, so every other sample is I,
900 // every other is Q. We just want power, so abs(I) + abs(Q) is
901 // close to what we want.
932 //-----------------------------------------------------------------------------
933 // Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
934 // all demodulation performed in arm rather than host. - greg
935 //-----------------------------------------------------------------------------
936 void ReaderIso15693(DWORD parameter
)
944 //DbpString(parameter);
946 BYTE
*receivedAnswer0
= (((BYTE
*)BigBuf
) + 3560); // allow 100 bytes per reponse (way too much)
947 BYTE
*receivedAnswer1
= (((BYTE
*)BigBuf
) + 3660); //
948 BYTE
*receivedAnswer2
= (((BYTE
*)BigBuf
) + 3760);
949 BYTE
*receivedAnswer3
= (((BYTE
*)BigBuf
) + 3860);
950 //BYTE *TagUID= (((BYTE *)BigBuf) + 3960); // where we hold the uid for hi15reader
951 int responseLen0
= 0;
952 int responseLen1
= 0;
953 int responseLen2
= 0;
954 int responseLen3
= 0;
958 for(j
= 0; j
< 100; j
++) {
959 receivedAnswer3
[j
] = 0;
960 receivedAnswer2
[j
] =0;
961 receivedAnswer1
[j
] = 0;
962 receivedAnswer0
[j
] = 0;
968 // Start from off (no field generated)
969 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
972 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
975 // Give the tags time to energize
976 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
989 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
990 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
991 BYTE TagUID
[7]; // where we hold the uid for hi15reader
994 // BuildIdentifyRequest();
995 // //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
996 // TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3
997 // // Now wait for a response
998 // responseLen0 = GetIso15693AnswerFromTag(receivedAnswer0, 100, &samples, &elapsed) ;
999 // if (responseLen0 >=12) // we should do a better check than this
1001 // // really we should check it is a valid mesg
1002 // // but for now just grab what we think is the uid
1003 // TagUID[0] = receivedAnswer0[2];
1004 // TagUID[1] = receivedAnswer0[3];
1005 // TagUID[2] = receivedAnswer0[4];
1006 // TagUID[3] = receivedAnswer0[5];
1007 // TagUID[4] = receivedAnswer0[6];
1008 // TagUID[5] = receivedAnswer0[7];
1009 // TagUID[6] = receivedAnswer0[8]; // IC Manufacturer code
1010 // DbpIntegers(TagUID[6],TagUID[5],TagUID[4]);
1013 // Now send the IDENTIFY command
1014 BuildIdentifyRequest();
1015 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
1016 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1017 // Now wait for a response
1018 responseLen1
= GetIso15693AnswerFromTag(receivedAnswer1
, 100, &samples
, &elapsed
) ;
1020 if (responseLen1
>=12) // we should do a better check than this
1023 TagUID
[0] = receivedAnswer1
[2];
1024 TagUID
[1] = receivedAnswer1
[3];
1025 TagUID
[2] = receivedAnswer1
[4];
1026 TagUID
[3] = receivedAnswer1
[5];
1027 TagUID
[4] = receivedAnswer1
[6];
1028 TagUID
[5] = receivedAnswer1
[7];
1029 TagUID
[6] = receivedAnswer1
[8]; // IC Manufacturer code
1031 // Now send the SELECT command
1032 BuildSelectRequest(*TagUID
);
1033 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1034 // Now wait for a response
1035 responseLen2
= GetIso15693AnswerFromTag(receivedAnswer2
, 100, &samples
, &elapsed
);
1037 // Now send the MULTI READ command
1038 // BuildArbitraryRequest(*TagUID,parameter);
1039 BuildArbitraryCustomRequest(*TagUID
,parameter
);
1040 // BuildReadBlockRequest(*TagUID,parameter);
1041 // BuildSysInfoRequest(*TagUID);
1042 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
1043 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1044 // Now wait for a response
1045 responseLen3
= GetIso15693AnswerFromTag(receivedAnswer3
, 100, &samples
, &elapsed
) ;
1055 itoa(responseLen1
,str1
);
1056 strcat(str1
," octets read from IDENTIFY request");
1058 for(i
= 0; i
< responseLen1
; i
+=3) {
1059 DbpIntegers(receivedAnswer1
[i
],receivedAnswer1
[i
+1],receivedAnswer1
[i
+2]);
1062 itoa(responseLen2
,str1
);
1063 strcat(str1
," octets read from SELECT request");
1065 for(i
= 0; i
< responseLen2
; i
+=3) {
1066 DbpIntegers(receivedAnswer2
[i
],receivedAnswer2
[i
+1],receivedAnswer2
[i
+2]);
1069 itoa(responseLen3
,str1
);
1070 strcat(str1
," octets read from XXX request");
1072 for(i
= 0; i
< responseLen3
; i
+=3) {
1073 DbpIntegers(receivedAnswer3
[i
],receivedAnswer3
[i
+1],receivedAnswer3
[i
+2]);
1078 // for(i = 0; i < responseLen3; i++) {
1079 // itoa(str1,receivedAnswer3[i]);
1080 // strcat(str2,str1);
1094 //-----------------------------------------------------------------------------
1095 // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1096 // all demodulation performed in arm rather than host. - greg
1097 //-----------------------------------------------------------------------------
1098 void SimTagIso15693(DWORD parameter
)
1106 //DbpString(parameter);
1108 BYTE
*receivedAnswer0
= (((BYTE
*)BigBuf
) + 3560); // allow 100 bytes per reponse (way too much)
1109 BYTE
*receivedAnswer1
= (((BYTE
*)BigBuf
) + 3660); //
1110 BYTE
*receivedAnswer2
= (((BYTE
*)BigBuf
) + 3760);
1111 BYTE
*receivedAnswer3
= (((BYTE
*)BigBuf
) + 3860);
1112 //BYTE *TagUID= (((BYTE *)BigBuf) + 3960); // where we hold the uid for hi15reader
1113 int responseLen0
= 0;
1114 int responseLen1
= 0;
1115 int responseLen2
= 0;
1116 int responseLen3
= 0;
1120 for(j
= 0; j
< 100; j
++) {
1121 receivedAnswer3
[j
] = 0;
1122 receivedAnswer2
[j
] =0;
1123 receivedAnswer1
[j
] = 0;
1124 receivedAnswer0
[j
] = 0;
1130 // Start from off (no field generated)
1131 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1134 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1137 // Give the tags time to energize
1138 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); // NO GOOD FOR SIM TAG!!!!
1151 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1152 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
1153 BYTE TagUID
[7]; // where we hold the uid for hi15reader
1157 // Now send the IDENTIFY command
1158 // BuildIdentifyRequest();
1159 // TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3
1162 // Now wait for a command from the reader
1164 // while(responseLen1=0) {
1165 // if(BUTTON_PRESS()) break;
1166 responseLen1
= GetIso15693AnswerFromSniff(receivedAnswer1
, 100, &samples
, &elapsed
) ;
1170 if (responseLen1
>=1) // we should do a better check than this
1172 // Build a suitable reponse to the reader INVENTORY cocmmand
1173 BuildInventoryResponse
;
1174 TransmitTo15693Reader(ToSend
,ToSendMax
,&tsamples
, &wait
);
1176 // Now wait for a command from the reader
1177 // responseLen2 = GetIso15693AnswerFromTag(receivedAnswer2, 100, &samples, &elapsed);
1180 // Now wait for a command from the reader
1181 // responseLen3 = GetIso15693AnswerFromTag(receivedAnswer3, 100, &samples, &elapsed) ;
1191 itoa(responseLen1
,str1
);
1192 strcat(str1
," octets read from reader command");
1194 for(i
= 0; i
< responseLen1
; i
+=3) {
1195 DbpIntegers(receivedAnswer1
[i
],receivedAnswer1
[i
+1],receivedAnswer1
[i
+2]);
1198 // itoa(responseLen2,str1);
1199 // strcat(str1," octets read from SELECT request");
1201 // for(i = 0; i < responseLen2; i+=3) {
1202 // DbpIntegers(receivedAnswer2[i],receivedAnswer2[i+1],receivedAnswer2[i+2]);
1205 // itoa(responseLen3,str1);
1206 // strcat(str1," octets read from XXX request");
1208 // for(i = 0; i < responseLen3; i+=3) {
1209 // DbpIntegers(receivedAnswer3[i],receivedAnswer3[i+1],receivedAnswer3[i+2]);
1214 // for(i = 0; i < responseLen3; i++) {
1215 // itoa(str1,receivedAnswer3[i]);
1216 // strcat(str2,str1);