[chronojump] Added MFRC22.py



commit 006a1da97a68c6de0830d7fecb6df553aacad1d4
Author: Xavier Padullés <x padulles gmail com>
Date:   Tue Jan 24 18:09:03 2017 +0100

    Added MFRC22.py

 rfid/MFRC522.py |  397 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 397 insertions(+), 0 deletions(-)
---
diff --git a/rfid/MFRC522.py b/rfid/MFRC522.py
new file mode 100644
index 0000000..42b971f
--- /dev/null
+++ b/rfid/MFRC522.py
@@ -0,0 +1,397 @@
+#!/usr/bin/env python
+# -*- coding: utf8 -*-
+
+import RPi.GPIO as GPIO
+import spi
+import signal
+import time
+  
+class MFRC522:
+  NRSTPD = 22
+  
+  MAX_LEN = 16
+  
+  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_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_NOTAGERR = 1
+  MI_ERR      = 2
+  
+  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
+    
+  serNum = []
+  
+  def __init__(self, dev='/dev/spidev0.0', spd=1000000):
+    spi.openSPI(device=dev,speed=spd)
+    GPIO.setmode(GPIO.BOARD)
+    GPIO.setup(22, GPIO.OUT)
+    GPIO.output(self.NRSTPD, 1)
+    self.MFRC522_Init()
+  
+  def MFRC522_Reset(self):
+    self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
+  
+  def Write_MFRC522(self, addr, val):
+    spi.transfer(((addr<<1)&0x7E,val))
+  
+  def Read_MFRC522(self, addr):
+    val = spi.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
+    lastBits = None
+    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 = 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 = 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_NOTAGERR
+      
+        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 = i + 1;
+      else:
+        status = self.MI_ERR
+
+    return (status,backData,backLen)
+  
+  
+  def MFRC522_Request(self, reqMode):
+    status = None
+    backBits = None
+    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):
+    backData = []
+    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 = i + 1
+        if serNumCheck != backData[i]:
+          status = self.MI_ERR
+      else:
+        status = self.MI_ERR
+  
+    return (status,backData)
+  
+  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 = i + 1
+    self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
+    i = 0xFF
+    while True:
+      n = self.Read_MFRC522(self.DivIrqReg)
+      i = i - 1
+      if not ((i != 0) and not (n&0x04)):
+        break
+    pOutData = []
+    pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
+    pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
+    return pOutData
+  
+  def MFRC522_SelectTag(self, serNum):
+    backData = []
+    buf = []
+    buf.append(self.PICC_SElECTTAG)
+    buf.append(0x70)
+    i = 0
+    while i<5:
+      buf.append(serNum[i])
+      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):
+      print "Size: " + str(backData[0])
+      return    backData[0]
+    else:
+      return 0
+  
+  def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
+    buff = []
+
+    # First byte should be the authMode (A or B)
+    buff.append(authMode)
+
+    # Second byte is the trailerBlock (usually 7)
+    buff.append(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 = i + 1
+    i = 0
+
+    # Next we append the first 4 bytes of the UID
+    while(i < 4):
+      buff.append(serNum[i])
+      i = i +1
+
+    # Now we start the authentication itself
+    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT,buff)
+
+    # Check if an error occurred
+    if not(status == self.MI_OK):
+      print "AUTH ERROR!!"
+    if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
+      print "AUTH ERROR(status2reg & 0x08) != 0"
+
+    # Return the status
+    return status
+  
+  def MFRC522_StopCrypto1(self):
+    self.ClearBitMask(self.Status2Reg, 0x08)
+
+  def MFRC522_Read(self, blockAddr):
+    recvData = []
+    recvData.append(self.PICC_READ)
+    recvData.append(blockAddr)
+    pOut = self.CalulateCRC(recvData)
+    recvData.append(pOut[0])
+    recvData.append(pOut[1])
+    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
+    if not(status == self.MI_OK):
+      print "Error while reading!"
+    i = 0
+    #xavi: not needed
+    #if len(backData) == 16:
+    #  print "Sector "+str(blockAddr)+" "+str(backData)
+  
+  def MFRC522_Write(self, blockAddr, writeData):
+    buff = []
+    buff.append(self.PICC_WRITE)
+    buff.append(blockAddr)
+    crc = self.CalulateCRC(buff)
+    buff.append(crc[0])
+    buff.append(crc[1])
+    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
+    if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
+        status = self.MI_ERR
+    
+    print 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 = 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 not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
+            print "Error while writing"
+        if status == self.MI_OK:
+            print "Data written"
+
+  def MFRC522_DumpClassic1K(self, key, uid):
+    i = 0
+    while i < 64:
+        status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
+        # Check if authenticated
+        if status == self.MI_OK:
+            self.MFRC522_Read(i)
+        else:
+            print "Authentication error"
+        i = i+1
+
+  def MFRC522_Init(self):
+    GPIO.output(self.NRSTPD, 1)
+  
+    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()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]