SPI and MFRC522 Module: SPI read/wirte not working

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Post Reply
Gabi
Posts: 18
Joined: Sat Mar 05, 2016 3:29 pm

SPI and MFRC522 Module: SPI read/wirte not working

Post by Gabi » Sun Aug 21, 2016 10:30 am

Hello everybody!

After a while, I finally get back to play with my WiPy :D

So, I want to use a RFID reader module: the MFRC522 (http://www.nxp.com/documents/data_sheet/MFRC522.pdf)

I found a python library on github: https://github.com/mxgxw/MFRC522-python

And I want to make it work in micropython.

I have configured the PINs and all:

Code: Select all

def __init__(self, spd=1000000):
    # first assign CLK, MISO, MOSI, CS to the correct pins
    self.pin_clk = Pin(self.CLK, mode=Pin.ALT, alt=7)    # CLK
    Pin(self.MISO, mode=Pin.ALT, alt=7)    # MISO
    Pin(self.MOSI, mode=Pin.ALT, alt=7)    # MOSI
    Pin(self.CS, mode=Pin.ALT, alt=7)    # NSS/CS

    self.spi = SPI(0)
    self.spi.init(mode=SPI.MASTER, baudrate=spd, polarity=0, phase=0, firstbit=SPI.MSB)
    self.pin_reset = Pin(self.RESET, mode=Pin.OUT)
    self.pin_reset.value(1)
    self.MFRC522_Init()
Yes, I use the default PIN for the SPI
Then, the init is:

Code: Select all

def MFRC522_Init(self):
    self.pin_reset.value(1)
    self.pin_reset.value(0)
    self.pin_reset.value(1)

    self.MFRC522_Reset();
    
    print("Test begin")
    self.Write_MFRC522(self.TModeReg, 0x8D)
    print("{} should be 0x8D".format(hex(self.Read_MFRC522(self.TModeReg))))
    print("Test end")
    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()
As you can see, I test that I the data I asked to be written in the register TModeReg has been written in it

Code: Select all

print("Test begin")
self.Write_MFRC522(self.TModeReg, 0x8D)
print("{} should be 0x8D".format(hex(self.Read_MFRC522(self.TModeReg))))
print("Test end")
My read/write methods are:

Code: Select all

def Write_MFRC522(self, addr, val):
    # 0(MSB = Write) ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 0(LSB = 0) DATA
    spiBytes = bytearray(2)
    spiBytes[0] = ((addr<<1)&0x7E) 
    spiBytes[1] = val
    return(self.spi.write(spiBytes))
  
def Read_MFRC522(self, addr):
    # 1(MSB = Read) ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 0(LSB = 0)
    spiAddr = bytearray(2)
    spiAddr[0] = ((addr<<1)&0x7E|0x80) 
    spiAddr[1] = 0x00
    data = bytearray(2)
    self.spi.write_readinto(spiAddr, data)
    print("read {} from {}".format(data, spiAddr))
    return data[1]
FYI, for this module, using SPI, to write data, for the first byte, MSB (first bit) shall be 0 and LSB (last bit) shall be 0 also. Then the 6 others bits are the address. The other bytes are the data we want to send.

To read, the behavior is similiar: each byte send is the address on which we want to read. The first bit of the byte (MSB) shall be 1 and the last bit (LSB) shall be 0, the others 6 bits are the address.
Now, to have the result, you need to read the next byte: you write the address on byte 0 and you have the value of the address in the byte 1.

To have the full detail, see page 10 and 11 of the doc I gave above ;)

But when I execute it on my WiPy, I have:

Code: Select all

>>> execfile('nfc.py')
>>> import nfc
>>> MIFAREReader = nfc.MFRC522()
Test begin
read bytearray(b'\xff\xff') from bytearray(b'\xd4\x00')
0xff should be 0x8D
Test end
So, here I am struggling: is my write failing or is my read not working correctly or did I miss to configure something?

If you have any idea, I would be grateful ;)

wendlers
Posts: 47
Joined: Wed Mar 16, 2016 10:07 pm

Re: SPI and MFRC522 Module: SPI read/wirte not working

Post by wendlers » Sun Aug 21, 2016 12:40 pm

Hi,

a while ago, I ported exactly that library you mentioned for WiPy and ESP. You might want to have a look at the results here:

https://github.com/wendlers/micropython-mfrc522

regards,
Stefan

Gabi
Posts: 18
Joined: Sat Mar 05, 2016 3:29 pm

Re: SPI and MFRC522 Module: SPI read/wirte not working

Post by Gabi » Sun Aug 21, 2016 2:50 pm

wendlers wrote:Hi,

a while ago, I ported exactly that library you mentioned for WiPy and ESP. You might want to have a look at the results here:

https://github.com/wendlers/micropython-mfrc522

regards,
Stefan
Hi,
Oh, that's great, thank you! :)

I've took a look and I have some questions ^^
  • - In the __init__, Why set the reset to 0 then set the CS to 1 and in the end, set the reset to 1? Why not set the reset and the CS to 1?
    - Why did you configure the PIN as out and not alternative on the SPI?
    - Why did you set the CS as HIGH in the init? Is it because the pin must be HIGH before communication? If yes, I guess that setting the CS as LOW in the read/write methods is to say to the board that data are sent. Am I correct?
    - In the _wreg method, why use the spi.write method twice by sending first the address and then the data and not use it once by sending both in the same time in the bytearray?
    - In the _rreg, I do not understand. In the doc, it says for the byte 0 send, you have to read the byte 1. In your method, you return the first byte returned by the spi.read, why?
For the rest of the code, it is similar to what I got from the library on github.

Anyway, thank you very much, I think the CS pin was my issue: I was never setting it, I only set the RESET to 1 in the __init__ method (I did not test it yet, but when I'll do, I'll let you know ;) )

Post Reply