atlasim

Untitled

Nov 17th, 2025
534
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.24 KB | None | 0 0
  1. from machine import Pin, SPI
  2. from os import uname
  3.  
  4.  
  5. class MFRC522:
  6.  
  7.     DEBUG = False
  8.     OK = 0
  9.     NOTAGERR = 1
  10.     ERR = 2
  11.  
  12.     REQIDL = 0x26
  13.     REQALL = 0x52
  14.     AUTHENT1A = 0x60
  15.     AUTHENT1B = 0x61
  16.  
  17.     PICC_ANTICOLL1 = 0x93
  18.     PICC_ANTICOLL2 = 0x95
  19.     PICC_ANTICOLL3 = 0x97
  20.  
  21.  
  22.     def __init__(self, sck, mosi, miso, rst, cs,baudrate=1000000,spi_id=0):
  23.  
  24.         self.sck = Pin(sck, Pin.OUT)
  25.         self.mosi = Pin(mosi, Pin.OUT)
  26.         self.miso = Pin(miso)
  27.         self.rst = Pin(rst, Pin.OUT)
  28.         self.cs = Pin(cs, Pin.OUT)
  29.  
  30.         self.rst.value(0)
  31.         self.cs.value(1)
  32.        
  33.         board = uname()[0]
  34.  
  35.         if board == 'WiPy' or board == 'LoPy' or board == 'FiPy':
  36.             self.spi = SPI(0)
  37.             self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso))
  38.         elif (board == 'esp8266') or (board == 'esp32'):
  39.             self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
  40.             self.spi.init()
  41.         elif board == 'rp2':
  42.             self.spi = SPI(spi_id,baudrate=baudrate,sck=self.sck, mosi= self.mosi, miso= self.miso)
  43.         else:
  44.             raise RuntimeError("Unsupported platform")
  45.  
  46.         self.rst.value(1)
  47.         self.init()
  48.  
  49.     def _wreg(self, reg, val):
  50.  
  51.         self.cs.value(0)
  52.         self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
  53.         self.spi.write(b'%c' % int(0xff & val))
  54.         self.cs.value(1)
  55.  
  56.     def _rreg(self, reg):
  57.  
  58.         self.cs.value(0)
  59.         self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
  60.         val = self.spi.read(1)
  61.         self.cs.value(1)
  62.  
  63.         return val[0]
  64.  
  65.     def _sflags(self, reg, mask):
  66.         self._wreg(reg, self._rreg(reg) | mask)
  67.  
  68.     def _cflags(self, reg, mask):
  69.         self._wreg(reg, self._rreg(reg) & (~mask))
  70.  
  71.     def _tocard(self, cmd, send):
  72.  
  73.         recv = []
  74.         bits = irq_en = wait_irq = n = 0
  75.         stat = self.ERR
  76.  
  77.         if cmd == 0x0E:
  78.             irq_en = 0x12
  79.             wait_irq = 0x10
  80.         elif cmd == 0x0C:
  81.             irq_en = 0x77
  82.             wait_irq = 0x30
  83.  
  84.         self._wreg(0x02, irq_en | 0x80)
  85.         self._cflags(0x04, 0x80)
  86.         self._sflags(0x0A, 0x80)
  87.         self._wreg(0x01, 0x00)
  88.  
  89.         for c in send:
  90.             self._wreg(0x09, c)
  91.         self._wreg(0x01, cmd)
  92.  
  93.         if cmd == 0x0C:
  94.             self._sflags(0x0D, 0x80)
  95.  
  96.         i = 2000
  97.         while True:
  98.             n = self._rreg(0x04)
  99.             i -= 1
  100.             if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
  101.                 break
  102.  
  103.         self._cflags(0x0D, 0x80)
  104.  
  105.         if i:
  106.             if (self._rreg(0x06) & 0x1B) == 0x00:
  107.                 stat = self.OK
  108.  
  109.                 if n & irq_en & 0x01:
  110.                     stat = self.NOTAGERR
  111.                 elif cmd == 0x0C:
  112.                     n = self._rreg(0x0A)
  113.                     lbits = self._rreg(0x0C) & 0x07
  114.                     if lbits != 0:
  115.                         bits = (n - 1) * 8 + lbits
  116.                     else:
  117.                         bits = n * 8
  118.  
  119.                     if n == 0:
  120.                         n = 1
  121.                     elif n > 16:
  122.                         n = 16
  123.  
  124.                     for _ in range(n):
  125.                         recv.append(self._rreg(0x09))
  126.             else:
  127.                 stat = self.ERR
  128.  
  129.         return stat, recv, bits
  130.  
  131.     def _crc(self, data):
  132.  
  133.         self._cflags(0x05, 0x04)
  134.         self._sflags(0x0A, 0x80)
  135.  
  136.         for c in data:
  137.             self._wreg(0x09, c)
  138.  
  139.         self._wreg(0x01, 0x03)
  140.  
  141.         i = 0xFF
  142.         while True:
  143.             n = self._rreg(0x05)
  144.             i -= 1
  145.             if not ((i != 0) and not (n & 0x04)):
  146.                 break
  147.  
  148.         return [self._rreg(0x22), self._rreg(0x21)]
  149.  
  150.     def init(self):
  151.  
  152.         self.reset()
  153.         self._wreg(0x2A, 0x8D)
  154.         self._wreg(0x2B, 0x3E)
  155.         self._wreg(0x2D, 30)
  156.         self._wreg(0x2C, 0)
  157.         self._wreg(0x15, 0x40)
  158.         self._wreg(0x11, 0x3D)
  159.         self.antenna_on()
  160.  
  161.     def reset(self):
  162.         self._wreg(0x01, 0x0F)
  163.  
  164.     def antenna_on(self, on=True):
  165.  
  166.         if on and ~(self._rreg(0x14) & 0x03):
  167.             self._sflags(0x14, 0x03)
  168.         else:
  169.             self._cflags(0x14, 0x03)
  170.  
  171.     def request(self, mode):
  172.  
  173.         self._wreg(0x0D, 0x07)
  174.         (stat, recv, bits) = self._tocard(0x0C, [mode])
  175.  
  176.         if (stat != self.OK) | (bits != 0x10):
  177.             stat = self.ERR
  178.  
  179.         return stat, bits
  180.  
  181.     def anticoll(self,anticolN):
  182.  
  183.         ser_chk = 0
  184.         ser = [anticolN, 0x20]
  185.  
  186.         self._wreg(0x0D, 0x00)
  187.         (stat, recv, bits) = self._tocard(0x0C, ser)
  188.  
  189.         if stat == self.OK:
  190.             if len(recv) == 5:
  191.                 for i in range(4):
  192.                     ser_chk = ser_chk ^ recv[i]
  193.                 if ser_chk != recv[4]:
  194.                     stat = self.ERR
  195.             else:
  196.                 stat = self.ERR
  197.  
  198.         return stat, recv
  199.  
  200.    
  201.     def PcdSelect(self, serNum,anticolN):
  202.         backData = []
  203.         buf = []
  204.         buf.append(anticolN)
  205.         buf.append(0x70)
  206.         #i = 0
  207.         ###xorsum=0;
  208.         for i in serNum:
  209.             buf.append(i)
  210.         #while i<5:
  211.         #    buf.append(serNum[i])
  212.         #    i = i + 1
  213.         pOut = self._crc(buf)
  214.         buf.append(pOut[0])
  215.         buf.append(pOut[1])
  216.         (status, backData, backLen) = self._tocard( 0x0C, buf)
  217.         if (status == self.OK) and (backLen == 0x18):
  218.             return  1
  219.         else:
  220.             return 0
  221.    
  222.    
  223.     def SelectTag(self, uid):
  224.         byte5 = 0
  225.        
  226.         #(status,puid)= self.anticoll(self.PICC_ANTICOLL1)
  227.         #print("uid",uid,"puid",puid)
  228.         for i in uid:
  229.             byte5 = byte5 ^ i
  230.         puid = uid + [byte5]
  231.        
  232.         if self.PcdSelect(puid,self.PICC_ANTICOLL1) == 0:
  233.             return (self.ERR,[])
  234.         return (self.OK , uid)
  235.        
  236.     def tohexstring(self,v):
  237.         s="["
  238.         for i in v:
  239.             if i != v[0]:
  240.                 s = s+ ", "
  241.             s=s+ "0x{:02X}".format(i)
  242.         s= s+ "]"
  243.         return s
  244.        
  245.  
  246.            
  247.    
  248.     def SelectTagSN(self):
  249.         valid_uid=[]
  250.         (status,uid)= self.anticoll(self.PICC_ANTICOLL1)
  251.         #print("Select Tag 1:",self.tohexstring(uid))
  252.         if status != self.OK:
  253.             return  (self.ERR,[])
  254.        
  255.         if self.DEBUG:   print("anticol(1) {}".format(uid))
  256.         if self.PcdSelect(uid,self.PICC_ANTICOLL1) == 0:
  257.             return (self.ERR,[])
  258.         if self.DEBUG:   print("pcdSelect(1) {}".format(uid))
  259.        
  260.         #check if first byte is 0x88
  261.         if uid[0] == 0x88 :
  262.             #ok we have another type of card
  263.             valid_uid.extend(uid[1:4])
  264.             (status,uid)=self.anticoll(self.PICC_ANTICOLL2)
  265.             #print("Select Tag 2:",self.tohexstring(uid))
  266.             if status != self.OK:
  267.                 return (self.ERR,[])
  268.             if self.DEBUG: print("Anticol(2) {}".format(uid))
  269.             rtn =  self.PcdSelect(uid,self.PICC_ANTICOLL2)
  270.             if self.DEBUG: print("pcdSelect(2) return={} uid={}".format(rtn,uid))
  271.             if rtn == 0:
  272.                 return (self.ERR,[])
  273.             if self.DEBUG: print("PcdSelect2() {}".format(uid))
  274.             #now check again if uid[0] is 0x88
  275.             if uid[0] == 0x88 :
  276.                 valid_uid.extend(uid[1:4])
  277.                 (status , uid) = self.anticoll(self.PICC_ANTICOLL3)
  278.                 #print("Select Tag 3:",self.tohexstring(uid))
  279.                 if status != self.OK:
  280.                     return (self.ERR,[])
  281.                 if self.DEBUG: print("Anticol(3) {}".format(uid))
  282.                 if self.MFRC522_PcdSelect(uid,self.PICC_ANTICOLL3) == 0:
  283.                     return (self.ERR,[])
  284.                 if self.DEBUG: print("PcdSelect(3) {}".format(uid))
  285.         valid_uid.extend(uid[0:5])
  286.         # if we are here than the uid is ok
  287.         # let's remove the last BYTE whic is the XOR sum
  288.        
  289.        return (self.OK , valid_uid[:len(valid_uid)-1])
  290.        #return (self.OK , valid_uid)
  291.    
  292.    
  293.  
  294.      
  295.    
  296.  
  297.    def auth(self, mode, addr, sect, ser):
  298.        return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
  299.    
  300.    def authKeys(self,uid,addr,keyA=None, keyB=None):
  301.        status = self.ERR
  302.        if keyA is not None:
  303.            status = self.auth(self.AUTHENT1A, addr, keyA, uid)
  304.        elif keyB is not None:
  305.            status = self.auth(self.AUTHENT1B, addr, keyB, uid)
  306.        return status
  307.      
  308.  
  309.    def stop_crypto1(self):
  310.        self._cflags(0x08, 0x08)
  311.  
  312.    def read(self, addr):
  313.  
  314.        data = [0x30, addr]
  315.        data += self._crc(data)
  316.        (stat, recv, _) = self._tocard(0x0C, data)
  317.        return stat, recv
  318.  
  319.    def write(self, addr, data):
  320.  
  321.        buf = [0xA0, addr]
  322.        buf += self._crc(buf)
  323.        (stat, recv, bits) = self._tocard(0x0C, buf)
  324.  
  325.        if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
  326.            stat = self.ERR
  327.        else:
  328.            buf = []
  329.            for i in range(16):
  330.                buf.append(data[i])
  331.            buf += self._crc(buf)
  332.            (stat, recv, bits) = self._tocard(0x0C, buf)
  333.            if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
  334.                stat = self.ERR
  335.        return stat
  336.  
  337.  
  338.    def writeSectorBlock(self,uid, sector, block, data, keyA=None, keyB = None):
  339.        absoluteBlock =  sector * 4 + (block % 4)
  340.        if absoluteBlock > 63 :
  341.            return self.ERR
  342.        if len(data) != 16:
  343.            return self.ERR
  344.        if self.authKeys(uid,absoluteBlock,keyA,keyB) != self.ERR :
  345.            return self.write(absoluteBlock, data)
  346.        return self.ERR
  347.  
  348.    def readSectorBlock(self,uid ,sector, block, keyA=None, keyB = None):
  349.        absoluteBlock =  sector * 4 + (block % 4)
  350.        if absoluteBlock > 63 :
  351.            return self.ERR, None
  352.        if self.authKeys(uid,absoluteBlock,keyA,keyB) != self.ERR :
  353.            return self.read(absoluteBlock)
  354.        return self.ERR, None
  355.  
  356.    def MFRC522_DumpClassic1K(self,uid, Start=0, End=64, keyA=None, keyB=None):
  357.        for absoluteBlock in range(Start,End):
  358.            status = self.authKeys(uid,absoluteBlock,keyA,keyB)
  359.            # Check if authenticated
  360.            print("{:02d} S{:02d} B{:1d}: ".format(absoluteBlock, absoluteBlock//4 , absoluteBlock % 4),end="")
  361.            if status == self.OK:                    
  362.                status, block = self.read(absoluteBlock)
  363.                if status == self.ERR:
  364.                    break
  365.                else:
  366.                    for value in block:
  367.                        print("{:02X} ".format(value),end="")
  368.                    print("  ",end="")
  369.                    for value in block:
  370.                        if (value > 0x20) and (value < 0x7f):
  371.                            print(chr(value),end="")
  372.                        else:
  373.                            print('.',end="")
  374.                    print("")
  375.            else:
  376.                break
  377.        if status == self.ERR:
  378.            print("Authentication error")
  379.            return self.ERR
  380.        return self.OK
  381.  
  382.  
Advertisement
Add Comment
Please, Sign In to add comment