PN532 NFC library for Seeed Studio's NFC Shield
Fork of PN532 by
Diff: PN532.cpp
- 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)); +} + +