PN532 & MIFARE

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

PN532 & MIFARE

Postby Nador » Wed Jun 06, 2012 6:46 am

Hi guys,

i've bought the pn532 breakout board couple of months ago, and now wanted to start with it.
I'm using a PIC18F4520 mcu and connected it via I2C (voltage level is 3.3V, PullUps included, communication works fine).
My goal is to emulate a mifare card with the pn532, so that i can read data with a nfc - enabled smartphone.

For starters, i want to read the mifare card which was included in the breakout board (mifare one IC, 8K Bit EEPROM).

Communication works, the pn532 acks the command, and returns status byte / return command, but the InListPassiveTarget (D4 4A 01 00 h) response tells me that there is no target detected. I've tried another mifare card (from the 2nd board i ordered) but it doesn't work either.

Can someone have a look at my code bulding the frame (to avoid a simple mistake there..):

Code: Select all
    unsigned int dataArray2[] = {0x4A, 0x01, 0x00};
    const int dataLength = 3;
    int count = 0;
    int dataFrame[dataLength + FRAME_OVERHEAD];
    //preamble
    dataFrame[0] = 0x00;
    //start code
    dataFrame[1] = 0x00;
    dataFrame[2] = 0xFF;
    //LEN = length data  + 1(TFI byte = frame identifier = 0xD4)
    dataFrame[3] = dataLength + 1;
    //length checksum LCS, lower byte of [LCS + LEN] = 0x00
    dataFrame[4] = (256 - (dataLength + 1));
    //TFI
    dataFrame[5] = 0xD4;
   
    //insert data into the frame   
    for(i = 0; i < dataLength; i++) {
        dataFrame[6 + i] = dataArray2[i];
    }

    //calculate DCS checksum, lower byte of [TFI + Data + DCS] = 0x00
    unsigned int dataChecksum  = 256 - 0xD4;

    for(i=0; i< dataLength; i++) {
        dataChecksum -= dataArray2[i];   
    }

    dataFrame[6 + dataLength] = dataChecksum;
    //postamble, end of data
    dataFrame[7 + dataLength] = 0x00;





Any help or hint will be appriciated.

Greetings from germany.
Jul

€dit: I hope this is the right sub-forum, if not: please relocate the thread.
Nador
 
Posts: 6
Joined: Wed Jun 06, 2012 6:29 am

Re: PN532 & MIFARE

Postby papyrus » Wed Jun 06, 2012 10:41 am

Your code looks okay, although I would recommend that you declare the array as an array of type unsigned char. You're using type int, which would work however you're wasting 8 bits of memory for each element since an int is 16 bits and you're only using 8 of those bits. In the code below, I'm using 'sum' as the sum of all the characters that make up the frame identifier and the packet data, and calculating the DCS as follows:

unsigned char DCS = (unsigned char)(0x00 - (unsigned char)sum)

Since you're getting an ACK frame and a response frame you're code is probably working, but you may want to use unsigned chars moving forward to save memory.

Back to your initial problem, which is not detecting a target when you try the InListPass command (D4 4A....). In my code (PIC32), I verify that the ACK frame is received then I poll in a loop for the next response frame, this gives the user time to actually place the MiFARE card in the field of the PN532. The code will basically loop infinitely until it detects a response frame on the UART receive pins. I've attached a code snippet, check it out, I am assuming your code does something similar

One thing you may want to check/verify is the parameter that governs how long InListPass will poll. It's called MxRtyPassiveActivation and can be set using the RFConfiguration command (bottom of page 103 of the PN532 user manual rev 02). By default it is set to 0xFF, which means it will try to activate targets relentlessly (eternally), so you should be okay, however in my experience setting this parameter to anything but 0xFF causes it to timeout almost instantly, not enough time time to tap a MiFare card. Verify that this parameter is set to 0xFF

You did not post the response frame you're getting, so I thought I'd post what a successful target activation looks like:

00 00 FF 00 FF 00 00 00 FF 0C F4 D5 4B 01 01 00 04 08 04 5D B0 06 A3 18 00

The first is the ACK frame, the next is the response frame after reading a MiFARE 1K card with UID= 5D B0 06 A3h. What response are you getting?
Attachments
code.c
(918 Bytes) Downloaded 82 times
papyrus
 
Posts: 7
Joined: Sat Dec 03, 2011 1:44 am

Re: PN532 & MIFARE

Postby Nador » Fri Jun 08, 2012 4:21 am

Thanks for your response.
I'm already using the RFConfiguration command (0x32, 0x05, 0x02, 0x01, 0xFF), but with this configuration the inListPassiveTarget returns only a acknowledge frame, and i keep polling the status byte infinitely..
When i want to receive a response frame, i need to change the number of retries to a value not equal 0xFF.

What i just discovered is that with increasing the databuffer (where i store the response frame) the pic reads the frame and afterwards receives 3 "random" bytes i can't explain.

RFConfiguration:
dataFrame -> 00 00 FF 06 FA D4 32 05 02 01 FE F4 00
ack <- 00 FF 00 FF 00
response <- 00 00 FF 02 FE D5 33 F8 00 [01 FE F4 00] <- "random" bytes

