rtgvc

Dependencies:   MFRC522_new mbed

Fork of Reading_RFID_MFRC522_WIZWiki_W7500 by Biswajit Padhi

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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