+
+//-----------------------------------------------------------------------------\r
+// Read a SRI512 ISO 14443 tag.\r
+//
+// SRI512 tags are just simple memory tags, here we're looking at making a dump
+// of the contents of the memory. No anticollision algorithm is done, we assume
+// we have a single tag in the field.
+//
+// I tried to be systematic and check every answer of the tag, every CRC, etc...\r
+//-----------------------------------------------------------------------------\r
+void ReadSRI512Iso14443(DWORD parameter)\r
+{\r
+ BYTE i = 0x00;
+\r
+ // Make sure that we start from off, since the tags are stateful;\r
+ // confusing things will happen if we don't reset them between reads.\r
+ LED_D_OFF();\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ SpinDelay(200);\r
+\r
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
+ FpgaSetupSsc();\r
+\r
+ // Now give it time to spin up.\r
+ // Signal field is on with the appropriate LED\r
+ LED_D_ON();\r
+ FpgaWriteConfWord(\r
+ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);\r
+ SpinDelay(200);\r
+
+ // First command: wake up the tag using the INITIATE command\r
+ BYTE cmd1[] = { 0x06, 0x00, 0x97, 0x5b};\r
+ CodeIso14443bAsReader(cmd1, sizeof(cmd1));\r
+ TransmitFor14443();\r
+// LED_A_ON();\r
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);\r
+// LED_A_OFF();\r
+
+ if (Demod.len == 0) {
+ DbpString("No response from tag");
+ return;
+ } else {
+ DbpString("Randomly generated UID from tag (+ 2 byte CRC):");
+ DbpIntegers(Demod.output[0], Demod.output[1],Demod.output[2]);
+ }
+ // There is a response, SELECT the uid
+ DbpString("Now SELECT tag:");
+ cmd1[0] = 0x0E; // 0x0E is SELECT
+ cmd1[1] = Demod.output[0];
+ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);\r
+ CodeIso14443bAsReader(cmd1, sizeof(cmd1));\r
+ TransmitFor14443();\r
+// LED_A_ON();\r
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);\r
+// LED_A_OFF();\r
+ if (Demod.len != 3) {
+ DbpString("Expected 3 bytes from tag, got:");
+ DbpIntegers(Demod.len,0x0,0x0);
+ return;
+ }
+ // Check the CRC of the answer:
+ ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);\r
+ if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {\r
+ DbpString("CRC Error reading select response.");
+ return;
+ }
+ // Check response from the tag: should be the same UID as the command we just sent:
+ if (cmd1[1] != Demod.output[0]) {
+ DbpString("Bad response to SELECT from Tag, aborting:");
+ DbpIntegers(cmd1[1],Demod.output[0],0x0);
+ return;
+ }
+ // Tag is now selected,
+ // First get the tag's UID:
+ cmd1[0] = 0x0B;
+ ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
+ CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one\r
+ TransmitFor14443();\r
+// LED_A_ON();\r
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);\r
+// LED_A_OFF();\r
+ if (Demod.len != 10) {
+ DbpString("Expected 10 bytes from tag, got:");
+ DbpIntegers(Demod.len,0x0,0x0);
+ return;
+ }
+ // The check the CRC of the answer (use cmd1 as temporary variable):
+ ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);\r
+ if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {\r
+ DbpString("CRC Error reading block! - Below: expected, got");
+ DbpIntegers( (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9],0);
+ // Do not return;, let's go on... (we should retry, maybe ?)
+ }
+ DbpString("Tag UID (64 bits):");
+ DbpIntegers((Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4], (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], 0);
+
+ // Now loop to read all 16 blocks, address from 0 to 15
+ DbpString("Tag memory dump, block 0 to 15");
+ cmd1[0] = 0x08;
+ i = 0x00;
+ for (;;) {
+ if (i == 0x10) {
+ DbpString("System area block (0xff):");
+ i = 0xff;
+ }
+ cmd1[1] = i;
+ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);\r
+ CodeIso14443bAsReader(cmd1, sizeof(cmd1));\r
+ TransmitFor14443();\r
+// LED_A_ON();\r
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);\r
+// LED_A_OFF();
+ if (Demod.len != 6) { // Check if we got an answer from the tag
+ DbpString("Expected 6 bytes from tag, got less...");
+ return;
+ }
+ // The check the CRC of the answer (use cmd1 as temporary variable):
+ ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);\r
+ if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {\r
+ DbpString("CRC Error reading block! - Below: expected, got");
+ DbpIntegers( (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5],0);
+ // Do not return;, let's go on... (we should retry, maybe ?)
+ }
+ // Now print out the memory location:
+ DbpString("Address , Contents, CRC");
+ DbpIntegers(i, (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], (Demod.output[4]<<8)+Demod.output[5]);
+ if (i == 0xff) {
+ break;
+ }
+ i++;
+ }
+}\r
+