test FDRM-KL25Z + RFID-RC522

Dependencies:   MFRC522 mbed

Fork of FRDM_MFRC522 by Martin Olejar

Committer:
AtomX
Date:
Wed Dec 18 00:46:40 2013 +0000
Revision:
1:8e41a7b03f45
Parent:
0:1d9c7c0b5015
Child:
2:00c97f5dfeaf
created MFRC522 lib

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 1:8e41a7b03f45 4 #if defined(TARGET_KL25Z)
AtomX 0:1d9c7c0b5015 5
AtomX 0:1d9c7c0b5015 6 /* KL25Z Pins for MFRC522 SPI interface */
AtomX 1:8e41a7b03f45 7 #define SPI_MOSI PTC6
AtomX 1:8e41a7b03f45 8 #define SPI_MISO PTC7
AtomX 1:8e41a7b03f45 9 #define SPI_SCLK PTC5
AtomX 1:8e41a7b03f45 10 #define SPI_CS PTC4
AtomX 0:1d9c7c0b5015 11
AtomX 0:1d9c7c0b5015 12 /* KL25Z Pin for MFRC522 reset */
AtomX 1:8e41a7b03f45 13 #define MF_RESET PTC3
AtomX 0:1d9c7c0b5015 14
AtomX 0:1d9c7c0b5015 15 /* KL25Z Pins for UART Debug port */
AtomX 0:1d9c7c0b5015 16 #define UART_RX PTA1
AtomX 0:1d9c7c0b5015 17 #define UART_TX PTA2
AtomX 0:1d9c7c0b5015 18
AtomX 1:8e41a7b03f45 19 #elif defined(TARGET_LPC11U24)
AtomX 0:1d9c7c0b5015 20
AtomX 0:1d9c7c0b5015 21 /* LPC11U24 Pins for MFRC522 SPI interface */
AtomX 1:8e41a7b03f45 22 #define SPI_MOSI P0_9
AtomX 1:8e41a7b03f45 23 #define SPI_MISO P0_8
AtomX 1:8e41a7b03f45 24 #define SPI_SCLK P1_29
AtomX 1:8e41a7b03f45 25 #define SPI_CS P0_2
AtomX 0:1d9c7c0b5015 26
AtomX 0:1d9c7c0b5015 27 /* LPC11U24 Pin for MFRC522 reset */
AtomX 1:8e41a7b03f45 28 #define MF_RESET P1_13
AtomX 0:1d9c7c0b5015 29
AtomX 0:1d9c7c0b5015 30 /* LPC11U24 Pins for UART Debug port */
AtomX 1:8e41a7b03f45 31 #define UART_RX P0_18
AtomX 1:8e41a7b03f45 32 #define UART_TX P0_19
AtomX 1:8e41a7b03f45 33
AtomX 1:8e41a7b03f45 34 /* LED Pins */
AtomX 1:8e41a7b03f45 35 #define LED_RED P0_7
AtomX 1:8e41a7b03f45 36 #define LED_GREEN P1_22
AtomX 0:1d9c7c0b5015 37
AtomX 0:1d9c7c0b5015 38 #endif
AtomX 0:1d9c7c0b5015 39
AtomX 1:8e41a7b03f45 40 DigitalOut LedRed (LED_RED);
AtomX 1:8e41a7b03f45 41 DigitalOut LedGreen (LED_GREEN);
AtomX 0:1d9c7c0b5015 42
AtomX 1:8e41a7b03f45 43 Serial DebugUART(UART_TX, UART_RX);
AtomX 1:8e41a7b03f45 44 MFRC522 RfChip (SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS, MF_RESET);
AtomX 0:1d9c7c0b5015 45
AtomX 1:8e41a7b03f45 46 /* Local functions */
AtomX 0:1d9c7c0b5015 47 void DumpMifareClassicToSerial (MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key);
AtomX 0:1d9c7c0b5015 48 void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector);
AtomX 0:1d9c7c0b5015 49 void DumpMifareUltralightToSerial (void);
AtomX 0:1d9c7c0b5015 50
AtomX 0:1d9c7c0b5015 51 /**
AtomX 0:1d9c7c0b5015 52 * Dumps debug info about the selected PICC to Serial.
AtomX 0:1d9c7c0b5015 53 * On success the PICC is halted after dumping the data.
AtomX 0:1d9c7c0b5015 54 * For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried.
AtomX 0:1d9c7c0b5015 55 */
AtomX 0:1d9c7c0b5015 56 void DumpToSerial(MFRC522::Uid *uid)
AtomX 0:1d9c7c0b5015 57 {
AtomX 0:1d9c7c0b5015 58 MFRC522::MIFARE_Key key;
AtomX 0:1d9c7c0b5015 59
AtomX 0:1d9c7c0b5015 60 // UID
AtomX 1:8e41a7b03f45 61 printf("Card UID: ");
AtomX 0:1d9c7c0b5015 62 for (uint8_t i = 0; i < uid->size; i++)
AtomX 0:1d9c7c0b5015 63 {
AtomX 0:1d9c7c0b5015 64 printf(" %X02", uid->uidByte[i]);
AtomX 0:1d9c7c0b5015 65 }
AtomX 0:1d9c7c0b5015 66 printf("\n\r");
AtomX 0:1d9c7c0b5015 67
AtomX 0:1d9c7c0b5015 68 // PICC type
AtomX 0:1d9c7c0b5015 69 uint8_t piccType = RfChip.PICC_GetType(uid->sak);
AtomX 1:8e41a7b03f45 70 printf("PICC Type: %s \n\r", RfChip.PICC_GetTypeName(piccType));
AtomX 0:1d9c7c0b5015 71
AtomX 0:1d9c7c0b5015 72
AtomX 0:1d9c7c0b5015 73 // Dump contents
AtomX 0:1d9c7c0b5015 74 switch (piccType)
AtomX 0:1d9c7c0b5015 75 {
AtomX 0:1d9c7c0b5015 76 case MFRC522::PICC_TYPE_MIFARE_MINI:
AtomX 0:1d9c7c0b5015 77 case MFRC522::PICC_TYPE_MIFARE_1K:
AtomX 0:1d9c7c0b5015 78 case MFRC522::PICC_TYPE_MIFARE_4K:
AtomX 0:1d9c7c0b5015 79 // All keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
AtomX 1:8e41a7b03f45 80 for (uint8_t i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; }
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 1:8e41a7b03f45 130 default:
AtomX 1:8e41a7b03f45 131 // Should not happen. Ignore.
AtomX 0:1d9c7c0b5015 132 break;
AtomX 0:1d9c7c0b5015 133 }
AtomX 0:1d9c7c0b5015 134
AtomX 0:1d9c7c0b5015 135 // Dump sectors, highest address first.
AtomX 0:1d9c7c0b5015 136 if (no_of_sectors)
AtomX 0:1d9c7c0b5015 137 {
AtomX 1:8e41a7b03f45 138 printf("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits \n\r");
AtomX 1:8e41a7b03f45 139 printf("----------------------------------------------------------------------------------------- \n\r");
AtomX 1:8e41a7b03f45 140 for (uint8_t i = no_of_sectors - 1; i > 0; i--)
AtomX 0:1d9c7c0b5015 141 {
AtomX 0:1d9c7c0b5015 142 DumpMifareClassicSectorToSerial(uid, key, i);
AtomX 0:1d9c7c0b5015 143 }
AtomX 0:1d9c7c0b5015 144 }
AtomX 0:1d9c7c0b5015 145
AtomX 0:1d9c7c0b5015 146 RfChip.PICC_HaltA(); // Halt the PICC before stopping the encrypted session.
AtomX 0:1d9c7c0b5015 147 RfChip.PCD_StopCrypto1();
AtomX 0:1d9c7c0b5015 148 } // End PICC_DumpMifareClassicToSerial()
AtomX 0:1d9c7c0b5015 149
AtomX 0:1d9c7c0b5015 150 /**
AtomX 0:1d9c7c0b5015 151 * Dumps memory contents of a sector of a MIFARE Classic PICC.
AtomX 0:1d9c7c0b5015 152 * Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1.
AtomX 0:1d9c7c0b5015 153 * Always uses PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits.
AtomX 0:1d9c7c0b5015 154 */
AtomX 0:1d9c7c0b5015 155 void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector)
AtomX 0:1d9c7c0b5015 156 {
AtomX 0:1d9c7c0b5015 157 uint8_t status;
AtomX 0:1d9c7c0b5015 158 uint8_t firstBlock; // Address of lowest address to dump actually last block dumped)
AtomX 0:1d9c7c0b5015 159 uint8_t no_of_blocks; // Number of blocks in sector
AtomX 0:1d9c7c0b5015 160 bool isSectorTrailer; // Set to true while handling the "last" (ie highest address) in the sector.
AtomX 0:1d9c7c0b5015 161
AtomX 0:1d9c7c0b5015 162 // The access bits are stored in a peculiar fashion.
AtomX 0:1d9c7c0b5015 163 // There are four groups:
AtomX 0:1d9c7c0b5015 164 // g[3] Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 165 // g[2] Access bits for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 166 // g[1] Access bits for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 167 // g[0] Access bits for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)
AtomX 0:1d9c7c0b5015 168 // Each group has access bits [C1 C2 C3]. In this code C1 is MSB and C3 is LSB.
AtomX 0:1d9c7c0b5015 169 // The four CX bits are stored together in a nible cx and an inverted nible cx_.
AtomX 0:1d9c7c0b5015 170 uint8_t c1, c2, c3; // Nibbles
AtomX 0:1d9c7c0b5015 171 uint8_t c1_, c2_, c3_; // Inverted nibbles
AtomX 1:8e41a7b03f45 172 bool invertedError = false; // True if one of the inverted nibbles did not match
AtomX 0:1d9c7c0b5015 173 uint8_t g[4]; // Access bits for each of the four groups.
AtomX 0:1d9c7c0b5015 174 uint8_t group; // 0-3 - active group for access bits
AtomX 0:1d9c7c0b5015 175 bool firstInGroup; // True for the first block dumped in the group
AtomX 0:1d9c7c0b5015 176
AtomX 0:1d9c7c0b5015 177 // Determine position and size of sector.
AtomX 0:1d9c7c0b5015 178 if (sector < 32)
AtomX 0:1d9c7c0b5015 179 { // Sectors 0..31 has 4 blocks each
AtomX 0:1d9c7c0b5015 180 no_of_blocks = 4;
AtomX 0:1d9c7c0b5015 181 firstBlock = sector * no_of_blocks;
AtomX 0:1d9c7c0b5015 182 }
AtomX 0:1d9c7c0b5015 183 else if (sector < 40)
AtomX 0:1d9c7c0b5015 184 { // Sectors 32-39 has 16 blocks each
AtomX 0:1d9c7c0b5015 185 no_of_blocks = 16;
AtomX 0:1d9c7c0b5015 186 firstBlock = 128 + (sector - 32) * no_of_blocks;
AtomX 0:1d9c7c0b5015 187 }
AtomX 0:1d9c7c0b5015 188 else
AtomX 0:1d9c7c0b5015 189 { // Illegal input, no MIFARE Classic PICC has more than 40 sectors.
AtomX 0:1d9c7c0b5015 190 return;
AtomX 0:1d9c7c0b5015 191 }
AtomX 0:1d9c7c0b5015 192
AtomX 0:1d9c7c0b5015 193 // Dump blocks, highest address first.
AtomX 0:1d9c7c0b5015 194 uint8_t byteCount;
AtomX 0:1d9c7c0b5015 195 uint8_t buffer[18];
AtomX 0:1d9c7c0b5015 196 uint8_t blockAddr;
AtomX 0:1d9c7c0b5015 197 isSectorTrailer = true;
AtomX 1:8e41a7b03f45 198 for (uint8_t blockOffset = no_of_blocks - 1; blockOffset > 0; blockOffset--)
AtomX 0:1d9c7c0b5015 199 {
AtomX 0:1d9c7c0b5015 200 blockAddr = firstBlock + blockOffset;
AtomX 1:8e41a7b03f45 201
AtomX 0:1d9c7c0b5015 202 // Sector number - only on first line
AtomX 0:1d9c7c0b5015 203 if (isSectorTrailer)
AtomX 0:1d9c7c0b5015 204 {
AtomX 0:1d9c7c0b5015 205 printf(" %2d ", sector);
AtomX 0:1d9c7c0b5015 206 }
AtomX 0:1d9c7c0b5015 207 else
AtomX 0:1d9c7c0b5015 208 {
AtomX 0:1d9c7c0b5015 209 printf(" ");
AtomX 0:1d9c7c0b5015 210 }
AtomX 1:8e41a7b03f45 211
AtomX 0:1d9c7c0b5015 212 // Block number
AtomX 1:8e41a7b03f45 213 printf(" %3d ", blockAddr);
AtomX 1:8e41a7b03f45 214
AtomX 0:1d9c7c0b5015 215 // Establish encrypted communications before reading the first block
AtomX 0:1d9c7c0b5015 216 if (isSectorTrailer)
AtomX 0:1d9c7c0b5015 217 {
AtomX 0:1d9c7c0b5015 218 status = RfChip.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, uid);
AtomX 0:1d9c7c0b5015 219 if (status != MFRC522::STATUS_OK)
AtomX 0:1d9c7c0b5015 220 {
AtomX 1:8e41a7b03f45 221 printf("PCD_Authenticate() failed: %s \r\n", RfChip.GetStatusCodeName(status));
AtomX 0:1d9c7c0b5015 222 return;
AtomX 0:1d9c7c0b5015 223 }
AtomX 0:1d9c7c0b5015 224 }
AtomX 1:8e41a7b03f45 225
AtomX 0:1d9c7c0b5015 226 // Read block
AtomX 0:1d9c7c0b5015 227 byteCount = sizeof(buffer);
AtomX 0:1d9c7c0b5015 228 status = RfChip.MIFARE_Read(blockAddr, buffer, &byteCount);
AtomX 0:1d9c7c0b5015 229 if (status != MFRC522::STATUS_OK)
AtomX 0:1d9c7c0b5015 230 {
AtomX 1:8e41a7b03f45 231 printf("MIFARE_Read() failed: %s \r\n", RfChip.GetStatusCodeName(status));
AtomX 0:1d9c7c0b5015 232 continue;
AtomX 0:1d9c7c0b5015 233 }
AtomX 1:8e41a7b03f45 234
AtomX 0:1d9c7c0b5015 235 // Dump data
AtomX 0:1d9c7c0b5015 236 for (uint8_t index = 0; index < 16; index++)
AtomX 0:1d9c7c0b5015 237 {
AtomX 1:8e41a7b03f45 238 printf(" %3d", buffer[index]);
AtomX 1:8e41a7b03f45 239 // if ((index % 4) == 3)
AtomX 1:8e41a7b03f45 240 // {
AtomX 1:8e41a7b03f45 241 // printf(" ");
AtomX 1:8e41a7b03f45 242 // }
AtomX 0:1d9c7c0b5015 243 }
AtomX 1:8e41a7b03f45 244
AtomX 0:1d9c7c0b5015 245 // Parse sector trailer data
AtomX 0:1d9c7c0b5015 246 if (isSectorTrailer)
AtomX 0:1d9c7c0b5015 247 {
AtomX 0:1d9c7c0b5015 248 c1 = buffer[7] >> 4;
AtomX 0:1d9c7c0b5015 249 c2 = buffer[8] & 0xF;
AtomX 0:1d9c7c0b5015 250 c3 = buffer[8] >> 4;
AtomX 0:1d9c7c0b5015 251 c1_ = buffer[6] & 0xF;
AtomX 0:1d9c7c0b5015 252 c2_ = buffer[6] >> 4;
AtomX 0:1d9c7c0b5015 253 c3_ = buffer[7] & 0xF;
AtomX 0:1d9c7c0b5015 254 invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF));
AtomX 1:8e41a7b03f45 255
AtomX 0:1d9c7c0b5015 256 g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0);
AtomX 0:1d9c7c0b5015 257 g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1);
AtomX 0:1d9c7c0b5015 258 g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2);
AtomX 0:1d9c7c0b5015 259 g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3);
AtomX 0:1d9c7c0b5015 260 isSectorTrailer = false;
AtomX 0:1d9c7c0b5015 261 }
AtomX 0:1d9c7c0b5015 262
AtomX 0:1d9c7c0b5015 263 // Which access group is this block in?
AtomX 0:1d9c7c0b5015 264 if (no_of_blocks == 4)
AtomX 0:1d9c7c0b5015 265 {
AtomX 0:1d9c7c0b5015 266 group = blockOffset;
AtomX 0:1d9c7c0b5015 267 firstInGroup = true;
AtomX 0:1d9c7c0b5015 268 }
AtomX 0:1d9c7c0b5015 269 else
AtomX 0:1d9c7c0b5015 270 {
AtomX 0:1d9c7c0b5015 271 group = blockOffset / 5;
AtomX 0:1d9c7c0b5015 272 firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5);
AtomX 0:1d9c7c0b5015 273 }
AtomX 0:1d9c7c0b5015 274
AtomX 0:1d9c7c0b5015 275 if (firstInGroup)
AtomX 0:1d9c7c0b5015 276 {
AtomX 0:1d9c7c0b5015 277 // Print access bits
AtomX 1:8e41a7b03f45 278 printf(" [ %d %d %d ] ", (g[group] >> 2) & 1, (g[group] >> 1) & 1, (g[group] >> 0) & 1);
AtomX 0:1d9c7c0b5015 279 if (invertedError)
AtomX 0:1d9c7c0b5015 280 {
AtomX 0:1d9c7c0b5015 281 printf(" Inverted access bits did not match! ");
AtomX 0:1d9c7c0b5015 282 }
AtomX 0:1d9c7c0b5015 283 }
AtomX 0:1d9c7c0b5015 284
AtomX 0:1d9c7c0b5015 285 if (group != 3 && (g[group] == 1 || g[group] == 6))
AtomX 0:1d9c7c0b5015 286 { // Not a sector trailer, a value block
AtomX 0:1d9c7c0b5015 287 printf(" Addr = 0x%02X, Value = 0x%02X%02X%02X%02X", buffer[12],
AtomX 0:1d9c7c0b5015 288 buffer[3],
AtomX 0:1d9c7c0b5015 289 buffer[2],
AtomX 0:1d9c7c0b5015 290 buffer[1],
AtomX 0:1d9c7c0b5015 291 buffer[0]);
AtomX 0:1d9c7c0b5015 292 }
AtomX 0:1d9c7c0b5015 293
AtomX 0:1d9c7c0b5015 294 printf("\n\r");
AtomX 0:1d9c7c0b5015 295 }
AtomX 0:1d9c7c0b5015 296
AtomX 0:1d9c7c0b5015 297 return;
AtomX 0:1d9c7c0b5015 298 } // End PICC_DumpMifareClassicSectorToSerial()
AtomX 0:1d9c7c0b5015 299
AtomX 0:1d9c7c0b5015 300 /**
AtomX 0:1d9c7c0b5015 301 * Dumps memory contents of a MIFARE Ultralight PICC.
AtomX 0:1d9c7c0b5015 302 */
AtomX 0:1d9c7c0b5015 303 void DumpMifareUltralightToSerial(void)
AtomX 0:1d9c7c0b5015 304 {
AtomX 0:1d9c7c0b5015 305 uint8_t status;
AtomX 0:1d9c7c0b5015 306 uint8_t byteCount;
AtomX 0:1d9c7c0b5015 307 uint8_t buffer[18];
AtomX 0:1d9c7c0b5015 308 uint8_t i;
AtomX 0:1d9c7c0b5015 309
AtomX 1:8e41a7b03f45 310 printf("Page 0 1 2 3");
AtomX 0:1d9c7c0b5015 311 // Try the mpages of the original Ultralight. Ultralight C has more pages.
AtomX 0:1d9c7c0b5015 312 for (uint8_t page = 0; page < 16; page +=4)
AtomX 0:1d9c7c0b5015 313 {
AtomX 0:1d9c7c0b5015 314 // Read pages
AtomX 0:1d9c7c0b5015 315 byteCount = sizeof(buffer);
AtomX 0:1d9c7c0b5015 316 status = RfChip.MIFARE_Read(page, buffer, &byteCount);
AtomX 0:1d9c7c0b5015 317 if (status != MFRC522::STATUS_OK)
AtomX 0:1d9c7c0b5015 318 {
AtomX 1:8e41a7b03f45 319 printf("MIFARE_Read() failed: %s \n\r", RfChip.GetStatusCodeName(status));
AtomX 0:1d9c7c0b5015 320 break;
AtomX 0:1d9c7c0b5015 321 }
AtomX 0:1d9c7c0b5015 322
AtomX 0:1d9c7c0b5015 323 // Dump data
AtomX 0:1d9c7c0b5015 324 for (uint8_t offset = 0; offset < 4; offset++)
AtomX 0:1d9c7c0b5015 325 {
AtomX 0:1d9c7c0b5015 326 i = page + offset;
AtomX 1:8e41a7b03f45 327 printf(" %2d ", i); // Pad with spaces
AtomX 0:1d9c7c0b5015 328 for (uint8_t index = 0; index < 4; index++)
AtomX 0:1d9c7c0b5015 329 {
AtomX 0:1d9c7c0b5015 330 i = 4 * offset + index;
AtomX 0:1d9c7c0b5015 331 printf(" %02X ", buffer[i]);
AtomX 0:1d9c7c0b5015 332 }
AtomX 0:1d9c7c0b5015 333
AtomX 0:1d9c7c0b5015 334 printf("\n\r");
AtomX 0:1d9c7c0b5015 335 }
AtomX 0:1d9c7c0b5015 336 }
AtomX 0:1d9c7c0b5015 337 } // End PICC_DumpMifareUltralightToSerial()
AtomX 0:1d9c7c0b5015 338
AtomX 0:1d9c7c0b5015 339 int main()
AtomX 0:1d9c7c0b5015 340 {
AtomX 1:8e41a7b03f45 341 /* Set debug UART speed */
AtomX 0:1d9c7c0b5015 342 DebugUART.baud(115200);
AtomX 1:8e41a7b03f45 343 printf("< mbed RFID demo >\n\r");
AtomX 1:8e41a7b03f45 344 printf("\n\r");
AtomX 0:1d9c7c0b5015 345
AtomX 1:8e41a7b03f45 346 /* Init. RC522 Chip */
AtomX 0:1d9c7c0b5015 347 RfChip.PCD_Init();
AtomX 0:1d9c7c0b5015 348
AtomX 1:8e41a7b03f45 349 /* Read RC522 version */
AtomX 1:8e41a7b03f45 350 uint8_t temp = RfChip.PCD_ReadRegister(MFRC522::VersionReg);
AtomX 1:8e41a7b03f45 351 printf("MFRC522 version: %d\n\r", temp & 0x07);
AtomX 1:8e41a7b03f45 352 printf("\n\r");
AtomX 1:8e41a7b03f45 353
AtomX 0:1d9c7c0b5015 354 while(1)
AtomX 0:1d9c7c0b5015 355 {
AtomX 1:8e41a7b03f45 356 LedRed = 1;
AtomX 1:8e41a7b03f45 357 LedGreen = 1;
AtomX 1:8e41a7b03f45 358
AtomX 0:1d9c7c0b5015 359 // Look for new cards
AtomX 0:1d9c7c0b5015 360 if ( ! RfChip.PICC_IsNewCardPresent())
AtomX 0:1d9c7c0b5015 361 {
AtomX 1:8e41a7b03f45 362 wait_ms(500);
AtomX 0:1d9c7c0b5015 363 continue;
AtomX 0:1d9c7c0b5015 364 }
AtomX 0:1d9c7c0b5015 365
AtomX 1:8e41a7b03f45 366 LedRed = 0;
AtomX 1:8e41a7b03f45 367
AtomX 0:1d9c7c0b5015 368 // Select one of the cards
AtomX 0:1d9c7c0b5015 369 if ( ! RfChip.PICC_ReadCardSerial())
AtomX 0:1d9c7c0b5015 370 {
AtomX 1:8e41a7b03f45 371 wait_ms(500);
AtomX 0:1d9c7c0b5015 372 continue;
AtomX 0:1d9c7c0b5015 373 }
AtomX 0:1d9c7c0b5015 374
AtomX 1:8e41a7b03f45 375 LedRed = 1;
AtomX 1:8e41a7b03f45 376 LedGreen = 0;
AtomX 1:8e41a7b03f45 377
AtomX 0:1d9c7c0b5015 378 // Dump debug info about the card. PICC_HaltA() is automatically called.
AtomX 0:1d9c7c0b5015 379 DumpToSerial(&(RfChip.uid));
AtomX 1:8e41a7b03f45 380 wait_ms(200);
AtomX 0:1d9c7c0b5015 381 }
AtomX 0:1d9c7c0b5015 382 }