
test FDRM-KL25Z + RFID-RC522
Fork of FRDM_MFRC522 by
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /** 00002 * @ version Forks dec 2014 00003 * @date 27/12/2014 00004 * @author F.BLANC 00005 */ 00006 #define VERSION "RFID_2014_12_27" 00007 #include "mbed.h" 00008 #include "MFRC522.h" 00009 00010 #if defined(TARGET_KL25Z) 00011 00012 /* KL25Z Pins for MFRC522 SPI interface */ 00013 #define CIBLE "KL25Z" 00014 #define SPI_MOSI PTD2 00015 #define SPI_MISO PTD3 00016 #define SPI_SCLK PTD1 00017 #define SPI_CS PTD0 00018 00019 /* KL25Z Pin for MFRC522 reset */ 00020 #define MF_RESET PTD5 00021 00022 /* KL25Z Pins for UART Debug port */ 00023 //#define UART_RX PTA1 00024 //#define UART_TX PTA2 00025 #define UART_RX USBRX 00026 #define UART_TX USBTX 00027 #elif defined(TARGET_LPC11U24) 00028 #define CIBLE "LPC11U24" 00029 /* LPC11U24 Pins for MFRC522 SPI interface */ 00030 #define SPI_MOSI P0_9 00031 #define SPI_MISO P0_8 00032 #define SPI_SCLK P1_29 00033 #define SPI_CS P0_2 00034 00035 /* LPC11U24 Pin for MFRC522 reset */ 00036 #define MF_RESET P1_13 00037 00038 /* LPC11U24 Pins for UART Debug port */ 00039 #define UART_RX P0_18 00040 #define UART_TX P0_19 00041 00042 /* LED Pins */ 00043 #define LED_RED P0_7 00044 #define LED_GREEN P1_22 00045 00046 #endif 00047 00048 DigitalOut LedRed (LED_RED); 00049 DigitalOut LedGreen (LED_GREEN); 00050 00051 Serial DebugUART(UART_TX, UART_RX); 00052 MFRC522 RfChip (SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS, MF_RESET); 00053 00054 /* Local functions */ 00055 void DumpMifareClassicToSerial (MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key); 00056 void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector); 00057 void DumpMifareUltralightToSerial (void); 00058 00059 /** 00060 * Dumps debug info about the selected PICC to Serial. 00061 * On success the PICC is halted after dumping the data. 00062 * For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried. 00063 */ 00064 void DumpToSerial(MFRC522::Uid *uid) 00065 { 00066 MFRC522::MIFARE_Key key; 00067 00068 // UID 00069 printf("Card UID: "); 00070 for (uint8_t i = 0; i < uid->size; i++) { 00071 printf(" %X02", uid->uidByte[i]); 00072 } 00073 printf("\n\r"); 00074 00075 // PICC type 00076 uint8_t piccType = RfChip.PICC_GetType(uid->sak); 00077 printf("PICC Type: %s \n\r", RfChip.PICC_GetTypeName(piccType)); 00078 00079 00080 // Dump contents 00081 switch (piccType) { 00082 case MFRC522::PICC_TYPE_MIFARE_MINI: 00083 case MFRC522::PICC_TYPE_MIFARE_1K: 00084 case MFRC522::PICC_TYPE_MIFARE_4K: 00085 // All keys are set to FFFFFFFFFFFFh at chip delivery from the factory. 00086 for (uint8_t i = 0; i < 6; i++) { 00087 key.keyByte[i] = 0xFF; 00088 } 00089 DumpMifareClassicToSerial(uid, piccType, &key); 00090 break; 00091 00092 case MFRC522::PICC_TYPE_MIFARE_UL: 00093 DumpMifareUltralightToSerial(); 00094 break; 00095 case MFRC522::PICC_TYPE_TNP3XXX: 00096 printf("Dumping memory contents not implemented for that PICC type. \n\r"); 00097 break; 00098 case MFRC522::PICC_TYPE_ISO_14443_4: 00099 case MFRC522::PICC_TYPE_ISO_18092: 00100 case MFRC522::PICC_TYPE_MIFARE_PLUS: 00101 printf("Dumping memory contents not implemented for that PICC type. \n\r"); 00102 break; 00103 00104 case MFRC522::PICC_TYPE_UNKNOWN: 00105 case MFRC522::PICC_TYPE_NOT_COMPLETE: 00106 default: 00107 break; // No memory dump here 00108 } 00109 00110 printf("\n\r"); 00111 00112 RfChip.PICC_HaltA(); // Already done if it was a MIFARE Classic PICC. 00113 } // End PICC_DumpToSerial() 00114 00115 /** 00116 * Dumps memory contents of a MIFARE Classic PICC. 00117 * On success the PICC is halted after dumping the data. 00118 */ 00119 void DumpMifareClassicToSerial(MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key) 00120 { 00121 uint8_t no_of_sectors = 0; 00122 switch (piccType) { 00123 case MFRC522::PICC_TYPE_MIFARE_MINI: 00124 // Has 5 sectors * 4 blocks/sector * 16 bytes/block = 320 bytes. 00125 no_of_sectors = 5; 00126 break; 00127 00128 case MFRC522::PICC_TYPE_MIFARE_1K: 00129 // Has 16 sectors * 4 blocks/sector * 16 bytes/block = 1024 bytes. 00130 no_of_sectors = 16; 00131 break; 00132 00133 case MFRC522::PICC_TYPE_MIFARE_4K: 00134 // Has (32 sectors * 4 blocks/sector + 8 sectors * 16 blocks/sector) * 16 bytes/block = 4096 bytes. 00135 no_of_sectors = 40; 00136 break; 00137 00138 default: 00139 // Should not happen. Ignore. 00140 break; 00141 } 00142 00143 // Dump sectors, highest address first. 00144 if (no_of_sectors) { 00145 printf("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits \n\r"); 00146 printf("----------------------------------------------------------------------------------------- \n\r"); 00147 for (uint8_t i = no_of_sectors - 1; i > 0; i--) { 00148 DumpMifareClassicSectorToSerial(uid, key, i); 00149 } 00150 } 00151 00152 RfChip.PICC_HaltA(); // Halt the PICC before stopping the encrypted session. 00153 RfChip.PCD_StopCrypto1(); 00154 } // End PICC_DumpMifareClassicToSerial() 00155 00156 /** 00157 * Dumps memory contents of a sector of a MIFARE Classic PICC. 00158 * Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1. 00159 * Always uses PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits. 00160 */ 00161 void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector) 00162 { 00163 uint8_t status; 00164 uint8_t firstBlock; // Address of lowest address to dump actually last block dumped) 00165 uint8_t no_of_blocks; // Number of blocks in sector 00166 bool isSectorTrailer; // Set to true while handling the "last" (ie highest address) in the sector. 00167 00168 // The access bits are stored in a peculiar fashion. 00169 // There are four groups: 00170 // g[3] Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39) 00171 // g[2] Access bits for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39) 00172 // g[1] Access bits for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39) 00173 // g[0] Access bits for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39) 00174 // Each group has access bits [C1 C2 C3]. In this code C1 is MSB and C3 is LSB. 00175 // The four CX bits are stored together in a nible cx and an inverted nible cx_. 00176 uint8_t c1, c2, c3; // Nibbles 00177 uint8_t c1_, c2_, c3_; // Inverted nibbles 00178 bool invertedError = false; // True if one of the inverted nibbles did not match 00179 uint8_t g[4]; // Access bits for each of the four groups. 00180 uint8_t group; // 0-3 - active group for access bits 00181 bool firstInGroup; // True for the first block dumped in the group 00182 00183 // Determine position and size of sector. 00184 if (sector < 32) { 00185 // Sectors 0..31 has 4 blocks each 00186 no_of_blocks = 4; 00187 firstBlock = sector * no_of_blocks; 00188 } else if (sector < 40) { 00189 // Sectors 32-39 has 16 blocks each 00190 no_of_blocks = 16; 00191 firstBlock = 128 + (sector - 32) * no_of_blocks; 00192 } else { 00193 // Illegal input, no MIFARE Classic PICC has more than 40 sectors. 00194 return; 00195 } 00196 00197 // Dump blocks, highest address first. 00198 uint8_t byteCount; 00199 uint8_t buffer[18]; 00200 uint8_t blockAddr; 00201 isSectorTrailer = true; 00202 for (uint8_t blockOffset = no_of_blocks - 1; blockOffset > 0; blockOffset--) { 00203 blockAddr = firstBlock + blockOffset; 00204 00205 // Sector number - only on first line 00206 if (isSectorTrailer) { 00207 printf(" %2d ", sector); 00208 } else { 00209 printf(" "); 00210 } 00211 00212 // Block number 00213 printf(" %3d ", blockAddr); 00214 00215 // Establish encrypted communications before reading the first block 00216 if (isSectorTrailer) { 00217 status = RfChip.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, uid); 00218 if (status != MFRC522::STATUS_OK) { 00219 printf("PCD_Authenticate() failed: %s \r\n", RfChip.GetStatusCodeName(status)); 00220 return; 00221 } 00222 } 00223 00224 // Read block 00225 byteCount = sizeof(buffer); 00226 status = RfChip.MIFARE_Read(blockAddr, buffer, &byteCount); 00227 if (status != MFRC522::STATUS_OK) { 00228 printf("MIFARE_Read() failed: %s \r\n", RfChip.GetStatusCodeName(status)); 00229 continue; 00230 } 00231 00232 // Dump data 00233 for (uint8_t index = 0; index < 16; index++) { 00234 printf(" %3d", buffer[index]); 00235 // if ((index % 4) == 3) 00236 // { 00237 // printf(" "); 00238 // } 00239 } 00240 00241 // Parse sector trailer data 00242 if (isSectorTrailer) { 00243 c1 = buffer[7] >> 4; 00244 c2 = buffer[8] & 0xF; 00245 c3 = buffer[8] >> 4; 00246 c1_ = buffer[6] & 0xF; 00247 c2_ = buffer[6] >> 4; 00248 c3_ = buffer[7] & 0xF; 00249 invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF)); 00250 00251 g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0); 00252 g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1); 00253 g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2); 00254 g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3); 00255 isSectorTrailer = false; 00256 } 00257 00258 // Which access group is this block in? 00259 if (no_of_blocks == 4) { 00260 group = blockOffset; 00261 firstInGroup = true; 00262 } else { 00263 group = blockOffset / 5; 00264 firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5); 00265 } 00266 00267 if (firstInGroup) { 00268 // Print access bits 00269 printf(" [ %d %d %d ] ", (g[group] >> 2) & 1, (g[group] >> 1) & 1, (g[group] >> 0) & 1); 00270 if (invertedError) { 00271 printf(" Inverted access bits did not match! "); 00272 } 00273 } 00274 00275 if (group != 3 && (g[group] == 1 || g[group] == 6)) { 00276 // Not a sector trailer, a value block 00277 printf(" Addr = 0x%02X, Value = 0x%02X%02X%02X%02X", buffer[12], 00278 buffer[3], 00279 buffer[2], 00280 buffer[1], 00281 buffer[0]); 00282 } 00283 00284 printf("\n\r"); 00285 } 00286 00287 return; 00288 } // End PICC_DumpMifareClassicSectorToSerial() 00289 00290 /** 00291 * Dumps memory contents of a MIFARE Ultralight PICC. 00292 */ 00293 void DumpMifareUltralightToSerial(void) 00294 { 00295 uint8_t status; 00296 uint8_t byteCount; 00297 uint8_t buffer[18]; 00298 uint8_t i; 00299 00300 printf("Page 0 1 2 3"); 00301 // Try the mpages of the original Ultralight. Ultralight C has more pages. 00302 for (uint8_t page = 0; page < 16; page +=4) { 00303 // Read pages 00304 byteCount = sizeof(buffer); 00305 status = RfChip.MIFARE_Read(page, buffer, &byteCount); 00306 if (status != MFRC522::STATUS_OK) { 00307 printf("MIFARE_Read() failed: %s \n\r", RfChip.GetStatusCodeName(status)); 00308 break; 00309 } 00310 00311 // Dump data 00312 for (uint8_t offset = 0; offset < 4; offset++) { 00313 i = page + offset; 00314 printf(" %2d ", i); // Pad with spaces 00315 for (uint8_t index = 0; index < 4; index++) { 00316 i = 4 * offset + index; 00317 printf(" %02X ", buffer[i]); 00318 } 00319 00320 printf("\n\r"); 00321 } 00322 } 00323 } // End PICC_DumpMifareUltralightToSerial() 00324 00325 int main() 00326 { 00327 /* Set debug UART speed */ 00328 printf("\n\rUART 115200 baud\n\r"); 00329 DebugUART.baud(115200); 00330 printf("\n\r%s %s\n\r",VERSION,CIBLE); 00331 00332 /* Init. RC522 Chip */ 00333 RfChip.PCD_Init(); 00334 00335 /* Read RC522 version */ 00336 uint8_t temp = RfChip.PCD_ReadRegister(MFRC522::VersionReg); 00337 printf("MFRC522 version: %d\n\r", temp & 0x07); 00338 printf("\n\r"); 00339 00340 while(1) { 00341 LedRed = 1; 00342 LedGreen = 1; 00343 00344 // Look for new cards 00345 if ( ! RfChip.PICC_IsNewCardPresent()) { 00346 wait_ms(500); 00347 continue; 00348 } 00349 00350 LedRed = 0; 00351 00352 // Select one of the cards 00353 if ( ! RfChip.PICC_ReadCardSerial()) { 00354 wait_ms(500); 00355 continue; 00356 } 00357 00358 LedRed = 1; 00359 LedGreen = 0; 00360 00361 // Dump debug info about the card. PICC_HaltA() is automatically called. 00362 DumpToSerial(&(RfChip.uid)); 00363 wait_ms(200); 00364 } 00365 }
Generated on Sat Jul 16 2022 20:17:16 by
