Program to read Write Cards

Dependencies:   MFRC522_Updated mbed

Files at this revision

API Documentation at this revision

Comitter:
shivanandgowdakr
Date:
Tue Sep 11 09:22:09 2018 +0000
Commit message:
RC522 Read Write MIFARE All Card Types

Changed in this revision

Card.cpp Show annotated file Show diff for this revision Revisions of this file
Card.h Show annotated file Show diff for this revision Revisions of this file
MFRC522.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Card.cpp	Tue Sep 11 09:22:09 2018 +0000
@@ -0,0 +1,448 @@
+#include "mbed.h"
+#include "MFRC522.h"
+
+#define     MIFARE_MOSI                 PB_5
+#define     MIFARE_MISO                 PB_4
+#define     MIFARE_SCLK                 PB_3
+#define     MIFARE_CS                   PA_8
+#define     MIFARE_RESET                PB_10
+#define     MIFARE_WAIT                 0.1
+
+
+
+MFRC522    mfrc522   (MIFARE_MOSI,MIFARE_MISO, MIFARE_SCLK, MIFARE_CS, MIFARE_RESET);
+DigitalOut LedGreen(LED1);
+
+bool New_Card=false,Read_Card=false;
+
+char  CARD_UID= {'\0'};
+MFRC522::MIFARE_Key key;
+void MIFARE_Init(void)
+
+{
+    mfrc522.PCD_Init();
+
+}
+
+void getHexa(char checkSum, char *str)
+{
+    char strtemp[3];
+
+    memset(strtemp, 0x00, sizeof(strtemp));
+    sprintf(strtemp, "%02X", checkSum);
+    memcpy(str, strtemp, 2);
+
+    return;
+}
+
+/**
+ * Dumps memory contents of a MIFARE Ultralight PICC.
+ */
+void DumpMifareUltralightToSerial(void)
+{
+    uint8_t status;
+    uint8_t byteCount;
+    uint8_t buffer[18];
+    uint8_t i;
+
+    printf("Page   0  1  2  3");
+    // Try the mpages of the original Ultralight. Ultralight C has more pages.
+    for (uint8_t page = 0; page < 16; page +=4) {
+        // Read pages
+        byteCount = sizeof(buffer);
+        status = mfrc522.MIFARE_Read(page, buffer, &byteCount);
+        if (status != MFRC522::STATUS_OK) {
+            printf("MIFARE_Read() failed: %s \n\r", mfrc522.GetStatusCodeName(status));
+            break;
+        }
+
+        // Dump data
+        for (uint8_t offset = 0; offset < 4; offset++) {
+            i = page + offset;
+            printf(" %2d  ", i); // Pad with spaces
+            for (uint8_t index = 0; index < 4; index++) {
+                i = 4 * offset + index;
+                printf(" %02X ", buffer[i]);
+            }
+
+            printf("\n\r");
+        }
+    }
+} // End PICC_DumpMifareUltralightToSerial()
+
+/**
+ * Dumps memory contents of a sector of a MIFARE Classic PICC.
+ * Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1.
+ * Always uses PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits.
+ */
+void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector)
+{
+    uint8_t status;
+    uint8_t firstBlock;    // Address of lowest address to dump actually last block dumped)
+    uint8_t no_of_blocks;    // Number of blocks in sector
+    bool    isSectorTrailer; // Set to true while handling the "last" (ie highest address) in the sector.
+
+    // The access bits are stored in a peculiar fashion.
+    // There are four groups:
+    //    g[3]  Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)
+    //    g[2]  Access bits for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)
+    //    g[1]  Access bits for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)
+    //    g[0]  Access bits for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)
+    // Each group has access bits [C1 C2 C3]. In this code C1 is MSB and C3 is LSB.
+    // The four CX bits are stored together in a nible cx and an inverted nible cx_.
+    uint8_t c1, c2, c3;      // Nibbles
+    uint8_t c1_, c2_, c3_;   // Inverted nibbles
+    bool    invertedError = false;   // True if one of the inverted nibbles did not match
+    uint8_t g[4];            // Access bits for each of the four groups.
+    uint8_t group;           // 0-3 - active group for access bits
+    bool    firstInGroup;    // True for the first block dumped in the group
+
+    // Determine position and size of sector.
+    if (sector < 32) {
+        // Sectors 0..31 has 4 blocks each
+        no_of_blocks = 4;
+        firstBlock = sector * no_of_blocks;
+    } else if (sector < 40) {
+        // Sectors 32-39 has 16 blocks each
+        no_of_blocks = 16;
+        firstBlock = 128 + (sector - 32) * no_of_blocks;
+    } else {
+        // Illegal input, no MIFARE Classic PICC has more than 40 sectors.
+        return;
+    }
+
+    // Dump blocks, highest address first.
+    uint8_t byteCount;
+    uint8_t buffer[18];
+    uint8_t blockAddr;
+    isSectorTrailer = true;
+    for (uint8_t blockOffset = no_of_blocks - 1; blockOffset > 0; blockOffset--) {
+        blockAddr = firstBlock + blockOffset;
+
+        // Sector number - only on first line
+        if (isSectorTrailer) {
+            printf("  %2d   ", sector);
+        } else {
+            printf("       ");
+        }
+
+        // Block number
+        printf(" %3d  ", blockAddr);
+
+        // Establish encrypted communications before reading the first block
+        if (isSectorTrailer) {
+            status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, uid);
+            if (status != MFRC522::STATUS_OK) {
+                printf("PCD_Authenticate() failed: %s \r\n", mfrc522.GetStatusCodeName(status));
+                return;
+            }
+        }
+
+        // Read block
+        byteCount = sizeof(buffer);
+        status = mfrc522.MIFARE_Read(blockAddr, buffer, &byteCount);
+        if (status != MFRC522::STATUS_OK) {
+            printf("MIFARE_Read() failed: %s \r\n", mfrc522.GetStatusCodeName(status));
+            continue;
+        }
+
+        // Dump data
+        for (uint8_t index = 0; index < 16; index++) {
+            printf(" %3d", buffer[index]);
+//      if ((index % 4) == 3)
+//      {
+//        printf(" ");
+//      }
+        }
+
+        // Parse sector trailer data
+        if (isSectorTrailer) {
+            c1  = buffer[7] >> 4;
+            c2  = buffer[8] & 0xF;
+            c3  = buffer[8] >> 4;
+            c1_ = buffer[6] & 0xF;
+            c2_ = buffer[6] >> 4;
+            c3_ = buffer[7] & 0xF;
+            invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF));
+
+            g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0);
+            g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1);
+            g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2);
+            g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3);
+            isSectorTrailer = false;
+        }
+
+        // Which access group is this block in?
+        if (no_of_blocks == 4) {
+            group = blockOffset;
+            firstInGroup = true;
+        } else {
+            group = blockOffset / 5;
+            firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5);
+        }
+
+        if (firstInGroup) {
+            // Print access bits
+            printf("   [ %d %d %d ] ", (g[group] >> 2) & 1, (g[group] >> 1) & 1, (g[group] >> 0) & 1);
+            if (invertedError) {
+                printf(" Inverted access bits did not match! ");
+            }
+        }
+
+        if (group != 3 && (g[group] == 1 || g[group] == 6)) {
+            // Not a sector trailer, a value block
+            printf(" Addr = 0x%02X, Value = 0x%02X%02X%02X%02X", buffer[12],
+                   buffer[3],
+                   buffer[2],
+                   buffer[1],
+                   buffer[0]);
+        }
+
+        printf("\n\r");
+    }
+
+    return;
+} // End PICC_DumpMifareClassicSectorToSerial()
+/**
+ * Dumps memory contents of a MIFARE Classic PICC.
+ * On success the PICC is halted after dumping the data.
+ */
+void DumpMifareClassicToSerial(MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key)
+{
+    uint8_t no_of_sectors = 0;
+    switch (piccType) {
+        case MFRC522::PICC_TYPE_MIFARE_MINI:
+            // Has 5 sectors * 4 blocks/sector * 16 bytes/block = 320 bytes.
+            no_of_sectors = 5;
+            break;
+
+        case MFRC522::PICC_TYPE_MIFARE_1K:
+            // Has 16 sectors * 4 blocks/sector * 16 bytes/block = 1024 bytes.
+            no_of_sectors = 16;
+            break;
+
+        case MFRC522::PICC_TYPE_MIFARE_4K:
+            // Has (32 sectors * 4 blocks/sector + 8 sectors * 16 blocks/sector) * 16 bytes/block = 4096 bytes.
+            no_of_sectors = 40;
+            break;
+
+        default:
+            // Should not happen. Ignore.
+            break;
+    }
+
+    // Dump sectors, highest address first.
+    if (no_of_sectors) {
+        printf("Sector  Block   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  AccessBits \n\r");
+        printf("----------------------------------------------------------------------------------------- \n\r");
+        for (uint8_t i = no_of_sectors - 1; i > 0; i--) {
+            DumpMifareClassicSectorToSerial(uid, key, i);
+        }
+    }
+
+    mfrc522.PICC_HaltA(); // Halt the PICC before stopping the encrypted session.
+    mfrc522.PCD_StopCrypto1();
+} // End PICC_DumpMifareClassicToSerial()
+
+/**
+ * Dumps debug info about the selected PICC to Serial.
+ * On success the PICC is halted after dumping the data.
+ * For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried.
+ */
+void DumpToSerial(MFRC522::Uid *uid)
+{
+    MFRC522::MIFARE_Key key;
+
+    // UID
+    printf("Card UID: ");
+    for (uint8_t i = 0; i < uid->size; i++) {
+        printf(" %X02", uid->uidByte[i]);
+    }
+    printf("\n\r");
+
+    // PICC type
+    uint8_t piccType = mfrc522.PICC_GetType(uid->sak);
+    printf("PICC Type: %s \n\r", mfrc522.PICC_GetTypeName(piccType));
+
+
+    // Dump contents
+    switch (piccType) {
+        case MFRC522::PICC_TYPE_MIFARE_MINI:
+        case MFRC522::PICC_TYPE_MIFARE_1K:
+        case MFRC522::PICC_TYPE_MIFARE_4K:
+            // All keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
+            for (uint8_t i = 0; i < 6; i++) {
+                key.keyByte[i] = 0xFF;
+            }
+            DumpMifareClassicToSerial(uid, piccType, &key);
+            break;
+
+        case MFRC522::PICC_TYPE_MIFARE_UL:
+            DumpMifareUltralightToSerial();
+            break;
+
+        case MFRC522::PICC_TYPE_ISO_14443_4:
+        case MFRC522::PICC_TYPE_ISO_18092:
+        case MFRC522::PICC_TYPE_MIFARE_PLUS:
+        case MFRC522::PICC_TYPE_TNP3XXX:
+            printf("Dumping memory contents not implemented for that PICC type. \n\r");
+            break;
+
+        case MFRC522::PICC_TYPE_UNKNOWN:
+        case MFRC522::PICC_TYPE_NOT_COMPLETE:
+        default:
+            break; // No memory dump here
+    }
+
+    printf("\n\r");
+
+    mfrc522.PICC_HaltA(); // Already done if it was a MIFARE Classic PICC.
+} // End PICC_DumpToSerial()
+
+
+
+
+void Read_Card_Details(char *CARD_UID)
+{
+    memset(CARD_UID,'\0',9);
+    for (uint8_t i = 0; i < 6; i++)
+        key.keyByte[i] = 0xFF;
+    LedGreen = 1;
+    // Look for new cards
+
+    if (  mfrc522.PICC_IsNewCardPresent()) {
+        wait_ms(50);
+        New_Card=true;
+    }
+
+    // Select one of the cards
+
+    if (  mfrc522.PICC_ReadCardSerial()) {
+
+        wait_ms(50);
+        Read_Card=true;
+    }
+
+    LedGreen = 0;
+    if(Read_Card==true && New_Card==true) {
+        char str1[3],str2[3],str3[3],str4[3];
+        getHexa(mfrc522.uid.uidByte[0], str1);
+        getHexa(mfrc522.uid.uidByte[1], str2);
+        getHexa(mfrc522.uid.uidByte[2], str3);
+        getHexa(mfrc522.uid.uidByte[3], str4);
+        CARD_UID[0]=str4[0];
+        CARD_UID[1]=str4[1];
+        CARD_UID[2]=str3[0];
+        CARD_UID[3]=str3[1];
+        CARD_UID[4]=str2[0];
+        CARD_UID[5]=str2[1];
+        CARD_UID[6]=str1[0];
+        CARD_UID[7]=str1[1];
+        CARD_UID[8]='\0';
+//             printf("CARD_UID here:   %s\r\n",CARD_UID);
+        Read_Card=false;
+        New_Card=false;
+    }
+}
+
+
+
+
+int writeBlock(int blockNumber, uint8_t  arrayAddress[])
+{
+
+    int largestModulo4Number=blockNumber/4*4;
+    int trailerBlock=largestModulo4Number+3;//determine trailer block for the sector
+    if (blockNumber > 2 && (blockNumber+1)%4 == 0) {
+        printf("%d ",blockNumber);    //block number is a trailer block (modulo 4); quit and send error code 2
+        printf(" is a trailer block:\r\n");
+        return 2;
+    }
+    printf("%d",blockNumber);
+    printf(" is a data block:");
+
+    /*****************************************authentication of the desired block for access***********************************************************/
+    uint8_t status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
+
+    if (status != MFRC522::STATUS_OK) {
+        printf("PCD_Authenticate() failed: ");
+        printf("%d\r\n",mfrc522.GetStatusCodeName(status));
+        return 3;//return "3" as error message
+    }
+
+    status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);//valueBlockA is the block number, MIFARE_Write(block number (0-15), byte array containing 16 values, number of bytes in block (=16))
+    //status = mfrc522.MIFARE_Write(9, value1Block, 16);
+    printf("Startus : %d\r\n",status);
+    if (status != MFRC522::STATUS_OK) {
+        printf("MIFARE_Write() failed: ");
+        printf("%d\r\n",mfrc522.GetStatusCodeName(status));
+        return 4;//return "4" as error message
+    }
+//    printf("block was written\r\n");
+}
+
+
+int readBlock(int blockNumber, uint8_t arrayAddress[])
+{
+    int largestModulo4Number=blockNumber/4*4;
+    int trailerBlock=largestModulo4Number+3;//determine trailer block for the sector
+    uint8_t status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
+    if (status != MFRC522::STATUS_OK) {
+        printf("PCD_Authenticate() failed (read): ");
+        printf("%d\r\n",mfrc522.GetStatusCodeName(status));
+        return 3;//return "3" as error message
+    }
+
+    uint8_t buffersize = 18;//we need to define a variable with the read buffer size, since the MIFARE_Read method below needs a pointer to the variable that contains the size...
+    status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize);//&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number
+    if (status != MFRC522::STATUS_OK) {
+        printf("MIFARE_read() failed: ");
+        printf("%d\r\n",mfrc522.GetStatusCodeName(status));
+        return 4;//return "4" as error message
+    }
+//    printf("block was read\r\n");
+}
+
+//This array is used for reading out a block. The MIFARE_Read method requires a buffer that is at least 18 bytes to hold the 16 bytes of a block.
+
+void Read_Write_Card(int block,char * writedata)
+{
+    uint8_t readbackblock[18]= {0};
+    
+    char carduid[10]= {'\0'};
+    MIFARE_Init();
+    Read_Card_Details(carduid);
+    if(carduid[0]!='\0')
+    {
+    
+    for (uint8_t i = 0; i < 6; i++)
+    {
+        key.keyByte[i] = 0xFF;
+        }
+          
+        uint8_t blockcontent[16] ;
+        for(int i=0;i<16;i++)
+        {
+            blockcontent[i]=(uint8_t)writedata[i];
+        }
+
+//        printf("card selected\r\n");
+        writeBlock(block, blockcontent);
+
+      
+      for (int j=0 ; j<16 ; j++)//print the block contents
+         {
+           readbackblock[j]=0;//Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
+         }
+//       printf("\r\n Am here \r\n \r\n"); 
+        readBlock(block, readbackblock);
+         for (int j=0 ; j<16 ; j++)//print the block contents
+         {
+           printf ("%c",(char) readbackblock[j]);//Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
+         }
+//        printf("read block done \r\n");
+    }
+    
+    }
+
+   
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Card.h	Tue Sep 11 09:22:09 2018 +0000
@@ -0,0 +1,14 @@
+#ifndef CARD_H
+#define CARD_H
+#include "mbed.h"
+void MIFARE_Init(void);
+void getHexa(char checkSum, char *str);
+void DumpMifareUltralightToSerial(void);
+void DumpMifareClassicSectorToSerial(MFRC522::Uid *uid, MFRC522::MIFARE_Key *key, uint8_t sector);
+void DumpMifareClassicToSerial(MFRC522::Uid *uid, uint8_t piccType, MFRC522::MIFARE_Key *key);
+void DumpToSerial(MFRC522::Uid *uid);
+void Read_Card_Details(char *CARD_UID);
+int writeBlock(int blockNumber, uint8_t  arrayAddress[]);
+int readBlock(int blockNumber, uint8_t arrayAddress[]);
+void Read_Write_Card(int block,char * writedata);
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MFRC522.lib	Tue Sep 11 09:22:09 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/shivanandgowdakr/code/MFRC522_Updated/#f0aa9cbf7f0e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Sep 11 09:22:09 2018 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+#include "MFRC522.h"
+#include "Card.h"
+
+#define     BUZZER                      PC_13
+DigitalOut buzzer(BUZZER);
+
+    int main() {
+        char card[10]={'\0'};
+        buzzer=0;
+       // Read_Card_Details(card);
+       while(1)
+       {
+         Read_Write_Card(9,"info to write");//info to write < 16 chars
+        }
+        wait(10);
+        printf("************************waiting Here****************************************\r\n");
+     
+       
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Sep 11 09:22:09 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e95d10626187
\ No newline at end of file