upm  1.7.1
Sensor/Actuator repository for libmraa (v2.0.0)
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes

API for the PN532 based NFC/RFID reader/writer. More...

Detailed Description

pn532.jpg

Identify a card and print out basic info

// Instantiate an PN532 on I2C bus 0 (default) using gpio 3 for the
// IRQ, and gpio 2 for the reset pin.
upm::PN532 nfc(3, 2);
if (!nfc.init())
cerr << "init() failed" << endl;
uint32_t vers = nfc.getFirmwareVersion();
if (vers)
printf("Got firmware version: 0x%08x\n", vers);
else {
printf("Could not identify PN532\n");
return 1;
}
// Now scan and identify any cards that come in range (1 for now)
// Retry forever
nfc.setPassiveActivationRetries(0xff);
nfc.SAMConfig();
uint8_t uidSize;
uint8_t uid[7];
while (shouldRun) {
memset(uid, 0, 7);
if (nfc.readPassiveTargetID(nfc.BAUD_MIFARE_ISO14443A, uid, &uidSize, 2000)) {
// found a card
printf("Found a card: UID len %d\n", uidSize);
printf("UID: ");
for (int i = 0; i < uidSize; i++)
printf("%02x ", uid[i]);
printf("\n");
printf("SAK: 0x%02x\n", nfc.getSAK());
printf("ATQA: 0x%04x\n\n", nfc.getATQA());
upm_delay(1);
} else {
printf("Waiting for a card...\n");
}
}

Add a URI to an already NDEF formatted ultralight or NTAG2XX tag

// Instantiate an PN532 on I2C bus 0 (default) using gpio 3 for the
// IRQ, and gpio 2 for the reset pin.
upm::PN532 nfc(3, 2);
if (!nfc.init())
cerr << "init() failed" << endl;
uint32_t vers = nfc.getFirmwareVersion();
if (vers)
printf("Got firmware version: 0x%08x\n", vers);
else {
printf("Could not identify PN532\n");
return 1;
}
// Now scan and identify any cards that come in range (1 for now)
// Retry forever
nfc.setPassiveActivationRetries(0xff);
nfc.SAMConfig();
uint8_t uidSize;
uint8_t uid[7];
bool foundCard = false;
while (!foundCard) {
memset(uid, 0, 7);
if (nfc.readPassiveTargetID(nfc.BAUD_MIFARE_ISO14443A, uid, &uidSize, 2000)) {
// found a card
printf("Found a card: UID len %d\n", uidSize);
printf("UID: ");
for (int i = 0; i < uidSize; i++)
printf("%02x ", uid[i]);
printf("\n");
printf("SAK: 0x%02x\n", nfc.getSAK());
printf("ATQA: 0x%04x\n\n", nfc.getATQA());
foundCard = true;
} else {
printf("Waiting for a card...\n");
}
}
if (uidSize != 7) {
printf("This example will only write an NDEF URI to preformatted\n");
printf("Mifare Ultralight or NTAG2XX tags\n");
return 1;
}
// 48 bytes is maximum data area on ultralight cards, so we use that
// as the maximum datasize here. Obviously if you have a bigger
// card, you can write more data.
if (!nfc.ntag2xx_WriteNDEFURI(nfc.NDEF_URIPREFIX_HTTP, url, 48)) {
// failure
printf("Failed to write NDEF record tag.\n");
return 1;
}
printf("Success, URL record written to tag.\n");

Public Types

enum  PN532_CMD_T {
  CMD_DIAGNOSE = 0x00, CMD_GETFIRMWAREVERSION = 0x02, CMD_GETGENERALSTATUS = 0x04, CMD_READREGISTER = 0x06,
  CMD_WRITEREGISTER = 0x08, CMD_READGPIO = 0x0C, CMD_WRITEGPIO = 0x0E, CMD_SETSERIALBAUDRATE = 0x10,
  CMD_SETPARAMETERS = 0x12, CMD_SAMCONFIGURATION = 0x14, CMD_POWERDOWN = 0x16, CMD_RFCONFIGURATION = 0x32,
  CMD_RFREGULATIONTEST = 0x58, CMD_INJUMPFORDEP = 0x56, CMD_INJUMPFORPSL = 0x46, CMD_INLISTPASSIVETARGET = 0x4A,
  CMD_INATR = 0x50, CMD_INPSL = 0x4E, CMD_INDATAEXCHANGE = 0x40, CMD_INCOMMUNICATETHRU = 0x42,
  CMD_INDESELECT = 0x44, CMD_INRELEASE = 0x52, CMD_INSELECT = 0x54, CMD_INAUTOPOLL = 0x60,
  CMD_TGINITASTARGET = 0x8C, CMD_TGSETGENERALBYTES = 0x92, CMD_TGGETDATA = 0x86, CMD_TGSETDATA = 0x8E,
  CMD_TGSETMETADATA = 0x94, CMD_TGGETINITIATORCOMMAND = 0x88, CMD_TGRESPONSETOINITIATOR = 0x90, CMD_TGGETTARGETSTATUS = 0x8A
}
 