inListPassiveTarget:
dataFrame -> 00 00 FF 04 FC D4 4A 01 00 E1 00
ack <- 00 FF 00 FF 00
response <- 00 00 FF 03 FD D5 4B 00 E0 00 [FE F4 00]

Here's my code snippet for the transmission (i hope there are no major mistakes..):

Code: Select all
i2c_start();
    delay_ms(15);
    while((ackStatusWrite =  i2c_write(NFC_ADDRESS_W)) != 0) {
      delay_ms(5);
   }

    //if the pn532 acks its address, start sending dataframe
    for(i=0; i<(dataLength + FRAME_OVERHEAD); i++) {
        i2c_write(dataFrame[i]);
    }

    //change to the device read address
    i2c_start();   
    delay_ms(15);
    while((ackStatusRead =  i2c_write(NFC_ADDRESS_R)) != 0) {
      delay_ms(5);
   }
   //poll the status byte; statusByte = 1: answer frame ready
    int statusByte = i2c_read();
    while(statusByte != 0x01) {
      count++;
      i2c_stop();
      i2c_start();
        ackStatusRead =  i2c_write(NFC_ADDRESS_R);
      statusByte = i2c_read();
   }
   
    //read acknowledge data
    for(i=0; i<6; i++) {
        ackBuffer[i] = i2c_read();
    }
   
   int frameACK = true;
    //check if ack is okay
    for(i = 0; i < 6; i++) {
        if(ackBuffer[i] != ackSequence[i]) {
            frameACK = false;
        }
    }

   //poll the status byte; statusByte = 1: answer frame ready   
    statusByte = i2c_read();
    while(statusByte != 0x01) {
      count++;
      i2c_stop();
      i2c_start();
        ackStatusRead =  i2c_write(NFC_ADDRESS_R);
      statusByte = i2c_read();
   }
          
   //read data from pn532
    for(i=0; i<18; i++) {
        dataBuffer2[i] = i2c_read();
    }

   //ack frame to slave
   i2c_start();
   i2c_write(NFC_ADDRESS_W);
   
   for(i=0; i<6; i++) {
        i2c_write(ackSequence[i]);
    }

    i2c_stop();


Again thanks for your efforts.

Jul
Nador
 
Posts: 6
Joined: Wed Jun 06, 2012 6:29 am

Re: PN532 & MIFARE

Postby papyrus » Sat Jun 09, 2012 2:24 pm

Sorry I just saw this now, I will look at your code when I have a bit of time to delve into it, however at first glance it seems you're doing pretty much what I have done, although I'm using a UART connection. What you're saying about the RFConfiguration command and needing to set the MxRtyPassiveActivation parameter to something not equal to 0xFF is a bit mystifying. Your description makes sense regarding getting an ACK frame and then no response frame at all makes perfect sense if the MIFARE card you're using is suspect. The PN532 will behave exactly as you describe with the 0xFF setting if it detects no card. You will have to abort the command (after some reasonable timeout) by sending another command, a benign one such as GetFirmwareVersion or some such. However I would immediately revert to the default 0xFF parameter since without it your card will have to be read in a matter of milliseconds only adding to the frustration in debugging this since your card may be good but just not ideally placed to couple to the PN532's RF field in that short a time.

What you've tried (I guess) is playing with that setting thinking it will help detect your card, however from what you're describing it seems that your initial thought was correct, that the card is damaged. I've seen some funny behavior with cards before so it's not impossible I suppose. What you could try is to read a Visa payWave card or Mastercard payPass card. With my setup I am able to read my Visa cards using the 106 kbs baud rate with type A framing (or at least those from Canadian banks I suppose). If you can read a Visa card then your MIFARE card could be damaged. If you can't read the Visa card but you know it works since you recently paid for something using it's contactless feature then there may be a larger issue with the PN532 perhaps. At that point, I would suggest running some diagnostics using the Diagnose command, although the antenna test is a bit odd from my experience and does not behave like the user manual suggests but that's a whole different post..

About your random bytes, I can't comment since I'm not too familiar with the I2C interface, however your random bytes are the same four bytes as the last four of your dataFrame, so that's probably not a coincidence. Since you're using an I2C interface it's harder to spy on that connection with a windows terminal program, however have you tried spying on what the PN532 is sending back using a program called Real Terminal? It has a feature for I2C buses, although I've never used it myself (this is the reason I started with a UART connection, so I could spy on it with a basic serial port)

Real Terminal: http://realterm.sourceforge.net/ It's an exceptional tool that has greatly aided in my development.

Good luck and I'll try to look into your code a bit later.
papyrus
 
Posts: 7
Joined: Sat Dec 03, 2011 1:44 am

Re: PN532 & MIFARE

Postby papyrus » Sat Jun 09, 2012 2:33 pm

I assume I shall hear no response until after the football match...otherwise I'd be disappointed...LOL
papyrus
 
Posts: 7
Joined: Sat Dec 03, 2011 1:44 am

