Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for extended frames, fixes #38 #39

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions Adafruit_PN532.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

@section HISTORY

v2.2 - Added support for extended frames

v2.1 - Added NTAG2xx helper functions

v2.0 - Refactored to add I2C support from Adafruit_NFCShield_I2C library.
Expand Down Expand Up @@ -643,14 +645,14 @@ bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, ui
@param responseLength Pointer to the response data length
*/
/**************************************************************************/
bool Adafruit_PN532::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint8_t * responseLength) {
bool Adafruit_PN532::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint16_t * responseLength) {
if (sendLength > PN532_PACKBUFFSIZ-2) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("APDU length too long for packet buffer"));
#endif
return false;
}
uint8_t i;
uint16_t i;

pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
pn532_packetbuffer[1] = _inListedTag;
Expand All @@ -675,17 +677,31 @@ bool Adafruit_PN532::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t
readdata(pn532_packetbuffer,sizeof(pn532_packetbuffer));

if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 && pn532_packetbuffer[2] == 0xff) {
uint8_t length = pn532_packetbuffer[3];
if (pn532_packetbuffer[4]!=(uint8_t)(~length+1)) {

uint16_t length;
uint8_t checksumOffset;
uint8_t lengthChecksum;
if (pn532_packetbuffer[3] == PN532_EXTENDED_FRAME_FIXED_VALUE && pn532_packetbuffer[4] == PN532_EXTENDED_FRAME_FIXED_VALUE) {
//It's an extended frame
length = (((uint16_t) pn532_packetbuffer[5]) << 8) | pn532_packetbuffer[6];
lengthChecksum = (uint8_t)(~(pn532_packetbuffer[5]+pn532_packetbuffer[6])+1);
checksumOffset = 3; //length is encoded in three more bytes (two fixed values 0xFF and an additional octet for the length itself)
} else {
length = pn532_packetbuffer[3];
lengthChecksum = (uint8_t)(~length+1);
checksumOffset = 0;
}

if (pn532_packetbuffer[checksumOffset+4]!=lengthChecksum) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("Length check invalid"));
PN532DEBUGPRINT.println(length,HEX);
PN532DEBUGPRINT.println((~length)+1,HEX);
#endif
return false;
}
if (pn532_packetbuffer[5]==PN532_PN532TOHOST && pn532_packetbuffer[6]==PN532_RESPONSE_INDATAEXCHANGE) {
if ((pn532_packetbuffer[7] & 0x3f)!=0) {
if (pn532_packetbuffer[checksumOffset+5]==PN532_PN532TOHOST && pn532_packetbuffer[checksumOffset+6]==PN532_RESPONSE_INDATAEXCHANGE) {
if ((pn532_packetbuffer[checksumOffset+7] & 0x3f)!=0) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("Status code indicates an error"));
#endif
Expand All @@ -699,8 +715,9 @@ bool Adafruit_PN532::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t
}

for (i=0; i<length; ++i) {
response[i] = pn532_packetbuffer[8+i];
response[i] = pn532_packetbuffer[checksumOffset+8+i];
}

*responseLength = length;

return true;
Expand Down Expand Up @@ -1564,7 +1581,7 @@ bool Adafruit_PN532::waitready(uint16_t timeout) {
@param n Number of bytes to be read
*/
/**************************************************************************/
void Adafruit_PN532::readdata(uint8_t* buff, uint8_t n) {
void Adafruit_PN532::readdata(uint8_t* buff, uint16_t n) {
if (_usingSPI) {
// SPI write.
#ifdef SPI_HAS_TRANSACTION
Expand All @@ -1577,7 +1594,7 @@ void Adafruit_PN532::readdata(uint8_t* buff, uint8_t n) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.print(F("Reading: "));
#endif
for (uint8_t i=0; i<n; i++) {
for (uint16_t i=0; i<n; i++) {
delay(1);
buff[i] = spi_read();
#ifdef PN532DEBUG
Expand Down Expand Up @@ -1605,10 +1622,10 @@ void Adafruit_PN532::readdata(uint8_t* buff, uint8_t n) {
PN532DEBUGPRINT.print(F("Reading: "));
#endif
// Start read (n+1 to take into account leading 0x01 with I2C)
WIRE.requestFrom((uint8_t)PN532_I2C_ADDRESS, (uint8_t)(n+2));
WIRE.requestFrom((uint8_t)PN532_I2C_ADDRESS, (uint16_t)(n+2));
// Discard the leading 0x01
i2c_recv();
for (uint8_t i=0; i<n; i++) {
for (uint16_t i=0; i<n; i++) {
delay(1);
buff[i] = i2c_recv();
#ifdef PN532DEBUG
Expand Down
5 changes: 3 additions & 2 deletions Adafruit_PN532.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define PN532_STARTCODE1 (0x00)
#define PN532_STARTCODE2 (0xFF)
#define PN532_POSTAMBLE (0x00)
#define PN532_EXTENDED_FRAME_FIXED_VALUE (0xFF)

#define PN532_HOSTTOPN532 (0xD4)
#define PN532_PN532TOHOST (0xD5)
Expand Down Expand Up @@ -170,7 +171,7 @@ class Adafruit_PN532{

// ISO14443A functions
bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, uint8_t * uidLength, uint16_t timeout = 0); //timeout 0 means no timeout - will block forever.
bool inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint8_t * responseLength);
bool inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint16_t * responseLength);
bool inListPassiveTarget();

// Mifare Classic functions
Expand Down Expand Up @@ -206,7 +207,7 @@ class Adafruit_PN532{
bool _hardwareSPI; // True is using hardware SPI, false if using software SPI.

// Low level communication functions that handle both SPI and I2C.
void readdata(uint8_t* buff, uint8_t n);
void readdata(uint8_t* buff, uint16_t n);
void writecommand(uint8_t* cmd, uint8_t cmdlen);
bool isready();
bool waitready(uint16_t timeout);
Expand Down