enum  PN532_RSP_T { RSP_INDATAEXCHANGE = 0x41, RSP_INLISTPASSIVETARGET = 0x4B }
 
enum  MIFARE_CMD_T {
  MIFARE_CMD_AUTH_A = 0x60, MIFARE_CMD_AUTH_B = 0x61, MIFARE_CMD_READ = 0x30, MIFARE_CMD_WRITE = 0xA0,
  MIFARE_CMD_TRANSFER = 0xB0, MIFARE_CMD_DECREMENT = 0xC0, MIFARE_CMD_INCREMENT = 0xC1, MIFARE_CMD_STORE = 0xC2,
  MIFARE_ULTRALIGHT_CMD_WRITE = 0xA2
}
 
enum  NDEF_URI_T {
  NDEF_URIPREFIX_NONE = 0x00, NDEF_URIPREFIX_HTTP_WWWDOT = 0x01, NDEF_URIPREFIX_HTTPS_WWWDOT = 0x02, NDEF_URIPREFIX_HTTP = 0x03,
  NDEF_URIPREFIX_HTTPS = 0x04, NDEF_URIPREFIX_TEL = 0x05, NDEF_URIPREFIX_MAILTO = 0x06, NDEF_URIPREFIX_FTP_ANONAT = 0x07,
  NDEF_URIPREFIX_FTP_FTPDOT = 0x08, NDEF_URIPREFIX_FTPS = 0x09, NDEF_URIPREFIX_SFTP = 0x0A, NDEF_URIPREFIX_SMB = 0x0B,
  NDEF_URIPREFIX_NFS = 0x0C, NDEF_URIPREFIX_FTP = 0x0D, NDEF_URIPREFIX_DAV = 0x0E, NDEF_URIPREFIX_NEWS = 0x0F,
  NDEF_URIPREFIX_TELNET = 0x10, NDEF_URIPREFIX_IMAP = 0x11, NDEF_URIPREFIX_RTSP = 0x12, NDEF_URIPREFIX_URN = 0x13,
  NDEF_URIPREFIX_POP = 0x14, NDEF_URIPREFIX_SIP = 0x15, NDEF_URIPREFIX_SIPS = 0x16, NDEF_URIPREFIX_TFTP = 0x17,
  NDEF_URIPREFIX_BTSPP = 0x18, NDEF_URIPREFIX_BTL2CAP = 0x19, NDEF_URIPREFIX_BTGOEP = 0x1A, NDEF_URIPREFIX_TCPOBEX = 0x1B,
  NDEF_URIPREFIX_IRDAOBEX = 0x1C, NDEF_URIPREFIX_FILE = 0x1D, NDEF_URIPREFIX_URN_EPC_ID = 0x1E, NDEF_URIPREFIX_URN_EPC_TAG = 0x1F,
  NDEF_URIPREFIX_URN_EPC_PAT = 0x20, NDEF_URIPREFIX_URN_EPC_RAW = 0x21, NDEF_URIPREFIX_URN_EPC = 0x22, NDEF_URIPREFIX_URN_NFC = 0x23
}
 
enum  BAUD_T { BAUD_MIFARE_ISO14443A = 0x00 }
 
enum  TAG_TYPE_T { TAG_TYPE_UNKNOWN = 0, TAG_TYPE_MIFARE_CLASSIC = 1, TAG_TYPE_NFC2 = 2 }
 

Public Member Functions

 PN532 (int irq, int reset, int bus=PN532_I2C_BUS, uint8_t address=PN532_DEFAULT_I2C_ADDR)
 
 ~PN532 ()
 
bool init ()
 
uint32_t getFirmwareVersion ()
 Checks the firmware version of the PN5xx chip. More...
 
bool sendCommandCheckAck (uint8_t *cmd, uint8_t cmdlen, uint16_t timeout=1000)
 Sends a command and waits a specified period for the ACK. More...
 
bool SAMConfig (void)
 Configures the SAM (Secure Access Module) More...
 
