PN532 Driver library This library provides an abstract API to drive the pn532 nfc chip, with I2C/HSU/SPI interface. Its based on the Seeed Studio's Arduino version.

Dependents:   PN532_ReadUid Nfctest2

Revision:
0:db8030e71f55
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532_IF/PN532_I2C.cpp	Tue Sep 13 06:01:19 2016 +0000
@@ -0,0 +1,179 @@
+////////////////////////////////////////////////////////////////////////////////
+// pn532 i2c interface for mbed platform
+// 
+// by dotnfc@163.com
+// 2016/09/10 18:16:00
+
+#include "PN532_I2C.h"
+#include "PN532_debug.h"
+#include "Arduino.h"
+
+
+PN532_I2C::PN532_I2C(mbed::I2C &wire)
+{
+    _wire = &wire;
+    command = 0;
+}
+
+void PN532_I2C::begin()
+{
+
+}
+
+void PN532_I2C::wakeup()
+{
+
+}
+
+int8_t PN532_I2C::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
+{
+    command = header[0];
+    MyBuffer <uint8_t> tBuf;
+        
+    tBuf.put (PN532_PREAMBLE);
+    tBuf.put (PN532_STARTCODE1);
+    tBuf.put (PN532_STARTCODE2);
+    
+    uint8_t length = hlen + blen + 1;   // length of data field: TFI + DATA
+    tBuf.put (length);
+    tBuf.put (~length + 1);                 // checksum of length
+    
+    tBuf.put (PN532_HOSTTOPN532);
+    uint8_t sum = PN532_HOSTTOPN532;    // sum of TFI + DATA
+    
+    DMSG("write: ");
+       
+    for (uint8_t i = 0; i < hlen; i++) {
+        tBuf.put (header[i]);
+        sum += header[i];
+        DMSG_HEX(header[i]);
+    }
+
+    for (uint8_t i = 0; i < blen; i++) {
+        tBuf.put (body[i]);
+        sum += body[i];
+        DMSG_HEX(body[i]);
+    }
+  
+    uint8_t checksum = ~sum + 1;            // checksum of TFI + DATA
+    tBuf.put (checksum);
+    tBuf.put (PN532_POSTAMBLE);
+    
+    _wire->write (PN532_I2C_ADDRESS, (const char *)tBuf.head(), tBuf.getLength());
+    
+    DMSG("\n");
+
+    return readAckFrame();
+}
+
+
+int16_t PN532_I2C::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
+{
+    uint8_t stat;
+    uint16_t tlen = 256 + 5;
+    MyBuffer <uint8_t> tBuf(256 + 5);
+    Timer timer;
+    if (timeout !=0) {
+        timer.start();
+    }
+    
+    do {
+        if (_wire->read (PN532_I2C_ADDRESS, (char *)&stat, 1) == 0) {
+
+            if (stat & 1) { // check the STATUS byte
+                wait_ms (2);
+                
+                if (tlen > len)
+                    tlen = len;
+                    
+                if (_wire->read(PN532_I2C_ADDRESS, (char *)tBuf.head(), tlen) == 0) {
+                    break;
+                }
+            }
+        }
+        
+        if (0 != timeout) {
+            if (timer.read_ms() > timeout) {
+                timer.stop ();
+                return -1;
+            }
+        }
+
+    } while (1); 
+    
+    if (0x01 != tBuf.get()      ||       // STATUS
+        0x00 != tBuf.get()      ||       // PREAMBLE
+        0x00 != tBuf.get()      ||       // STARTCODE1
+        0xFF != tBuf.get()               // STARTCODE2
+        ) {
+        
+        return PN532_INVALID_FRAME;
+    }
+    
+    uint8_t length = tBuf.get();
+    if (0 != (uint8_t)(length + tBuf.get())) {   // checksum of length
+        return PN532_INVALID_FRAME;
+    }
+    
+    uint8_t cmd = command + 1;               // response command
+    if (PN532_PN532TOHOST != tBuf.get() || (cmd) != tBuf.get()) {
+        return PN532_INVALID_FRAME;
+    }
+    
+    length -= 2;
+    if (length > len) {
+        return PN532_NO_SPACE;  // not enough space
+    }
+    
+    DMSG("read:  ");
+    DMSG_HEX(cmd);
+    
+    uint8_t sum = PN532_PN532TOHOST + cmd;
+    for (uint8_t i = 0; i < length; i++) {
+        buf[i] = tBuf.get();
+        sum += buf[i];
+        
+        DMSG_HEX(buf[i]);
+    }
+    DMSG("\n");
+    
+    uint8_t checksum = tBuf.get();
+    if (0 != (uint8_t)(sum + checksum)) {
+        DMSG("checksum is not ok\n");
+        return PN532_INVALID_FRAME;
+    }
+    //tBuf.get();         // POSTAMBLE
+    
+    return length;
+}
+
+int8_t PN532_I2C::readAckFrame()
+{
+    const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
+    MyBuffer <uint8_t> ackBuf(sizeof(PN532_ACK) + 1);
+    
+    Timer timer;
+    timer.start();
+    
+    do {
+        // if (_wire->requestFrom(PN532_I2C_ADDRESS,  sizeof(PN532_ACK) + 1)) {
+        if (_wire->read(PN532_I2C_ADDRESS, (char *)ackBuf.head(), sizeof(PN532_ACK) + 1) == 0) {
+            if (ackBuf.get() & 1) {  // check first byte --- status
+                break;         // PN532 is ready
+            }
+        }
+
+        if (timer.read_ms() > PN532_ACK_WAIT_TIME) {
+            DMSG("Time out when waiting for ACK\n");
+            timer.stop ();
+            return PN532_TIMEOUT;
+        }
+    } while (1);
+    
+    for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
+        if (ackBuf.get() != PN532_ACK[i])
+            return PN532_INVALID_ACK;
+    }
+    
+    return 0;
+}