PN532 NFC library for Seeed Studio's NFC Shield

Fork of PN532 by Yihui Xiong

Revision:
3:4189a10038e6
Parent:
2:f618fb2169c4
Child:
4:0774b8298eb8
diff -r f618fb2169c4 -r 4189a10038e6 PN532.cpp
--- a/PN532.cpp	Thu Oct 17 06:51:32 2013 +0000
+++ b/PN532.cpp	Thu Nov 21 04:30:49 2013 +0000
@@ -1,73 +1,22 @@
 /**************************************************************************/
 /*!
     @file     PN532.cpp
-    @author   Adafruit Industries & Seeed Technology Inc.
-
-    NXP's PN532 NFC/13.56MHz RFID Transceiver
-
-    @section  HISTORY
-    v1.6 - Ported to mbed
-
-    v1.5 - Modified to support I2C and SPI
-
-    v1.4 - Added setPassiveActivationRetries()
-
-    v1.3 - Modified to work with I2C
-
-    v1.2 - Added writeGPIO()
-         - Added readGPIO()
-
-    v1.1 - Changed readPassiveTargetID() to handle multiple UID sizes
-         - Added the following helper functions for text display
-             static void PrintHex(const uint8_t * data, const uint32_t numBytes)
-             static void PrintHexChar(const uint8_t * pbtData, const uint32_t numBytes)
-         - Added the following Mifare Classic functions:
-             bool mifareclassic_IsFirstBlock (uint32_t uiBlock)
-             bool mifareclassic_IsTrailerBlock (uint32_t uiBlock)
-             uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData)
-             uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data)
-             uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
-         - Added the following Mifare Ultalight functions:
-             uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
+    @author   Adafruit Industries & Seeed Studio
+    @license  BSD
 */
 /**************************************************************************/
 
+#include "PN532.h"
+#include "PN532_debug.h"
 #include <string.h>
-#include "PN532.h"
-#include "debug.h"
-
-#include "PN532_SPI.h"
 
 #define HAL(func)   (_interface->func)
 
-uint8_t pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
-
-// Uncomment these lines to enable debug output for PN532(I2C) and/or MIFARE related code
-#define PN532DEBUG
-// #define MIFAREDEBUG
-
-#define PN532_PACKBUFFSIZ 128
-uint8_t pn532_packetbuffer[PN532_PACKBUFFSIZ];
-
-
 PN532::PN532(PN532Interface &interface)
 {
     _interface = &interface;
 }
 
-PN532::PN532(PinName mosi, PinName miso, PinName sclk, PinName cs)
-{
-    _spi = new SPI(mosi, miso, sclk);
-    _interface = new PN532_SPI(_spi, cs);
-}
-
-PN532::~PN532()
-{
-    if (_spi) {
-        delete _spi;
-    }
-}
-
 /**************************************************************************/
 /*!
     @brief  Setups the HW
@@ -89,11 +38,22 @@
 /**************************************************************************/
 void PN532::PrintHex(const uint8_t *data, const uint32_t numBytes)
 {
+#ifdef ARDUINO
     for (uint8_t i = 0; i < numBytes; i++) {
-        DMSG("0x");
-        DMSG_HEX(data[i]);
+        if (data[i] < 0x10) {
+            Serial.print(" 0");
+        } else {
+            Serial.print(' ');
+        }
+        Serial.print(data[i], HEX);
     }
-    DMSG("\n");
+    Serial.println("");
+#else
+    for (uint8_t i = 0; i < numBytes; i++) {
+        printf(" %2X", data[i]);
+    }
+    printf("\n");
+#endif
 }
 
 /**************************************************************************/
@@ -109,11 +69,40 @@
 /**************************************************************************/
 void PN532::PrintHexChar(const uint8_t *data, const uint32_t numBytes)
 {
+#ifdef ARDUINO
     for (uint8_t i = 0; i < numBytes; i++) {
-        DMSG("0x");
-        DMSG_HEX(data[i]);
+        if (data[i] < 0x10) {
+            Serial.print(" 0");
+        } else {
+            Serial.print(' ');
+        }
+        Serial.print(data[i], HEX);
+    }
+    Serial.print("    ");
+    for (uint8_t i = 0; i < numBytes; i++) {
+        char c = data[i];
+        if (c <= 0x1f || c > 0x7f) {
+            Serial.print('.');
+        } else {
+            Serial.print(c);
+        }
     }
-    DMSG("\n");
+    Serial.println("");
+#else
+    for (uint8_t i = 0; i < numBytes; i++) {
+        printf(" %2X", data[i]);
+    }
+    printf("    ");
+    for (uint8_t i = 0; i < numBytes; i++) {
+        char c = data[i];
+        if (c <= 0x1f || c > 0x7f) {
+            printf(".");
+        } else {
+            printf("%c", c);
+        }
+        printf("\n");
+    }
+#endif
 }
 
 /**************************************************************************/
@@ -247,6 +236,8 @@
     pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
     pn532_packetbuffer[3] = 0x01; // use IRQ pin!
 
+    DMSG("SAMConfig\n");
+
     if (HAL(writeCommand)(pn532_packetbuffer, 4))
         return false;
 
