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"
15 // FROM winsrc\prox.h //////////////////////////////////
16 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
18 //-----------------------------------------------------------------------------
19 // Map a sequence of octets (~layer 2 command) into the set of bits to feed
20 // to the FPGA, to transmit that command to the tag.
21 //-----------------------------------------------------------------------------
23 // The sampling rate is 106.353 ksps/s, for T = 18.8 us
26 // 1) Unmodulated time of 56.64us
27 // 2) 24 pulses of 423.75khz
28 // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
30 static const int FrameSOF
[] = {
31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
40 static const int Logic0
[] = {
46 static const int Logic1
[] = {
54 // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
55 // 2) 24 pulses of 423.75khz
56 // 3) Unmodulated time of 56.64us
58 static const int FrameEOF
[] = {
63 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
66 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
69 static void CodeIso15693AsReader(uint8_t *cmd
, int n
)
75 // Give it a bit of slack at the beginning
76 for(i
= 0; i
< 24; i
++) {
88 for(i
= 0; i
< n
; i
++) {
89 for(j
= 0; j
< 8; j
+= 2) {
90 int these
= (cmd
[i
] >> j
) & 3;
140 // And slack at the end, too.
141 for(i
= 0; i
< 24; i
++) {
146 //-----------------------------------------------------------------------------
147 // The CRC used by ISO 15693.
148 //-----------------------------------------------------------------------------
149 static uint16_t Crc(uint8_t *v
, int n
)
155 for(i
= 0; i
< n
; i
++) {
156 reg
= reg
^ ((uint32_t)v
[i
]);
157 for (j
= 0; j
< 8; j
++) {
159 reg
= (reg
>> 1) ^ 0x8408;
169 char *strcat(char *dest
, const char *src
)
171 size_t dest_len
= strlen(dest
);
174 for (i
= 0 ; src
[i
] != '\0' ; i
++)
175 dest
[dest_len
+ i
] = src
[i
];
176 dest
[dest_len
+ i
] = '\0';
181 ////////////////////////////////////////// code to do 'itoa'
183 /* reverse: reverse string s in place */
184 void reverse(char s
[])
188 for (i
= 0, j
= strlen(s
)-1; i
<j
; i
++, j
--) {
195 /* itoa: convert n to characters in s */
196 void itoa(int n
, char s
[])
200 if ((sign
= n
) < 0) /* record sign */
201 n
= -n
; /* make n positive */
203 do { /* generate digits in reverse order */
204 s
[i
++] = n
% 10 + '0'; /* get next digit */
205 } while ((n
/= 10) > 0); /* delete it */
212 //////////////////////////////////////// END 'itoa' CODE
214 //-----------------------------------------------------------------------------
215 // Encode (into the ToSend buffers) an identify request, which is the first
216 // thing that you must send to a tag to get a response.
217 //-----------------------------------------------------------------------------
218 static void BuildIdentifyRequest(void)
223 // one sub-carrier, inventory, 1 slot, fast rate
224 // AFI is at bit 5 (1<<4) when doing an INVENTORY
225 cmd
[0] = (1 << 2) | (1 << 5) | (1 << 1);
226 // inventory command code
235 CodeIso15693AsReader(cmd
, sizeof(cmd
));
238 static void __attribute__((unused
)) BuildSysInfoRequest(uint8_t *uid
)
243 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
244 // followed by teh block data
245 // one sub-carrier, inventory, 1 slot, fast rate
246 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
247 // System Information command code
249 // UID may be optionally specified here
258 cmd
[9]= 0xe0; // always e0 (not exactly unique)
260 crc
= Crc(cmd
, 10); // the crc needs to be calculated over 2 bytes
261 cmd
[10] = crc
& 0xff;
264 CodeIso15693AsReader(cmd
, sizeof(cmd
));
267 static void BuildSelectRequest( uint8_t uid
[])
270 // uid[6]=0x31; // this is getting ignored - the uid array is not happening...
274 // one sub-carrier, inventory, 1 slot, fast rate
275 //cmd[0] = (1 << 2) | (1 << 5) | (1 << 1); // INVENTROY FLAGS
276 cmd
[0] = (1 << 4) | (1 << 5) | (1 << 1); // Select and addressed FLAGS
277 // SELECT command code
280 // cmd[2] = uid[0];//0x32;
281 // cmd[3]= uid[1];//0x4b;
282 // cmd[4] = uid[2];//0x03;
283 // cmd[5] = uid[3];//0x01;
284 // cmd[6] = uid[4];//0x00;
285 // cmd[7] = uid[5];//0x10;
286 // cmd[8] = uid[6];//0x05;
293 cmd
[8] = 0x05; // infineon?
295 cmd
[9]= 0xe0; // always e0 (not exactly unique)
297 // DbpIntegers(cmd[8],cmd[7],cmd[6]);
299 crc
= Crc(cmd
, 10); // the crc needs to be calculated over 10 bytes
300 cmd
[10] = crc
& 0xff;
303 CodeIso15693AsReader(cmd
, sizeof(cmd
));
306 static void __attribute__((unused
)) BuildReadBlockRequest(uint8_t *uid
, uint8_t blockNumber
)
311 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
312 // followed by teh block data
313 // one sub-carrier, inventory, 1 slot, fast rate
314 cmd
[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit
315 // READ BLOCK command code
317 // UID may be optionally specified here
326 cmd
[9]= 0xe0; // always e0 (not exactly unique)
327 // Block number to read
328 cmd
[10] = blockNumber
;//0x00;
330 crc
= Crc(cmd
, 11); // the crc needs to be calculated over 2 bytes
331 cmd
[11] = crc
& 0xff;
334 CodeIso15693AsReader(cmd
, sizeof(cmd
));
337 static void __attribute__((unused
)) BuildReadMultiBlockRequest(uint8_t *uid
)
342 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
343 // followed by teh block data
344 // one sub-carrier, inventory, 1 slot, fast rate
345 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
346 // READ Multi BLOCK command code
348 // UID may be optionally specified here
357 cmd
[9]= 0xe0; // always e0 (not exactly unique)
358 // First Block number to read
360 // Number of Blocks to read
361 cmd
[11] = 0x2f; // read quite a few
363 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
364 cmd
[12] = crc
& 0xff;
367 CodeIso15693AsReader(cmd
, sizeof(cmd
));
370 static void __attribute__((unused
)) BuildArbitraryRequest(uint8_t *uid
,uint8_t CmdCode
)
375 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
376 // followed by teh block data
377 // one sub-carrier, inventory, 1 slot, fast rate
378 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
379 // READ BLOCK command code
381 // UID may be optionally specified here
390 cmd
[9]= 0xe0; // always e0 (not exactly unique)
396 // cmd[13] = 0x00; //Now the CRC
397 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
398 cmd
[12] = crc
& 0xff;
401 CodeIso15693AsReader(cmd
, sizeof(cmd
));
404 static void __attribute__((unused
)) BuildArbitraryCustomRequest(uint8_t uid
[], uint8_t CmdCode
)
409 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
410 // followed by teh block data
411 // one sub-carrier, inventory, 1 slot, fast rate
412 cmd
[0] = (1 << 5) | (1 << 1); // no SELECT bit
413 // READ BLOCK command code
415 // UID may be optionally specified here
424 cmd
[9]= 0xe0; // always e0 (not exactly unique)
426 cmd
[10] = 0x05; // for custom codes this must be manufcturer code
430 // cmd[13] = 0x00; //Now the CRC
431 crc
= Crc(cmd
, 12); // the crc needs to be calculated over 2 bytes
432 cmd
[12] = crc
& 0xff;
435 CodeIso15693AsReader(cmd
, sizeof(cmd
));
438 /////////////////////////////////////////////////////////////////////////
439 // Now the VICC>VCD responses when we are simulating a tag
440 ////////////////////////////////////////////////////////////////////
442 static void BuildInventoryResponse(void)
447 // one sub-carrier, inventory, 1 slot, fast rate
448 // AFI is at bit 5 (1<<4) when doing an INVENTORY
449 cmd
[0] = 0; //(1 << 2) | (1 << 5) | (1 << 1);
462 cmd
[10] = crc
& 0xff;
465 CodeIso15693AsReader(cmd
, sizeof(cmd
));
468 //-----------------------------------------------------------------------------
469 // Transmit the command (to the tag) that was placed in ToSend[].
470 //-----------------------------------------------------------------------------
471 static void TransmitTo15693Tag(const uint8_t *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(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
481 // AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
484 // if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
485 // volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
493 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
494 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
500 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
501 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
506 *samples
= (c
+ *wait
) << 3;
509 //-----------------------------------------------------------------------------
510 // Transmit the command (to the reader) that was placed in ToSend[].
511 //-----------------------------------------------------------------------------
512 static void TransmitTo15693Reader(const uint8_t *cmd
, int len
, int *samples
, int *wait
)
516 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
517 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
); // No requirement to energise my coils
518 if(*wait
< 10) { *wait
= 10; }
522 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
523 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
529 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
530 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
535 *samples
= (c
+ *wait
) << 3;
538 static int GetIso15693AnswerFromTag(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
541 uint8_t *dest
= (uint8_t *)BigBuf
;
547 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
548 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
552 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
553 AT91C_BASE_SSC
->SSC_THR
= 0x43;
555 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
557 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
559 // The samples are correlations against I and Q versions of the
560 // tone that the tag AM-modulates, so every other sample is I,
561 // every other is Q. We just want power, so abs(I) + abs(Q) is
562 // close to what we want.
577 dest
[c
++] = (uint8_t)r
;
590 //////////////////////////////////////////
591 /////////// DEMODULATE ///////////////////
592 //////////////////////////////////////////
595 int max
= 0, maxPos
=0;
599 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
601 // First, correlate for SOF
602 for(i
= 0; i
< 100; i
++) {
604 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
605 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
612 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
614 int k
= 0; // this will be our return value
616 // greg - If correlation is less than 1 then there's little point in continuing
617 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1)
620 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
623 memset(outBuf
, 0, sizeof(outBuf
));
626 int corr0
= 0, corr1
= 0, corrEOF
= 0;
627 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
628 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
630 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
631 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
633 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
634 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
636 // Even things out by the length of the target waveform.
640 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
641 // DbpString("EOF at %d", i);
643 } else if(corr1
> corr0
) {
644 i
+= arraylen(Logic1
)/skip
;
647 i
+= arraylen(Logic0
)/skip
;
654 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
655 DbpString("ran off end!");
660 DbpString("error, uneven octet! (discard extra bits!)");
661 /// DbpString(" mask=%02x", mask);
665 // strcat(str1," octets read");
667 // DbpString( str1); // DbpString("%d octets", k);
669 // for(i = 0; i < k; i+=3) {
670 // //DbpString("# %2d: %02x ", i, outBuf[i]);
671 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
674 for(i
= 0; i
< k
; i
++) {
675 receivedResponse
[i
] = outBuf
[i
];
677 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
678 return k
; // return the number of bytes demodulated
680 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
684 // Now the GetISO15693 message from sniffing command
685 static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
688 uint8_t *dest
= (uint8_t *)BigBuf
;
694 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
695 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
699 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
700 AT91C_BASE_SSC
->SSC_THR
= 0x43;
702 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
704 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
706 // The samples are correlations against I and Q versions of the
707 // tone that the tag AM-modulates, so every other sample is I,
708 // every other is Q. We just want power, so abs(I) + abs(Q) is
709 // close to what we want.
724 dest
[c
++] = (uint8_t)r
;
737 //////////////////////////////////////////
738 /////////// DEMODULATE ///////////////////
739 //////////////////////////////////////////
742 int max
= 0, maxPos
=0;
746 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
748 // First, correlate for SOF
749 for(i
= 0; i
< 19000; i
++) {
751 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
752 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
759 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
761 int k
= 0; // this will be our return value
763 // greg - If correlation is less than 1 then there's little point in continuing
764 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1) // THIS SHOULD BE 1
767 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
770 memset(outBuf
, 0, sizeof(outBuf
));
773 int corr0
= 0, corr1
= 0, corrEOF
= 0;
774 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
775 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
777 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
778 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
780 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
781 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
783 // Even things out by the length of the target waveform.
787 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
788 // DbpString("EOF at %d", i);
790 } else if(corr1
> corr0
) {
791 i
+= arraylen(Logic1
)/skip
;
794 i
+= arraylen(Logic0
)/skip
;
801 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
802 DbpString("ran off end!");
807 DbpString("error, uneven octet! (discard extra bits!)");
808 /// DbpString(" mask=%02x", mask);
812 // strcat(str1," octets read");
814 // DbpString( str1); // DbpString("%d octets", k);
816 // for(i = 0; i < k; i+=3) {
817 // //DbpString("# %2d: %02x ", i, outBuf[i]);
818 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
821 for(i
= 0; i
< k
; i
++) {
822 receivedResponse
[i
] = outBuf
[i
];
824 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
825 return k
; // return the number of bytes demodulated
827 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
830 //-----------------------------------------------------------------------------
831 // Start to read an ISO 15693 tag. We send an identify request, then wait
832 // for the response. The response is not demodulated, just left in the buffer
833 // so that it can be downloaded to a PC and processed there.
834 //-----------------------------------------------------------------------------
835 void AcquireRawAdcSamplesIso15693(void)
838 uint8_t *dest
= (uint8_t *)BigBuf
;
843 BuildIdentifyRequest();
845 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
847 // Give the tags time to energize
848 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
851 // Now send the command
853 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
857 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
858 AT91C_BASE_SSC
->SSC_THR
= ToSend
[c
];
860 if(c
== ToSendMax
+3) {
864 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
865 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
871 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
876 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
877 AT91C_BASE_SSC
->SSC_THR
= 0x43;
879 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
881 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
883 // The samples are correlations against I and Q versions of the
884 // tone that the tag AM-modulates, so every other sample is I,
885 // every other is Q. We just want power, so abs(I) + abs(Q) is
886 // close to what we want.
901 dest
[c
++] = (uint8_t)r
;
915 //-----------------------------------------------------------------------------
916 // Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
917 // all demodulation performed in arm rather than host. - greg
918 //-----------------------------------------------------------------------------
919 void ReaderIso15693(uint32_t parameter
)
926 //DbpString(parameter);
928 //uint8_t *answer0 = (((uint8_t *)BigBuf) + 3560); // allow 100 bytes per reponse (way too much)
929 uint8_t *answer1
= (((uint8_t *)BigBuf
) + 3660); //
930 uint8_t *answer2
= (((uint8_t *)BigBuf
) + 3760);
931 uint8_t *answer3
= (((uint8_t *)BigBuf
) + 3860);
932 //uint8_t *TagUID= (((uint8_t *)BigBuf) + 3960); // where we hold the uid for hi15reader
933 // int answerLen0 = 0;
939 memset(BigBuf
+ 3660, 0, 300);
944 // Start from off (no field generated)
945 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
948 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
951 // Give the tags time to energize
952 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
965 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
966 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
967 uint8_t TagUID
[7]; // where we hold the uid for hi15reader
969 // BuildIdentifyRequest();
970 // //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
971 // TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); // No longer ToSendMax+3
972 // // Now wait for a response
973 // responseLen0 = GetIso15693AnswerFromTag(receivedAnswer0, 100, &samples, &elapsed) ;
974 // if (responseLen0 >=12) // we should do a better check than this
976 // // really we should check it is a valid mesg
977 // // but for now just grab what we think is the uid
978 // TagUID[0] = receivedAnswer0[2];
979 // TagUID[1] = receivedAnswer0[3];
980 // TagUID[2] = receivedAnswer0[4];
981 // TagUID[3] = receivedAnswer0[5];
982 // TagUID[4] = receivedAnswer0[6];
983 // TagUID[5] = receivedAnswer0[7];
984 // TagUID[6] = receivedAnswer0[8]; // IC Manufacturer code
985 // DbpIntegers(TagUID[6],TagUID[5],TagUID[4]);
988 // Now send the IDENTIFY command
989 BuildIdentifyRequest();
990 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
991 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
992 // Now wait for a response
993 answerLen1
= GetIso15693AnswerFromTag(answer1
, 100, &samples
, &elapsed
) ;
995 if (answerLen1
>=12) // we should do a better check than this
998 TagUID
[0] = answer1
[2];
999 TagUID
[1] = answer1
[3];
1000 TagUID
[2] = answer1
[4];
1001 TagUID
[3] = answer1
[5];
1002 TagUID
[4] = answer1
[6];
1003 TagUID
[5] = answer1
[7];
1004 TagUID
[6] = answer1
[8]; // IC Manufacturer code
1006 // Now send the SELECT command
1007 BuildSelectRequest(TagUID
);
1008 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1009 // Now wait for a response
1010 answerLen2
= GetIso15693AnswerFromTag(answer2
, 100, &samples
, &elapsed
);
1012 // Now send the MULTI READ command
1013 // BuildArbitraryRequest(*TagUID,parameter);
1014 BuildArbitraryCustomRequest(TagUID
,parameter
);
1015 // BuildReadBlockRequest(*TagUID,parameter);
1016 // BuildSysInfoRequest(*TagUID);
1017 //TransmitTo15693Tag(ToSend,ToSendMax+3,&tsamples, &wait);
1018 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
); // No longer ToSendMax+3
1019 // Now wait for a response
1020 answerLen3
= GetIso15693AnswerFromTag(answer3
, 100, &samples
, &elapsed
) ;
1024 Dbprintf("%d octets read from IDENTIFY request: %x %x %x %x %x %x %x %x %x", answerLen1
,
1025 answer1
[0], answer1
[1], answer1
[2],
1026 answer1
[3], answer1
[4], answer1
[5],
1027 answer1
[6], answer1
[7], answer1
[8]);
1029 Dbprintf("%d octets read from SELECT request: %x %x %x %x %x %x %x %x %x", answerLen2
,
1030 answer2
[0], answer2
[1], answer2
[2],
1031 answer2
[3], answer2
[4], answer2
[5],
1032 answer2
[6], answer2
[7], answer2
[8]);
1034 Dbprintf("%d octets read from XXX request: %x %x %x %x %x %x %x %x %x", answerLen3
,
1035 answer3
[0], answer3
[1], answer3
[2],
1036 answer3
[3], answer3
[4], answer3
[5],
1037 answer3
[6], answer3
[7], answer3
[8]);
1041 // for(i = 0; i < responseLen3; i++) {
1042 // itoa(str1,receivedAnswer3[i]);
1043 // strcat(str2,str1);
1053 //-----------------------------------------------------------------------------
1054 // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1055 // all demodulation performed in arm rather than host. - greg
1056 //-----------------------------------------------------------------------------
1057 void SimTagIso15693(uint32_t parameter
)
1064 uint8_t *answer1
= (((uint8_t *)BigBuf
) + 3660); //
1068 memset(answer1
, 0, 100);
1073 // Start from off (no field generated)
1074 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1077 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1080 // Give the tags time to energize
1081 // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); // NO GOOD FOR SIM TAG!!!!
1094 answerLen1
= GetIso15693AnswerFromSniff(answer1
, 100, &samples
, &elapsed
) ;
1096 if (answerLen1
>=1) // we should do a better check than this
1098 // Build a suitable reponse to the reader INVENTORY cocmmand
1099 BuildInventoryResponse();
1100 TransmitTo15693Reader(ToSend
,ToSendMax
, &tsamples
, &wait
);
1103 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1
,
1104 answer1
[0], answer1
[1], answer1
[2],
1105 answer1
[3], answer1
[4], answer1
[5],
1106 answer1
[6], answer1
[7], answer1
[8]);