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 Felica Support #22

Open
wants to merge 3 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
245 changes: 164 additions & 81 deletions Adafruit_PN532.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ static inline uint8_t i2c_recv(void)
*/
/**************************************************************************/
Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss):
_ss(ss),
_clk(clk),
_miso(miso),
_mosi(mosi),
_ss(ss),
_miso(miso),
_irq(0),
_reset(0),
_usingSPI(true),
Expand All @@ -146,10 +146,10 @@ Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t
*/
/**************************************************************************/
Adafruit_PN532::Adafruit_PN532(uint8_t irq, uint8_t reset):
_ss(0),
_clk(0),
_miso(0),
_mosi(0),
_ss(0),
_miso(0),
_irq(irq),
_reset(reset),
_usingSPI(false),
Expand All @@ -167,10 +167,10 @@ Adafruit_PN532::Adafruit_PN532(uint8_t irq, uint8_t reset):
*/
/**************************************************************************/
Adafruit_PN532::Adafruit_PN532(uint8_t ss):
_ss(ss),
_clk(0),
_miso(0),
_mosi(0),
_ss(ss),
_miso(0),
_irq(0),
_reset(0),
_usingSPI(true),
Expand Down Expand Up @@ -558,75 +558,156 @@ bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, ui
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
pn532_packetbuffer[2] = cardbaudrate;

if (!sendCommandCheckAck(pn532_packetbuffer, 3, timeout))
{
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("No card(s) read"));
#endif
return 0x0; // no cards read
}

// wait for a card to enter the field (only possible with I2C)
if (!_usingSPI) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("Waiting for IRQ (indicates card presence)"));
#endif
if (!waitready(timeout)) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("IRQ Timeout"));
#endif
return 0x0;
}
}

// read data packet
readdata(pn532_packetbuffer, 20);
// check some basic stuff

/* ISO14443A card response should be in the following format:

byte Description
------------- ------------------------------------------
b0..6 Frame header and preamble
b7 Tags Found
b8 Tag Number (only one used in this example)
b9..10 SENS_RES
b11 SEL_RES
b12 NFCID Length
b13..NFCIDLen NFCID */

#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("Found ")); PN532DEBUGPRINT.print(pn532_packetbuffer[7], DEC); PN532DEBUGPRINT.println(F(" tags"));
#endif
if (pn532_packetbuffer[7] != 1)
return 0;

uint16_t sens_res = pn532_packetbuffer[9];
sens_res <<= 8;
sens_res |= pn532_packetbuffer[10];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("ATQA: 0x")); PN532DEBUGPRINT.println(sens_res, HEX);
PN532DEBUGPRINT.print(F("SAK: 0x")); PN532DEBUGPRINT.println(pn532_packetbuffer[11], HEX);
#endif

/* Card appears to be Mifare Classic */
*uidLength = pn532_packetbuffer[12];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("UID:"));
#endif
for (uint8_t i=0; i < pn532_packetbuffer[12]; i++)
{
uid[i] = pn532_packetbuffer[13+i];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F(" 0x"));PN532DEBUGPRINT.print(uid[i], HEX);
#endif
}
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.println();
#endif

return 1;

switch(cardbaudrate){
case PN532_MIFARE_ISO14443A:{ //==================================================================================================
if (!sendCommandCheckAck(pn532_packetbuffer, 3, timeout)) //no extra info is needed to ask for MiFare information
{
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("No card(s) read"));
#endif
return 0x0; // no cards read
}

// wait for a card to enter the field (only possible with I2C)
if (!_usingSPI) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("Waiting for IRQ (indicates card presence)"));
#endif
if (!waitready(timeout)) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("IRQ Timeout"));
#endif
return 0x0;
}
}
// read data packet
readdata(pn532_packetbuffer, 20);
// check some basic stuff

/* ISO14443A card response should be in the following format: page 116 of http://www.nxp.com/documents/user_manual/141520.pdf

byte Description
------------- ------------------------------------------
b0..6 Frame header and preamble
b7 Tags Found
b8 Tag Number (only one used in this example)
b9..10 SENS_RES
b11 SEL_RES
b12 NFCID Length
b13..NFCIDLen NFCID */

#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("Found ")); PN532DEBUGPRINT.print(pn532_packetbuffer[7], DEC); PN532DEBUGPRINT.println(F(" tags"));
#endif
if (pn532_packetbuffer[7] != 1)
return 0;

uint16_t sens_res = pn532_packetbuffer[9];
sens_res <<= 8;
sens_res |= pn532_packetbuffer[10];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("ATQA: 0x")); PN532DEBUGPRINT.println(sens_res, HEX);
PN532DEBUGPRINT.print(F("SAK: 0x")); PN532DEBUGPRINT.println(pn532_packetbuffer[11], HEX);
#endif

/* Card appears to be Mifare Classic */
*uidLength = pn532_packetbuffer[12];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("UID:"));
#endif
for (uint8_t i=0; i < pn532_packetbuffer[12]; i++)
{
uid[i] = pn532_packetbuffer[13+i];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F(" 0x"));PN532DEBUGPRINT.print(uid[i], HEX);
#endif
}
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.println();
#endif

return 1;
}case PN532_FELICA_212:case PN532_FELICA_424:{ //==================================================================================================
//Both types have the exact same response and so we can group them with this single bit of code
//We have some extra things to send to the chip to ask for Felica UIDs
pn532_packetbuffer[3] = 0x00;
pn532_packetbuffer[4] = 0xFF;
pn532_packetbuffer[5] = 0xFF;
pn532_packetbuffer[6] = 0x01;
pn532_packetbuffer[7] = 0x00;

if (!sendCommandCheckAck(pn532_packetbuffer, 8, timeout))
{
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("No card(s) read"));
#endif
return 0x0; // no cards read
}

