nanoFramework.Iot.Device.Pn532 1.2.883

Prefix Reserved
dotnet add package nanoFramework.Iot.Device.Pn532 --version 1.2.883
                    
NuGet\Install-Package nanoFramework.Iot.Device.Pn532 -Version 1.2.883
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="nanoFramework.Iot.Device.Pn532" Version="1.2.883" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="nanoFramework.Iot.Device.Pn532" Version="1.2.883" />
                    
Directory.Packages.props
<PackageReference Include="nanoFramework.Iot.Device.Pn532" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add nanoFramework.Iot.Device.Pn532 --version 1.2.883
                    
#r "nuget: nanoFramework.Iot.Device.Pn532, 1.2.883"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package nanoFramework.Iot.Device.Pn532@1.2.883
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=nanoFramework.Iot.Device.Pn532&version=1.2.883
                    
Install as a Cake Addin
#tool nuget:?package=nanoFramework.Iot.Device.Pn532&version=1.2.883
                    
Install as a Cake Tool

PN532 - RFID and NFC reader

PN532 is a RFID and NFC reader. It does supports various standards: IsoIec14443TypeA, IsoIec14443TypeB, Iso18092. This implementation should support as well PN533 which is a full ASB serial only implementation and have few more registers and functions but looks retro compatible with this implementation.

Documentation

  • Official documentation can be fond here
  • Check out the [sample]'./samples) which contains more detailed on how to read other type of cards like Ultralight

Usage

You first need to create the class thru I2C, SPI or Serial.

string device = "COM2";
pn532 = new Pn532(device);

To act as a card reader, the PN532 has to be in listening mode. 2 options are available, either thru using the ListPassiveTarget either the AutoPoll functions.

Example with polling a simple passive 14443 type A card like a Mifare:

byte[] retData = null;
while (true)
{
    retData = pn532.ListPassiveTarget(MaxTarget.One, TargetBaudRate.B106kbpsTypeA);
    if (retData is object)
        break;
    // Give time to PN532 to process
    Thread.Sleep(200);
}

if (retData is null)
    return;

// You need to remove the first element at it's the number of tags read
// In, this case we will assume we are reading only 1 tag at a time
var tagData = new SpanByte(retData, 1, retData.Length - 1);
var decrypted = pn532.TryDecode106kbpsTypeA(tagData);

Example pooling a 14443 type B card like a credit card:

byte[] retData = null;
while (true)
{
    retData = pn532.AutoPoll(5, 300, new PollingType[] { PollingType.Passive106kbpsISO144443_4B });
    if (retData is object)
    {
        if (retData.Length >= 3)
            break;
    }

    // Give time to PN532 to process
    Thread.Sleep(200);
}

if (retData is null)
    return;

// Check how many tags and the type
Debug.WriteLine($"Num tags: {retData[0]}, Type: {(PollingType)retData[1]}");
// See documentation page 145
// You need to remove the first element at it's the number of tags read
// In, this case we will assume we are reading only 1 tag at a time
// The second element is the type of the card. In our case, because we are using a Credit Card, we already know it's a Type B card
// The thrid element is the size of the data
var tagData = new SpanByte(retData, 3, retData.Length - 3);
var decrypted = pn532.TryDecodeData106kbpsTypeB(tagData);

Reading or writing to cards

PN532 implement a ReadWrite function that allows to use a high level Mifare card class. This implementation abstract the reader which is used.

Once detected and selected like in the previous example, this fully dump the content of a classical Mifare 1K card:

