Writing ntag213 (Mifare Ultralight C) with mxgxw/MFRC522-python Library and MFRC522 Reader on Raspi 2

2.7k views Asked by At

For a school project we are trying to write on ntag213 (Mifare Ultralight C 180Bytes) and we are not capable of writing on it. Beside of that the library is working fine with reading the Ultralight C/ntag213.

The same setting, library and hardware is working well on the Mifare 1K Tags 1024kB.

Is there someone out there who already did this with this library in PYTHON with an MFRC522 Reader and an Mifare Ultralight C tag (ntag213)?

Links:
https://github.com/mxgxw/MFRC522-python http://cache.nxp.com/documents/data_sheet/NTAG213_215_216.pdf?pspll=1

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)

#because of a timeout in function ToCard, backdata after this is empty!!!!!!!!!

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"

So we are looking into ToCard function to search for the error:

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)
#!!!!!!!!!!!!!!!!!!!!!!!!!!!
# as we saw in the data sheet we figured out that until here everything looks correctly.
# despite of this fact self.Read_MFRC522(self.CommIrqReg) never gets an ACK
#!!!!!!!!!!!!!!!!!!!!!!!!!!!
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)
1

There are 1 answers

0
Himura On

I'm trying to do the same thing, it probably linked with the fact that ultralight cards needs no authorization. As for the place of code you highlighted, I suggest to rewrite it

        while True:
        n = self.dev_read(0x04)
        if n == 0:
            continue  # Too fast
        if n & irq_wait:
            break  # Got it!
        if n & 0x01:
            error = True
            break  # The timer decrements the timer value in register TCounterValReg to zero