From 950cdee303fa3921a17b79678063ecccc86f79e5 Mon Sep 17 00:00:00 2001 From: danjperron Date: Fri, 20 Sep 2019 15:16:54 -0400 Subject: [PATCH] add 7/10 bytes ID --- examples/read.py | 87 ++++---- examples/write.py | 50 ----- mfrc522.py | 522 ++++++++++++++++++++++++++-------------------- 3 files changed, 334 insertions(+), 325 deletions(-) delete mode 100644 examples/write.py diff --git a/examples/read.py b/examples/read.py index 783d554..845ef37 100644 --- a/examples/read.py +++ b/examples/read.py @@ -1,46 +1,41 @@ -import mfrc522 -from os import uname - - -def do_read(): - - if uname()[0] == 'WiPy': - rdr = mfrc522.MFRC522("GP14", "GP16", "GP15", "GP22", "GP17") - elif uname()[0] == 'esp8266': - rdr = mfrc522.MFRC522(0, 2, 4, 5, 14) - else: - raise RuntimeError("Unsupported platform") - - print("") - print("Place card before reader to read from address 0x08") - print("") - - try: - while True: - - (stat, tag_type) = rdr.request(rdr.REQIDL) - - if stat == rdr.OK: - - (stat, raw_uid) = rdr.anticoll() - - if stat == rdr.OK: - print("New card detected") - print(" - tag type: 0x%02x" % tag_type) - print(" - uid : 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3])) - print("") - - if rdr.select_tag(raw_uid) == rdr.OK: - - key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] - - if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK: - print("Address 8 data: %s" % rdr.read(8)) - rdr.stop_crypto1() - else: - print("Authentication error") - else: - print("Failed to select tag") - - except KeyboardInterrupt: - print("Bye") \ No newline at end of file +import mfrc522 +from os import uname + + +def uidToString(uid): + mystring = "" + for i in uid: + mystring = "%02X" % i + mystring + return mystring + +def do_read(): + + if uname()[0] == 'WiPy': + rdr = mfrc522.MFRC522("GP14", "GP16", "GP15", "GP22", "GP17") + elif uname()[0] == 'esp32': + rdr = mfrc522.MFRC522(sck=18,mosi=23,miso=19,rst=22,cs=21) + else: + raise RuntimeError("Unsupported platform") + + print("") + print("Place card before reader to read from address 0x08") + print("") + + try: + while True: + + (stat, tag_type) = rdr.request(rdr.REQIDL) + + if stat == rdr.OK: + + (stat, uid) = rdr.SelectTagSN() + + if stat == rdr.OK: + print("Card detected %s" % uidToString(uid)) + else: + print("Authentication error") + + except KeyboardInterrupt: + print("Bye") + + diff --git a/examples/write.py b/examples/write.py deleted file mode 100644 index 7878d83..0000000 --- a/examples/write.py +++ /dev/null @@ -1,50 +0,0 @@ -import mfrc522 -from os import uname - - -def do_write(): - - if uname()[0] == 'WiPy': - rdr = mfrc522.MFRC522("GP14", "GP16", "GP15", "GP22", "GP17") - elif uname()[0] == 'esp8266': - rdr = mfrc522.MFRC522(0, 2, 4, 5, 14) - else: - raise RuntimeError("Unsupported platform") - - print("") - print("Place card before reader to write address 0x08") - print("") - - try: - while True: - - (stat, tag_type) = rdr.request(rdr.REQIDL) - - if stat == rdr.OK: - - (stat, raw_uid) = rdr.anticoll() - - if stat == rdr.OK: - print("New card detected") - print(" - tag type: 0x%02x" % tag_type) - print(" - uid : 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3])) - print("") - - if rdr.select_tag(raw_uid) == rdr.OK: - - key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] - - if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK: - stat = rdr.write(8, b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f") - rdr.stop_crypto1() - if stat == rdr.OK: - print("Data written to card") - else: - print("Failed to write data to card") - else: - print("Authentication error") - else: - print("Failed to select tag") - - except KeyboardInterrupt: - print("Bye") diff --git a/mfrc522.py b/mfrc522.py index 1833d75..c603b58 100644 --- a/mfrc522.py +++ b/mfrc522.py @@ -1,229 +1,293 @@ -from machine import Pin, SPI -from os import uname - - -class MFRC522: - - OK = 0 - NOTAGERR = 1 - ERR = 2 - - REQIDL = 0x26 - REQALL = 0x52 - AUTHENT1A = 0x60 - AUTHENT1B = 0x61 - - def __init__(self, sck, mosi, miso, rst, cs): - - 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] - - 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': - self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso) - self.spi.init() - else: - raise RuntimeError("Unsupported platform") - - self.rst.value(1) - self.init() - - 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) - - 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) - - return val[0] - - 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 _tocard(self, cmd, send): - - 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 - - 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) - - 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 - - self._cflags(0x0D, 0x80) - - 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 == 0: - n = 1 - elif n > 16: - n = 16 - - for _ in range(n): - recv.append(self._rreg(0x09)) - else: - stat = self.ERR - - return stat, recv, bits - - def _crc(self, data): - - self._cflags(0x05, 0x04) - self._sflags(0x0A, 0x80) - - for c in data: - self._wreg(0x09, c) - - self._wreg(0x01, 0x03) - - 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)] - - 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() - - def reset(self): - self._wreg(0x01, 0x0F) - - def antenna_on(self, on=True): - - if on and ~(self._rreg(0x14) & 0x03): - self._sflags(0x14, 0x03) - else: - self._cflags(0x14, 0x03) - - def request(self, mode): - - self._wreg(0x0D, 0x07) - (stat, recv, bits) = self._tocard(0x0C, [mode]) - - if (stat != self.OK) | (bits != 0x10): - stat = self.ERR - - return stat, bits - - def anticoll(self): - - ser_chk = 0 - ser = [0x93, 0x20] - - 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 - - return stat, recv - - def select_tag(self, ser): - - buf = [0x93, 0x70] + ser[:5] - buf += self._crc(buf) - (stat, recv, bits) = self._tocard(0x0C, buf) - return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR - - 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 read(self, addr): - - 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): - - 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 +from machine import Pin, SPI +from os import uname + + +class MFRC522: + + DEBUG = False + OK = 0 + NOTAGERR = 1 + ERR = 2 + + REQIDL = 0x26 + REQALL = 0x52 + AUTHENT1A = 0x60 + AUTHENT1B = 0x61 + + PICC_ANTICOLL1 = 0x93 + PICC_ANTICOLL2 = 0x95 + PICC_ANTICOLL3 = 0x97 + + + def __init__(self, sck, mosi, miso, rst, cs): + + 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] + + 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() + else: + raise RuntimeError("Unsupported platform") + + self.rst.value(1) + self.init() + + 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) + + 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) + + return val[0] + + 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 _tocard(self, cmd, send): + + 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 + + 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) + + 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 + + self._cflags(0x0D, 0x80) + + 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 == 0: + n = 1 + elif n > 16: + n = 16 + + for _ in range(n): + recv.append(self._rreg(0x09)) + else: + stat = self.ERR + + return stat, recv, bits + + def _crc(self, data): + + self._cflags(0x05, 0x04) + self._sflags(0x0A, 0x80) + + for c in data: + self._wreg(0x09, c) + + self._wreg(0x01, 0x03) + + 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)] + + 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() + + def reset(self): + self._wreg(0x01, 0x0F) + + def antenna_on(self, on=True): + + if on and ~(self._rreg(0x14) & 0x03): + self._sflags(0x14, 0x03) + else: + self._cflags(0x14, 0x03) + + def request(self, mode): + + self._wreg(0x0D, 0x07) + (stat, recv, bits) = self._tocard(0x0C, [mode]) + + if (stat != self.OK) | (bits != 0x10): + stat = self.ERR + + return stat, bits + + def anticoll(self,anticolN): + + ser_chk = 0 + ser = [anticolN, 0x20] + + 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 + + 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 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.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) + + + + + + + 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 read(self, addr): + + 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): + + 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 + + +