1 //-----------------------------------------------------------------------------
2 // Jonathan Westhues, split Nov 2006
3 // Modified by Greg Jones, Jan 2009
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // Routines to support ISO 15693. This includes both the reader software and
10 // the `fake tag' modes, but at the moment I've implemented only the reader
11 // stuff, and that barely.
12 // Modified to perform modulation onboard in arm rather than on PC
13 // Also added additional reader commands (SELECT, READ etc.)
14 //-----------------------------------------------------------------------------
16 #include "proxmark3.h"
21 // FROM winsrc\prox.h //////////////////////////////////
22 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
24 //-----------------------------------------------------------------------------
25 // Map a sequence of octets (~layer 2 command) into the set of bits to feed
26 // to the FPGA, to transmit that command to the tag.
27 //-----------------------------------------------------------------------------
29 // The sampling rate is 106.353 ksps/s, for T = 18.8 us
32 // 1) Unmodulated time of 56.64us
33 // 2) 24 pulses of 423.75khz
34 // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
36 static const int FrameSOF
[] = {
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,
39 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
46 static const int Logic0
[] = {
52 static const int Logic1
[] = {
60 // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
61 // 2) 24 pulses of 423.75khz
62 // 3) Unmodulated time of 56.64us
64 static const int FrameEOF
[] = {
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,
71 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
72 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
75 static void CodeIso15693AsReader(uint8_t *cmd
, int n
)
81 // Give it a bit of slack at the beginning
82 for(i
= 0; i
< 24; i
++) {
94 for(i
= 0; i
< n
; i
++) {
95 for(j
= 0; j
< 8; j
+= 2) {
96 int these
= (cmd
[i
] >> j
) & 3;
146 // And slack at the end, too.
147 for(i
= 0; i
< 24; i
++) {
152 //-----------------------------------------------------------------------------
153 // The CRC used by ISO 15693.
154 //-----------------------------------------------------------------------------
155 static uint16_t Crc(uint8_t *v
, int n
)
161 for(i
= 0; i
< n
; i
++) {
162 reg
= reg
^ ((uint32_t)v
[i
]);
163 for (j
= 0; j
< 8; j
++) {
165 reg
= (reg
>> 1) ^ 0x8408;
175 char *strcat(char *dest
, const char *src
)
177 size_t dest_len
= strlen(dest
);
180 for (i
= 0 ; src
[i
] != '\0' ; i
++)
181 dest
[dest_len
+ i
] = src
[i
];
182 dest
[dest_len
+ i
] = '\0';
187 ////////////////////////////////////////// code to do 'itoa'
189 /* reverse: reverse string s in place */
190 void reverse(char s
[])
194 for (i
= 0, j
= strlen(s
)-1; i
<j
; i
++, j
--) {
201 /* itoa: convert n to characters in s */
202 void itoa(int n
, char s
[])
206 if ((sign
= n
) < 0) /* record sign */
207 n
= -n
; /* make n positive */
209 do { /* generate digits in reverse order */
210 s
[i
++] = n
% 10 + '0'; /* get next digit */
211 } while ((n
/= 10) > 0); /* delete it */
218 //////////////////////////////////////// END 'itoa' CODE
220 //-----------------------------------------------------------------------------
221 // Encode (into the ToSend buffers) an identify request, which is the first
222 // thing that you must send to a tag to get a response.
223 //-----------------------------------------------------------------------------
224 static void BuildIdentifyRequest(void)
229 // one sub-carrier, inventory, 1 slot, fast rate
230 // AFI is at bit 5 (1<<4) when doing an INVENTORY
231 cmd
[0] = (1 << 2) | (1 << 5) | (1 << 1);
232 // inventory command code
241 CodeIso15693AsReader(cmd
, sizeof(cmd
));
244 static void __attribute__((unused
)) BuildSysInfoRequest(uint8_t *uid
)
249 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
250 // followed by teh block data
251 // one sub-carrier, inventory, 1 slot, fast rate
252 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
253 // System Information command code
255 // UID may be optionally specified here
264 cmd
[9]= 0xe0; // always e0 (not exactly unique)
266 crc
= Crc(cmd
, 10); // the crc needs to be calculated over 2 bytes
267 cmd
[10] = crc
& 0xff;
270 CodeIso15693AsReader(cmd
, sizeof(cmd
));
273 static void BuildSelectRequest( uint8_t uid
[])
276 // uid[6]=0x31; // this is getting ignored - the uid array is not happening...
280 // one sub-carrier, inventory, 1 slot, fast rate
281 //cmd[0] = (1 << 2) | (1 << 5) | (1 << 1); // INVENTROY FLAGS
282 cmd
[0] = (1 << 4) | (1 << 5) | (1 << 1); // Select and addressed FLAGS
283 // SELECT command code
286 // cmd[2] = uid[0];//0x32;
287 // cmd[3]= uid[1];//0x4b;
288 // cmd[4] = uid[2];//0x03;
289 // cmd[5] = uid[3];//0x01;
290 // cmd[6] = uid[4];//0x00;
291 // cmd[7] = uid[5];//0x10;
292 // cmd[8] = uid[6];//0x05;
299 cmd
[8] = 0x05; // infineon?
301 cmd
[9]= 0xe0; // always e0 (not exactly unique)
303 // DbpIntegers(cmd[8],cmd[7],cmd[6]);
305 crc
= Crc(cmd
, 10); // the crc needs to be calculated over 10 bytes
306 cmd
[10] = crc
& 0xff;
309 CodeIso15693AsReader(cmd
, sizeof(cmd
));
312 static void __attribute__((unused
)) BuildReadBlockRequest(uint8_t *uid
, uint8_t blockNumber
)
317 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
318 // followed by teh block data
319 // one sub-carrier, inventory, 1 slot, fast rate
320 cmd
[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit
321 // READ BLOCK command code
323 // UID may be optionally specified here
332 cmd
[9]= 0xe0; // always e0 (not exactly unique)
333 // Block number to read
334 cmd
[10] = blockNumber
;//0x00;
336 crc
= Crc(cmd
, 11); // the crc needs to be calculated over 2 bytes
337 cmd
[11] = crc
& 0xff;
340 CodeIso15693AsReader(cmd
, sizeof(cmd
));
343 static void __attribute__((unused
)) BuildReadMultiBlockRequest(uint8_t *uid
)
348 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
349 // followed by teh block data
350 // one sub-carrier, inventory, 1 slot, fast rate
351 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
352 // READ Multi BLOCK command code
354 // UID may be optionally specified here
363 cmd
[9]= 0xe0; // always e0 (not exactly unique)
364 // First Block number to read
366 // Number of Blocks to read
367 cmd
[11] = 0x2f; // read quite a few
369 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
370 cmd
[12] = crc
& 0xff;
373 CodeIso15693AsReader(cmd
, sizeof(cmd
));
376 static void __attribute__((unused
)) BuildArbitraryRequest(uint8_t *uid
,uint8_t CmdCode
)
381 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
382 // followed by teh block data
383 // one sub-carrier, inventory, 1 slot, fast rate
384 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
385 // READ BLOCK command code
387 // UID may be optionally specified here
396 cmd
[9]= 0xe0; // always e0 (not exactly unique)
402 // cmd[13] = 0x00; //Now the CRC
403 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
404 cmd
[12] = crc
& 0xff;
407 CodeIso15693AsReader(cmd
, sizeof(cmd
));
410 static void __attribute__((unused
)) BuildArbitraryCustomRequest(uint8_t uid
[], uint8_t CmdCode
)
415 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
416 // followed by teh block data
417 // one sub-carrier, inventory, 1 slot, fast rate
418 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
419 // READ BLOCK command code
421 // UID may be optionally specified here
430 cmd
[9]= 0xe0; // always e0 (not exactly unique)
432 cmd
[10] = 0x05; // for custom codes this must be manufcturer code
436 // cmd[13] = 0x00; //Now the CRC
437 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
438 cmd
[12] = crc
& 0xff;
441 CodeIso15693AsReader(cmd
, sizeof(cmd
));
444 /////////////////////////////////////////////////////////////////////////
445 // Now the VICC>VCD responses when we are simulating a tag
446 ////////////////////////////////////////////////////////////////////
448 static void BuildInventoryResponse(void)
453 // one sub-carrier, inventory, 1 slot, fast rate
454 // AFI is at bit 5 (1<<4) when doing an INVENTORY
455 cmd
[0] = 0; //(1 << 2) | (1 << 5) | (1 << 1);
468 cmd
[10] = crc
& 0xff;
471 CodeIso15693AsReader(cmd
, sizeof(cmd
));
474 //-----------------------------------------------------------------------------
475 // Transmit the command (to the tag) that was placed in ToSend[].
476 //-----------------------------------------------------------------------------
477 static void TransmitTo15693Tag(const uint8_t *cmd
, int len
, int *samples
, int *wait
)
481 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
482 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
483 if(*wait
< 10) { *wait
= 10; }
485 // for(c = 0; c < *wait;) {
486 // if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
487 // AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
490 // if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
491 // volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
499 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
500 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
506 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
507 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
512 *samples
= (c
+ *wait
) << 3;
515 //-----------------------------------------------------------------------------
516 // Transmit the command (to the reader) that was placed in ToSend[].
517 //-----------------------------------------------------------------------------
518 static void TransmitTo15693Reader(const uint8_t *cmd
, int len
, int *samples
, int *wait
)
522 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
523 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
); // No requirement to energise my coils
524 if(*wait
< 10) { *wait
= 10; }
528 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
529 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
535 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
536 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
541 *samples
= (c
+ *wait
) << 3;
544 static int GetIso15693AnswerFromTag(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
547 uint8_t *dest
= (uint8_t *)BigBuf
;
553 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
554 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
558 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
559 AT91C_BASE_SSC
->SSC_THR
= 0x43;
561 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
563 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
565 // The samples are correlations against I and Q versions of the
566 // tone that the tag AM-modulates, so every other sample is I,
567 // every other is Q. We just want power, so abs(I) + abs(Q) is
568 // close to what we want.
583 dest
[c
++] = (uint8_t)r
;
596 //////////////////////////////////////////
597 /////////// DEMODULATE ///////////////////
598 //////////////////////////////////////////
601 int max
= 0, maxPos
=0;
605 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
607 // First, correlate for SOF
608 for(i
= 0; i
< 100; i
++) {
610 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
611 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
618 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
620 int k
= 0; // this will be our return value
622 // greg - If correlation is less than 1 then there's little point in continuing
623 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1)
626 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
629 memset(outBuf
, 0, sizeof(outBuf
));
632 int corr0
= 0, corr1
= 0, corrEOF
= 0;
633 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
634 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
636 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
637 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
639 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
640 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
642 // Even things out by the length of the target waveform.
646 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
647 // DbpString("EOF at %d", i);
649 } else if(corr1
> corr0
) {
650 i
+= arraylen(Logic1
)/skip
;
653 i
+= arraylen(Logic0
)/skip
;
660 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
661 DbpString("ran off end!");
666 DbpString("error, uneven octet! (discard extra bits!)");
667 /// DbpString(" mask=%02x", mask);
671 // strcat(str1," octets read");
673 // DbpString( str1); // DbpString("%d octets", k);
675 // for(i = 0; i < k; i+=3) {
676 // //DbpString("# %2d: %02x ", i, outBuf[i]);
677 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
680 for(i
= 0; i
< k
; i
++) {
681 receivedResponse
[i
] = outBuf
[i
];
683 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
684 return k
; // return the number of bytes demodulated
686 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
690 // Now the GetISO15693 message from sniffing command
691 static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
694 uint8_t *dest
= (uint8_t *)BigBuf
;
700 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
701 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
705 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
706 AT91C_BASE_SSC
->SSC_THR
= 0x43;
708 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
710 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
712 // The samples are correlations against I and Q versions of the
713 // tone that the tag AM-modulates, so every other sample is I,
714 // every other is Q. We just want power, so abs(I) + abs(Q) is
715 // close to what we want.
730 dest
[c
++] = (uint8_t)r
;
743 //////////////////////////////////////////
744 /////////// DEMODULATE ///////////////////
745 //////////////////////////////////////////
748 int max
= 0, maxPos
=0;
752 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
754 // First, correlate for SOF
755 for(i
= 0; i
< 19000; i
++) {
757 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
758 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
765 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
767 int k
= 0; // this will be our return value
769 // greg - If correlation is less than 1 then there's little point in continuing
770 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1) // THIS SHOULD BE 1
773 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
776 memset(outBuf
, 0, sizeof(outBuf
));
779 int corr0
= 0, corr1
= 0, corrEOF
= 0;
780 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
781 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
783 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
784 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
786 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
787 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
789 // Even things out by the length of the target waveform.
793 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
794 // DbpString("EOF at %d", i);
796 } else if(corr1
> corr0
) {
797 i
+= arraylen(Logic1
)/skip
;
800 i
+= arraylen(Logic0
)/skip
;
807 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
808 DbpString("ran off end!");
813 DbpString("error, uneven octet! (discard extra bits!)");
814 /// DbpString(" mask=%02x", mask);
818 // strcat(str1," octets read");
820 // DbpString( str1); // DbpString("%d octets", k);
822 // for(i = 0; i < k; i+=3) {
823 // //DbpString("# %2d: %02x ", i, outBuf[i]);
824 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
827 for(i
= 0; i
< k
; i
++) {
828 receivedResponse
[i
] = outBuf
[i
];
830 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
831 return k
; // return the number of bytes demodulated
833 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
836 //-----------------------------------------------------------------------------
837 // Start to read an ISO 15693 tag. We send an identify request, then wait
838 // for the response. The response is not demodulated, just left in the buffer
839 // so that it can be downloaded to a PC and processed there.
840 //-----------------------------------------------------------------------------
841 void AcquireRawAdcSamplesIso15693(void)
844 uint8_t *dest
= (uint8_t *)BigBuf
;
849 BuildIdentifyRequest();
851 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
853 // Give the tags time to energize
854 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
857 // Now send the command
859 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
863 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
864 AT91C_BASE_SSC
->SSC_THR
= ToSend
[c
];
866 if(c
== ToSendMax
+3) {
870 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
871 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
877 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
882 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
883 AT91C_BASE_SSC
->SSC_THR
= 0x43;
885 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
887 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
889 // The samples are correlations against I and Q versions of the
890 // tone that the tag AM-modulates, so every other sample is I,
891 // every other is Q. We just want power, so abs(I) + abs(Q) is
892 // close to what we want.
907 dest
[c
++] = (uint8_t)r
;
921 //-----------------------------------------------------------------------------
922 // Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
923 // all demodulation performed in arm rather than host. - greg
924 //-----------------------------------------------------------------------------
925 void ReaderIso15693(uint32_t parameter
)
932 //DbpString(parameter);
934 //uint8_t *answer0 = (((uint8_t *)BigBuf) + 3560); // allow 100 bytes per reponse (way too much)
935 uint8_t *answer1
= (((uint8_t *)BigBuf
) + 3660); //
936 uint8_t *answer2
= (((uint8_t *)BigBuf
) + 3760);
937 uint8_t *answer3
= (((uint8_t *)BigBuf
) + 3860);
938 //uint8_t *TagUID= (((uint8_t *)BigBuf) + 3960); // where we hold the uid for hi15reader
939 // int answerLen0 = 0;
945 memset(BigBuf
+ 3660, 0, 300);
950 // Start from off (no field generated)
951 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
954 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
957 // Give the tags time to energize
958 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
971 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
972 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
973 uint8_t TagUID
[7]; // where we hold the uid for hi15reader
975 // BuildIdentifyRequest();
976 // //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
977 // TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3
978 // // Now wait for a response
979 // responseLen0 = GetIso15693AnswerFromTag(receivedAnswer0, 100, &samples, &elapsed) ;
980 // if (responseLen0 >=12) // we should do a better check than this
982 // // really we should check it is a valid mesg
983 // // but for now just grab what we think is the uid
984 // TagUID[0] = receivedAnswer0[2];
985 // TagUID[1] = receivedAnswer0[3];
986 // TagUID[2] = receivedAnswer0[4];
987 // TagUID[3] = receivedAnswer0[5];
988 // TagUID[4] = receivedAnswer0[6];
989 // TagUID[5] = receivedAnswer0[7];
990 // TagUID[6] = receivedAnswer0[8]; // IC Manufacturer code
991 // DbpIntegers(TagUID[6],TagUID[5],TagUID[4]);
994 // Now send the IDENTIFY command
995 BuildIdentifyRequest();
996 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
997 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
998 // Now wait for a response
999 answerLen1
= GetIso15693AnswerFromTag(answer1
, 100, &samples
, &elapsed
) ;
1001 if (answerLen1
>=12) // we should do a better check than this
1004 TagUID
[0] = answer1
[2];
1005 TagUID
[1] = answer1
[3];
1006 TagUID
[2] = answer1
[4];
1007 TagUID
[3] = answer1
[5];
1008 TagUID
[4] = answer1
[6];
1009 TagUID
[5] = answer1
[7];
1010 TagUID
[6] = answer1
[8]; // IC Manufacturer code
1012 // Now send the SELECT command
1013 BuildSelectRequest(TagUID
);
1014 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1015 // Now wait for a response
1016 answerLen2
= GetIso15693AnswerFromTag(answer2
, 100, &samples
, &elapsed
);
1018 // Now send the MULTI READ command
1019 // BuildArbitraryRequest(*TagUID,parameter);
1020 BuildArbitraryCustomRequest(TagUID
,parameter
);
1021 // BuildReadBlockRequest(*TagUID,parameter);
1022 // BuildSysInfoRequest(*TagUID);
1023 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
1024 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1025 // Now wait for a response
1026 answerLen3
= GetIso15693AnswerFromTag(answer3
, 100, &samples
, &elapsed
) ;
1030 Dbprintf("%d octets read from IDENTIFY request: %x %x %x %x %x %x %x %x %x", answerLen1
,
1031 answer1
[0], answer1
[1], answer1
[2],
1032 answer1
[3], answer1
[4], answer1
[5],
1033 answer1
[6], answer1
[7], answer1
[8]);
1035 Dbprintf("%d octets read from SELECT request: %x %x %x %x %x %x %x %x %x", answerLen2
,
1036 answer2
[0], answer2
[1], answer2
[2],
1037 answer2
[3], answer2
[4], answer2
[5],
1038 answer2
[6], answer2
[7], answer2
[8]);
1040 Dbprintf("%d octets read from XXX request: %x %x %x %x %x %x %x %x %x", answerLen3
,
1041 answer3
[0], answer3
[1], answer3
[2],
1042 answer3
[3], answer3
[4], answer3
[5],
1043 answer3
[6], answer3
[7], answer3
[8]);
1047 // for(i = 0; i < responseLen3; i++) {
1048 // itoa(str1,receivedAnswer3[i]);
1049 // strcat(str2,str1);
1059 //-----------------------------------------------------------------------------
1060 // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1061 // all demodulation performed in arm rather than host. - greg
1062 //-----------------------------------------------------------------------------
1063 void SimTagIso15693(uint32_t parameter
)
1070 uint8_t *answer1
= (((uint8_t *)BigBuf
) + 3660); //
1074 memset(answer1
, 0, 100);
1079 // Start from off (no field generated)
1080 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1083 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1086 // Give the tags time to energize
1087 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); // NO GOOD FOR SIM TAG!!!!
1100 answerLen1
= GetIso15693AnswerFromSniff(answer1
, 100, &samples
, &elapsed
) ;
1102 if (answerLen1
>=1) // we should do a better check than this
1104 // Build a suitable reponse to the reader INVENTORY cocmmand
1105 BuildInventoryResponse();
1106 TransmitTo15693Reader(ToSend
,ToSendMax
, &tsamples
, &wait
);
1109 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1
,
1110 answer1
[0], answer1
[1], answer1
[2],
1111 answer1
[3], answer1
[4], answer1
[5],
1112 answer1
[6], answer1
[7], answer1
[8]);