test FDRM-KL25Z + RFID-RC522

Dependencies:   MFRC522 mbed

Fork of FRDM_MFRC522 by Martin Olejar

Committer:
fblanc
Date:
Thu Feb 12 13:00:53 2015 +0000
Revision:
2:00c97f5dfeaf
Parent:
1:8e41a7b03f45
test ok

Who changed what in which revision?

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