Use Seeeduino Arch (or Arch Pro) + NFC Shield to read a Mifare Classic tag

Dependencies:   PN532 mbed

Fork of PN532_P2P by Yihui Xiong

Revision:
0:21ac4fe1ccf8
Child:
1:a9df716f8a64
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Oct 17 07:14:21 2013 +0000
@@ -0,0 +1,139 @@
+/**
+ * Seeeduino Arch + NFC Shield write a NDEF record to a NFC tag
+ */
+
+
+#include "mbed.h"
+#include "PN532.h"
+
+#if 0
+
+#define LOG(args...)
+
+#else
+#include "USBSerial.h"
+
+#define LOG(args...)        pc.printf(args)
+
+USBSerial pc;
+//Serial pc(USBTX, USBRX);
+#endif
+
+// PN532(mosi, miso, clk, cs)
+PN532 nfc(P1_22, P1_21, P1_20, P0_2);
+
+DigitalOut led1(LED1);
+
+/*
+    We can encode many different kinds of pointers to the card,
+    from a URL, to an Email address, to a phone number, and many more
+    check the library header .h file to see the large # of supported
+    prefixes!
+*/
+// For a http://www. url:
+const char *url = "seeedstudio.com";
+uint8_t ndefprefix = NDEF_URIPREFIX_HTTP_WWWDOT;
+
+// for an email address
+//const char * url = "mail@example.com";
+//uint8_t ndefprefix = NDEF_URIPREFIX_MAILTO;
+
+// for a phone number
+//const char * url = "+1 212 555 1212";
+//uint8_t ndefprefix = NDEF_URIPREFIX_TEL;
+
+int main()
+{
+
+    nfc.begin();
+    uint32_t versiondata = nfc.getFirmwareVersion();
+    if (! versiondata) {
+        LOG("Didn't find PN532\r\n");
+        while (1) {
+            led1 = !led1;
+            wait(0.1);
+        }
+    }
+
+    LOG("Found chip PN5%2X\r\n", versiondata >> 24);
+    LOG("Firmware V%d.%d\r\n", (versiondata >> 16) & 0xFF, (versiondata >> 8) & 0xFF);
+
+    nfc.SAMConfig();
+
+
+    while (1) {
+        uint8_t success;                          // Flag to check if there was an error with the PN532
+        uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the continueed UID
+        uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
+        bool authenticated = false;               // Flag to indicate if the sector is authenticated
+
+        // Use the default NDEF keys (these would have have set by mifareclassic_formatndef.pde!)
+        uint8_t keya[6] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 };
+        uint8_t keyb[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };
+
+        LOG("Place your NDEF formatted Mifare Classic card on the reader to update the NDEF record\r\n");
+
+        // Wait for an ISO14443A type card (Mifare, etc.).  When one is found
+        // 'uid' will be populated with the UID, and uidLength will indicate
+        // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
+        success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 0);
+
+        if (success) {
+            // Display some basic information about the card
+            LOG("Found an ISO14443A card\r\n");
+            LOG("UID length: %d\r\nUID Value: ", uidLength);
+            for (uint8_t i = 0; i < uidLength; i++) {
+                LOG("0x%X ", uid[i]);
+            }
+
+            // Make sure this is a Mifare Classic card
+            if (uidLength != 4) {
+                LOG("Ooops ... this doesn't seem to be a Mifare Classic card!\r\n");
+                continue;
+            }
+
+            // We probably have a Mifare Classic card ...
+            LOG("Seems to be a Mifare Classic card (4 byte UID)\r\n");
+
+            // Check if this is an NDEF card (using first block of sector 1 from mifareclassic_formatndef.pde)
+            // Must authenticate on the first key using 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7
+            success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 4, 0, keyb);
+            if (!success) {
+                LOG("Unable to authenticate block 4 ... is this card NDEF formatted?\r\n");
+                continue;
+            }
+
+            LOG("Authentication succeeded (seems to be an NDEF/NFC Forum tag) ...\r\n");
+
+            // Authenticated seems to have worked
+            // Try to write an NDEF record to sector 1
+            // Use 0x01 for the URI Identifier Code to prepend "http://www."
+            // to the url (and save some space).  For information on URI ID Codes
+            // see http://www.ladyada.net/wiki/private/articlestaging/nfc/ndef
+            if (strlen(url) > 38) {
+                // The length is also checked in the WriteNDEFURI function, but lets
+                // warn users here just in case they change the value and it's bigger
+                // than it should be
+                LOG("URI is too long ... must be less than 38 characters!\r\n");
+                continue;
+            }
+
+            LOG("Updating sector 1 with URI as NDEF Message\r\n");
+
+            // URI is within size limits ... write it to the card and report success/failure
+            success = nfc.mifareclassic_WriteNDEFURI(1, ndefprefix, url);
+            if (success) {
+                LOG("NDEF URI Record written to sector 1\r\n");
+                LOG("\r\n");
+            } else {
+                LOG("NDEF Record creation failed! :(\r\n");
+            }
+        } else {
+            LOG("Didn't find a NFC tag\r\n");
+        }
+
+        // Wait a bit before trying again
+        LOG("\n\nDone!\r\n");
+        wait(1);
+    }
+}