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:47:22 2013 +0000
Revision:
1:a9df716f8a64
Parent:
0:21ac4fe1ccf8
Child:
2:b238c6772bc4
Read Mifare card

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:21ac4fe1ccf8 1 #include "mbed.h"
yihui 0:21ac4fe1ccf8 2 #include "PN532.h"
yihui 0:21ac4fe1ccf8 3
yihui 1:a9df716f8a64 4 #if 0 // Output debug message or not
yihui 0:21ac4fe1ccf8 5 #define LOG(args...)
yihui 0:21ac4fe1ccf8 6 #else
yihui 0:21ac4fe1ccf8 7 #include "USBSerial.h"
yihui 0:21ac4fe1ccf8 8 #define LOG(args...) pc.printf(args)
yihui 0:21ac4fe1ccf8 9
yihui 1:a9df716f8a64 10 USBSerial pc; // Use USB to Serial
yihui 0:21ac4fe1ccf8 11 //Serial pc(USBTX, USBRX);
yihui 0:21ac4fe1ccf8 12 #endif
yihui 0:21ac4fe1ccf8 13
yihui 0:21ac4fe1ccf8 14 // PN532(mosi, miso, clk, cs)
yihui 0:21ac4fe1ccf8 15 PN532 nfc(P1_22, P1_21, P1_20, P0_2);
yihui 0:21ac4fe1ccf8 16
yihui 0:21ac4fe1ccf8 17 DigitalOut led1(LED1);
yihui 0:21ac4fe1ccf8 18
yihui 0:21ac4fe1ccf8 19 int main()
yihui 0:21ac4fe1ccf8 20 {
yihui 0:21ac4fe1ccf8 21 nfc.begin();
yihui 0:21ac4fe1ccf8 22 uint32_t versiondata = nfc.getFirmwareVersion();
yihui 0:21ac4fe1ccf8 23 if (! versiondata) {
yihui 0:21ac4fe1ccf8 24 LOG("Didn't find PN532\r\n");
yihui 0:21ac4fe1ccf8 25 while (1) {
yihui 0:21ac4fe1ccf8 26 led1 = !led1;
yihui 0:21ac4fe1ccf8 27 wait(0.1);
yihui 0:21ac4fe1ccf8 28 }
yihui 0:21ac4fe1ccf8 29 }
yihui 0:21ac4fe1ccf8 30
yihui 0:21ac4fe1ccf8 31 LOG("Found chip PN5%2X\r\n", versiondata >> 24);
yihui 0:21ac4fe1ccf8 32 LOG("Firmware V%d.%d\r\n", (versiondata >> 16) & 0xFF, (versiondata >> 8) & 0xFF);
yihui 0:21ac4fe1ccf8 33
yihui 0:21ac4fe1ccf8 34 nfc.SAMConfig();
yihui 0:21ac4fe1ccf8 35
yihui 0:21ac4fe1ccf8 36 while (1) {
yihui 1:a9df716f8a64 37 uint8_t success;
yihui 1:a9df716f8a64 38 uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
yihui 0:21ac4fe1ccf8 39 uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
yihui 0:21ac4fe1ccf8 40
yihui 1:a9df716f8a64 41 // Wait for an ISO14443A type cards (Mifare, etc.). When one is found
yihui 0:21ac4fe1ccf8 42 // 'uid' will be populated with the UID, and uidLength will indicate
yihui 0:21ac4fe1ccf8 43 // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
yihui 0:21ac4fe1ccf8 44 success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 0);
yihui 0:21ac4fe1ccf8 45
yihui 0:21ac4fe1ccf8 46 if (success) {
yihui 0:21ac4fe1ccf8 47 // Display some basic information about the card
yihui 0:21ac4fe1ccf8 48 LOG("Found an ISO14443A card\r\n");
yihui 0:21ac4fe1ccf8 49 LOG("UID length: %d\r\nUID Value: ", uidLength);
yihui 0:21ac4fe1ccf8 50 for (uint8_t i = 0; i < uidLength; i++) {
yihui 0:21ac4fe1ccf8 51 LOG("0x%X ", uid[i]);
yihui 0:21ac4fe1ccf8 52 }
yihui 0:21ac4fe1ccf8 53
yihui 1:a9df716f8a64 54 if (uidLength == 4) {
yihui 1:a9df716f8a64 55 // We probably have a Mifare Classic card ...
yihui 1:a9df716f8a64 56 LOG("Seems to be a Mifare Classic card (4 byte UID)\r\n");
yihui 1:a9df716f8a64 57
yihui 1:a9df716f8a64 58 // Now we need to try to authenticate it for read/write access
yihui 1:a9df716f8a64 59 // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
yihui 1:a9df716f8a64 60 LOG("Trying to authenticate block 4 with default KEYA value\r\n");
yihui 1:a9df716f8a64 61 uint8_t keya[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };
yihui 1:a9df716f8a64 62
yihui 1:a9df716f8a64 63 // Start with block 4 (the first block of sector 1) since sector 0
yihui 1:a9df716f8a64 64 // contains the manufacturer data and it's probably better just
yihui 1:a9df716f8a64 65 // to leave it alone unless you know what you're doing
yihui 1:a9df716f8a64 66 success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
yihui 1:a9df716f8a64 67
yihui 1:a9df716f8a64 68 if (success) {
yihui 1:a9df716f8a64 69 LOG("Sector 1 (Blocks 4..7) has been authenticated\r\n");
yihui 1:a9df716f8a64 70 uint8_t data[16];
yihui 0:21ac4fe1ccf8 71
yihui 1:a9df716f8a64 72 // If you want to write something to block 4 to test with, uncomment
yihui 1:a9df716f8a64 73 // the following line and this text should be read back in a minute
yihui 1:a9df716f8a64 74 // data = { 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0};
yihui 1:a9df716f8a64 75 // success = nfc.mifareclassic_WriteDataBlock (4, data);
yihui 1:a9df716f8a64 76
yihui 1:a9df716f8a64 77 // Try to read the contents of block 4
yihui 1:a9df716f8a64 78 success = nfc.mifareclassic_ReadDataBlock(4, data);
yihui 0:21ac4fe1ccf8 79
yihui 1:a9df716f8a64 80 if (success) {
yihui 1:a9df716f8a64 81 // Data seems to have been read ... spit it out
yihui 1:a9df716f8a64 82 LOG("Reading Block 4:\r\n");
yihui 1:a9df716f8a64 83 for (int i = 0; i < 16; i++) {
yihui 1:a9df716f8a64 84 LOG("%2X ", data[i]);
yihui 1:a9df716f8a64 85 }
yihui 1:a9df716f8a64 86 LOG(" ");
yihui 1:a9df716f8a64 87 for (int i = 0; i < 16; i++) {
yihui 1:a9df716f8a64 88 LOG("%c", (char)data[i]);
yihui 1:a9df716f8a64 89 }
yihui 1:a9df716f8a64 90 LOG("\r\n");
yihui 1:a9df716f8a64 91 } else {
yihui 1:a9df716f8a64 92 LOG("Ooops ... unable to read the requested block. Try another key?\r\n");
yihui 1:a9df716f8a64 93 }
yihui 1:a9df716f8a64 94 } else {
yihui 1:a9df716f8a64 95 LOG("Ooops ... authentication failed: Try another key?\r\n");
yihui 1:a9df716f8a64 96 }
yihui 0:21ac4fe1ccf8 97 }
yihui 0:21ac4fe1ccf8 98
yihui 1:a9df716f8a64 99 if (uidLength == 7) {
yihui 1:a9df716f8a64 100 // We probably have a Mifare Ultralight card ...
yihui 1:a9df716f8a64 101 LOG("Seems to be a Mifare Ultralight tag (7 byte UID)\r\n");
yihui 0:21ac4fe1ccf8 102
yihui 1:a9df716f8a64 103 // Try to read the first general-purpose user page (#4)
yihui 1:a9df716f8a64 104 LOG("Reading page 4\r\n");
yihui 1:a9df716f8a64 105 uint8_t data[32];
yihui 1:a9df716f8a64 106 success = nfc.mifareultralight_ReadPage (4, data);
yihui 1:a9df716f8a64 107 if (success) {
yihui 1:a9df716f8a64 108 // Data seems to have been read ... spit it out
yihui 1:a9df716f8a64 109 for (int i = 0; i < 4; i++) {
yihui 1:a9df716f8a64 110 LOG("%2X ", data[i]);
yihui 1:a9df716f8a64 111 }
yihui 1:a9df716f8a64 112 LOG(" ");
yihui 1:a9df716f8a64 113 for (int i = 0; i < 4; i++) {
yihui 1:a9df716f8a64 114 LOG("%c", (char)data[i]);
yihui 1:a9df716f8a64 115 }
yihui 1:a9df716f8a64 116 LOG("\r\n");
yihui 1:a9df716f8a64 117 } else {
yihui 1:a9df716f8a64 118 LOG("Ooops ... unable to read the requested page!?\r\n");
yihui 1:a9df716f8a64 119 }
yihui 0:21ac4fe1ccf8 120 }
yihui 0:21ac4fe1ccf8 121 }
yihui 1:a9df716f8a64 122
yihui 1:a9df716f8a64 123 wait(3);
yihui 0:21ac4fe1ccf8 124 }
yihui 0:21ac4fe1ccf8 125 }
yihui 1:a9df716f8a64 126