Use Seeeduino Arch (or Arch Pro) + NFC Shield to read a Mifare Classic tag
Fork of PN532_P2P by
main.cpp@1:a9df716f8a64, 2013-10-17 (annotated)
- 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?
User | Revision | Line number | New 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 |