bool setPassiveActivationRetries (uint8_t maxRetries)
 
bool readPassiveTargetID (BAUD_T cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
 
bool inDataExchange (uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength)
 Exchanges an APDU with the currently inlisted peer. More...
 
bool inListPassiveTarget ()
 'InLists' a passive target. PN532 acting as reader/initiator, peer acting as card/responder. More...
 
bool mifareclassic_IsFirstBlock (uint32_t uiBlock)
 
bool mifareclassic_IsTrailerBlock (uint32_t uiBlock)
 
bool mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData)
 
bool mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
 
bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data)
 
bool mifareclassic_FormatNDEF (void)
 
bool mifareclassic_WriteNDEFURI (uint8_t sectorNumber, NDEF_URI_T uriIdentifier, const char *url)
 
bool ntag2xx_ReadPage (uint8_t page, uint8_t *buffer)
 
bool ntag2xx_WritePage (uint8_t page, uint8_t *data)
 
bool ntag2xx_WriteNDEFURI (NDEF_URI_T uriIdentifier, char *url, uint8_t dataLen)
 
uint16_t getATQA ()
 
uint8_t getSAK ()
 
mraa::I2c & i2cContext ()
 
void pn532Debug (bool enable)
 
void mifareDebug (bool enable)
 
TAG_TYPE_T tagType ()
 

Protected Member Functions

bool readAck ()
 Tries to read/verify the ACK packet.
 
bool isReady ()
 Return true if the PN532 is ready with a response.
 
bool waitForReady (uint16_t timeout)
 Waits until the PN532 is ready. More...
 
void readData (uint8_t *buff, uint8_t n)
 Reads n bytes of data from the PN532 via SPI or I2C. More...
 
void writeCommand (uint8_t *cmd, uint8_t cmdlen)
 Writes a command to the PN532, automatically inserting the preamble and required frame details (checksum, len, etc.) More...
 

Protected Attributes

mraa::Gpio m_gpioIRQ
 
mraa::Gpio m_gpioReset
 
mraa::I2c m_i2c
 

Member Enumeration Documentation

PN532 commands

Response bytes

MIFARE commands

enum NDEF_URI_T

NDEF prefixes

enum BAUD_T

Card baud rates

enum TAG_TYPE_T

Tag types

Constructor & Destructor Documentation

PN532 ( int  irq,
int  reset,
int  bus = PN532_I2C_BUS,
uint8_t  address = PN532_DEFAULT_I2C_ADDR 
)

pn532 constructor

Parameters
irqpin to use for IRQ
resetreset pin
busi2c bus to use
addressthe address for this device

Here is the call graph for this function:

~PN532 ( )

PN532 Destructor

Member Function Documentation

bool init ( )

set up initial values and start operation

Returns
true if successful
uint32_t getFirmwareVersion ( )

Checks the firmware version of the PN5xx chip

Returns
the chip's firmware version and ID
The chip's firmware version and ID

Here is the call graph for this function:

bool sendCommandCheckAck ( uint8_t *  cmd,
uint8_t  cmdlen,
uint16_t  timeout = 1000 
)

sends a command and waits a specified period for the ACK

Parameters
cmdPointer to the command buffer
cmdlenthe size of the command in bytes
timeouttimeout before giving up (in ms)
Returns
true if everything is OK, false if timeout occurred before an ACK was received
Parameters
cmdPointer to the command buffer
cmdlenThe size of the command in bytes
timeouttimeout before giving up
Returns
1 if everything is OK, 0 if timeout occurred before an ACK was received

Here is the call graph for this function:

Here is the caller graph for this function:

bool SAMConfig ( void  )

configures the SAM (Secure Access Module)

Returns
true if successfully configured

Here is the call graph for this function:

bool setPassiveActivationRetries ( uint8_t  maxRetries)

sets the MxRtyPassiveActivation byte of the RFConfiguration register. By default the pn532 will retry indefinitely.

Parameters
maxRetries0xFF to wait forever, 0x00..0xFE to timeout after maxRetries. 0x00 means try once, with no retries on failure.
Returns
true if everything executed properly, false for an error

Sets the MxRtyPassiveActivation byte of the RFConfiguration register

Parameters
maxRetries0xFF to wait forever, 0x00..0xFE to timeout after mxRetries
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

bool readPassiveTargetID ( BAUD_T  cardbaudrate,
uint8_t *  uid,
uint8_t *  uidLength,
uint16_t  timeout 
)

waits for an ISO14443A target to enter the field

