B4R Library rPN532 RFID reader/writer

kolbe

Active Member
Licensed User
Here's a library using the Adafruit arduino library for SPI and I2C access to the PN532 RFID/Near Field Communication chip.

I've tested the SPI but not I2C. I've also tested all the Mifare functions. Not all the methods in the original library are exposed as at this point I'm not sure what they all do.

This library should be event driven for card detection as the the MFRC522 library does but I don't fully understand how to do that. The method readPassiveTargetID will block until a card is present but you can set a timeout to limit how long your program is blocked.


B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Public nfc As PN532
    Public high As ULong
    Public keya(6)=Array As Byte(0xff,0xff,0xff,0xff,0xff,0xff) As Byte
    Public uid(7)=Array As Byte(0,0,0,0,0,0,0) As Byte
    Public uid_len(1) As Byte
    Public bc As ByteConverter
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
  
    nfc.Initialize1(10)
  
    Public low=nfc.FirmwareVersion As ULong
    high=low
    RunNative("shift_right", Null) '32bit shift, return top 16 bits
    Log("chip: ",Bit.HighByte(high))
    Log("version: ",Bit.LowByte(high))
    Log("revision: ",Bit.HighByte(low))
    Log("support: ",Bit.LowByte(low))
  
    nfc.PassiveActivationRetries(0xff)
  
    If nfc.SAMConfig Then
        Log("config passed")
        AddLooper("read_card_data")
'        write_read
    Else
        Log("reader config problem")
    End If
End Sub

Sub write_read
  
    'detect a card over the reader, blocks code, timeout 1 secs
    If nfc.readPassiveTargetID(0,uid,uid_len,10000) Then
        Log("uid length is: ",uid_len(0))
        nfc.PrintHex(uid,uid_len(0))
      
        Public data(16)=Array As Byte(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) As Byte
        Public blck=5 As Int
      
        'must authenticate a sector with key before reading
        Log("auth: ",nfc.mifareclassic_AuthenticateBlock(uid,uid_len(0),blck,0,keya))
      
        'now we can read the block
        Log("read: ",nfc.mifareclassic_ReadDataBlock(blck,data))
        nfc.PrintHexChar(data,16)
      
        'create byte array to write to card
        data=Array As Byte(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
        Public str()=bc.StringToBytes("your data here") As Byte
        bc.ArrayCopy2(str,0,data,0,str.Length)
        nfc.PrintHexChar(data,data.Length)
      
        'write array to card
        Log("write: ",nfc.mifareclassic_WriteDataBlock(blck,data))
      
        'read block that was just written
        Log("read: ",nfc.mifareclassic_ReadDataBlock(blck,data))
        nfc.PrintHexChar(data,16)
    Else
        Log("no card timeout")
    End If
End Sub

Sub read_card_data
    Public success As Boolean
  
    If nfc.readPassiveTargetID(0,uid,uid_len,1000) Then
        Log("uid length is: ",uid_len(0))
        nfc.PrintHex(uid,uid_len(0))
      
        Public data(16)=Array As Byte(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) As Byte
        For i = 0 To 63
            If nfc.mifareclassic_IsFirstBlock(i) Then
                success=nfc.mifareclassic_AuthenticateBlock(uid,uid_len(0),i,0,keya)
                Log("block auth: ",i)
            End If
            If success Then
                If nfc.mifareclassic_ReadDataBlock(i,data) Then
                    nfc.PrintHexChar(data,16)
                Else
                    Log("failed to read block")
                End If
            Else
                Log("block auth failure")
                Return
            End If
        Next
    Else
        Log("no card")
    End If
End Sub

#if C
void shift_right(B4R::Object* unused)
{
b4r_main::_high = b4r_main::_high >> 16;
}
#End If
 

Attachments

Last edited by a moderator:
Top