test FDRM-KL25Z + RFID-RC522

Dependencies:   MFRC522 mbed

Fork of FRDM_MFRC522 by Martin Olejar

Committer:
AtomX
Date:
Sat Dec 14 21:41:08 2013 +0000
Revision:
0:1d9c7c0b5015
Child:
1:8e41a7b03f45
Created MFRC522 project

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AtomX 0:1d9c7c0b5015 1 #include "mbed.h"
AtomX 0:1d9c7c0b5015 2 #include "MFRC522.h"
AtomX 0:1d9c7c0b5015 3
AtomX 0:1d9c7c0b5015 4 #define BOARD_KL25Z 1
AtomX 0:1d9c7c0b5015 5 //#define BOARD_LPC11U24 1
AtomX 0:1d9c7c0b5015 6
AtomX 0:1d9c7c0b5015 7
AtomX 0:1d9c7c0b5015 8 #if defined(BOARD_KL25Z)
AtomX 0:1d9c7c0b5015 9
AtomX 0:1d9c7c0b5015 10 /* KL25Z Pins for MFRC522 SPI interface */
AtomX 0:1d9c7c0b5015 11 #define SPI_MOSI PTA16
AtomX 0:1d9c7c0b5015 12 #define SPI_MISO PTA17
AtomX 0:1d9c7c0b5015 13 #define SPI_SCLK PTD1
AtomX 0:1d9c7c0b5015 14 #define SPI_CS PTD3
AtomX 0:1d9c7c0b5015 15
AtomX 0:1d9c7c0b5015 16 /* KL25Z Pin for MFRC522 reset */
AtomX 0:1d9c7c0b5015 17 #define MF_RESET PTD2
AtomX 0:1d9c7c0b5015 18
AtomX 0:1d9c7c0b5015 19 /* KL25Z Pins for UART Debug port */
AtomX 0:1d9c7c0b5015 20 #define UART_RX PTA1
AtomX 0:1d9c7c0b5015 21 #define UART_TX PTA2
AtomX 0:1d9c7c0b5015 22
AtomX 0:1d9c7c0b5015 23 #elif defined(BOARD_LPC11U24)
AtomX 0:1d9c7c0b5015 24
AtomX 0:1d9c7c0b5015 25 /* LPC11U24 Pins for MFRC522 SPI interface */
AtomX 0:1d9c7c0b5015 26 #define SPI_MOSI p16
AtomX 0:1d9c7c0b5015 27 #define SPI_MISO p15
AtomX 0:1d9c7c0b5015 28 #define SPI_SCLK p13
AtomX 0:1d9c7c0b5015 29 #define SPI_CS p34
AtomX 0:1d9c7c0b5015 30
AtomX 0:1d9c7c0b5015 31 /* LPC11U24 Pin for MFRC522 reset */
AtomX 0:1d9c7c0b5015 32 #define MF_RESET p17
AtomX 0:1d9c7c0b5015 33
AtomX 0:1d9c7c0b5015 34 /* LPC11U24 Pins for UART Debug port */
AtomX 0:1d9c7c0b5015 35 #define UART_RX p20
AtomX 0:1d9c7c0b5015 36 #define UART_TX p19
AtomX 0:1d9c7c0b5015 37
AtomX 0:1d9c7c0b5015 38 #endif
AtomX 0:1d9c7c0b5015 39
AtomX 0:1d9c7c0b5015 40 Serial DebugUART (UART_TX, UART_RX);
AtomX 0:1d9c7c0b5015 41 MFRC522 RfChip (SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS, MF_RESET);
AtomX 0:1d9c7c0b5015 42
AtomX 0:1d9c7c0b5015 43
AtomX 0:1d9c7c0b5015 44 void DumpMifareClassicToSerial (MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key);
AtomX 0:1d9c7c0b5015 45 void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector);
AtomX 0:1d9c7c0b5015 46 void DumpMifareUltralightToSerial (void);
AtomX 0:1d9c7c0b5015 47
AtomX 0:1d9c7c0b5015 48 /**
AtomX 0:1d9c7c0b5015 49 * Dumps debug info about the selected PICC to Serial.
AtomX 0:1d9c7c0b5015 50 * On success the PICC is halted after dumping the data.
AtomX 0:1d9c7c0b5015 51 * For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried.
AtomX 0:1d9c7c0b5015 52 */
AtomX 0:1d9c7c0b5015 53 void DumpToSerial(MFRC522::Uid *uid)
AtomX 0:1d9c7c0b5015 54 {
AtomX 0:1d9c7c0b5015 55 MFRC522::MIFARE_Key key;
AtomX 0:1d9c7c0b5015 56
AtomX 0:1d9c7c0b5015 57 // UID
AtomX 0:1d9c7c0b5015 58 printf("Card UID:");
AtomX 0:1d9c7c0b5015 59 for (uint8_t i = 0; i < uid->size; i++)
AtomX 0:1d9c7c0b5015 60 {
AtomX 0:1d9c7c0b5015 61 printf(" %X02", uid->uidByte[i]);
AtomX 0:1d9c7c0b5015 62 }
AtomX 0:1d9c7c0b5015 63 printf("\n\r");
AtomX 0:1d9c7c0b5015 64
AtomX 0:1d9c7c0b5015 65 // PICC type
AtomX 0:1d9c7c0b5015 66 uint8_t piccType = RfChip.PICC_GetType(uid->sak);
AtomX 0:1d9c7c0b5015 67 printf("PICC type: %s \n\r", RfChip.PICC_GetTypeName(piccType).c_str());
AtomX 0:1d9c7c0b5015 68
AtomX 0:1d9c7c0b5015 69
AtomX 0:1d9c7c0b5015 70 // Dump contents
AtomX 0:1d9c7c0b5015 71 switch (piccType)
AtomX 0:1d9c7c0b5015 72 {
AtomX 0:1d9c7c0b5015 73 case MFRC522::PICC_TYPE_MIFARE_MINI:
AtomX 0:1d9c7c0b5015 74 case MFRC522::PICC_TYPE_MIFARE_1K:
AtomX 0:1d9c7c0b5015 75 case MFRC522::PICC_TYPE_MIFARE_4K:
AtomX 0:1d9c7c0b5015 76 // All keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
AtomX 0:1d9c7c0b5015 77 for (uint8_t i = 0; i < 6; i++)
AtomX 0:1d9c7c0b5015 78 {
AtomX 0:1d9c7c0b5015 79 key.keyByte[i] = 0xFF;
AtomX 0:1d9c7c0b5015 80 }
AtomX 0:1d9c7c0b5015 81 DumpMifareClassicToSerial(uid, piccType, &key);
AtomX 0:1d9c7c0b5015 82 break;
AtomX 0:1d9c7c0b5015 83
AtomX 0:1d9c7c0b5015 84 case MFRC522::PICC_TYPE_MIFARE_UL:
AtomX 0:1d9c7c0b5015 85 DumpMifareUltralightToSerial();
AtomX 0:1d9c7c0b5015 86 break;
AtomX 0:1d9c7c0b5015 87
AtomX 0:1d9c7c0b5015 88 case MFRC522::PICC_TYPE_ISO_14443_4:
AtomX 0:1d9c7c0b5015 89 case MFRC522::PICC_TYPE_ISO_18092:
AtomX 0:1d9c7c0b5015 90 case MFRC522::PICC_TYPE_MIFARE_PLUS:
AtomX 0:1d9c7c0b5015 91 case MFRC522::PICC_TYPE_TNP3XXX:
AtomX 0:1d9c7c0b5015 92 printf("Dumping memory contents not implemented for that PICC type. \n\r");
AtomX 0:1d9c7c0b5015 93 break;
AtomX 0:1d9c7c0b5015 94
AtomX 0:1d9c7c0b5015 95 case MFRC522::PICC_TYPE_UNKNOWN:
AtomX 0:1d9c7c0b5015 96 case MFRC522::PICC_TYPE_NOT_COMPLETE:
AtomX 0:1d9c7c0b5015 97 default:
AtomX 0:1d9c7c0b5015 98 break; // No memory dump here
AtomX 0:1d9c7c0b5015 99 }
AtomX 0:1d9c7c0b5015 100
AtomX 0:1d9c7c0b5015 101 printf("\n\r");
AtomX 0:1d9c7c0b5015 102
AtomX 0:1d9c7c0b5015 103 RfChip.PICC_HaltA(); // Already done if it was a MIFARE Classic PICC.
AtomX 0:1d9c7c0b5015 104 } // End PICC_DumpToSerial()
AtomX 0:1d9c7c0b5015 105
AtomX 0:1d9c7c0b5015 106 /**
AtomX 0:1d9c7c0b5015 107 * Dumps memory contents of a MIFARE Classic PICC.
AtomX 0:1d9c7c0b5015 108 * On success the PICC is halted after dumping the data.
AtomX 0:1d9c7c0b5015 109 */
AtomX 0:1d9c7c0b5015 110 void DumpMifareClassicToSerial(MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key)
AtomX 0:1d9c7c0b5015 111 {
AtomX 0:1d9c7c0b5015 112 uint8_t no_of_sectors = 0;
AtomX 0:1d9c7c0b5015 113 switch (piccType)
AtomX 0:1d9c7c0b5015 114 {
AtomX 0:1d9c7c0b5015 115 case MFRC522::PICC_TYPE_MIFARE_MINI:
AtomX 0:1d9c7c0b5015 116 // Has 5 sectors * 4 blocks/sector * 16 bytes/block = 320 bytes.
AtomX 0:1d9c7c0b5015 117 no_of_sectors = 5;
AtomX 0:1d9c7c0b5015 118 break;
AtomX 0:1d9c7c0b5015 119
AtomX 0:1d9c7c0b5015 120 case MFRC522::PICC_TYPE_MIFARE_1K:
AtomX 0:1d9c7c0b5015 121 // Has 16 sectors * 4 blocks/sector * 16 bytes/block = 1024 bytes.
AtomX 0:1d9c7c0b5015 122 no_of_sectors = 16;
AtomX 0:1d9c7c0b5015 123 break;
AtomX 0:1d9c7c0b5015 124
AtomX 0:1d9c7c0b5015 125 case MFRC522::PICC_TYPE_MIFARE_4K:
AtomX 0:1d9c7c0b5015 126 // Has (32 sectors * 4 blocks/sector + 8 sectors * 16 blocks/sector) * 16 bytes/block = 4096 bytes.
AtomX 0:1d9c7c0b5015 127 no_of_sectors = 40;
AtomX 0:1d9c7c0b5015 128 break;
AtomX 0:1d9c7c0b5015 129
AtomX 0:1d9c7c0b5015 130 default: // Should not happen. Ignore.
AtomX 0:1d9c7c0b5015 131 break;
AtomX 0:1d9c7c0b5015 132 }
AtomX 0:1d9c7c0b5015 133
AtomX 0:1d9c7c0b5015 134 // Dump sectors, highest address first.
AtomX 0:1d9c7c0b5015 135 if (no_of_sectors)
AtomX 0:1d9c7c0b5015 136 {
AtomX 0:1d9c7c0b5015 137 printf("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits \n\r");
AtomX 0:1d9c7c0b5015 138 for (uint8_t i = no_of_sectors - 1; i >= 0; i--)
AtomX 0:1d9c7c0b5015 139 {
AtomX 0:1d9c7c0b5015 140 DumpMifareClassicSectorToSerial(uid, key, i);
AtomX 0:1d9c7c0b5015 141 }
AtomX 0:1d9c7c0b5015 142 }
AtomX 0:1d9c7c0b5015 143
AtomX 0:1d9c7c0b5015 144 RfChip.PICC_HaltA(); // Halt the PICC before stopping the encrypted session.
AtomX 0:1d9c7c0b5015 145 RfChip.PCD_StopCrypto1();
AtomX 0:1d9c7c0b5015 146 } // End PICC_DumpMifareClassicToSerial()
AtomX 0:1d9c7c0b5015 147
AtomX 0:1d9c7c0b5015 148 /**
AtomX 0:1d9c7c0b5015 149 * Dumps memory contents of a sector of a MIFARE Classic PICC.
AtomX 0:1d9c7c0b5015 150 * Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1.
AtomX 0:1d9c7c0b5015 151 * Always uses PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits.
AtomX 0:1d9c7c0b5015 152 */
AtomX 0:1d9c7c0b5015 153 void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector)
AtomX 0:1d9c7c0b5015 154 {
AtomX 0:1d9c7c0b5015 155 uint8_t status;
AtomX 0:1d9c7c0b5015 156 uint8_t firstBlock; // Address of lowest address to dump actually last block dumped)
AtomX 0:1d9c7c0b5015 157 uint8_t no_of_blocks; // Number of blocks in sector
AtomX 0:1d9c7c0b5015 158 bool isSectorTrailer; // Set to true while handling the "last" (ie highest address) in the sector.
AtomX 0:1d9c7c0b5015 159
AtomX 0:1d9c7c0b5015 160 // The access bits are stored in a peculiar fashion.
AtomX 0:1d9c7c0b5015 161 // There are four groups:
AtomX 0:1d9c7c0b5015 162 // g[3] Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 163 // g[2] Access bits for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 164 // g[1] Access bits for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 165 // g[0] Access bits for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 166 // Each group has access bits [C1 C2 C3]. In this code C1 is MSB and C3 is LSB.
AtomX 0:1d9c7c0b5015 167 // The four CX bits are stored together in a nible cx and an inverted nible cx_.
AtomX 0:1d9c7c0b5015 168 uint8_t c1, c2, c3; // Nibbles
AtomX 0:1d9c7c0b5015 169 uint8_t c1_, c2_, c3_; // Inverted nibbles
AtomX 0:1d9c7c0b5015 170 bool invertedError; // True if one of the inverted nibbles did not match
AtomX 0:1d9c7c0b5015 171 uint8_t g[4]; // Access bits for each of the four groups.
AtomX 0:1d9c7c0b5015 172 uint8_t group; // 0-3 - active group for access bits
AtomX 0:1d9c7c0b5015 173 bool firstInGroup; // True for the first block dumped in the group
AtomX 0:1d9c7c0b5015 174
AtomX 0:1d9c7c0b5015 175 // Determine position and size of sector.
AtomX 0:1d9c7c0b5015 176 if (sector < 32)
AtomX 0:1d9c7c0b5015 177 { // Sectors 0..31 has 4 blocks each
AtomX 0:1d9c7c0b5015 178 no_of_blocks = 4;
AtomX 0:1d9c7c0b5015 179 firstBlock = sector * no_of_blocks;
AtomX 0:1d9c7c0b5015 180 }
AtomX 0:1d9c7c0b5015 181 else if (sector < 40)
AtomX 0:1d9c7c0b5015 182 { // Sectors 32-39 has 16 blocks each
AtomX 0:1d9c7c0b5015 183 no_of_blocks = 16;
AtomX 0:1d9c7c0b5015 184 firstBlock = 128 + (sector - 32) * no_of_blocks;
AtomX 0:1d9c7c0b5015 185 }
AtomX 0:1d9c7c0b5015 186 else
AtomX 0:1d9c7c0b5015 187 { // Illegal input, no MIFARE Classic PICC has more than 40 sectors.
AtomX 0:1d9c7c0b5015 188 return;
AtomX 0:1d9c7c0b5015 189 }
AtomX 0:1d9c7c0b5015 190
AtomX 0:1d9c7c0b5015 191 // Dump blocks, highest address first.
AtomX 0:1d9c7c0b5015 192 uint8_t byteCount;
AtomX 0:1d9c7c0b5015 193 uint8_t buffer[18];
AtomX 0:1d9c7c0b5015 194 uint8_t blockAddr;
AtomX 0:1d9c7c0b5015 195 isSectorTrailer = true;
AtomX 0:1d9c7c0b5015 196 for (char blockOffset = no_of_blocks - 1; blockOffset >= 0; blockOffset--)
AtomX 0:1d9c7c0b5015 197 {
AtomX 0:1d9c7c0b5015 198 blockAddr = firstBlock + blockOffset;
AtomX 0:1d9c7c0b5015 199 // Sector number - only on first line
AtomX 0:1d9c7c0b5015 200 if (isSectorTrailer)
AtomX 0:1d9c7c0b5015 201 {
AtomX 0:1d9c7c0b5015 202 printf(" %2d ", sector);
AtomX 0:1d9c7c0b5015 203 }
AtomX 0:1d9c7c0b5015 204 else
AtomX 0:1d9c7c0b5015 205 {
AtomX 0:1d9c7c0b5015 206 printf(" ");
AtomX 0:1d9c7c0b5015 207 }
AtomX 0:1d9c7c0b5015 208 // Block number
AtomX 0:1d9c7c0b5015 209 printf(" %3d ", blockAddr);
AtomX 0:1d9c7c0b5015 210 // Establish encrypted communications before reading the first block
AtomX 0:1d9c7c0b5015 211 if (isSectorTrailer)
AtomX 0:1d9c7c0b5015 212 {
AtomX 0:1d9c7c0b5015 213 status = RfChip.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, uid);
AtomX 0:1d9c7c0b5015 214 if (status != MFRC522::STATUS_OK)
AtomX 0:1d9c7c0b5015 215 {
AtomX 0:1d9c7c0b5015 216 printf("PCD_Authenticate() failed: %s \r\n", RfChip.GetStatusCodeName(status).c_str());
AtomX 0:1d9c7c0b5015 217 return;
AtomX 0:1d9c7c0b5015 218 }
AtomX 0:1d9c7c0b5015 219 }
AtomX 0:1d9c7c0b5015 220 // Read block
AtomX 0:1d9c7c0b5015 221 byteCount = sizeof(buffer);
AtomX 0:1d9c7c0b5015 222 status = RfChip.MIFARE_Read(blockAddr, buffer, &byteCount);
AtomX 0:1d9c7c0b5015 223 if (status != MFRC522::STATUS_OK)
AtomX 0:1d9c7c0b5015 224 {
AtomX 0:1d9c7c0b5015 225 printf("MIFARE_Read() failed: %s \r\n", RfChip.GetStatusCodeName(status).c_str());
AtomX 0:1d9c7c0b5015 226 continue;
AtomX 0:1d9c7c0b5015 227 }
AtomX 0:1d9c7c0b5015 228 // Dump data
AtomX 0:1d9c7c0b5015 229 for (uint8_t index = 0; index < 16; index++)
AtomX 0:1d9c7c0b5015 230 {
AtomX 0:1d9c7c0b5015 231 printf(" %2d", buffer[index]);
AtomX 0:1d9c7c0b5015 232 if ((index % 4) == 3)
AtomX 0:1d9c7c0b5015 233 {
AtomX 0:1d9c7c0b5015 234 printf(" ");
AtomX 0:1d9c7c0b5015 235 }
AtomX 0:1d9c7c0b5015 236 }
AtomX 0:1d9c7c0b5015 237 // Parse sector trailer data
AtomX 0:1d9c7c0b5015 238 if (isSectorTrailer)
AtomX 0:1d9c7c0b5015 239 {
AtomX 0:1d9c7c0b5015 240 c1 = buffer[7] >> 4;
AtomX 0:1d9c7c0b5015 241 c2 = buffer[8] & 0xF;
AtomX 0:1d9c7c0b5015 242 c3 = buffer[8] >> 4;
AtomX 0:1d9c7c0b5015 243 c1_ = buffer[6] & 0xF;
AtomX 0:1d9c7c0b5015 244 c2_ = buffer[6] >> 4;
AtomX 0:1d9c7c0b5015 245 c3_ = buffer[7] & 0xF;
AtomX 0:1d9c7c0b5015 246 invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF));
AtomX 0:1d9c7c0b5015 247
AtomX 0:1d9c7c0b5015 248 g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0);
AtomX 0:1d9c7c0b5015 249 g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1);
AtomX 0:1d9c7c0b5015 250 g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2);
AtomX 0:1d9c7c0b5015 251 g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3);
AtomX 0:1d9c7c0b5015 252 isSectorTrailer = false;
AtomX 0:1d9c7c0b5015 253 }
AtomX 0:1d9c7c0b5015 254
AtomX 0:1d9c7c0b5015 255 // Which access group is this block in?
AtomX 0:1d9c7c0b5015 256 if (no_of_blocks == 4)
AtomX 0:1d9c7c0b5015 257 {
AtomX 0:1d9c7c0b5015 258 group = blockOffset;
AtomX 0:1d9c7c0b5015 259 firstInGroup = true;
AtomX 0:1d9c7c0b5015 260 }
AtomX 0:1d9c7c0b5015 261 else
AtomX 0:1d9c7c0b5015 262 {
AtomX 0:1d9c7c0b5015 263 group = blockOffset / 5;
AtomX 0:1d9c7c0b5015 264 firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5);
AtomX 0:1d9c7c0b5015 265 }
AtomX 0:1d9c7c0b5015 266
AtomX 0:1d9c7c0b5015 267 if (firstInGroup)
AtomX 0:1d9c7c0b5015 268 {
AtomX 0:1d9c7c0b5015 269 // Print access bits
AtomX 0:1d9c7c0b5015 270 printf(" [ %d %d %d ] ", (g[group] >> 2) & 1, (g[group] >> 1) & 1, (g[group] >> 0) & 1);
AtomX 0:1d9c7c0b5015 271 if (invertedError)
AtomX 0:1d9c7c0b5015 272 {
AtomX 0:1d9c7c0b5015 273 printf(" Inverted access bits did not match! ");
AtomX 0:1d9c7c0b5015 274 }
AtomX 0:1d9c7c0b5015 275 }
AtomX 0:1d9c7c0b5015 276
AtomX 0:1d9c7c0b5015 277 if (group != 3 && (g[group] == 1 || g[group] == 6))
AtomX 0:1d9c7c0b5015 278 { // Not a sector trailer, a value block
AtomX 0:1d9c7c0b5015 279 printf(" Addr = 0x%02X, Value = 0x%02X%02X%02X%02X", buffer[12],
AtomX 0:1d9c7c0b5015 280 buffer[3],
AtomX 0:1d9c7c0b5015 281 buffer[2],
AtomX 0:1d9c7c0b5015 282 buffer[1],
AtomX 0:1d9c7c0b5015 283 buffer[0]);
AtomX 0:1d9c7c0b5015 284 }
AtomX 0:1d9c7c0b5015 285
AtomX 0:1d9c7c0b5015 286 printf("\n\r");
AtomX 0:1d9c7c0b5015 287 }
AtomX 0:1d9c7c0b5015 288
AtomX 0:1d9c7c0b5015 289 return;
AtomX 0:1d9c7c0b5015 290 } // End PICC_DumpMifareClassicSectorToSerial()
AtomX 0:1d9c7c0b5015 291
AtomX 0:1d9c7c0b5015 292 /**
AtomX 0:1d9c7c0b5015 293 * Dumps memory contents of a MIFARE Ultralight PICC.
AtomX 0:1d9c7c0b5015 294 */
AtomX 0:1d9c7c0b5015 295 void DumpMifareUltralightToSerial(void)
AtomX 0:1d9c7c0b5015 296 {
AtomX 0:1d9c7c0b5015 297 uint8_t status;
AtomX 0:1d9c7c0b5015 298 uint8_t byteCount;
AtomX 0:1d9c7c0b5015 299 uint8_t buffer[18];
AtomX 0:1d9c7c0b5015 300 uint8_t i;
AtomX 0:1d9c7c0b5015 301
AtomX 0:1d9c7c0b5015 302 printf("Page 0 1 2 3");
AtomX 0:1d9c7c0b5015 303 // Try the mpages of the original Ultralight. Ultralight C has more pages.
AtomX 0:1d9c7c0b5015 304 for (uint8_t page = 0; page < 16; page +=4)
AtomX 0:1d9c7c0b5015 305 {
AtomX 0:1d9c7c0b5015 306 // Read pages
AtomX 0:1d9c7c0b5015 307 byteCount = sizeof(buffer);
AtomX 0:1d9c7c0b5015 308 status = RfChip.MIFARE_Read(page, buffer, &byteCount);
AtomX 0:1d9c7c0b5015 309 if (status != MFRC522::STATUS_OK)
AtomX 0:1d9c7c0b5015 310 {
AtomX 0:1d9c7c0b5015 311 printf("MIFARE_Read() failed: %s \n\r", RfChip.GetStatusCodeName(status).c_str());
AtomX 0:1d9c7c0b5015 312 break;
AtomX 0:1d9c7c0b5015 313 }
AtomX 0:1d9c7c0b5015 314
AtomX 0:1d9c7c0b5015 315 // Dump data
AtomX 0:1d9c7c0b5015 316 for (uint8_t offset = 0; offset < 4; offset++)
AtomX 0:1d9c7c0b5015 317 {
AtomX 0:1d9c7c0b5015 318 i = page + offset;
AtomX 0:1d9c7c0b5015 319 printf(" %2d ", i); // Pad with spaces
AtomX 0:1d9c7c0b5015 320 for (uint8_t index = 0; index < 4; index++)
AtomX 0:1d9c7c0b5015 321 {
AtomX 0:1d9c7c0b5015 322 i = 4 * offset + index;
AtomX 0:1d9c7c0b5015 323 printf(" %02X ", buffer[i]);
AtomX 0:1d9c7c0b5015 324 }
AtomX 0:1d9c7c0b5015 325
AtomX 0:1d9c7c0b5015 326 printf("\n\r");
AtomX 0:1d9c7c0b5015 327 }
AtomX 0:1d9c7c0b5015 328 }
AtomX 0:1d9c7c0b5015 329 } // End PICC_DumpMifareUltralightToSerial()
AtomX 0:1d9c7c0b5015 330
AtomX 0:1d9c7c0b5015 331 int main()
AtomX 0:1d9c7c0b5015 332 {
AtomX 0:1d9c7c0b5015 333 DebugUART.baud(115200);
AtomX 0:1d9c7c0b5015 334
AtomX 0:1d9c7c0b5015 335 RfChip.PCD_Init();
AtomX 0:1d9c7c0b5015 336
AtomX 0:1d9c7c0b5015 337 while(1)
AtomX 0:1d9c7c0b5015 338 {
AtomX 0:1d9c7c0b5015 339 // Look for new cards
AtomX 0:1d9c7c0b5015 340 if ( ! RfChip.PICC_IsNewCardPresent())
AtomX 0:1d9c7c0b5015 341 {
AtomX 0:1d9c7c0b5015 342 continue;
AtomX 0:1d9c7c0b5015 343 }
AtomX 0:1d9c7c0b5015 344
AtomX 0:1d9c7c0b5015 345 // Select one of the cards
AtomX 0:1d9c7c0b5015 346 if ( ! RfChip.PICC_ReadCardSerial())
AtomX 0:1d9c7c0b5015 347 {
AtomX 0:1d9c7c0b5015 348 continue;
AtomX 0:1d9c7c0b5015 349 }
AtomX 0:1d9c7c0b5015 350
AtomX 0:1d9c7c0b5015 351 // Dump debug info about the card. PICC_HaltA() is automatically called.
AtomX 0:1d9c7c0b5015 352 DumpToSerial(&(RfChip.uid));
AtomX 0:1d9c7c0b5015 353 }
AtomX 0:1d9c7c0b5015 354 }