Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PN532 by
Diff: PN532.cpp
- Revision:
- 3:4189a10038e6
- Parent:
- 2:f618fb2169c4
- Child:
- 4:0774b8298eb8
--- 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)); +} + +