// wait for a card to enter the field (only possible with I2C)
if (!_usingSPI) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("Waiting for IRQ (indicates card presence)"));
#endif
if (!waitready(timeout)) {
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F("IRQ Timeout"));
#endif
return 0x0;
}
}
// read data packet
readdata(pn532_packetbuffer, 28);
// check some basic stuff

/* Felica card response should be in the following format: page 116 of http://www.nxp.com/documents/user_manual/141520.pdf

byte Description
------------- ------------------------------------------
b0..6 Frame header and preamble
b7 Tags Found
b8 Tag Number (only one used in this example)
b9 POL_RES length
b10 0x01 (response code)
b11..18 NFCID2t
b19..26 Pad
b27..28 SYST_CODE (optional)
*/

#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("Found ")); PN532DEBUGPRINT.print(pn532_packetbuffer[7], DEC); PN532DEBUGPRINT.println(F(" tags"));
#endif

if (pn532_packetbuffer[7] != 1)
return 0;

uint8_t POL_RES = pn532_packetbuffer[9];
uint8_t uid_length=8; //this is hard set in the protocol
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("UID Length: 0x")); PN532DEBUGPRINT.println(POL_RES, HEX);
#endif


/* Card appears to be Felica */
*uidLength = uid_length;
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F("UID:"));
#endif
for (uint8_t i=0; i < uid_length; i++)
{
uid[i] = pn532_packetbuffer[11+i];
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.print(F(" 0x"));PN532DEBUGPRINT.print(uid[i], HEX);
#endif
}
#ifdef MIFAREDEBUG
PN532DEBUGPRINT.println();
#endif

return 1;
}
}
}

/**************************************************************************/
Expand Down Expand Up @@ -1543,7 +1624,9 @@ bool Adafruit_PN532::waitready(uint16_t timeout) {
if (timeout != 0) {
timer += 10;
if (timer > timeout) {
PN532DEBUGPRINT.println("TIMEOUT!");
#ifdef PN532DEBUG
PN532DEBUGPRINT.println("TIMEOUT!");
#endif
return false;
}
}
Expand Down Expand Up @@ -1666,7 +1749,7 @@ void Adafruit_PN532::writecommand(uint8_t* cmd, uint8_t cmdlen) {
PN532DEBUGPRINT.print(F(" 0x")); PN532DEBUGPRINT.print(cmdlen, HEX);
PN532DEBUGPRINT.print(F(" 0x")); PN532DEBUGPRINT.print(~cmdlen + 1, HEX);
PN532DEBUGPRINT.print(F(" 0x")); PN532DEBUGPRINT.print(PN532_HOSTTOPN532, HEX);
#endif
#endif

for (uint8_t i=0; i<cmdlen-1; i++) {
spi_write(cmd[i]);
Expand Down Expand Up @@ -1762,16 +1845,16 @@ void Adafruit_PN532::spi_write(uint8_t c) {
else {
// Software SPI write.
int8_t i;
digitalWrite(_clk, HIGH);
digitalWrite(_clk, LOW);

for (i=0; i<8; i++) {
digitalWrite(_clk, LOW);
if (c & _BV(i)) {
digitalWrite(_mosi, HIGH);
} else {
digitalWrite(_mosi, LOW);
}
digitalWrite(_clk, HIGH);
digitalWrite(_clk, LOW);
}
}
}
Expand All @@ -1793,14 +1876,14 @@ uint8_t Adafruit_PN532::spi_read(void) {
}
else {
// Software SPI read.
digitalWrite(_clk, HIGH);
digitalWrite(_clk, LOW);

for (i=0; i<8; i++) {
digitalWrite(_clk, HIGH);
if (digitalRead(_miso)) {
x |= _BV(i);
}
digitalWrite(_clk, LOW);
digitalWrite(_clk, HIGH);
}
}

Expand Down
13 changes: 13 additions & 0 deletions Adafruit_PN532.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
- Added 'verbose' mode flag to constructor to toggle debug output
- Changed readPassiveTargetID() to return variable length values

@reference
user manual for PN532 -- http://www.nxp.com/documents/user_manual/141520.pdf
resource used for adding Felica support -- http://lantaukwcounter.blogspot.com/2015/11/reading-octopus-card-ids-felica-with.html
*/
/**************************************************************************/

Expand Down Expand Up @@ -95,6 +98,11 @@
#define PN532_I2C_READYTIMEOUT (20)

#define PN532_MIFARE_ISO14443A (0x00)
#define PN532_FELICA_212 (0x01)
#define PN532_FELICA_424 (0x02)
//untested below
//#define PN532_MIFARE_ISO14443-3B (0x03)
//#define PN532_JEWEL (0x04)

// Mifare Commands
#define MIFARE_CMD_AUTH_A (0x60)
Expand Down Expand Up @@ -153,6 +161,8 @@
#define PN532_GPIO_P34 (4)
#define PN532_GPIO_P35 (5)

//#define PN532DEBUG (1)

class Adafruit_PN532{
public:
Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss); // Software SPI
Expand Down Expand Up @@ -191,6 +201,9 @@ class Adafruit_PN532{
uint8_t ntag2xx_WritePage (uint8_t page, uint8_t * data);
uint8_t ntag2xx_WriteNDEFURI (uint8_t uriIdentifier, char * url, uint8_t dataLen);

// Felica functions
// coming soon

// Help functions to display formatted text
static void PrintHex(const byte * data, const uint32_t numBytes);
static void PrintHexChar(const byte * pbtData, const uint32_t numBytes);
Expand Down