Pn532 + rc522 = ?

Hi all. I am trying to communicate with PN532 in ISO-14443-4 Tag mode with using RC522 Mini module.

There is my code for PN532 side. I am using C# and Iot.Device.Bindings library 3.1.0

using Iot.Device.Bmxx80;
using Iot.Device.Common;
using Iot.Device.FtCommon;
using Iot.Device.Pn532;
using Iot.Device.Pn532.AsTarget;
using Iot.Device.Pn532.RfConfiguration;
using Microsoft.Extensions.Logging;
using System.Text;

namespace pn532_clean
{
  class Device : IDisposable
  {
    public Device(string port)
    {
      _device = new Pn532(port);
      _device.SetAnalog106kbpsTypeA(new Analog106kbpsTypeAMode());
      Console.WriteLine($"Firmware version: {_device.FirmwareVersion}");
    }



    public void Dispose()
    {
      _device?.Dispose();
      _device = null;
    }

    private Pn532? _device;
  }

  class Program
  {
    public static Pn532 CreateDevice(string port)
    {
      var device = new Pn532(port);
      Console.WriteLine($"Firmware version: {device.FirmwareVersion}");
      Console.WriteLine($"Parameters flags: {device.ParametersFlags}");
      return device;
    }

    public static string ModeToString(TargetModeInitialized? mode)
    {
      var stringBuilder = new StringBuilder();
      if (mode != null)
      {
        stringBuilder.AppendLine($"Is ISO14443-4: {mode.IsISO14443_4Picc}");
        stringBuilder.Append("Framing type: ");
        switch (mode.TargetFramingType)
        {
          case TargetFramingType.Mifare:
            stringBuilder.AppendLine("Mifare");
            break;
          case TargetFramingType.ActiveMode:
            stringBuilder.AppendLine("Active mode");
            break;
          case TargetFramingType.FeliCa:
            stringBuilder.AppendLine("FeliCa");
            break;
        }
        stringBuilder.Append("Baud rate: ");
        switch (mode.TargetBaudRate)
        {
          case TargetBaudRateInialized.B106kbps:
            stringBuilder.AppendLine("106 kbps");
            break;
          case TargetBaudRateInialized.B212kbps:
            stringBuilder.AppendLine("212 kbps");
            break;
          case TargetBaudRateInialized.B424kbps:
            stringBuilder.AppendLine("424 kbps");
            break;
        }
      }
      return stringBuilder.ToString();
    }

    public static void Main(string[] args)
    {
      var port = "COM3";
      if (args.Length == 1)
      {
        port = args[0];
      }
      Console.WriteLine($"Port: {port}");

      // setup logs
      var loggerFactory = new SimpleConsoleLoggerFactory(LogLevel.Debug);
      LogDispatcher.LoggerFactory = loggerFactory;

      // setup device
      var device = CreateDevice(port);

      var mifareParams = new TargetMifareParameters();
      mifareParams.Atqa = [0x04, 0x00];
      mifareParams.Sak = 0x20;
      mifareParams.NfcId3 = [0x21, 0x22, 0x23];
      var felicaParams = new TargetFeliCaParameters();
      var piccParams = new TargetPiccParameters();
      while (true)
      {
        try
        {
          var (mode, initiator) = device.InitAsTarget(TargetModeInitialization.PiccOnly, mifareParams, felicaParams, piccParams);
          Console.Write(ModeToString(mode));
          if (initiator != null)
          {
            Console.WriteLine($"Initiator: {BitConverter.ToString(initiator)}");
            if (mode.IsISO14443_4Picc)
            {
              Span<byte> dataOut = [0x90, 0x00];
              Span<byte> dataIn = new byte[100];

              var numberOfBytes = device.ReadDataAsTarget(dataIn);
              if (numberOfBytes > 0)
              {
                Console.WriteLine($"Read from PCD [{numberOfBytes} bytes]: {BitConverter.ToString(dataIn.ToArray(), 0, numberOfBytes)}");
                dataOut[0] = 0x90;
                dataOut[1] = 0x00;
                device.WriteDataAsTarget(dataOut);
              }
              else
              {
                Console.WriteLine("Read from PCD failed");
                dataOut[0] = 0x90;
                dataOut[0] = 0x00;
                device.WriteDataAsTarget(dataOut);
              }
            }
          }
        }
        catch (TimeoutException ex)
        {
          Console.WriteLine($"Timeout exception: {ex}");
        }
        catch (Exception ex)
        {
          Console.WriteLine($"Exception: {ex}");
          device.Dispose();

          device = CreateDevice(port);
        }

      }
    }
  }
}