Re: PN532 & MIFARE

Postby Nador » Mon Jun 11, 2012 3:21 am

You're right, football took lot of my time recently :D

Since it was my initial thought, i replaced the card with a MIFARE 1K card from a friend (working, we can read it with a nexus), and i also tried
my student identity card and so on.. so i guess there must be something wrong with my code or hardware.

On the I2C: i'm going to have access to a bus pirate and try to examine the connection, as soon as i have an result, i'll post it here.

Thanks again.
Nador
 
Posts: 6
Joined: Wed Jun 06, 2012 6:29 am

Re: PN532 & MIFARE

Postby Nador » Thu Jun 14, 2012 6:08 am

Ok, so i tried various approaches to check the i2c - connection, and it seems fine so far.
The "random" bytes are data trash in my opinion, and eventually don't bother me because i know
the length of the data frames.

But i could not make a step ahead with the mifare reading.

So any hint will be appreciated.
Nador
 
Posts: 6
Joined: Wed Jun 06, 2012 6:29 am

Re: PN532 & MIFARE

Postby papyrus » Thu Jun 14, 2012 9:43 am

What about the diagnostics of the PN532? How did that go?
papyrus
 
Posts: 7
Joined: Sat Dec 03, 2011 1:44 am

Re: PN532 & MIFARE

Postby Nador » Fri Jun 15, 2012 5:50 am

diagnostics: ROM test -> fine
communication line test -> fine
RAM test -> fine
I can't use the antenna self test, since i don't know which parameter i should use for the threshold,
the datasheet says nothing about it.

But looking at the results, i would say communication and controller are working...
Nador
 
Posts: 6
Joined: Wed Jun 06, 2012 6:29 am

Re: PN532 & MIFARE

Postby papyrus » Sat Jun 16, 2012 1:35 pm

Hmm...I should look more closely into how I have done the antenna test then. Perhaps the threshold is H
Threshold = 0.1875 A/m as per the EMCA-340 specification. Are you using the Adafruit breakout board? What is your hardware?

It seems that you can easily issue and successfully process the response from commands that have an "immediate" response rather than a staggered one. For example, you're able to do the ROM and RAM tests, and the RFConfig command, all of which the PN532 can process quickly and respond to almost instantly (approximately 650 us with the UART set at 115.2 kBaud as per some scope traces I took)

Now commands that have a staggered response seem to be tripping up your code. This could be the way you're polling for the response. In my code I had to wait for the buffer to become full before I began processing a response frame from a command such as InListPass before I could use that command successfully. I use an interrupt (the source of which is the UART receive line) to properly buffer characters whenever they are sent from the PN532. Now it also helps that my code generally polls the buffer status at precisely the right time so that the buffer never overflows (buff size = 300 for me). In fact, the first thing I do before attempt to read an ACK or a response frame, is wait (Delayms()) about 10 ms, just so that the processor has time to be interrupted and buffer the response the next few lines of code will attempt to process.

I had a similar problem as you before I cleaned up the code to wait for the buffer to be full in the case of commands that the PN532 does not respond to quickly, especially InListPass since a card needs to be detected before the response is sent (if the timeout is set at the default 0xFF)

Keep at it, since I doubt there is a problem with your H/W or your cards. Can you switch to a UART to just get it working, then try the I2C? That was my approach.
papyrus
 
Posts: 7
Joined: Sat Dec 03, 2011 1:44 am

Re: PN532 & MIFARE

Postby Nador » Mon Jun 18, 2012 7:49 am

Hardware: Adafruit breakout board, PIC18F4520, MPlab ICD 3(Debugger)
Software: MPlab IDE, CCS Compiler

Here's how i understand the I2C - communication, just to avoid a misunderstanding (without handshake, page 42/43 user manual):

1) send command
2) poll the status byte until it is 0x01 (as mentioned in the manual by re-establishing the I2C - communication)
3)read acknowledge
4)if acknowdlege is okay, poll the status byte (as above)
5)read answer frame
6)send ackframe to the pn532

As soon as i have the time, i'll try using the pn532 via UART or SPI, but i have to present the results i have so far
on thursday... ^^
Nador
 
Posts: 6
Joined: Wed Jun 06, 2012 6:29 am

Re: PN532 & MIFARE

Postby cesarcardoso » Thu Apr 04, 2013 7:12 am

Hello.

Nador I see you using PIC on your project. I started my project with PIC16F877 and I am with some difficulties. Maybe you can know the answer to some of my questions and if you do not mind contact me, and maybe we can discuss commun problems related to I2C communication with PIC's.

viewtopic.php?f=8&t=38633&p=191019#p191019

César Cardoso
cesarcardoso@ua.pt
cesarcardoso
 
Posts: 3
Joined: Wed Apr 03, 2013 9:53 am


Return to General Project help

Who is online

Users browsing this forum: Google [Bot] and 8 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [108]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[31]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[34]
LCDs & Displays[48]
Components & Parts[70]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[111]
 
Wireless[14]
Cables[62]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]