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

Dependencies:   PN532 mbed

Fork of PN532_P2P by Yihui Xiong

main.cpp

Committer:
yihui
Date:
2013-10-17
Revision:
1:a9df716f8a64
Parent:
0:21ac4fe1ccf8
Child:
2:b238c6772bc4

File content as of revision 1:a9df716f8a64:

#include "mbed.h"
#include "PN532.h"

#if 0   // Output debug message or not
#define LOG(args...)
#else
#include "USBSerial.h"
#define LOG(args...)        pc.printf(args)

USBSerial pc;               // Use USB to Serial
//Serial pc(USBTX, USBRX);
#endif

// PN532(mosi, miso, clk, cs)
PN532 nfc(P1_22, P1_21, P1_20, P0_2);

DigitalOut led1(LED1);

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;
        uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
        uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

        // Wait for an ISO14443A type cards (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]);
            }

            if (uidLength == 4) {
                // We probably have a Mifare Classic card ...
                LOG("Seems to be a Mifare Classic card (4 byte UID)\r\n");

                // Now we need to try to authenticate it for read/write access
                // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
                LOG("Trying to authenticate block 4 with default KEYA value\r\n");
                uint8_t keya[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };

                // Start with block 4 (the first block of sector 1) since sector 0
                // contains the manufacturer data and it's probably better just
                // to leave it alone unless you know what you're doing
                success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);

                if (success) {
                    LOG("Sector 1 (Blocks 4..7) has been authenticated\r\n");
                    uint8_t data[16];

                    // If you want to write something to block 4 to test with, uncomment
                    // the following line and this text should be read back in a minute
                    // data = { 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0};
                    // success = nfc.mifareclassic_WriteDataBlock (4, data);

                    // Try to read the contents of block 4
                    success = nfc.mifareclassic_ReadDataBlock(4, data);

                    if (success) {
                        // Data seems to have been read ... spit it out
                        LOG("Reading Block 4:\r\n");
                        for (int i = 0; i < 16; i++) {
                            LOG("%2X ", data[i]);
                        }
                        LOG("       ");
                        for (int i = 0; i < 16; i++) {
                            LOG("%c", (char)data[i]);
                        }
                        LOG("\r\n");
                    } else {
                        LOG("Ooops ... unable to read the requested block.  Try another key?\r\n");
                    }
                } else {
                    LOG("Ooops ... authentication failed: Try another key?\r\n");
                }
            }

            if (uidLength == 7) {
                // We probably have a Mifare Ultralight card ...
                LOG("Seems to be a Mifare Ultralight tag (7 byte UID)\r\n");

                // Try to read the first general-purpose user page (#4)
                LOG("Reading page 4\r\n");
                uint8_t data[32];
                success = nfc.mifareultralight_ReadPage (4, data);
                if (success) {
                    // Data seems to have been read ... spit it out
                    for (int i = 0; i < 4; i++) {
                            LOG("%2X ", data[i]);
                        }
                        LOG("       ");
                        for (int i = 0; i < 4; i++) {
                            LOG("%c", (char)data[i]);
                        }
                    LOG("\r\n");
                } else {
                    LOG("Ooops ... unable to read the requested page!?\r\n");
                }
            }
        }
        
        wait(3);
    }
}