if (decrypted is object)
{
    Debug.WriteLine($"Tg: {decrypted.TargetNumber}, ATQA: {decrypted.Atqa} SAK: {decrypted.Sak}, NFCID: {BitConverter.ToString(decrypted.NfcId)}");
    if (decrypted.Ats is object)
    Debug.WriteLine($", ATS: {BitConverter.ToString(decrypted.Ats)}");
    
    MifareCard mifareCard = new MifareCard(pn532, decrypted.TargetNumber) { BlockNumber = 0, Command = MifareCardCommand.AuthenticationA };
    mifareCard.SetCapacity(decrypted.Atqa, decrypted.Sak);
    mifareCard.SerialNumber = decrypted.NfcId;
    mifareCard.KeyA = new byte[6] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    mifareCard.KeyB = new byte[6] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };/
    for (byte block = 0; block < 64; block++)
    {
        mifareCard.BlockNumber = block;
        mifareCard.Command = MifareCardCommand.AuthenticationB;
        var ret = mifareCard.RunMifiCardCommand();
        if (ret < 0)
        {
            // Try another one
            mifareCard.Command = MifareCardCommand.AuthenticationA;
            ret = mifareCard.RunMifiCardCommand();
        }

        if (ret >= 0)
        {
            mifareCard.BlockNumber = block;
            mifareCard.Command = MifareCardCommand.Read16Bytes;
            ret = mifareCard.RunMifiCardCommand();
            if (ret >= 0)
                Debug.WriteLine($"Bloc: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
            else
            {
                Debug.WriteLine($"Error reading bloc: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
            }

            if (block % 4 == 3)
            {
                // Check what are the permissions
                for (byte j = 3; j > 0; j--)
                {
                    var access = mifareCard.BlockAccess((byte)(block - j), mifareCard.Data);
                    Debug.WriteLine($"Bloc: {block - j}, Access: {access}");
                }
                var sector = mifareCard.SectorTailerAccess(block, mifareCard.Data);
                Debug.WriteLine($"Bloc: {block}, Access: {sector}");
            }
        }
        else
        {
            Debug.WriteLine($"Authentication error");
        }
    }

PN532 as a target

It's possible to change the PN532 mode to be seen as a target byt another reader. A phone with NFC for example. The bellow example shows how to transform the PN532 into a Credit Card:

static void AsTarget(Pn532 pn532)
{
    byte[] retData = null;
    TargetModeInitialized modeInitialized = null;
    while (true)
    {
        (modeInitialized, retData) = pn532.InitAsTarget(
            TargetModeInitialization.PiccOnly, 
            new TargetMifareParameters() { Atqa = new byte[] { 0x08, 0x00 }, Sak = 0x60 },
            new TargetFeliCaParameters() { NfcId2 = new byte[] { 0x01, 0xFE, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7 }, Pad = new byte[] { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7 } },
            new TargetPiccParameters() { NfcId3 = new byte[] { 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, GeneralTarget = new byte[0], HistoricalTarget = new byte[0] });
        if (modeInitialized is object)
            break;

        // Give time to PN532 to process
        Thread.Sleep(200);
    }
    
    if (modeInitialized is null)
        return;

    Debug.WriteLine($"PN532 as a target: ISDep: {modeInitialized.IsDep}, IsPicc {modeInitialized.IsISO14443_4Picc}, {modeInitialized.TargetBaudRate}, {modeInitialized.TargetFramingType}");
    Debug.WriteLine($"Initiator: {BitConverter.ToString(retData)}");
    // 25-D4-00-E8-11-6A-0A-69-1C-46-5D-2D-7C-00-00-00-32-46-66-6D-01-01-12-02-02-07-FF-03-02-00-13-04-01-64-07-01-03
    // 11-D4-00-01-FE-A2-A3-A4-A5-A6-A7-00-00-00-00-00-30            
    // E0-80

    Span<byte> read = stackalloc byte[512];
    int ret = -1;
    while (ret<0)
        ret = pn532.ReadDataAsTarget(read);

    // For example: 00-00-A4-04-00-0E-32-50-41-59-2E-53-59-53-2E-44-44-46-30-31-00
    Debug.WriteLine($"Status: {read[0]}, Data: {BitConverter.ToString(read.Slice(1).ToArray())}");            
}

Note that this is just the first phase showing how to initialize the process, get the first data and read data. In this specific case, the emulation have to understand the commands sent by the reader and emulate properly a card.

It is possible to emulate any Type A, Type B and Felica cards.

Current implementation

Communication support:

  • HSU serial port: fully supported
  • I2C: supported
  • SPI: supported but using a specific chip select pin
    • SPI Mode should be Mode0 and LSB first
  • Hardware reset pin: This can be done with the user code

Miscellaneous commands:

  • Diagnose. Note: partial implementation, basics tests implemented only
  • GetFirmwareVersion
  • GetGeneralStatus
  • ReadRegister
  • WriteRegister
  • ReadGPIO
  • WriteGPIO
  • SetSerialBaudRate
  • SetParameters
  • SAMConfiguration
  • PowerDown

RF communication commands:

  • RFConfiguration
  • RFRegulationTest

PN532 as an initiator (reader) commands:

  • InJumpForDEP
  • InJumpForPSL
  • InListPassiveTarget
  • InATR
  • InPSL
  • InDataExchange
  • InCommunicateThru
  • InDeselect
  • InRelease
  • InSelect
  • InAutoPoll

PN532 as a Target (acting like a card)

  • TgInitAsTarget
  • TgSetGeneralBytes
  • TgGetData
  • TgSetData
  • TgSetMetaData
  • TgGetInitiatorCommand
  • TgResponseToInitiator
  • TgGetTargetStatus
Product Compatible and additional computed target framework versions.
.NET Framework net is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.883 184 4/28/2025
1.2.880 177 4/24/2025
1.2.864 202 4/2/2025
1.2.852 193 3/11/2025
1.2.842 240 3/5/2025
1.2.838 133 3/3/2025
1.2.835 161 2/27/2025
1.2.822 138 2/26/2025
1.2.790 149 2/5/2025
1.2.787 130 2/4/2025
1.2.775 129 2/4/2025
1.2.772 124 2/4/2025
1.2.755 137 1/31/2025
1.2.737 125 1/13/2025
1.2.729 124 1/8/2025
1.2.704 141 12/18/2024
1.2.696 134 12/16/2024
1.2.691 139 12/11/2024
1.2.673 158 10/23/2024
1.2.656 142 10/3/2024
1.2.631 137 8/28/2024
1.2.606 106 8/2/2024
1.2.595 139 7/24/2024
1.2.590 133 7/17/2024
1.2.570 152 6/14/2024
1.2.560 151 5/29/2024
1.2.548 148 5/15/2024
1.2.536 169 4/15/2024
1.2.486 184 2/2/2024
1.2.479 151 1/27/2024
1.2.446 276 11/17/2023
1.2.439 147 11/14/2023
1.2.436 158 11/10/2023
1.2.416 152 11/8/2023
1.2.329 242 5/26/2023
1.2.313 196 5/12/2023
1.2.297 220 5/3/2023
1.2.212 386 1/5/2023
1.2.203 345 12/28/2022
1.2.159 440 11/14/2022
1.2.153 429 11/5/2022
1.2.141 469 10/25/2022
1.2.128 464 10/22/2022
1.2.122 496 10/12/2022
1.2.118 484 10/11/2022
1.2.117 477 10/10/2022
1.2.114 444 10/8/2022
1.2.95 508 9/22/2022
1.2.89 510 9/16/2022
1.2.87 551 9/15/2022
1.2.73 482 9/8/2022
1.2.40 495 8/6/2022
1.2.35 483 8/4/2022
1.2.5 537 7/13/2022
1.1.141.41205 519 7/6/2022
1.1.116.8772 510 6/24/2022
1.1.113.2032 501 6/23/2022
1.1.111.5739 509 6/17/2022
1.1.109.32999 507 6/16/2022
1.1.99.36719 505 6/14/2022
1.1.97.17326 524 6/13/2022
1.1.92.53000 499 6/8/2022
1.1.67.25390 514 5/27/2022
1.1.48.19401 507 5/19/2022
1.1.38 519 5/4/2022
1.1.27 535 4/26/2022
1.1.20 529 4/21/2022
1.1.3 560 4/15/2022
1.1.1 546 4/14/2022
1.0.300 528 4/3/2022
1.0.278-preview.125 191 3/25/2022
1.0.278-preview.124 192 3/25/2022
1.0.278-preview.118 184 3/24/2022
1.0.278-preview.115 184 3/22/2022
1.0.278-preview.111 194 3/19/2022
1.0.278-preview.105 194 3/15/2022
1.0.278-preview.101 191 3/11/2022
1.0.278-preview.98 193 3/10/2022
1.0.278-preview.97 195 3/8/2022
1.0.278-preview.84 196 2/25/2022
1.0.278-preview.70 199 2/11/2022
1.0.278-preview.64 194 2/9/2022
1.0.278-preview.62 206 2/8/2022
1.0.278-preview.61 219 2/5/2022
1.0.278-preview.59 214 2/4/2022
1.0.278-preview.52 213 1/31/2022
1.0.278-preview.31 202 1/27/2022
1.0.278-preview.29 206 1/27/2022
1.0.278-preview.16 211 1/24/2022
1.0.278-preview.14 206 1/21/2022
1.0.278-preview.1 218 1/14/2022
1.0.272 243 1/10/2022
1.0.259 411 12/9/2021
1.0.221 253 10/19/2021
1.0.219 249 10/19/2021
1.0.218 282 10/18/2021
1.0.217 269 10/16/2021
1.0.194 285 10/1/2021
1.0.193 239 9/30/2021
1.0.191 255 9/29/2021
1.0.146 260 7/22/2021
1.0.140 263 7/20/2021