class MFRC522: # RST Pin number,default 22 NRSTPD = 22 MAX_LEN = 16 # RC522命令字 PCD_IDLE = 0x00 PCD_AUTHENT = 0x0E PCD_RECEIVE = 0x08 PCD_TRANSMIT = 0x04 PCD_TRANSCEIVE = 0x0C PCD_RESETPHASE = 0x0F PCD_CALCCRC = 0x03 # PICC命令字 PICC_REQIDL = 0x26 PICC_REQALL = 0x52 PICC_ANTICOLL = 0x93 PICC_SElECTTAG = 0x93 PICC_AUTHENT1A = 0x60 PICC_AUTHENT1B = 0x61 PICC_READ = 0x30 PICC_WRITE = 0xA0 PICC_DECREMENT = 0xC0 PICC_INCREMENT = 0xC1 PICC_RESTORE = 0xC2 PICC_TRANSFER = 0xB0 PICC_HALT = 0x50 # 返回状态 MI_OK = 0 MI_NO_TAG_ERR = 1 MI_ERR = 2 # RC522寄存器地址 Reserved00 = 0x00 CommandReg = 0x01 CommIEnReg = 0x02 DivlEnReg = 0x03 CommIrqReg = 0x04 DivIrqReg = 0x05 ErrorReg = 0x06 Status1Reg = 0x07 Status2Reg = 0x08 FIFODataReg = 0x09 FIFOLevelReg = 0x0A WaterLevelReg = 0x0B ControlReg = 0x0C BitFramingReg = 0x0D CollReg = 0x0E Reserved01 = 0x0F Reserved10 = 0x10 ModeReg = 0x11 TxModeReg = 0x12 RxModeReg = 0x13 TxControlReg = 0x14 TxAutoReg = 0x15 TxSelReg = 0x16 RxSelReg = 0x17 RxThresholdReg = 0x18 DemodReg = 0x19 Reserved11 = 0x1A Reserved12 = 0x1B MifareReg = 0x1C Reserved13 = 0x1D Reserved14 = 0x1E SerialSpeedReg = 0x1F Reserved20 = 0x20 CRCResultRegM = 0x21 CRCResultRegL = 0x22 Reserved21 = 0x23 ModWidthReg = 0x24 Reserved22 = 0x25 RFCfgReg = 0x26 GsNReg = 0x27 CWGsPReg = 0x28 ModGsPReg = 0x29 TModeReg = 0x2A TPrescalerReg = 0x2B TReloadRegH = 0x2C TReloadRegL = 0x2D TCounterValueRegH = 0x2E TCounterValueRegL = 0x2F Reserved30 = 0x30 TestSel1Reg = 0x31 TestSel2Reg = 0x32 TestPinEnReg = 0x33 TestPinValueReg = 0x34 TestBusReg = 0x35 AutoTestReg = 0x36 VersionReg = 0x37 AnalogTestReg = 0x38 TestDAC1Reg = 0x39 TestDAC2Reg = 0x3A TestADCReg = 0x3B Reserved31 = 0x3C Reserved32 = 0x3D Reserved33 = 0x3E Reserved34 = 0x3F def __init__(self, dev='/dev/spidev0.0', speed=1000000): self.__spiDev = SPI(device=dev, speed=speed) self.MFRC522_Init() def __debug(self, s): # print (s) pass # 复位读卡器 def MFRC522_Reset(self): self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE) # 向读卡器中写数据 def Write_MFRC522(self, addr, val): self.__spiDev.transfer(((addr << 1) & 0x7E, val)) # 读取读卡器中的数据 def Read_MFRC522(self, addr): val = self.__spiDev.transfer((((addr << 1) & 0x7E) | 0x80, 0)) return val[1] # 设置位掩码 def SetBitMask(self, reg, mask): tmp = self.Read_MFRC522(reg) self.Write_MFRC522(reg, tmp | mask) # 清除位掩码 def ClearBitMask(self, reg, mask): tmp = self.Read_MFRC522(reg) self.Write_MFRC522(reg, tmp & (~mask)) # 打开天线 def AntennaOn(self): temp = self.Read_MFRC522(self.TxControlReg) if ~(temp & 0x03): self.SetBitMask(self.TxControlReg, 0x03) # 关闭天线 def AntennaOff(self): self.ClearBitMask(self.TxControlReg, 0x03) def MFRC522_ToCard(self, command, sendData): backData = [] backLen = 0 status = self.MI_ERR irqEn = 0x00 waitIRq = 0x00 n = 0 i = 0 if command == self.PCD_AUTHENT: irqEn = 0x12 waitIRq = 0x10 if command == self.PCD_TRANSCEIVE: irqEn = 0x77 waitIRq = 0x30 self.Write_MFRC522(self.CommIEnReg, irqEn | 0x80) self.ClearBitMask(self.CommIrqReg, 0x80) self.SetBitMask(self.FIFOLevelReg, 0x80) self.Write_MFRC522(self.CommandReg, self.PCD_IDLE) while i < len(sendData): self.Write_MFRC522(self.FIFODataReg, sendData[i]) i += 1 self.Write_MFRC522(self.CommandReg, command) if command == self.PCD_TRANSCEIVE: self.SetBitMask(self.BitFramingReg, 0x80) i = 2000 while True: n = self.Read_MFRC522(self.CommIrqReg) i -= 1 if ~((i != 0) and ~(n & 0x01) and ~(n & waitIRq)): break self.ClearBitMask(self.BitFramingReg, 0x80) if i != 0: if (self.Read_MFRC522(self.ErrorReg) & 0x1B) == 0x00: status = self.MI_OK if n & irqEn & 0x01: status = self.MI_NO_TAG_ERR if command == self.PCD_TRANSCEIVE: n = self.Read_MFRC522(self.FIFOLevelReg) lastBits = self.Read_MFRC522(self.ControlReg) & 0x07 if lastBits != 0: backLen = (n - 1) * 8 + lastBits else: backLen = n * 8 if n == 0: n = 1 if n > self.MAX_LEN: n = self.MAX_LEN i = 0 while i < n: backData.append(self.Read_MFRC522(self.FIFODataReg)) i += 1 else: status = self.MI_ERR return status, backData, backLen def MFRC522_Request(self, reqMode): TagType = [] self.Write_MFRC522(self.BitFramingReg, 0x07) TagType.append(reqMode) (status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType) if (status != self.MI_OK) | (backBits != 0x10): status = self.MI_ERR return status, backBits def MFRC522_Anticoll(self): serNumCheck = 0 serNum = [] self.Write_MFRC522(self.BitFramingReg, 0x00) serNum.append(self.PICC_ANTICOLL) serNum.append(0x20) (status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, serNum) if status == self.MI_OK: i = 0 if len(backData) == 5: while i < 4: serNumCheck = serNumCheck ^ backData[i] i += 1 if serNumCheck != backData[i]: status = self.MI_ERR else: status = self.MI_ERR return status, backData # 计算 CRC 值 def CalulateCRC(self, pIndata): self.ClearBitMask(self.DivIrqReg, 0x04) self.SetBitMask(self.FIFOLevelReg, 0x80) i = 0 while i < len(pIndata): self.Write_MFRC522(self.FIFODataReg, pIndata[i]) i += 1 self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC) i = 0xFF while True: n = self.Read_MFRC522(self.DivIrqReg) i -= 1 if not ((i != 0) and not (n & 0x04)): break pOutData = [self.Read_MFRC522(self.CRCResultRegL), self.Read_MFRC522(self.CRCResultRegM)] return pOutData # 选择标签 def MFRC522_SelectTag(self, serNum): buf = [self.PICC_SElECTTAG, 0x70] i = 0 while i < 5: buf.append(serNum[i]) i += 1 pOut = self.CalulateCRC(buf) buf.append(pOut[0]) buf.append(pOut[1]) (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf) if (status == self.MI_OK) and (backLen == 0x18): self.__debug("Size: " + str(backData[0])) return backData[0] else: return 0 def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum): # First byte should be the authMode (A or B) # Second byte is the trailerBlock (usually 7) buff = [authMode, BlockAddr] # Now we need to append the authKey which usually is 6 bytes of 0xFF i = 0 while i < len(Sectorkey): buff.append(Sectorkey[i]) i += 1 i = 0 # Next we append the first 4 bytes of the UID while i < 4: buff.append(serNum[i]) i += 1 # Now we start the authentication itself (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT, buff) # 检查是否发生错误 if not (status == self.MI_OK): self.__debug("AUTH ERROR!!") if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0: self.__debug("AUTH ERROR(status2reg & 0x08) != 0") # 返回状态码 return status def MFRC522_StopCrypto1(self): self.ClearBitMask(self.Status2Reg, 0x08) # 读卡 def MFRC522_Read(self, blockAddr): recvData = [self.PICC_READ, blockAddr] pOut = self.CalulateCRC(recvData) recvData.append(pOut[0]) recvData.append(pOut[1]) status, backData, backLen = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData) return status, backData, backLen # 写卡 def MFRC522_Write(self, blockAddr, writeData): buff = [self.PICC_WRITE, blockAddr] crc = self.CalulateCRC(buff) buff.append(crc[0]) buff.append(crc[1]) status, backData, backLen = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff) if status == self.MI_OK and backLen != 4 and (backData[0] & 0x0F) != 0x0A: status = self.MI_ERR self.__debug(str(backLen) + " backdata &0x0F == 0x0A " + str(backData[0] & 0x0F)) if status == self.MI_OK: i = 0 buf = [] while i < 16: buf.append(writeData[i]) i += 1 crc = self.CalulateCRC(buf) buf.append(crc[0]) buf.append(crc[1]) status, backData, backLen = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf) if status == self.MI_OK and backLen != 4 and (backData[0] & 0x0F) != 0x0A: self.__debug("Error while writing") if status == self.MI_OK: self.__debug("Data written") # 导出1K字节, 64个扇区 def MFRC522_DumpClassic1K(self, key, uid): i = 0 while i < 64: status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid) # 检查是否认证成功 if status == self.MI_OK: self.MFRC522_Read(i) else: self.__debug("Authentication error") i += 1 def MFRC522_Init(self): self.MFRC522_Reset() self.Write_MFRC522(self.TModeReg, 0x8D) self.Write_MFRC522(self.TPrescalerReg, 0x3E) self.Write_MFRC522(self.TReloadRegL, 30) self.Write_MFRC522(self.TReloadRegH, 0) self.Write_MFRC522(self.TxAutoReg, 0x40) self.Write_MFRC522(self.ModeReg, 0x3D) self.AntennaOn()