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

Dependencies:   PN532 mbed

Fork of PN532_P2P by Yihui Xiong

Committer:
yihui
Date:
Thu Oct 17 07:14:21 2013 +0000
Revision:
0:21ac4fe1ccf8
Child:
1:a9df716f8a64
initial, write a NDEF record to a NFC tag

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:21ac4fe1ccf8 1 /**
yihui 0:21ac4fe1ccf8 2 * Seeeduino Arch + NFC Shield write a NDEF record to a NFC tag
yihui 0:21ac4fe1ccf8 3 */
yihui 0:21ac4fe1ccf8 4
yihui 0:21ac4fe1ccf8 5
yihui 0:21ac4fe1ccf8 6 #include "mbed.h"
yihui 0:21ac4fe1ccf8 7 #include "PN532.h"
yihui 0:21ac4fe1ccf8 8
yihui 0:21ac4fe1ccf8 9 #if 0
yihui 0:21ac4fe1ccf8 10
yihui 0:21ac4fe1ccf8 11 #define LOG(args...)
yihui 0:21ac4fe1ccf8 12
yihui 0:21ac4fe1ccf8 13 #else
yihui 0:21ac4fe1ccf8 14 #include "USBSerial.h"
yihui 0:21ac4fe1ccf8 15
yihui 0:21ac4fe1ccf8 16 #define LOG(args...) pc.printf(args)
yihui 0:21ac4fe1ccf8 17
yihui 0:21ac4fe1ccf8 18 USBSerial pc;
yihui 0:21ac4fe1ccf8 19 //Serial pc(USBTX, USBRX);
yihui 0:21ac4fe1ccf8 20 #endif
yihui 0:21ac4fe1ccf8 21
yihui 0:21ac4fe1ccf8 22 // PN532(mosi, miso, clk, cs)
yihui 0:21ac4fe1ccf8 23 PN532 nfc(P1_22, P1_21, P1_20, P0_2);
yihui 0:21ac4fe1ccf8 24
yihui 0:21ac4fe1ccf8 25 DigitalOut led1(LED1);
yihui 0:21ac4fe1ccf8 26
yihui 0:21ac4fe1ccf8 27 /*
yihui 0:21ac4fe1ccf8 28 We can encode many different kinds of pointers to the card,
yihui 0:21ac4fe1ccf8 29 from a URL, to an Email address, to a phone number, and many more
yihui 0:21ac4fe1ccf8 30 check the library header .h file to see the large # of supported
yihui 0:21ac4fe1ccf8 31 prefixes!
yihui 0:21ac4fe1ccf8 32 */
yihui 0:21ac4fe1ccf8 33 // For a http://www. url:
yihui 0:21ac4fe1ccf8 34 const char *url = "seeedstudio.com";
yihui 0:21ac4fe1ccf8 35 uint8_t ndefprefix = NDEF_URIPREFIX_HTTP_WWWDOT;
yihui 0:21ac4fe1ccf8 36
yihui 0:21ac4fe1ccf8 37 // for an email address
yihui 0:21ac4fe1ccf8 38 //const char * url = "mail@example.com";
yihui 0:21ac4fe1ccf8 39 //uint8_t ndefprefix = NDEF_URIPREFIX_MAILTO;
yihui 0:21ac4fe1ccf8 40
yihui 0:21ac4fe1ccf8 41 // for a phone number
yihui 0:21ac4fe1ccf8 42 //const char * url = "+1 212 555 1212";
yihui 0:21ac4fe1ccf8 43 //uint8_t ndefprefix = NDEF_URIPREFIX_TEL;
yihui 0:21ac4fe1ccf8 44
yihui 0:21ac4fe1ccf8 45 int main()
yihui 0:21ac4fe1ccf8 46 {
yihui 0:21ac4fe1ccf8 47
yihui 0:21ac4fe1ccf8 48 nfc.begin();
yihui 0:21ac4fe1ccf8 49 uint32_t versiondata = nfc.getFirmwareVersion();
yihui 0:21ac4fe1ccf8 50 if (! versiondata) {
yihui 0:21ac4fe1ccf8 51 LOG("Didn't find PN532\r\n");
yihui 0:21ac4fe1ccf8 52 while (1) {
yihui 0:21ac4fe1ccf8 53 led1 = !led1;
yihui 0:21ac4fe1ccf8 54 wait(0.1);
yihui 0:21ac4fe1ccf8 55 }
yihui 0:21ac4fe1ccf8 56 }
yihui 0:21ac4fe1ccf8 57
yihui 0:21ac4fe1ccf8 58 LOG("Found chip PN5%2X\r\n", versiondata >> 24);
yihui 0:21ac4fe1ccf8 59 LOG("Firmware V%d.%d\r\n", (versiondata >> 16) & 0xFF, (versiondata >> 8) & 0xFF);
yihui 0:21ac4fe1ccf8 60
yihui 0:21ac4fe1ccf8 61 nfc.SAMConfig();
yihui 0:21ac4fe1ccf8 62
yihui 0:21ac4fe1ccf8 63
yihui 0:21ac4fe1ccf8 64 while (1) {
yihui 0:21ac4fe1ccf8 65 uint8_t success; // Flag to check if there was an error with the PN532
yihui 0:21ac4fe1ccf8 66 uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the continueed UID
yihui 0:21ac4fe1ccf8 67 uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
yihui 0:21ac4fe1ccf8 68 bool authenticated = false; // Flag to indicate if the sector is authenticated
yihui 0:21ac4fe1ccf8 69
yihui 0:21ac4fe1ccf8 70 // Use the default NDEF keys (these would have have set by mifareclassic_formatndef.pde!)
yihui 0:21ac4fe1ccf8 71 uint8_t keya[6] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 };
yihui 0:21ac4fe1ccf8 72 uint8_t keyb[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };
yihui 0:21ac4fe1ccf8 73
yihui 0:21ac4fe1ccf8 74 LOG("Place your NDEF formatted Mifare Classic card on the reader to update the NDEF record\r\n");
yihui 0:21ac4fe1ccf8 75
yihui 0:21ac4fe1ccf8 76 // Wait for an ISO14443A type card (Mifare, etc.). When one is found
yihui 0:21ac4fe1ccf8 77 // 'uid' will be populated with the UID, and uidLength will indicate
yihui 0:21ac4fe1ccf8 78 // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
yihui 0:21ac4fe1ccf8 79 success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 0);
yihui 0:21ac4fe1ccf8 80
yihui 0:21ac4fe1ccf8 81 if (success) {
yihui 0:21ac4fe1ccf8 82 // Display some basic information about the card
yihui 0:21ac4fe1ccf8 83 LOG("Found an ISO14443A card\r\n");
yihui 0:21ac4fe1ccf8 84 LOG("UID length: %d\r\nUID Value: ", uidLength);
yihui 0:21ac4fe1ccf8 85 for (uint8_t i = 0; i < uidLength; i++) {
yihui 0:21ac4fe1ccf8 86 LOG("0x%X ", uid[i]);
yihui 0:21ac4fe1ccf8 87 }
yihui 0:21ac4fe1ccf8 88
yihui 0:21ac4fe1ccf8 89 // Make sure this is a Mifare Classic card
yihui 0:21ac4fe1ccf8 90 if (uidLength != 4) {
yihui 0:21ac4fe1ccf8 91 LOG("Ooops ... this doesn't seem to be a Mifare Classic card!\r\n");
yihui 0:21ac4fe1ccf8 92 continue;
yihui 0:21ac4fe1ccf8 93 }
yihui 0:21ac4fe1ccf8 94
yihui 0:21ac4fe1ccf8 95 // We probably have a Mifare Classic card ...
yihui 0:21ac4fe1ccf8 96 LOG("Seems to be a Mifare Classic card (4 byte UID)\r\n");
yihui 0:21ac4fe1ccf8 97
yihui 0:21ac4fe1ccf8 98 // Check if this is an NDEF card (using first block of sector 1 from mifareclassic_formatndef.pde)
yihui 0:21ac4fe1ccf8 99 // Must authenticate on the first key using 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7
yihui 0:21ac4fe1ccf8 100 success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 4, 0, keyb);
yihui 0:21ac4fe1ccf8 101 if (!success) {
yihui 0:21ac4fe1ccf8 102 LOG("Unable to authenticate block 4 ... is this card NDEF formatted?\r\n");
yihui 0:21ac4fe1ccf8 103 continue;
yihui 0:21ac4fe1ccf8 104 }
yihui 0:21ac4fe1ccf8 105
yihui 0:21ac4fe1ccf8 106 LOG("Authentication succeeded (seems to be an NDEF/NFC Forum tag) ...\r\n");
yihui 0:21ac4fe1ccf8 107
yihui 0:21ac4fe1ccf8 108 // Authenticated seems to have worked
yihui 0:21ac4fe1ccf8 109 // Try to write an NDEF record to sector 1
yihui 0:21ac4fe1ccf8 110 // Use 0x01 for the URI Identifier Code to prepend "http://www."
yihui 0:21ac4fe1ccf8 111 // to the url (and save some space). For information on URI ID Codes
yihui 0:21ac4fe1ccf8 112 // see http://www.ladyada.net/wiki/private/articlestaging/nfc/ndef
yihui 0:21ac4fe1ccf8 113 if (strlen(url) > 38) {
yihui 0:21ac4fe1ccf8 114 // The length is also checked in the WriteNDEFURI function, but lets
yihui 0:21ac4fe1ccf8 115 // warn users here just in case they change the value and it's bigger
yihui 0:21ac4fe1ccf8 116 // than it should be
yihui 0:21ac4fe1ccf8 117 LOG("URI is too long ... must be less than 38 characters!\r\n");
yihui 0:21ac4fe1ccf8 118 continue;
yihui 0:21ac4fe1ccf8 119 }
yihui 0:21ac4fe1ccf8 120
yihui 0:21ac4fe1ccf8 121 LOG("Updating sector 1 with URI as NDEF Message\r\n");
yihui 0:21ac4fe1ccf8 122
yihui 0:21ac4fe1ccf8 123 // URI is within size limits ... write it to the card and report success/failure
yihui 0:21ac4fe1ccf8 124 success = nfc.mifareclassic_WriteNDEFURI(1, ndefprefix, url);
yihui 0:21ac4fe1ccf8 125 if (success) {
yihui 0:21ac4fe1ccf8 126 LOG("NDEF URI Record written to sector 1\r\n");
yihui 0:21ac4fe1ccf8 127 LOG("\r\n");
yihui 0:21ac4fe1ccf8 128 } else {
yihui 0:21ac4fe1ccf8 129 LOG("NDEF Record creation failed! :(\r\n");
yihui 0:21ac4fe1ccf8 130 }
yihui 0:21ac4fe1ccf8 131 } else {
yihui 0:21ac4fe1ccf8 132 LOG("Didn't find a NFC tag\r\n");
yihui 0:21ac4fe1ccf8 133 }
yihui 0:21ac4fe1ccf8 134
yihui 0:21ac4fe1ccf8 135 // Wait a bit before trying again
yihui 0:21ac4fe1ccf8 136 LOG("\n\nDone!\r\n");
yihui 0:21ac4fe1ccf8 137 wait(1);
yihui 0:21ac4fe1ccf8 138 }
yihui 0:21ac4fe1ccf8 139 }