├── .gitignore ├── MFRC522.py ├── README.md ├── read.py ├── wipe.py └── write.py /.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /docs 3 | /dumps 4 | .DS_Store -------------------------------------------------------------------------------- /MFRC522.py: -------------------------------------------------------------------------------- 1 | # Created by: https://github.com/mxgxw/MFRC522-python/blob/master/MFRC522.py 2 | # Modified by: Tobias Schneider https://github.com/tsndr/ 3 | 4 | import RPi.GPIO as GPIO 5 | import spi 6 | import signal 7 | import time 8 | 9 | class MFRC522: 10 | NRSTPD = 25 11 | 12 | MAX_LEN = 16 13 | 14 | PCD_IDLE = 0x00 15 | PCD_AUTHENT = 0x0E 16 | PCD_RECEIVE = 0x08 17 | PCD_TRANSMIT = 0x04 18 | PCD_TRANSCEIVE = 0x0C 19 | PCD_RESETPHASE = 0x0F 20 | PCD_CALCCRC = 0x03 21 | 22 | PICC_REQIDL = 0x26 23 | PICC_REQALL = 0x52 24 | PICC_ANTICOLL = 0x93 25 | PICC_SELECTTAG = 0x93 26 | PICC_AUTHENT1A = 0x60 27 | PICC_AUTHENT1B = 0x61 28 | PICC_READ = 0x30 29 | PICC_WRITE = 0xA0 30 | PICC_DECREMENT = 0xC0 31 | PICC_INCREMENT = 0xC1 32 | PICC_RESTORE = 0xC2 33 | PICC_TRANSFER = 0xB0 34 | PICC_HALT = 0x50 35 | 36 | MI_OK = 0 37 | MI_NOTAGERR = 1 38 | MI_ERR = 2 39 | 40 | Reserved00 = 0x00 41 | CommandReg = 0x01 42 | CommIEnReg = 0x02 43 | DivlEnReg = 0x03 44 | CommIrqReg = 0x04 45 | DivIrqReg = 0x05 46 | ErrorReg = 0x06 47 | Status1Reg = 0x07 48 | Status2Reg = 0x08 49 | FIFODataReg = 0x09 50 | FIFOLevelReg = 0x0A 51 | WaterLevelReg = 0x0B 52 | ControlReg = 0x0C 53 | BitFramingReg = 0x0D 54 | CollReg = 0x0E 55 | Reserved01 = 0x0F 56 | 57 | Reserved10 = 0x10 58 | ModeReg = 0x11 59 | TxModeReg = 0x12 60 | RxModeReg = 0x13 61 | TxControlReg = 0x14 62 | TxAutoReg = 0x15 63 | TxSelReg = 0x16 64 | RxSelReg = 0x17 65 | RxThresholdReg = 0x18 66 | DemodReg = 0x19 67 | Reserved11 = 0x1A 68 | Reserved12 = 0x1B 69 | MifareReg = 0x1C 70 | Reserved13 = 0x1D 71 | Reserved14 = 0x1E 72 | SerialSpeedReg = 0x1F 73 | 74 | Reserved20 = 0x20 75 | CRCResultRegM = 0x21 76 | CRCResultRegL = 0x22 77 | Reserved21 = 0x23 78 | ModWidthReg = 0x24 79 | Reserved22 = 0x25 80 | RFCfgReg = 0x26 81 | GsNReg = 0x27 82 | CWGsPReg = 0x28 83 | ModGsPReg = 0x29 84 | TModeReg = 0x2A 85 | TPrescalerReg = 0x2B 86 | TReloadRegH = 0x2C 87 | TReloadRegL = 0x2D 88 | TCounterValueRegH = 0x2E 89 | TCounterValueRegL = 0x2F 90 | 91 | Reserved30 = 0x30 92 | TestSel1Reg = 0x31 93 | TestSel2Reg = 0x32 94 | TestPinEnReg = 0x33 95 | TestPinValueReg = 0x34 96 | TestBusReg = 0x35 97 | AutoTestReg = 0x36 98 | VersionReg = 0x37 99 | AnalogTestReg = 0x38 100 | TestDAC1Reg = 0x39 101 | TestDAC2Reg = 0x3A 102 | TestADCReg = 0x3B 103 | Reserved31 = 0x3C 104 | Reserved32 = 0x3D 105 | Reserved33 = 0x3E 106 | Reserved34 = 0x3F 107 | 108 | serNum = [] 109 | 110 | def __init__(self, dev='/dev/spidev0.0', spd=1000000): 111 | spi.openSPI(device=dev,speed=spd) 112 | GPIO.setmode(GPIO.BCM) 113 | GPIO.setup(25, GPIO.OUT) 114 | GPIO.output(self.NRSTPD, 1) 115 | self.Init() 116 | 117 | def Reset(self): 118 | self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE) 119 | 120 | def Write_MFRC522(self, addr, val): 121 | spi.transfer(((addr<<1)&0x7E,val)) 122 | 123 | def Read_MFRC522(self, addr): 124 | val = spi.transfer((((addr<<1)&0x7E) | 0x80,0)) 125 | return val[1] 126 | 127 | def SetBitMask(self, reg, mask): 128 | tmp = self.Read_MFRC522(reg) 129 | self.Write_MFRC522(reg, tmp | mask) 130 | 131 | def ClearBitMask(self, reg, mask): 132 | tmp = self.Read_MFRC522(reg) 133 | self.Write_MFRC522(reg, tmp & (~mask)) 134 | 135 | def AntennaOn(self): 136 | temp = self.Read_MFRC522(self.TxControlReg) 137 | if(~(temp & 0x03)): 138 | self.SetBitMask(self.TxControlReg, 0x03) 139 | 140 | def AntennaOff(self): 141 | self.ClearBitMask(self.TxControlReg, 0x03) 142 | 143 | def ToCard(self,command,sendData): 144 | backData = [] 145 | backLen = 0 146 | status = self.MI_ERR 147 | irqEn = 0x00 148 | waitIRq = 0x00 149 | lastBits = None 150 | n = 0 151 | i = 0 152 | 153 | if command == self.PCD_AUTHENT: 154 | irqEn = 0x12 155 | waitIRq = 0x10 156 | if command == self.PCD_TRANSCEIVE: 157 | irqEn = 0x77 158 | waitIRq = 0x30 159 | 160 | self.Write_MFRC522(self.CommIEnReg, irqEn|0x80) 161 | self.ClearBitMask(self.CommIrqReg, 0x80) 162 | self.SetBitMask(self.FIFOLevelReg, 0x80) 163 | 164 | self.Write_MFRC522(self.CommandReg, self.PCD_IDLE); 165 | 166 | while(i self.MAX_LEN: 202 | n = self.MAX_LEN 203 | 204 | i = 0 205 | while i 0: 28 | message = "Sector [1 - %s]: " % (TagSize - 1) 29 | else: 30 | message = "Sector: " 31 | 32 | try: 33 | Sector = input(message) 34 | except: 35 | print "" 36 | break 37 | else: 38 | print "Waiting for Tag...\n" 39 | 40 | while True: 41 | 42 | (Status, TagSize) = RFID.Request(RFID.PICC_REQIDL) 43 | 44 | if Status != RFID.MI_OK: 45 | continue 46 | 47 | if TagSize < 1: 48 | print("Can't read tag properly!") 49 | break 50 | 51 | if Sector < 1 or Sector > (TagSize - 1): 52 | print "Sector out of range (1 - %s)\n" % (TagSize - 1) 53 | break 54 | 55 | # Selecting blocks 56 | BaseBlockLength = 4 57 | if Sector < 32: 58 | BlockLength = BaseBlockLength 59 | StartAddr = Sector * BlockLength 60 | else: 61 | BlockLength = 16 62 | StartAddr = 32 * BaseBlockLength + (Sector - 32) * BlockLength 63 | 64 | BlockAddrs = [] 65 | for i in range(0, (BlockLength - 1)): 66 | BlockAddrs.append((StartAddr + i)) 67 | TrailerBlockAddr = (StartAddr + (BlockLength - 1)) 68 | 69 | # Initializing tag 70 | (Status, UID) = RFID.Anticoll() 71 | 72 | if Status != RFID.MI_OK: 73 | break 74 | 75 | # Reading sector 76 | RFID.SelectTag(UID) 77 | Status = RFID.Auth(RFID.PICC_AUTHENT1A, TrailerBlockAddr, KEY, UID) 78 | data = [] 79 | text_read = "" 80 | if Status == RFID.MI_OK: 81 | for block_num in BlockAddrs: 82 | block = RFID.Read(block_num) 83 | if block: 84 | data += block 85 | if data: 86 | text_read = "".join(chr(i) for i in data) 87 | print "UID: ", format_uid(UID) 88 | print "Data: ", text_read,"\n" 89 | else: 90 | print "Can't access sector", Sector, "!\n" 91 | RFID.StopCrypto1() 92 | break 93 | 94 | RFID.AntennaOff() 95 | GPIO.cleanup() -------------------------------------------------------------------------------- /wipe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | import RPi.GPIO as GPIO 4 | import MFRC522 5 | 6 | # Keys 7 | DEFAULT_KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] 8 | 9 | # Selecting key 10 | KEY = DEFAULT_KEY 11 | 12 | RFID = MFRC522.MFRC522() 13 | 14 | print("# RFID Wipe\n") 15 | 16 | print("Waiting for tag...\n") 17 | 18 | while True: 19 | 20 | Sector = 1 21 | 22 | while True: 23 | 24 | (Status, TagSize) = RFID.Request(RFID.PICC_REQIDL) 25 | 26 | if Status != RFID.MI_OK: 27 | continue 28 | 29 | if TagSize < 1: 30 | print("Can't read tag properly!") 31 | break 32 | 33 | if Sector >= TagSize: 34 | break 35 | 36 | # Only for formatting 37 | Spacer = "" 38 | if Sector < 10: 39 | Spacer = " " 40 | 41 | print("Wiping sector %s%s ... " % (Spacer, Sector), end="") 42 | 43 | # Selecting blocks 44 | BaseBlockLength = 4 45 | if Sector < 32: 46 | BlockLength = BaseBlockLength 47 | StartAddr = Sector * BlockLength 48 | else: 49 | BlockLength = 16 50 | StartAddr = 32 * BaseBlockLength + (Sector - 32) * BlockLength 51 | 52 | BlockAddrs = [] 53 | for i in range(0, (BlockLength - 1)): 54 | BlockAddrs.append((StartAddr + i)) 55 | TrailerBlockAddr = (StartAddr + (BlockLength - 1)) 56 | 57 | # Initializing tag 58 | (Status, UID) = RFID.Anticoll() 59 | 60 | if Status != RFID.MI_OK: 61 | break 62 | 63 | # Wiping sector 64 | RFID.SelectTag(UID) 65 | Status = RFID.Auth(RFID.PICC_AUTHENT1A, TrailerBlockAddr, KEY, UID) 66 | if Status == RFID.MI_OK: 67 | data = bytearray() 68 | data.extend(bytearray("".ljust(len(BlockAddrs) * 16))) 69 | i = 0 70 | for block_num in BlockAddrs: 71 | RFID.Write(block_num, data[(i*16):(i+1)*16]) 72 | i += 1 73 | print("OK!") 74 | else: 75 | print("NO ACCESS!") 76 | RFID.StopCrypto1() 77 | Sector += 1 78 | 79 | print("\nTag wiped!") 80 | break 81 | 82 | GPIO.cleanup() -------------------------------------------------------------------------------- /write.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import RPi.GPIO as GPIO 3 | import MFRC522 4 | 5 | # Keys 6 | DEFAULT_KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] 7 | 8 | # Selecting key 9 | KEY = DEFAULT_KEY 10 | 11 | def format_uid(uid): 12 | s = "" 13 | for i in range(0, len(uid)): 14 | s += "%x" % uid[i] 15 | return s.upper() 16 | 17 | RFID = MFRC522.MFRC522() 18 | 19 | print "# RFID Writer\n" 20 | print "Info: Leave the sector field empty to exit.\n" 21 | 22 | # Get tag size if available 23 | (status, TagSize) = RFID.Request(RFID.PICC_REQIDL) 24 | 25 | while True: 26 | if TagSize > 0: 27 | message = "Sector [1 - %s]: " % (TagSize - 1) 28 | else: 29 | message = "Sector: " 30 | 31 | try: 32 | Sector = input(message) 33 | except: 34 | print "" 35 | break 36 | else: 37 | if TagSize > 0: 38 | if Sector >= 32: 39 | MaxChars = 16 * 15 40 | else: 41 | MaxChars = 16 * 3 42 | message = "Data [max %s chars]: " % MaxChars 43 | else: 44 | message = "Data: " 45 | try: 46 | text = raw_input(message) 47 | except: 48 | print "\n" 49 | continue 50 | else: 51 | print "Waiting for Tag...\n" 52 | 53 | while True: 54 | (status, TagSize) = RFID.Request(RFID.PICC_REQIDL) 55 | 56 | if status != RFID.MI_OK: 57 | continue 58 | 59 | if Sector < 1 or Sector > (TagSize - 1): 60 | print "Sector out of range (1 - %s)\n" % (TagSize - 1) 61 | break 62 | 63 | # Selecting blocks 64 | BaseBlockLength = 4 65 | if Sector < 32: 66 | BlockLength = BaseBlockLength 67 | StartAddr = Sector * BlockLength 68 | else: 69 | BlockLength = 16 70 | StartAddr = 32 * BaseBlockLength + (Sector - 32) * BlockLength 71 | 72 | BlockAddrs = [] 73 | for i in range(0, (BlockLength - 1)): 74 | BlockAddrs.append((StartAddr + i)) 75 | TrailerBlockAddr = (StartAddr + (BlockLength - 1)) 76 | 77 | # Initializing tag 78 | (Status, UID) = RFID.Anticoll() 79 | 80 | if Status != RFID.MI_OK: 81 | break 82 | 83 | # Writing data 84 | RFID.SelectTag(UID) 85 | status = RFID.Auth(RFID.PICC_AUTHENT1A, TrailerBlockAddr, KEY, UID) 86 | if status == RFID.MI_OK: 87 | data = bytearray() 88 | data.extend(bytearray(text.ljust(len(BlockAddrs) * 16))) 89 | i = 0 90 | for block_num in BlockAddrs: 91 | RFID.Write(block_num, data[(i*16):(i+1)*16]) 92 | i += 1 93 | print "UID: ", format_uid(UID) 94 | print "Data: ", text[0:(len(BlockAddrs) * 16)], "\n" 95 | else: 96 | print "Can't access sector", Sector, "!\n" 97 | RFID.StopCrypto1() 98 | break 99 | 100 | RFID.AntennaOff() 101 | GPIO.cleanup() --------------------------------------------------------------------------------