PN532 NFC library for Seeed Studio's NFC Shield

Fork of PN532 by Yihui Xiong

Revision:
0:9c6b9280c0e1
Child:
1:b8cab5222fd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532_SPI.cpp	Tue Oct 08 08:33:22 2013 +0000
@@ -0,0 +1,203 @@
+
+#include "PN532_SPI.h"
+#include "debug.h"
+
+#define STATUS_READ     2
+#define DATA_WRITE      1
+#define DATA_READ       3
+
+PN532_SPI::PN532_SPI(SPI &spi, PinName ss) : _ss(ss)
+{
+    command = 0;
+    _spi = &spi;
+    _spi->format(8, 0);
+    _spi->frequency(2000000);
+    
+    _ss  = 1;
+}
+
+PN532_SPI::PN532_SPI(SPI *spi, PinName ss) : _ss(ss)
+{
+        command = 0;
+    _spi = spi;
+    _spi->format(8, 0);
+    _spi->frequency(2000000);
+    
+    _ss  = 1;
+}
+
+void PN532_SPI::begin()
+{
+
+}
+
+void PN532_SPI::wakeup()
+{
+    _ss = 0;
+    wait_ms(2);
+    _ss = 1;
+}
+
+int8_t PN532_SPI::writeCommand(const uint8_t buf[], uint8_t len)
+{
+    command = buf[0];
+    writeFrame(buf, len);
+    
+    uint8_t timeout = PN532_ACK_WAIT_TIME;
+    while (!isReady()) {
+        wait_ms(1);
+        timeout--;
+        if (0 == timeout) {
+            DMSG("Time out when waiting for ACK\n");
+            return -2;
+        }
+    }
+    if (readAckFrame()) {
+        DMSG("Invalid ACK\n");
+        return PN532_INVALID_ACK;
+    }
+    return 0;
+}
+
+int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
+{
+    uint16_t time = 0;
+    while (!isReady()) {
+        wait_ms(1);
+        time++;
+        if (timeout > 0 && time > timeout) {
+            return PN532_TIMEOUT;
+        }
+    }
+    
+    _ss = 0;
+    wait_ms(1);
+
+    int16_t result;
+    do {
+        write(DATA_READ);
+        
+        if (0x00 != read()      ||       // PREAMBLE
+                0x00 != read()  ||       // STARTCODE1
+                0xFF != read()           // STARTCODE2
+            ) {
+            
+            result = PN532_INVALID_FRAME;
+            break;
+        }
+        
+        uint8_t length = read();
+        if (0 != (uint8_t)(length + read())) {   // checksum of length
+            result = PN532_INVALID_FRAME;
+            break;
+        }
+        
+        uint8_t cmd = command + 1;               // response command
+        if (PN532_PN532TOHOST != read() || (cmd) != read()) {
+            result = PN532_INVALID_FRAME;
+            break;
+        }
+        
+        DMSG("read:  ");
+        DMSG_HEX(cmd);
+        
+        length -= 2;
+        if (length > len) {
+            for (uint8_t i = 0; i < length; i++) {
+                DMSG_HEX(read());                 // dump message
+            }
+            DMSG("\nNot enough space\n");
+            read();                                     
+            read();
+            result = PN532_NO_SPACE;  // not enough space
+            break;
+        }
+        
+        uint8_t sum = PN532_PN532TOHOST + cmd;
+        for (uint8_t i = 0; i < length; i++) {
+            buf[i] = read();
+            sum += buf[i];
+            
+            DMSG_HEX(buf[i]);
+        }
+        DMSG("\n");
+        
+        uint8_t checksum = read();
+        if (0 != (uint8_t)(sum + checksum)) {
+            DMSG("checksum is not ok\n");
+            result = PN532_INVALID_FRAME;
+            break;
+        }
+        read();         // POSTAMBLE
+        
+        result = length;
+    } while (0);
+    
+    _ss = 1;
+    
+    return result;
+}
+
+bool PN532_SPI::isReady()
+{
+    _ss = 0;
+    
+    write(STATUS_READ);
+    uint8_t status = read() & 1;
+    _ss = 1;
+    return status;
+}
+
+void PN532_SPI::writeFrame(const uint8_t buf[], uint8_t len)
+{
+    _ss = 0;
+    wait_ms(2);               // wake up PN532
+    
+    write(DATA_WRITE);
+    write(PN532_PREAMBLE);
+    write(PN532_STARTCODE1);
+    write(PN532_STARTCODE2);
+    
+    uint8_t length = len + 1;   // length of data field: TFI + DATA
+    write(length);
+    write(~length + 1);         // checksum of length
+    
+    write(PN532_HOSTTOPN532);
+    uint8_t sum = PN532_HOSTTOPN532;    // sum of TFI + DATA
+    
+    DMSG("write: ");
+    
+    for (uint8_t i = 0; i < len; i++) {
+        write(buf[i]);
+        sum += buf[i];
+        
+        DMSG_HEX(buf[i]);
+    }
+    
+    uint8_t checksum = ~sum + 1;        // checksum of TFI + DATA
+    write(checksum);
+    write(PN532_POSTAMBLE);
+    
+    _ss = 1; 
+    
+    DMSG("\n");
+}
+
+int8_t PN532_SPI::readAckFrame()
+{
+    const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
+    
+    uint8_t ackBuf[sizeof(PN532_ACK)];
+    
+    _ss = 0;
+    wait_ms(1);
+    write(DATA_READ);
+    
+    for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
+        ackBuf[i] = read();
+    }
+    
+    _ss = 1;
+    
+    return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK));
+}