Quellcode für fusion_hat.modules.rc522

import spidev as SPI
import time

[Doku] class RC522(): PCD_IDLE = 0x00 PCD_AUTHENT = 0x0E PCD_RECEIVE = 0x08 PCD_TRANSMIT = 0x04 PCD_TRANSCEIVE = 0x0C PCD_RESETPHASE = 0x0F PCD_CALCCRC = 0x03 PICC_REQIDL = 0x26 PICC_REQALL = 0x52 PICC_ANTICOLL1 = 0x93 PICC_ANTICOLL2 = 0x95 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 # PAGE 0 RFU00 = 0x00 CommandReg = 0x01 ComIEnReg = 0x02 DivlEnReg = 0x03 ComIrqReg = 0x04 DivIrqReg = 0x05 ErrorReg = 0x06 Status1Reg = 0x07 Status2Reg = 0x08 FIFODataReg = 0x09 FIFOLevelReg = 0x0A WaterLevelReg = 0x0B ControlReg = 0x0C BitFramingReg = 0x0D CollReg = 0x0E RFU0F = 0x0F # PAGE 1 RFU10 = 0x10 ModeReg = 0x11 TxModeReg = 0x12 RxModeReg = 0x13 TxControlReg = 0x14 TxAutoReg = 0x15 TxSelReg = 0x16 RxSelReg = 0x17 RxThresholdReg = 0x18 DemodReg = 0x19 RFU1A = 0x1A RFU1B = 0x1B MifareReg = 0x1C RFU1D = 0x1D RFU1E = 0x1E SerialSpeedReg = 0x1F # PAGE 2 RFU20 = 0x20 CRCResultRegM = 0x21 CRCResultRegL = 0x22 RFU23 = 0x23 ModWidthReg = 0x24 RFU25 = 0x25 RFCfgReg = 0x26 GsNReg = 0x27 CWGsCfgReg = 0x28 ModGsCfgReg = 0x29 TModeReg = 0x2A TPrescalerReg = 0x2B TReloadRegH = 0x2C TReloadRegL = 0x2D TCounterValueRegH = 0x2E TCounterValueRegL = 0x2F # PAGE 3 RFU30 = 0x30 TestSel1Reg = 0x31 TestSel2Reg = 0x32 TestPinEnReg = 0x33 TestPinValueReg = 0x34 TestBusReg = 0x35 AutoTestReg = 0x36 VersionReg = 0x37 AnalogTestReg = 0x38 TestDAC1Reg = 0x39 TestDAC2Reg = 0x3A TestADCReg = 0x3B RFU3C = 0x3C RFU3D = 0x3D RFU3E = 0x3E RFU3F = 0x3F def __init__(self): self.spi = SPI.SpiDev() self.spi.open(0, 0) self.spi.max_speed_hz= 15600000 self.key = [0xff,0xff,0xff,0xff,0xff,0xff] self.ct = [0x0]*2 self.sn = [0x0]*4
[Doku] def Pcd_start(self): self.PcdReset() self.PcdAntennaOff() time.sleep(0.02) self.PcdAntennaOn() self.M500PcdConfigISOType( 'A' )
[Doku] def WriteRawRC(self, reg, Value): addr = (reg<<1) & 0x7e li = [addr, Value] self.spi.xfer2(li)
[Doku] def ReadRawRC(self, reg): addr = ((reg<<1) & 0xfe) | 0x80 li = [addr, 0xFF] value = self.spi.xfer2(li) return value[1]
[Doku] def SetBitMask(self, reg, data): tmp = self.ReadRawRC(reg) self.WriteRawRC(reg, tmp | data)
[Doku] def ClearBitMask(self, reg, data): tmp = self.ReadRawRC(reg) self.WriteRawRC(reg, tmp & ~data)
[Doku] def PcdAntennaOn(self): i = self.ReadRawRC(self.TxControlReg) if (i & 0x03) == 0: self.SetBitMask(self.TxControlReg, 0x03)
[Doku] def PcdAntennaOff(self): self.ClearBitMask(self.TxControlReg, 0x03)
[Doku] def PcdReset(self): self.WriteRawRC(self.CommandReg, self.PCD_RESETPHASE) self.WriteRawRC(self.CommandReg, self.PCD_RESETPHASE) # time.sleep(0.01) self.WriteRawRC(self.ModeReg, 0x3D) self.WriteRawRC(self.TReloadRegL, 30) self.WriteRawRC(self.TReloadRegH, 0) self.WriteRawRC(self.TModeReg, 0x8D) self.WriteRawRC(self.TPrescalerReg, 0x3E) self.WriteRawRC(self.TxAutoReg, 0x40)
[Doku] def M500PcdConfigISOType(self, ty): if ty == 'A': self.ClearBitMask(self.Status2Reg, 0x08) self.WriteRawRC(self.ModeReg, 0x3D) self.WriteRawRC(self.RxSelReg, 0x86) self.WriteRawRC(self.RFCfgReg, 0x7F) self.WriteRawRC(self.TReloadRegL, 30) self.WriteRawRC(self.TReloadRegH, 0) self.WriteRawRC(self.TModeReg, 0x8D) self.WriteRawRC(self.TPrescalerReg, 0x3E) time.sleep(1) self.PcdAntennaOn() else: return 1 return 0
[Doku] def CalulateCRC(self, data): self.ClearBitMask(self.DivIrqReg, 0x04) self.WriteRawRC(self.CommandReg, self.PCD_IDLE) self.SetBitMask(self.FIFOLevelReg, 0x80) for i in range(len(data)): self.WriteRawRC(self.FIFODataReg, data[i]) self.WriteRawRC(self.CommandReg, self.PCD_CALCCRC) j = 0xff n = 0 while j != 0 and not(n & 0x04): n = self.ReadRawRC(self.DivIrqReg) j -=1 data.append(self.ReadRawRC(self.CRCResultRegL)) data.append(self.ReadRawRC(self.CRCResultRegM)) return data
[Doku] def PcdHalt(self): data = [self.PICC_HALT, 0] data = self.CalulateCRC(data) self.len1 = 0 status = self.PcdComMF522(self.PCD_TRANSCEIVE, data) return status
[Doku] def PcdComMF522(self, com, data): # print("PcdComMF522") data_len = 0 if com == self.PCD_AUTHENT: irqEn = 0x12 waitFor = 0x10 elif com == self.PCD_TRANSCEIVE: irqEn = 0x77 waitFor = 0x30 else: irqEn = 0 waitFor = 0 self.WriteRawRC(self.ComIEnReg, (irqEn|0x80)) self.ClearBitMask(self.ComIrqReg, 0x80) self.WriteRawRC(self.CommandReg, self.PCD_IDLE) self.SetBitMask(self.FIFOLevelReg, 0x80) for i in range(len(data)): self.WriteRawRC(self.FIFODataReg, data[i]) self.WriteRawRC(self.CommandReg, com) if com == self.PCD_TRANSCEIVE: self.SetBitMask(self.BitFramingReg, 0x80) try_times = 2000 n = self.ReadRawRC(self.ComIrqReg) # print("ComIrqReg: %s"%n) while try_times !=0 and not(n & 0x01) and not(n & waitFor) : n = self.ReadRawRC(self.ComIrqReg) # print("ComIrqReg: %s"%n) try_times -= 1 self.ClearBitMask(self.BitFramingReg, 0x80) status = 2 if try_times != 0: if not(self.ReadRawRC(self.ErrorReg) & 0x1B): status = 0 # print(n) if n & irqEn & 0x01: status = 1 return None, status, None if com == self.PCD_TRANSCEIVE: n = self.ReadRawRC(self.FIFOLevelReg) # print("FIFOLevelReg: %s"%n) lastBits = self.ReadRawRC(self.ControlReg) & 0x07 # print("lastBits: %s"%lastBits) if lastBits: data_len = (n-1)*8 + lastBits # print("data_len: %s"%data_len) # print(data_len) else: data_len = n * 8 if n == 0: n = 1 if n > 18: n = 18 data = [] for i in range(n): data.append(self.ReadRawRC(self.FIFODataReg)) # print(data[i]) else: status = 2 self.SetBitMask(self.ControlReg, 0x80) self.WriteRawRC(self.CommandReg, self.PCD_IDLE) # if return data, status, data_len
[Doku] def PcdWrite(self, addr, data): temp = [self.PICC_WRITE, addr] temp = self.CalulateCRC(temp) temp, status, data_len = self.PcdComMF522(self.PCD_TRANSCEIVE, temp) if status != 0 or data_len != 4 or (temp[0] & 0x0F) != 0x0A: status = 2 if status == 0: if len(data) < 16: data += [0]*(16 - len(data)) elif len(data) > 16: data = data[0:16] temp = data temp = self.CalulateCRC(temp) temp, status, data_len = self.PcdComMF522(self.PCD_TRANSCEIVE, temp) if status != 0 or data_len != 4 or (temp[0] & 0x0F) != 0x0A: status = 2 return status
[Doku] def PcdRead(self, addr): temp = [self.PICC_READ, addr] temp = self.CalulateCRC(temp) temp, status, data_len = self.PcdComMF522(self.PCD_TRANSCEIVE, temp) if status == 0 and data_len == 0x90: return status, temp else: return 2,temp
[Doku] def PcdAuthState(self, mode, addr, key, snr): temp = [mode, addr] temp += key + snr temp, status, _ = self.PcdComMF522(self.PCD_AUTHENT, temp) if status != 0 or not(self.ReadRawRC(self.Status2Reg) & 0x08): status = 2 return status
[Doku] def PcdSelect(self, snr): temp = [self.PICC_ANTICOLL1, 0x70, 0, 0, 0, 0, 0] for i in range(4): temp[i+2] = snr[i] temp[6] ^= snr[i] temp = self.CalulateCRC(temp) self.ClearBitMask(self.Status2Reg, 0x08) temp, status, data_len = self.PcdComMF522(self.PCD_TRANSCEIVE, temp) if status == 0 and data_len == 0x18: status = 0 else: status = 2 return status
[Doku] def PcdAnticoll(self, snr): snr_check = 0 self.ClearBitMask(self.Status2Reg, 0x08) self.WriteRawRC(self.BitFramingReg, 0x00) self.ClearBitMask(self.CollReg, 0x80) temp = [self.PICC_ANTICOLL1, 0x20] temp, status, _ = self.PcdComMF522(self.PCD_TRANSCEIVE, temp) # print(temp) if temp == None or len(temp) != 5: return 2 if status == 0: for i in range(len(temp)-1): snr[i] = temp[i] snr_check ^= temp[i] if snr_check != temp[4]: status = 2 self.SetBitMask(self.CollReg, 0x80) return status
[Doku] def PcdRequest(self, mode, cardtype): # print("PcdRequest") temp = [mode] self.ClearBitMask(self.Status2Reg, 0x08) self.WriteRawRC(self.BitFramingReg, 0x07) self.SetBitMask(self.TxControlReg, 0x03) temp, status, data_len = self.PcdComMF522(self.PCD_TRANSCEIVE, temp) # print("status: %s"%status) if status == 0 and data_len == 0x10: cardtype[0] = temp[0] cardtype[1] = temp[1] else: status = 2 return status
[Doku] def read_card(self): # print("read_card") status = self.PcdRequest(self.PICC_REQIDL, self.ct) if status == 0: status = self.PcdAnticoll(self.sn) # if self.ct[0] == 0x44: # print("Card type:Mifare_UltraLight") # elif self.ct[0] == 4: # print("Card type:FOne_S50") # elif self.ct[0] == 2: # print("Card type:FOne_S70") # elif self.ct[0] == 8: # print("Card type:Mifare_Pro(X)") # print("Card number:",end='') # for i in self.sn: # print(hex(i),end='') # print(',',end='') # print("\b ") if status == 0: status = self.PcdSelect(self.sn) return status
[Doku] def read_card_info(self): if self.ct[0] == 0x44: print("Card type:Mifare_UltraLight") elif self.ct[0] == 4: print("Card type:FOne_S50") elif self.ct[0] == 2: print("Card type:FOne_S70") elif self.ct[0] == 8: print("Card type:Mifare_Pro(X)") print("Card number:",end='') uid_str = ''.join(['%02X' % i for i in self.sn]) print(uid_str)
[Doku] def write_card_data(self, addr, data): # print("write:") status = self.read_card() if status == 0: status = self.PcdAuthState(self.PICC_AUTHENT1A, 3, self.key, self.sn) if status == 0: status = self.PcdWrite(addr, data) if status == 0: pass # print("write data:", data[0:16]) return status
[Doku] def read_card_data(self, addr): # print("read:") data_read = [] status = self.read_card() if status == 0: status = self.PcdAuthState(self.PICC_AUTHENT1A, 3, self.key, self.sn) if status ==0: status, data_read = self.PcdRead(addr) if status == 0: data_read = [chr(data_read[i]) for i in range(len(data_read))] #print("data:", data_read[0:16]) return status,data_read return status,None
[Doku] def read(self,addr,max_retries=3): best_attempt = ['\x00'] * 16 retry_count =0 while retry_count < max_retries: status,current_read = self.read_card_data(addr) if status == 0 and current_read != None: current_data = current_read[0:16] best_attempt = [best_attempt[i] if best_attempt[i] != '\x00' else current_data[i] for i in range(16)] retry_count += 1 else: continue #print("Successfully retrieved data block:", best_attempt) #self.read_card_info() uid_str = ''.join(['%02X' % i for i in self.sn]) result_string = ''.join([x for x in best_attempt if x != 0x00]) return uid_str,result_string
[Doku] def write(self,addr,data): status = 2 while status != 0: status = self.write_card_data(addr, data) print("Successfully write data block.") return
if __name__ == "__main__": rc = RC522() rc.Pcd_start() data = [1, 2, 3, 4, 5] rc.write(2, data) time.sleep(2) print("Card UID:", rc.get_uid()) print(rc.read(2))