Parameters
cardbaudratebaud rate of the card, one of the BAUD_T values
uidPointer to the array that will be populated with the cards UID, up to 7 bytes
uidLengthPointer to the variable that will hold the length of the card's UID.
timeoutthe number of milliseconds to wait
Returns
true if everything executed properly, false for an error

Waits for an ISO14443A target to enter the field

Parameters
cardBaudRateBaud rate of the card
uidPointer to the array that will be populated with the card's UID (up to 7 bytes)
uidLengthPointer to the variable that will hold the length of the card's UID.
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

bool inDataExchange ( uint8_t *  send,
uint8_t  sendLength,
uint8_t *  response,
uint8_t *  responseLength 
)

exchanges an APDU (Application Protocol Data Unit) with the currently inlisted peer

Parameters
sendPointer to data to send
sendLengthLength of the data to send
responsePointer to response data
responseLengthPointer to the response data length
Returns
true if everything executed properly, false for an error
Parameters
sendPointer to data to send
sendLengthLength of the data to send
responsePointer to response data
responseLengthPointer to the response data length

Here is the call graph for this function:

bool inListPassiveTarget ( )

'InLists' a passive target. PN532 acting as reader/initiator, peer acting as card/responder.

Returns
true if everything executed properly, false for an error

Here is the call graph for this function:

bool mifareclassic_IsFirstBlock ( uint32_t  uiBlock)

Indicates whether the specified block number is the first block in the sector (block 0 relative to the current sector)

Returns
true if it's the first block, false otherwise

Indicates whether the specified block number is the first block in the sector (block 0 relative to the current sector)

bool mifareclassic_IsTrailerBlock ( uint32_t  uiBlock)

indicates whether the specified block number is the sector trailer

Returns
true if it's the trailer block, false otherwise

Indicates whether the specified block number is the sector trailer

bool mifareclassic_AuthenticateBlock ( uint8_t *  uid,
uint8_t  uidLen,
uint32_t  blockNumber,
uint8_t  keyNumber,
uint8_t *  keyData 
)

tries to authenticate a block of memory on a MIFARE card using the INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual for more information on sending MIFARE and other commands.

Parameters
uidPointer to a byte array containing the card UID
uidLenThe length (in bytes) of the card's UID (Should be 4 for MIFARE Classic)
blockNumberThe block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards).
keyNumberWhich key type to use during authentication (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
keyDataPointer to a byte array containing the 6 byte key value
Returns
true if everything executed properly, false for an error

Tries to authenticate a block of memory on a MIFARE card using the INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual for more information on sending MIFARE and other commands.

Parameters
uidPointer to a byte array containing the card UID
uidLenThe length (in bytes) of the card's UID (Should be 4 for MIFARE Classic)
blockNumberThe block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards).
keyNumberWhich key type to use during authentication (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
keyDataPointer to a byte array containing the 6 byte key value
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

bool mifareclassic_ReadDataBlock ( uint8_t  blockNumber,
uint8_t *  data 
)

tries to read an entire 16-byte data block at the specified block address.

Parameters
blockNumberThe block number to read (0..63 for 1KB cards, and 0..255 for 4KB cards).
dataPointer to the byte array that will hold the retrieved data (if any)
Returns
true if everything executed properly, false for an error

Tries to read an entire 16-byte data block at the specified block address.

Parameters
blockNumberThe block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards).
dataPointer to the byte array that will hold the retrieved data (if any)
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

bool mifareclassic_WriteDataBlock ( uint8_t  blockNumber,
uint8_t *  data 
)

tries to write an entire 16-byte data block at the specified block address.

Parameters
blockNumberThe block number to write. (0..63 for 1KB cards, and 0..255 for 4KB cards).
dataThe byte array that contains the data to write.
Returns
true if everything executed properly, false for an error

Tries to write an entire 16-byte data block at the specified block address.

Parameters
blockNumberThe block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards).
dataThe byte array that contains the data to write.
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

Here is the caller graph for this function:

bool mifareclassic_FormatNDEF ( void  )

formats a Mifare Classic card to store NDEF Records

Returns
true if everything executed properly, false for an error

Formats a Mifare Classic card to store NDEF Records

Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

bool mifareclassic_WriteNDEFURI ( uint8_t  sectorNumber,
NDEF_URI_T  uriIdentifier,
const char *  url 
)

writes an NDEF URI Record to the specified sector (1..15)

Note that this function assumes that the Mifare Classic card is already formatted to work as an "NFC Forum Tag" and uses a MAD1 file system. You can use the NXP TagWriter app on Android to properly format cards for this.