@@ -274,7 +265,7 @@
     if (HAL(writeCommand)(pn532_packetbuffer, 5))
         return 0x0;  // no ACK
 
-    return 1;
+    return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
 }
 
 /***** ISO14443A Commands ******/
@@ -670,44 +661,34 @@
 /**************************************************************************/
 bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength)
 {
-    if (sendLength > PN532_PACKBUFFSIZ - 2) {
-        DMSG("APDU length too long for packet buffer");
-
-        return false;
-    }
     uint8_t i;
 
     pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
     pn532_packetbuffer[1] = inListedTag;
-    for (i = 0; i < sendLength; ++i) {
-        pn532_packetbuffer[i + 2] = send[i];
-    }
 
-    if (HAL(writeCommand)(pn532_packetbuffer, sendLength + 2)) {
+    if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) {
         return false;
     }
 
-
-    int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 1000);
+    int16_t status = HAL(readResponse)(response, *responseLength, 1000);
     if (status < 0) {
         return false;
     }
 
-    uint8_t length = status;
-
-    if ((pn532_packetbuffer[0] & 0x3f) != 0) {
+    if ((response[0] & 0x3f) != 0) {
         DMSG("Status code indicates an error\n");
         return false;
     }
 
+    uint8_t length = status;
     length -= 1;
 
     if (length > *responseLength) {
         length = *responseLength; // silent truncation...
     }
 
-    for (i = 0; i < length; ++i) {
-        response[i] = pn532_packetbuffer[1 + i];
+    for (uint8_t i = 0; i < length; i++) {
+        response[i] = response[i + 1];
     }
     *responseLength = length;
 
@@ -746,12 +727,29 @@
     return true;
 }
 
+int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout){
+  
+  int8_t status = HAL(writeCommand)(command, len);
+    if (status < 0) {
+        return -1;
+    }
+
+    status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout);
+    if (status > 0) {
+        return 1;
+    } else if (PN532_TIMEOUT == status) {
+        return 0;
+    } else {
+        return -2;
+    }
+}
+
 /**
  * Peer to Peer
  */
-int8_t PN532::tgInitAsTarget()
+int8_t PN532::tgInitAsTarget(uint16_t timeout)
 {
-    static const uint8_t command[] = {
+    const uint8_t command[] = {
         PN532_COMMAND_TGINITASTARGET,
         0,
         0x00, 0x00,         //SENS_RES
@@ -766,54 +764,49 @@
 
         0x06, 0x46,  0x66, 0x6D, 0x01, 0x01, 0x10, 0x00// LLCP magic number and version parameter
     };
+    return tgInitAsTarget(command, sizeof(command), timeout);
+}
 
-    int8_t status = HAL(writeCommand)(command, sizeof(command));
-    if (status < 0) {
+int16_t PN532::tgGetData(uint8_t *buf, uint8_t len)
+{
+    buf[0] = PN532_COMMAND_TGGETDATA;
+
+    if (HAL(writeCommand)(buf, 1)) {
+        return -1;
+    }
+
+    int16_t status = HAL(readResponse)(buf, len, 3000);
+    if (0 >= status) {
         return status;
     }
 
-    return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 0);
-}
-
-int16_t PN532::tgGetData(uint8_t *buf, uint16_t len)
-{
-    pn532_packetbuffer[0] = PN532_COMMAND_TGGETDATA;
-
-    if (HAL(writeCommand)(pn532_packetbuffer, 1)) {
-        return -1;
-    }
+    uint16_t length = status - 1;
 
-    int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000);
-    if (0 > status) {
-        return status;
-    }
 
-    uint16_t length = status;
-    if (length > len) {
-        return -4;
-    }
-
-    if (pn532_packetbuffer[0] != 0) {
+    if (buf[0] != 0) {
         DMSG("status is not ok\n");
         return -5;
     }
 
-    memcpy(buf, pn532_packetbuffer + 1, length - 1);
+    for (uint8_t i = 0; i < length; i++) {
+        buf[i] = buf[i + 1];
+    }
 
-
-    return length - 1;
+    return length;
 }
 
-bool PN532::tgSetData(const uint8_t *buf, uint16_t len)
+bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
 {
-    pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
-    if (len > (sizeof(pn532_packetbuffer) + 1)) {
+    if (hlen > (sizeof(pn532_packetbuffer) - 1)) {
         return false;
     }
 
-    memcpy(pn532_packetbuffer + 1, buf, len);
+    for (int8_t i = hlen - 1; i >= 0; i--){
+        pn532_packetbuffer[i + 1] = header[i];
+    }
+    pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
 
-    if (HAL(writeCommand)(pn532_packetbuffer, len + 1)) {
+    if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) {
         return false;
     }
 
@@ -827,3 +820,18 @@
 
     return true;
 }
+
+int16_t PN532::inRelease(const uint8_t relevantTarget){
+
+    pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
+    pn532_packetbuffer[1] = relevantTarget;
+
+    if (HAL(writeCommand)(pn532_packetbuffer, 2)) {
+        return 0;
+    }
+
+    // read data packet
+    return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
+}
+
+