From 6dd14764b9a9eb5d262862e0886caddfd602e0a1 Mon Sep 17 00:00:00 2001 From: danjperron Date: Mon, 15 Feb 2021 12:09:53 -0500 Subject: [PATCH] add write example --- examples/Pico_write.py | 48 +++++ mfrc522.py | 454 +++++++++++++++++++++-------------------- 2 files changed, 282 insertions(+), 220 deletions(-) create mode 100644 examples/Pico_write.py diff --git a/examples/Pico_write.py b/examples/Pico_write.py new file mode 100644 index 0000000..380f4a2 --- /dev/null +++ b/examples/Pico_write.py @@ -0,0 +1,48 @@ +from mfrc522 import MFRC522 + + +def uidToString(uid): + mystring = "" + for i in uid: + mystring = "%02X" % i + mystring + return mystring + +reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0) + +print("") +print("Place card before reader to read from address 0x08") +print("") + +key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] + +try: + while True: + + (stat, tag_type) = reader.request(reader.REQIDL) + + if stat == reader.OK: + (stat, uid) = reader.SelectTagSN() + if stat == reader.OK: + print(uid) + print("Card detected %s" % uidToString(uid)) + reader.MFRC522_DumpClassic1K(key, uid) + print("Test ! writing sector 2, block 0 (absolute block(8)") + print("with [ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 ]") + absoluteBlock=8 + value=[] + for i in range(16): + value.append(i) + status = reader.auth(reader.AUTHENT1A, absoluteBlock, key, uid) + if status == reader.OK: + status = reader.write(absoluteBlock,value) + if status == reader.OK: + reader.MFRC522_DumpClassic1K(key, uid) + else: + print("unable to write") + else: + print("Authentication error for writing") + break +except KeyboardInterrupt: + print("Bye") + + diff --git a/mfrc522.py b/mfrc522.py index 3cf7b4b..ff53fe8 100644 --- a/mfrc522.py +++ b/mfrc522.py @@ -4,292 +4,306 @@ from os import uname class MFRC522: - DEBUG = False - OK = 0 - NOTAGERR = 1 - ERR = 2 + DEBUG = False + OK = 0 + NOTAGERR = 1 + ERR = 2 - REQIDL = 0x26 - REQALL = 0x52 - AUTHENT1A = 0x60 - AUTHENT1B = 0x61 + REQIDL = 0x26 + REQALL = 0x52 + AUTHENT1A = 0x60 + AUTHENT1B = 0x61 - PICC_ANTICOLL1 = 0x93 - PICC_ANTICOLL2 = 0x95 - PICC_ANTICOLL3 = 0x97 + PICC_ANTICOLL1 = 0x93 + PICC_ANTICOLL2 = 0x95 + PICC_ANTICOLL3 = 0x97 - def __init__(self, sck, mosi, miso, rst, cs,baudrate=1000000,spi_id=0): + def __init__(self, sck, mosi, miso, rst, cs,baudrate=1000000,spi_id=0): - self.sck = Pin(sck, Pin.OUT) - self.mosi = Pin(mosi, Pin.OUT) - self.miso = Pin(miso) - self.rst = Pin(rst, Pin.OUT) - self.cs = Pin(cs, Pin.OUT) + self.sck = Pin(sck, Pin.OUT) + self.mosi = Pin(mosi, Pin.OUT) + self.miso = Pin(miso) + self.rst = Pin(rst, Pin.OUT) + self.cs = Pin(cs, Pin.OUT) - self.rst.value(0) - self.cs.value(1) - - board = uname()[0] + self.rst.value(0) + self.cs.value(1) + + board = uname()[0] - if board == 'WiPy' or board == 'LoPy' or board == 'FiPy': - self.spi = SPI(0) - self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso)) - elif (board == 'esp8266') or (board == 'esp32'): - self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso) - self.spi.init() - elif board == 'rp2': - self.spi = SPI(spi_id,baudrate=baudrate,sck=self.sck, mosi= self.mosi, miso= self.miso) - else: - raise RuntimeError("Unsupported platform") + if board == 'WiPy' or board == 'LoPy' or board == 'FiPy': + self.spi = SPI(0) + self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso)) + elif (board == 'esp8266') or (board == 'esp32'): + self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso) + self.spi.init() + elif board == 'rp2': + self.spi = SPI(spi_id,baudrate=baudrate,sck=self.sck, mosi= self.mosi, miso= self.miso) + else: + raise RuntimeError("Unsupported platform") - self.rst.value(1) - self.init() + self.rst.value(1) + self.init() - def _wreg(self, reg, val): + def _wreg(self, reg, val): - self.cs.value(0) - self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e))) - self.spi.write(b'%c' % int(0xff & val)) - self.cs.value(1) + self.cs.value(0) + self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e))) + self.spi.write(b'%c' % int(0xff & val)) + self.cs.value(1) - def _rreg(self, reg): + def _rreg(self, reg): - self.cs.value(0) - self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80))) - val = self.spi.read(1) - self.cs.value(1) + self.cs.value(0) + self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80))) + val = self.spi.read(1) + self.cs.value(1) - return val[0] + return val[0] - def _sflags(self, reg, mask): - self._wreg(reg, self._rreg(reg) | mask) + def _sflags(self, reg, mask): + self._wreg(reg, self._rreg(reg) | mask) - def _cflags(self, reg, mask): - self._wreg(reg, self._rreg(reg) & (~mask)) + def _cflags(self, reg, mask): + self._wreg(reg, self._rreg(reg) & (~mask)) - def _tocard(self, cmd, send): + def _tocard(self, cmd, send): - recv = [] - bits = irq_en = wait_irq = n = 0 - stat = self.ERR + recv = [] + bits = irq_en = wait_irq = n = 0 + stat = self.ERR - if cmd == 0x0E: - irq_en = 0x12 - wait_irq = 0x10 - elif cmd == 0x0C: - irq_en = 0x77 - wait_irq = 0x30 + if cmd == 0x0E: + irq_en = 0x12 + wait_irq = 0x10 + elif cmd == 0x0C: + irq_en = 0x77 + wait_irq = 0x30 - self._wreg(0x02, irq_en | 0x80) - self._cflags(0x04, 0x80) - self._sflags(0x0A, 0x80) - self._wreg(0x01, 0x00) + self._wreg(0x02, irq_en | 0x80) + self._cflags(0x04, 0x80) + self._sflags(0x0A, 0x80) + self._wreg(0x01, 0x00) - for c in send: - self._wreg(0x09, c) - self._wreg(0x01, cmd) + for c in send: + self._wreg(0x09, c) + self._wreg(0x01, cmd) - if cmd == 0x0C: - self._sflags(0x0D, 0x80) + if cmd == 0x0C: + self._sflags(0x0D, 0x80) - i = 2000 - while True: - n = self._rreg(0x04) - i -= 1 - if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)): - break + i = 2000 + while True: + n = self._rreg(0x04) + i -= 1 + if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)): + break - self._cflags(0x0D, 0x80) + self._cflags(0x0D, 0x80) - if i: - if (self._rreg(0x06) & 0x1B) == 0x00: - stat = self.OK + if i: + if (self._rreg(0x06) & 0x1B) == 0x00: + stat = self.OK - if n & irq_en & 0x01: - stat = self.NOTAGERR - elif cmd == 0x0C: - n = self._rreg(0x0A) - lbits = self._rreg(0x0C) & 0x07 - if lbits != 0: - bits = (n - 1) * 8 + lbits - else: - bits = n * 8 + if n & irq_en & 0x01: + stat = self.NOTAGERR + elif cmd == 0x0C: + n = self._rreg(0x0A) + lbits = self._rreg(0x0C) & 0x07 + if lbits != 0: + bits = (n - 1) * 8 + lbits + else: + bits = n * 8 - if n == 0: - n = 1 - elif n > 16: - n = 16 + if n == 0: + n = 1 + elif n > 16: + n = 16 - for _ in range(n): - recv.append(self._rreg(0x09)) - else: - stat = self.ERR + for _ in range(n): + recv.append(self._rreg(0x09)) + else: + stat = self.ERR - return stat, recv, bits + return stat, recv, bits - def _crc(self, data): + def _crc(self, data): - self._cflags(0x05, 0x04) - self._sflags(0x0A, 0x80) + self._cflags(0x05, 0x04) + self._sflags(0x0A, 0x80) - for c in data: - self._wreg(0x09, c) + for c in data: + self._wreg(0x09, c) - self._wreg(0x01, 0x03) + self._wreg(0x01, 0x03) - i = 0xFF - while True: - n = self._rreg(0x05) - i -= 1 - if not ((i != 0) and not (n & 0x04)): - break + i = 0xFF + while True: + n = self._rreg(0x05) + i -= 1 + if not ((i != 0) and not (n & 0x04)): + break - return [self._rreg(0x22), self._rreg(0x21)] + return [self._rreg(0x22), self._rreg(0x21)] - def init(self): + def init(self): - self.reset() - self._wreg(0x2A, 0x8D) - self._wreg(0x2B, 0x3E) - self._wreg(0x2D, 30) - self._wreg(0x2C, 0) - self._wreg(0x15, 0x40) - self._wreg(0x11, 0x3D) - self.antenna_on() + self.reset() + self._wreg(0x2A, 0x8D) + self._wreg(0x2B, 0x3E) + self._wreg(0x2D, 30) + self._wreg(0x2C, 0) + self._wreg(0x15, 0x40) + self._wreg(0x11, 0x3D) + self.antenna_on() - def reset(self): - self._wreg(0x01, 0x0F) + def reset(self): + self._wreg(0x01, 0x0F) - def antenna_on(self, on=True): + def antenna_on(self, on=True): - if on and ~(self._rreg(0x14) & 0x03): - self._sflags(0x14, 0x03) - else: - self._cflags(0x14, 0x03) + if on and ~(self._rreg(0x14) & 0x03): + self._sflags(0x14, 0x03) + else: + self._cflags(0x14, 0x03) - def request(self, mode): + def request(self, mode): - self._wreg(0x0D, 0x07) - (stat, recv, bits) = self._tocard(0x0C, [mode]) + self._wreg(0x0D, 0x07) + (stat, recv, bits) = self._tocard(0x0C, [mode]) - if (stat != self.OK) | (bits != 0x10): - stat = self.ERR + if (stat != self.OK) | (bits != 0x10): + stat = self.ERR - return stat, bits + return stat, bits - def anticoll(self,anticolN): + def anticoll(self,anticolN): - ser_chk = 0 - ser = [anticolN, 0x20] + ser_chk = 0 + ser = [anticolN, 0x20] - self._wreg(0x0D, 0x00) - (stat, recv, bits) = self._tocard(0x0C, ser) + self._wreg(0x0D, 0x00) + (stat, recv, bits) = self._tocard(0x0C, ser) - if stat == self.OK: - if len(recv) == 5: - for i in range(4): - ser_chk = ser_chk ^ recv[i] - if ser_chk != recv[4]: - stat = self.ERR - else: - stat = self.ERR + if stat == self.OK: + if len(recv) == 5: + for i in range(4): + ser_chk = ser_chk ^ recv[i] + if ser_chk != recv[4]: + stat = self.ERR + else: + stat = self.ERR - return stat, recv + return stat, recv - def PcdSelect(self, serNum,anticolN): - backData = [] - buf = [] - buf.append(anticolN) - buf.append(0x70) - i = 0 - while i<5: - buf.append(serNum[i]) - i = i + 1 - pOut = self._crc(buf) - buf.append(pOut[0]) - buf.append(pOut[1]) - (status, backData, backLen) = self._tocard( 0x0C, buf) - if (status == self.OK) and (backLen == 0x18): - return 1 - else: - return 0 + def PcdSelect(self, serNum,anticolN): + backData = [] + buf = [] + buf.append(anticolN) + buf.append(0x70) + i = 0 + while i<5: + buf.append(serNum[i]) + i = i + 1 + pOut = self._crc(buf) + buf.append(pOut[0]) + buf.append(pOut[1]) + (status, backData, backLen) = self._tocard( 0x0C, buf) + if (status == self.OK) and (backLen == 0x18): + return 1 + else: + return 0 - def SelectTagSN(self): - valid_uid=[] - (status,uid)= self.anticoll(self.PICC_ANTICOLL1) - if status != self.OK: - return (self.ERR,[]) + def SelectTagSN(self): + valid_uid=[] + (status,uid)= self.anticoll(self.PICC_ANTICOLL1) + if status != self.OK: + return (self.ERR,[]) - if self.DEBUG: print("anticol(1) {}".format(uid)) - if self.PcdSelect(uid,self.PICC_ANTICOLL1) == 0: - return (self.ERR,[]) - if self.DEBUG: print("pcdSelect(1) {}".format(uid)) + if self.DEBUG: print("anticol(1) {}".format(uid)) + if self.PcdSelect(uid,self.PICC_ANTICOLL1) == 0: + return (self.MI_ERR,[]) + if self.DEBUG: print("pcdSelect(1) {}".format(uid)) - #check if first byte is 0x88 - if uid[0] == 0x88 : - #ok we have another type of card - valid_uid.extend(uid[1:4]) - (status,uid)=self.anticoll(self.PICC_ANTICOLL2) - if status != self.OK: - return (self.ERR,[]) - if self.DEBUG: print("Anticol(2) {}".format(uid)) - rtn = self.PcdSelect(uid,self.PICC_ANTICOLL2) - if self.DEBUG: print("pcdSelect(2) return={} uid={}".format(rtn,uid)) - if rtn == 0: - return (self.ERR,[]) - if self.DEBUG: print("PcdSelect2() {}".format(uid)) - #now check again if uid[0] is 0x88 - if uid[0] == 0x88 : - valid_uid.extend(uid[1:4]) - (status , uid) = self.anticoll(self.PICC_ANTICOLL3) - if status != self.OK: - return (self.ERR,[]) - if self.DEBUG: print("Anticol(3) {}".format(uid)) - if self.MFRC522_PcdSelect(uid,self.PICC_ANTICOLL3) == 0: - return (self.ERR,[]) - if self.DEBUG: print("PcdSelect(3) {}".format(uid)) - valid_uid.extend(uid[0:4]) - return (self.OK , valid_uid) + #check if first byte is 0x88 + if uid[0] == 0x88 : + #ok we have another type of card + valid_uid.extend(uid[1:4]) + (status,uid)=self.anticoll(self.PICC_ANTICOLL2) + if status != self.OK: + return (self.ERR,[]) + if self.DEBUG: print("Anticol(2) {}".format(uid)) + rtn = self.PcdSelect(uid,self.PICC_ANTICOLL2) + if self.DEBUG: print("pcdSelect(2) return={} uid={}".format(rtn,uid)) + if rtn == 0: + return (self.ERR,[]) + if self.DEBUG: print("PcdSelect2() {}".format(uid)) + #now check again if uid[0] is 0x88 + if uid[0] == 0x88 : + valid_uid.extend(uid[1:4]) + (status , uid) = self.anticoll(self.PICC_ANTICOLL3) + if status != self.OK: + return (self.ERR,[]) + if self.DEBUG: print("Anticol(3) {}".format(uid)) + if self.MFRC522_PcdSelect(uid,self.PICC_ANTICOLL3) == 0: + return (self.ERR,[]) + if self.DEBUG: print("PcdSelect(3) {}".format(uid)) + valid_uid.extend(uid[0:5]) + return (self.OK , valid_uid) - def auth(self, mode, addr, sect, ser): - return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0] + def auth(self, mode, addr, sect, ser): + return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0] - def stop_crypto1(self): - self._cflags(0x08, 0x08) + def stop_crypto1(self): + self._cflags(0x08, 0x08) - def read(self, addr): + def read(self, addr): - data = [0x30, addr] - data += self._crc(data) - (stat, recv, _) = self._tocard(0x0C, data) - return recv if stat == self.OK else None + data = [0x30, addr] + data += self._crc(data) + (stat, recv, _) = self._tocard(0x0C, data) + return recv if stat == self.OK else None - def write(self, addr, data): + def write(self, addr, data): - buf = [0xA0, addr] - buf += self._crc(buf) - (stat, recv, bits) = self._tocard(0x0C, buf) + buf = [0xA0, addr] + buf += self._crc(buf) + (stat, recv, bits) = self._tocard(0x0C, buf) - if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A): - stat = self.ERR - else: - buf = [] - for i in range(16): - buf.append(data[i]) - buf += self._crc(buf) - (stat, recv, bits) = self._tocard(0x0C, buf) - if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A): - stat = self.ERR - - return stat + if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A): + stat = self.ERR + else: + buf = [] + for i in range(16): + buf.append(data[i]) + buf += self._crc(buf) + (stat, recv, bits) = self._tocard(0x0C, buf) + if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A): + stat = self.ERR + return stat + def MFRC522_DumpClassic1K(self, key, uid): + for i in range(64): + status = self.auth(self.AUTHENT1A, i, key, uid) + # Check if authenticated + print("{:02d}: ".format(i),end="") + if status == self.OK: + block = self.read(i) + if block is None: + print("-- ") + else: + for value in block: + print("{:02X} ".format(value),end="") + print("") + else: + print("Authentication error")