Below is RC522 side. I am using library miguelbalboa/rfid 1.4.11:

#include <SPI.h>
#include <MFRC522Extended.h>

#include <array>

#define SS_PIN  (D8)
#define RST_PIN (D4)

MFRC522Extended mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance.

void setup() {
  Serial.begin(115200);  // Initiate a serial communication
  while(!Serial)
    delay(50);

  SPI.begin();  // Initiate  SPI bus

  mfrc522.PCD_Init();  // Initiate MFRC522

  Serial.println("Approximate your card to the reader...");
  Serial.println();

  mfrc522.PCD_SetAntennaGain(MFRC522::RxGain_48dB);
  Serial.print("Antenna gain: ");
  Serial.println(mfrc522.PCD_GetAntennaGain());

  Serial.print("Final antenna gain: ");
  Serial.println(mfrc522.PCD_GetAntennaGain());
}

void loop() {
  // Look for new cards
  if (!mfrc522.PICC_IsNewCardPresent()) {
    delay(50);
    return;
  }

  // Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial()) {
    delay(50);
    return;
  }

  mfrc522.PICC_DumpDetailsToSerial(&mfrc522.uid);
  mfrc522.PICC_DumpISO14443_4(&mfrc522.tag);
  dumpAts(&mfrc522.tag.ats);

  std::array<byte, 100> dataIn = {};
  byte dataInSize = dataIn.size();
  std::array<byte, 14> dataOut = {0x00, 0x00, 0xa4, 0x04, 0x00, 0x07, 0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00};

  for (auto i = 0; i < dataOut.size(); ++i) {
    dataOut[i] = i;
  }

  auto status = mfrc522.TCL_Transceive(&mfrc522.tag, dataOut.data(), dataOut.size(), dataIn.data(), &dataInSize);
  // auto status = mfrc522.PCD_TransceiveData(dataOut.data(), dataOut.size(), dataIn.data(), &dataInSize);
  if (status == MFRC522::STATUS_OK) {
    Serial.printf("Received [%d bytes]: ", dataInSize);
    for (int i = 0; i < dataInSize; ++i) {
      Serial.printf("%02x ", dataIn[i]);
    }
    Serial.println("");
  } else {
    Serial.printf("Transfer failed with status: %s\n", MFRC522::GetStatusCodeName(status));
  }

  mfrc522.TCL_Deselect(&mfrc522.tag);
}

I have received next ATS from PN532:
05 75 33 92 03

what means

T0:
TA1 = True
TB1 = True
TC1 = True
FSCI = 5

TA1:
DiffDivs = False
DS8 = False
DS4 = True
DS2 = True
DR8 = False
DR4 = True
DR2 = True

TC1:
CID = True
NAD = True

Based on erceived ATS values RC522 library check DS2 bit in TA1 byte and send PPS request to card to accept speed of 212 kBd. PN532 and answer OK to PPS and RC522 apply this speed to itself.

Then PN532 exit out of call InitAsTarget and tell me, that mode is 106 kBd, what's seems wrong. Afterwards PN532 TgGetData alwasy return or 0x2 error, or 0x13.

I've tried to force 106 kBd speed in RC522 library (change the code after receiveing ATS) but it didn't help.

Maybe somebody faced with similar problem or have an idea, what i need to check to resolve communication issues?

Forget to say, that with NFC tool on the phone all works. Not stable, but works.

What is the arduino board on this side?

@b707 It is nodemcu 1.0

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.