Parameters
sectorNumberThe sector that the URI record should be written to (can be 1..15 for a 1K card)
uriIdentifierThe uri identifier code (one of the NDEF_URI_T values
urlthe uri text to write (max 38 characters).
Returns
true if everything executed properly, false for an error

Writes an NDEF URI Record to the specified sector (1..15)

Note that this function assumes that the Mifare Classic card is already formatted to work as an "NFC Forum Tag" and uses a MAD1 file system. You can use the NXP TagWriter app on Android to properly format cards for this.

Parameters
sectorNumberThe sector that the URI record should be written to (can be 1..15 for a 1K card)
uriIdentifierThe uri identifier code (0 = none, 0x01 = "http://www.", etc.)
urlThe uri text to write (max 38 characters).
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

bool ntag2xx_ReadPage ( uint8_t  page,
uint8_t *  buffer 
)

read an entire 4-byte page at the specified address

Parameters
pageThe page number (0..63 in most cases)
bufferPointer to the byte array that will hold the retrieved data (if any)
Returns
true if everything executed properly, false for an error

Tries to read an entire 4-byte page at the specified address.

Parameters
pageThe page number (0..63 in most cases)
bufferPointer to the byte array that will hold the retrieved data (if any)

Here is the call graph for this function:

bool ntag2xx_WritePage ( uint8_t  page,
uint8_t *  data 
)

write an entire 4-byte page at the specified block address

Parameters
pageThe page number to write. (0..63 for most cases)
dataThe byte array that contains the data to write. Should be exactly 4 bytes long.
Returns
true if everything executed properly, false for an error

Tries to write an entire 4-byte page at the specified block address.

Parameters
pageThe page number to write. (0..63 for most cases)
dataThe byte array that contains the data to write. Should be exactly 4 bytes long.
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

Here is the caller graph for this function:

bool ntag2xx_WriteNDEFURI ( NDEF_URI_T  uriIdentifier,
char *  url,
uint8_t  dataLen 
)

writes an NDEF URI Record starting at the specified page (4..nn)

Note that this function assumes that the NTAG2xx card is already formatted to work as an "NFC Forum Tag".

Parameters
uriIdentifierThe uri identifier code (one of the NDEF_URI_T values
urlThe uri text to write (null-terminated string).
dataLenThe size of the data area for overflow checks.
Returns
true if everything executed properly, false for an error

Writes an NDEF URI Record starting at the specified page (4..nn)

Note that this function assumes that the NTAG2xx card is already formatted to work as an "NFC Forum Tag".

Parameters
uriIdentifierThe uri identifier code (0 = none, 0x01 = "http://www.", etc.)
urlThe uri text to write (null-terminated string).
dataLenThe size of the data area for overflow checks.
Returns
1 if everything executed properly, 0 for an error

Here is the call graph for this function:

uint16_t getATQA ( )
inline

return the ATQA (Answer to Request Acknowledge) value. This value is only valid after a successful call to readPassiveTargetID()

Returns
ATQA value
uint8_t getSAK ( )
inline

return the SAK (Select Acknowledge) value. This value is only valid after a successful call to readPassiveTargetID()

Returns
SAK value
mraa::I2c& i2cContext ( )
inline

provide public access to the class's MRAA i2C context for direct user access

Returns
a reference to the class i2c context
void pn532Debug ( bool  enable)
inline

enable or disable debugging output for pn532 related operations

Parameters
enabletrue to enabloe debug output, false to disable

Here is the caller graph for this function:

void mifareDebug ( bool  enable)
inline

enable or disable debugging output for mifare related operations

Parameters
enabletrue to enabloe debug output, false to disable

Here is the call graph for this function:

Here is the caller graph for this function:

PN532::TAG_TYPE_T tagType ( )

try to determine the tag type

Returns
one of the TAG_TYPE_T values

Here is the caller graph for this function:

bool waitForReady ( uint16_t  timeout)
protected
Parameters
timeoutTimeout before giving up

Here is the call graph for this function:

Here is the caller graph for this function:

void readData ( uint8_t *  buff,
uint8_t  n 
)
protected
Parameters
buffPointer to the buffer where data will be written
nNumber of bytes to be read

Here is the caller graph for this function:

void writeCommand ( uint8_t *  cmd,
uint8_t  cmdlen 
)
protected
Parameters
cmdPointer to the command buffer
cmdlenCommand length in bytes

Here is the caller graph for this function:


The documentation for this class was generated from the following files: