Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of FRDM_MFRC522 by
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
1.7.2
