Krolyxon
Commit 0b8b30d

Branches

Tags

Refs →

orion-rfsrclibsAdafruit_PN532.cpp

1820 lines · 58.8 KB · C++

1/**************************************************************************/
2/*!
3 @file Adafruit_PN532.cpp
4
5 @section intro_sec Introduction
6
7 Driver for NXP's PN532 NFC/13.56MHz RFID Transceiver
8
9 This is a library for the Adafruit PN532 NFC/RFID breakout boards
10 This library works with the Adafruit NFC breakout
11 ----> https://www.adafruit.com/products/364
12
13 Check out the links above for our tutorials and wiring diagrams
14 These chips use SPI or I2C to communicate.
15
16 Adafruit invests time and resources providing this open source code,
17 please support Adafruit and open-source hardware by purchasing
18 products from Adafruit!
19
20 @section author Author
21
22 Adafruit Industries
23
24 @section license License
25
26 BSD (see license.txt)
27
28 @section HISTORY
29
30 v2.2 - Added startPassiveTargetIDDetection() to start card detection and
31 readDetectedPassiveTargetID() to read it, useful when using the
32 IRQ pin.
33
34 v2.1 - Added NTAG2xx helper functions
35
36 v2.0 - Refactored to add I2C support from Adafruit_NFCShield_I2C library.
37
38 v1.4 - Added setPassiveActivationRetries()
39
40 v1.2 - Added writeGPIO()
41 - Added readGPIO()
42
43 v1.1 - Changed readPassiveTargetID() to handle multiple UID sizes
44 - Added the following helper functions for text display
45 static void PrintHex(const byte * data, const uint32_t numBytes)
46 static void PrintHexChar(const byte * pbtData, const uint32_t
47 numBytes)
48 - Added the following Mifare Classic functions:
49 bool mifareclassic_IsFirstBlock (uint32_t uiBlock)
50 bool mifareclassic_IsTrailerBlock (uint32_t uiBlock)
51 uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t
52 uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData) uint8_t
53 mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data) uint8_t
54 mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
55 - Added the following Mifare Ultalight functions:
56 uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
57*/
58/**************************************************************************/
59
60#include "Adafruit_PN532.h"
61
62byte pn532ack[] = {0x00, 0x00, 0xFF,
63 0x00, 0xFF, 0x00}; ///< ACK message from PN532
64byte pn532response_firmwarevers[] = {
65 0x00, 0x00, 0xFF,
66 0x06, 0xFA, 0xD5}; ///< Expected firmware version message from PN532
67
68// Uncomment these lines to enable debug output for PN532(SPI) and/or MIFARE
69// related code
70
71// #define PN532DEBUG
72// #define MIFAREDEBUG
73
74// If using Native Port on Arduino Zero or Due define as SerialUSB
75#define PN532DEBUGPRINT Serial ///< Fixed name for debug Serial instance
76// #define PN532DEBUGPRINT SerialUSB ///< Fixed name for debug Serial instance
77
78#define PN532_PACKBUFFSIZ 64 ///< Packet buffer size in bytes
79byte pn532_packetbuffer[PN532_PACKBUFFSIZ]; ///< Packet buffer used in various
80 ///< transactions
81
82/**************************************************************************/
83/*!
84 @brief Instantiates a new PN532 class using software SPI.
85
86 @param clk SPI clock pin (SCK)
87 @param miso SPI MISO pin
88 @param mosi SPI MOSI pin
89 @param ss SPI chip select pin (CS/SSEL)
90*/
91/**************************************************************************/
92Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi,
93 uint8_t ss) {
94 _cs = ss;
95 spi_dev = new Adafruit_SPIDevice(ss, clk, miso, mosi, 1000000,
96 SPI_BITORDER_LSBFIRST, SPI_MODE0);
97}
98
99/**************************************************************************/
100/*!
101 @brief Instantiates a new PN532 class using I2C.
102
103 @param irq Location of the IRQ pin
104 @param reset Location of the RSTPD_N pin
105 @param theWire pointer to I2C bus to use
106*/
107/**************************************************************************/
108Adafruit_PN532::Adafruit_PN532(uint8_t irq, uint8_t reset, TwoWire *theWire)
109 : _irq(irq), _reset(reset) {
110 pinMode(_irq, INPUT);
111 pinMode(_reset, OUTPUT);
112 i2c_dev = new Adafruit_I2CDevice(PN532_I2C_ADDRESS, theWire);
113}
114
115/**************************************************************************/
116/*!
117 @brief Instantiates a new PN532 class using hardware SPI.
118
119 @param ss SPI chip select pin (CS/SSEL)
120 @param theSPI pointer to the SPI bus to use
121*/
122/**************************************************************************/
123Adafruit_PN532::Adafruit_PN532(uint8_t ss, SPIClass *theSPI) {
124 _cs = ss;
125 spi_dev = new Adafruit_SPIDevice(ss, 1000000, SPI_BITORDER_LSBFIRST,
126 SPI_MODE0, theSPI);
127}
128
129/**************************************************************************/
130/*!
131 @brief Instantiates a new PN532 class using hardware UART (HSU).
132
133 @param reset Location of the RSTPD_N pin
134 @param theSer pointer to HardWare Serial bus to use
135*/
136/**************************************************************************/
137Adafruit_PN532::Adafruit_PN532(uint8_t reset, HardwareSerial *theSer)
138 : _reset(reset) {
139 pinMode(_reset, OUTPUT);
140 ser_dev = theSer;
141}
142
143/**************************************************************************/
144/*!
145 @brief Setups the HW
146
147 @returns true if successful, otherwise false
148*/
149/**************************************************************************/
150bool Adafruit_PN532::begin() {
151 if (spi_dev) {
152 // SPI initialization
153 if (!spi_dev->begin()) {
154 return false;
155 }
156 } else if (i2c_dev) {
157 // I2C initialization
158 // PN532 will fail address check since its asleep, so suppress
159 if (!i2c_dev->begin(false)) {
160 return false;
161 }
162 } else if (ser_dev) {
163 ser_dev->begin(115200);
164 // clear out anything in read buffer
165 while (ser_dev->available())
166 ser_dev->read();
167 } else {
168 // no interface specified
169 return false;
170 }
171 reset(); // HW reset - put in known state
172 delay(10);
173 wakeup(); // hey! wakeup!
174 return true;
175}
176
177/**************************************************************************/
178/*!
179 @brief Perform a hardware reset. Requires reset pin to have been provided.
180*/
181/**************************************************************************/
182void Adafruit_PN532::reset(void) {
183 // see Datasheet p.209, Fig.48 for timings
184 if (_reset != -1) {
185 digitalWrite(_reset, LOW);
186 delay(1); // min 20ns
187 digitalWrite(_reset, HIGH);
188 delay(2); // max 2ms
189 }
190}
191
192/**************************************************************************/
193/*!
194 @brief Wakeup from LowVbat mode into Normal Mode.
195*/
196/**************************************************************************/
197void Adafruit_PN532::wakeup(void) {
198 // interface specific wakeups - each one is unique!
199 if (spi_dev) {
200 // hold CS low for 2ms
201 digitalWrite(_cs, LOW);
202 delay(2);
203 } else if (ser_dev) {
204 uint8_t w[3] = {0x55, 0x00, 0x00};
205 ser_dev->write(w, 3);
206 delay(2);
207 }
208
209 // PN532 will clock stretch I2C during SAMConfig as a "wakeup"
210
211 // need to config SAM to stay in Normal Mode
212 SAMConfig();
213}
214
215/**************************************************************************/
216/*!
217 @brief Prints a hexadecimal value in plain characters
218
219 @param data Pointer to the byte data
220 @param numBytes Data length in bytes
221*/
222/**************************************************************************/
223void Adafruit_PN532::PrintHex(const byte *data, const uint32_t numBytes) {
224 uint32_t szPos;
225 for (szPos = 0; szPos < numBytes; szPos++) {
226 PN532DEBUGPRINT.print(F("0x"));
227 // Append leading 0 for small values
228 if (data[szPos] <= 0xF)
229 PN532DEBUGPRINT.print(F("0"));
230 PN532DEBUGPRINT.print(data[szPos] & 0xff, HEX);
231 if ((numBytes > 1) && (szPos != numBytes - 1)) {
232 PN532DEBUGPRINT.print(F(" "));
233 }
234 }
235 PN532DEBUGPRINT.println();
236}
237
238/**************************************************************************/
239/*!
240 @brief Prints a hexadecimal value in plain characters, along with
241 the char equivalents in the following format
242
243 00 00 00 00 00 00 ......
244
245 @param data Pointer to the byte data
246 @param numBytes Data length in bytes
247*/
248/**************************************************************************/
249void Adafruit_PN532::PrintHexChar(const byte *data, const uint32_t numBytes) {
250 uint32_t szPos;
251 for (szPos = 0; szPos < numBytes; szPos++) {
252 // Append leading 0 for small values
253 if (data[szPos] <= 0xF)
254 PN532DEBUGPRINT.print(F("0"));
255 PN532DEBUGPRINT.print(data[szPos], HEX);
256 if ((numBytes > 1) && (szPos != numBytes - 1)) {
257 PN532DEBUGPRINT.print(F(" "));
258 }
259 }
260 PN532DEBUGPRINT.print(F(" "));
261 for (szPos = 0; szPos < numBytes; szPos++) {
262 if (data[szPos] <= 0x1F)
263 PN532DEBUGPRINT.print(F("."));
264 else
265 PN532DEBUGPRINT.print((char)data[szPos]);
266 }
267 PN532DEBUGPRINT.println();
268}
269
270/**************************************************************************/
271/*!
272 @brief Checks the firmware version of the PN5xx chip
273
274 @returns The chip's firmware version and ID
275*/
276/**************************************************************************/
277uint32_t Adafruit_PN532::getFirmwareVersion(void) {
278 uint32_t response;
279
280 pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
281
282 if (!sendCommandCheckAck(pn532_packetbuffer, 1)) {
283 return 0;
284 }
285
286 // read data packet
287 readdata(pn532_packetbuffer, 13);
288
289 // check some basic stuff
290 if (0 != memcmp((char *)pn532_packetbuffer,
291 (char *)pn532response_firmwarevers, 6)) {
292#ifdef PN532DEBUG
293 PN532DEBUGPRINT.println(F("Firmware doesn't match!"));
294#endif
295 return 0;
296 }
297
298 int offset = 7;
299 response = pn532_packetbuffer[offset++];
300 response <<= 8;
301 response |= pn532_packetbuffer[offset++];
302 response <<= 8;
303 response |= pn532_packetbuffer[offset++];
304 response <<= 8;
305 response |= pn532_packetbuffer[offset++];
306
307 return response;
308}
309
310/**************************************************************************/
311/*!
312 @brief Sends a command and waits a specified period for the ACK
313
314 @param cmd Pointer to the command buffer
315 @param cmdlen The size of the command in bytes
316 @param timeout timeout before giving up
317
318 @returns 1 if everything is OK, 0 if timeout occured before an
319 ACK was recieved
320*/
321/**************************************************************************/
322// default timeout of one second
323bool Adafruit_PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen,
324 uint16_t timeout) {
325
326 // I2C works without using IRQ pin by polling for RDY byte
327 // seems to work best with some delays between transactions
328 uint8_t SLOWDOWN = 0;
329 if (i2c_dev || spi_dev) // SPI and I2C need 1ms slow for page reads
330 SLOWDOWN = 1;
331
332 // write the command
333 writecommand(cmd, cmdlen);
334
335 // I2C TUNING
336 delay(SLOWDOWN);
337
338 // Wait for chip to say its ready!
339 if (!waitready(timeout)) {
340 return false;
341 }
342
343#ifdef PN532DEBUG
344 if (spi_dev == NULL) {
345 PN532DEBUGPRINT.println(F("IRQ received"));
346 }
347#endif
348
349 // read acknowledgement
350 if (!readack()) {
351#ifdef PN532DEBUG
352 PN532DEBUGPRINT.println(F("No ACK frame received!"));
353#endif
354 return false;
355 }
356
357 // I2C TUNING
358 delay(SLOWDOWN);
359
360 // Wait for chip to say its ready!
361 if (!waitready(timeout)) {
362 return false;
363 }
364
365 return true; // ack'd command
366}
367
368/**************************************************************************/
369/*!
370 @brief Writes an 8-bit value that sets the state of the PN532's GPIO
371 pins.
372 @param pinstate P3 pins state.
373
374 @warning This function is provided exclusively for board testing and
375 is dangerous since it will throw an error if any pin other
376 than the ones marked "Can be used as GPIO" are modified! All
377 pins that can not be used as GPIO should ALWAYS be left high
378 (value = 1) or the system will become unstable and a HW reset
379 will be required to recover the PN532.
380
381 pinState[0] = P30 Can be used as GPIO
382 pinState[1] = P31 Can be used as GPIO
383 pinState[2] = P32 *** RESERVED (Must be 1!) ***
384 pinState[3] = P33 Can be used as GPIO
385 pinState[4] = P34 *** RESERVED (Must be 1!) ***
386 pinState[5] = P35 Can be used as GPIO
387
388 @return 1 if everything executed properly, 0 for an error
389*/
390/**************************************************************************/
391bool Adafruit_PN532::writeGPIO(uint8_t pinstate) {
392 // uint8_t errorbit;
393
394 // Make sure pinstate does not try to toggle P32 or P34
395 pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
396
397 // Fill command buffer
398 pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
399 pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins
400 pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by SPI)
401
402#ifdef PN532DEBUG
403 PN532DEBUGPRINT.print(F("Writing P3 GPIO: "));
404 PN532DEBUGPRINT.println(pn532_packetbuffer[1], HEX);
405#endif
406
407 // Send the WRITEGPIO command (0x0E)
408 if (!sendCommandCheckAck(pn532_packetbuffer, 3))
409 return 0x0;
410
411 // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0F) DATACHECKSUM
412 // 00)
413 readdata(pn532_packetbuffer, 8);
414
415#ifdef PN532DEBUG
416 PN532DEBUGPRINT.print(F("Received: "));
417 PrintHex(pn532_packetbuffer, 8);
418 PN532DEBUGPRINT.println();
419#endif
420
421 int offset = 6;
422 return (pn532_packetbuffer[offset] == 0x0F);
423}
424
425/**************************************************************************/
426/*!
427 Reads the state of the PN532's GPIO pins
428
429 @returns An 8-bit value containing the pin state where:
430
431 pinState[0] = P30
432 pinState[1] = P31
433 pinState[2] = P32
434 pinState[3] = P33
435 pinState[4] = P34
436 pinState[5] = P35
437*/
438/**************************************************************************/
439uint8_t Adafruit_PN532::readGPIO(void) {
440 pn532_packetbuffer[0] = PN532_COMMAND_READGPIO;
441
442 // Send the READGPIO command (0x0C)
443 if (!sendCommandCheckAck(pn532_packetbuffer, 1))
444 return 0x0;
445
446 // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0D) P3 P7 IO1
447 // DATACHECKSUM 00)
448 readdata(pn532_packetbuffer, 11);
449
450 /* READGPIO response should be in the following format:
451
452 byte Description
453 ------------- ------------------------------------------
454 b0..5 Frame header and preamble (with I2C there is an extra 0x00)
455 b6 P3 GPIO Pins
456 b7 P7 GPIO Pins (not used ... taken by SPI)
457 b8 Interface Mode Pins (not used ... bus select pins)
458 b9..10 checksum */
459
460 int p3offset = 7;
461
462#ifdef PN532DEBUG
463 PN532DEBUGPRINT.print(F("Received: "));
464 PrintHex(pn532_packetbuffer, 11);
465 PN532DEBUGPRINT.println();
466 PN532DEBUGPRINT.print(F("P3 GPIO: 0x"));
467 PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset], HEX);
468 PN532DEBUGPRINT.print(F("P7 GPIO: 0x"));
469 PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset + 1], HEX);
470 PN532DEBUGPRINT.print(F("IO GPIO: 0x"));
471 PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset + 2], HEX);
472 // Note: You can use the IO GPIO value to detect the serial bus being used
473 switch (pn532_packetbuffer[p3offset + 2]) {
474 case 0x00: // Using UART
475 PN532DEBUGPRINT.println(F("Using UART (IO = 0x00)"));
476 break;
477 case 0x01: // Using I2C
478 PN532DEBUGPRINT.println(F("Using I2C (IO = 0x01)"));
479 break;
480 case 0x02: // Using SPI
481 PN532DEBUGPRINT.println(F("Using SPI (IO = 0x02)"));
482 break;
483 }
484#endif
485
486 return pn532_packetbuffer[p3offset];
487}
488
489/**************************************************************************/
490/*!
491 @brief Configures the SAM (Secure Access Module)
492 @return true on success, false otherwise.
493*/
494/**************************************************************************/
495bool Adafruit_PN532::SAMConfig(void) {
496 pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
497 pn532_packetbuffer[1] = 0x01; // normal mode;
498 pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
499 pn532_packetbuffer[3] = 0x01; // use IRQ pin!
500
501 if (!sendCommandCheckAck(pn532_packetbuffer, 4))
502 return false;
503
504 // read data packet
505 readdata(pn532_packetbuffer, 9);
506
507 int offset = 6;
508 return (pn532_packetbuffer[offset] == 0x15);
509}
510
511/**************************************************************************/
512/*!
513 Sets the MxRtyPassiveActivation byte of the RFConfiguration register
514
515 @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout
516 after mxRetries
517
518 @returns 1 if everything executed properly, 0 for an error
519*/
520/**************************************************************************/
521bool Adafruit_PN532::setPassiveActivationRetries(uint8_t maxRetries) {
522 pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
523 pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
524 pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
525 pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
526 pn532_packetbuffer[4] = maxRetries;
527
528#ifdef MIFAREDEBUG
529 PN532DEBUGPRINT.print(F("Setting MxRtyPassiveActivation to "));
530 PN532DEBUGPRINT.print(maxRetries, DEC);
531 PN532DEBUGPRINT.println(F(" "));
532#endif
533
534 if (!sendCommandCheckAck(pn532_packetbuffer, 5))
535 return 0x0; // no ACK
536
537 return 1;
538}
539
540/***** ISO14443A Commands ******/
541
542/**************************************************************************/
543/*!
544 @brief Waits for an ISO14443A target to enter the field and reads
545 its ID.
546
547 @param cardbaudrate Baud rate of the card
548 @param uid Pointer to the array that will be populated
549 with the card's UID (up to 7 bytes)
550 @param uidLength Pointer to the variable that will hold the
551 length of the card's UID.
552 @param timeout Timeout in milliseconds.
553
554 @return 1 if everything executed properly, 0 for an error
555*/
556/**************************************************************************/
557bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid,
558 uint8_t *uidLength, uint16_t timeout) {
559 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
560 pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
561 pn532_packetbuffer[2] = cardbaudrate;
562
563 if (!sendCommandCheckAck(pn532_packetbuffer, 3, timeout)) {
564#ifdef PN532DEBUG
565 PN532DEBUGPRINT.println(F("No card(s) read"));
566#endif
567 return 0x0; // no cards read
568 }
569
570 return readDetectedPassiveTargetID(uid, uidLength);
571}
572
573/**************************************************************************/
574/*!
575 @brief Put the reader in detection mode, non blocking so interrupts
576 must be enabled.
577 @param cardbaudrate Baud rate of the card
578 @return 1 if everything executed properly, 0 for an error
579*/
580/**************************************************************************/
581bool Adafruit_PN532::startPassiveTargetIDDetection(uint8_t cardbaudrate) {
582 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
583 pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
584 pn532_packetbuffer[2] = cardbaudrate;
585
586 return sendCommandCheckAck(pn532_packetbuffer, 3);
587}
588
589/**************************************************************************/
590/*!
591 Reads the ID of the passive target the reader has deteceted.
592
593 @param uid Pointer to the array that will be populated
594 with the card's UID (up to 7 bytes)
595 @param uidLength Pointer to the variable that will hold the
596 length of the card's UID.
597
598 @returns 1 if everything executed properly, 0 for an error
599*/
600/**************************************************************************/
601bool Adafruit_PN532::readDetectedPassiveTargetID(uint8_t *uid,
602 uint8_t *uidLength) {
603 // read data packet
604 readdata(pn532_packetbuffer, 20);
605 // check some basic stuff
606
607 /* ISO14443A card response should be in the following format:
608
609 byte Description
610 ------------- ------------------------------------------
611 b0..6 Frame header and preamble
612 b7 Tags Found
613 b8 Tag Number (only one used in this example)
614 b9..10 SENS_RES
615 b11 SEL_RES
616 b12 NFCID Length
617 b13..NFCIDLen NFCID */
618
619#ifdef MIFAREDEBUG
620 PN532DEBUGPRINT.print(F("Found "));
621 PN532DEBUGPRINT.print(pn532_packetbuffer[7], DEC);
622 PN532DEBUGPRINT.println(F(" tags"));
623#endif
624 if (pn532_packetbuffer[7] != 1)
625 return 0;
626
627 uint16_t sens_res = pn532_packetbuffer[9];
628 sens_res <<= 8;
629 sens_res |= pn532_packetbuffer[10];
630#ifdef MIFAREDEBUG
631 PN532DEBUGPRINT.print(F("ATQA: 0x"));
632 PN532DEBUGPRINT.println(sens_res, HEX);
633 PN532DEBUGPRINT.print(F("SAK: 0x"));
634 PN532DEBUGPRINT.println(pn532_packetbuffer[11], HEX);
635#endif
636
637 /* Card appears to be Mifare Classic */
638 *uidLength = pn532_packetbuffer[12];
639#ifdef MIFAREDEBUG
640 PN532DEBUGPRINT.print(F("UID:"));
641#endif
642 for (uint8_t i = 0; i < pn532_packetbuffer[12]; i++) {
643 uid[i] = pn532_packetbuffer[13 + i];
644#ifdef MIFAREDEBUG
645 PN532DEBUGPRINT.print(F(" 0x"));
646 PN532DEBUGPRINT.print(uid[i], HEX);
647#endif
648 }
649#ifdef MIFAREDEBUG
650 PN532DEBUGPRINT.println();
651#endif
652
653 return 1;
654}
655
656/**************************************************************************/
657/*!
658 @brief Exchanges an APDU with the currently inlisted peer
659
660 @param send Pointer to data to send
661 @param sendLength Length of the data to send
662 @param response Pointer to response data
663 @param responseLength Pointer to the response data length
664 @return true on success, false otherwise.
665*/
666/**************************************************************************/
667bool Adafruit_PN532::inDataExchange(uint8_t *send, uint8_t sendLength,
668 uint8_t *response,
669 uint8_t *responseLength) {
670 if (sendLength > PN532_PACKBUFFSIZ - 2) {
671#ifdef PN532DEBUG
672 PN532DEBUGPRINT.println(F("APDU length too long for packet buffer"));
673#endif
674 return false;
675 }
676 uint8_t i;
677
678 pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
679 pn532_packetbuffer[1] = _inListedTag;
680 for (i = 0; i < sendLength; ++i) {
681 pn532_packetbuffer[i + 2] = send[i];
682 }
683
684 if (!sendCommandCheckAck(pn532_packetbuffer, sendLength + 2, 1000)) {
685#ifdef PN532DEBUG
686 PN532DEBUGPRINT.println(F("Could not send APDU"));
687#endif
688 return false;
689 }
690
691 if (!waitready(1000)) {
692#ifdef PN532DEBUG
693 PN532DEBUGPRINT.println(F("Response never received for APDU..."));
694#endif
695 return false;
696 }
697
698 readdata(pn532_packetbuffer, sizeof(pn532_packetbuffer));
699
700 if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 &&
701 pn532_packetbuffer[2] == 0xff) {
702 uint8_t length = pn532_packetbuffer[3];
703 if (pn532_packetbuffer[4] != (uint8_t)(~length + 1)) {
704#ifdef PN532DEBUG
705 PN532DEBUGPRINT.println(F("Length check invalid"));
706 PN532DEBUGPRINT.println(length, HEX);
707 PN532DEBUGPRINT.println((~length) + 1, HEX);
708#endif
709 return false;
710 }
711 if (pn532_packetbuffer[5] == PN532_PN532TOHOST &&
712 pn532_packetbuffer[6] == PN532_RESPONSE_INDATAEXCHANGE) {
713 if ((pn532_packetbuffer[7] & 0x3f) != 0) {
714#ifdef PN532DEBUG
715 PN532DEBUGPRINT.println(F("Status code indicates an error"));
716#endif
717 return false;
718 }
719
720 length -= 3;
721
722 if (length > *responseLength) {
723 length = *responseLength; // silent truncation...
724 }
725
726 for (i = 0; i < length; ++i) {
727 response[i] = pn532_packetbuffer[8 + i];
728 }
729 *responseLength = length;
730
731 return true;
732 } else {
733 PN532DEBUGPRINT.print(F("Don't know how to handle this command: "));
734 PN532DEBUGPRINT.println(pn532_packetbuffer[6], HEX);
735 return false;
736 }
737 } else {
738 PN532DEBUGPRINT.println(F("Preamble missing"));
739 return false;
740 }
741}
742
743/**************************************************************************/
744/*!
745 @brief 'InLists' a passive target. PN532 acting as reader/initiator,
746 peer acting as card/responder.
747 @return true on success, false otherwise.
748*/
749/**************************************************************************/
750bool Adafruit_PN532::inListPassiveTarget() {
751 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
752 pn532_packetbuffer[1] = 1;
753 pn532_packetbuffer[2] = 0;
754
755#ifdef PN532DEBUG
756 PN532DEBUGPRINT.print(F("About to inList passive target"));
757#endif
758
759 if (!sendCommandCheckAck(pn532_packetbuffer, 3, 1000)) {
760#ifdef PN532DEBUG
761 PN532DEBUGPRINT.println(F("Could not send inlist message"));
762#endif
763 return false;
764 }
765
766 if (!waitready(30000)) {
767 return false;
768 }
769
770 readdata(pn532_packetbuffer, sizeof(pn532_packetbuffer));
771
772 if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 &&
773 pn532_packetbuffer[2] == 0xff) {
774 uint8_t length = pn532_packetbuffer[3];
775 if (pn532_packetbuffer[4] != (uint8_t)(~length + 1)) {
776#ifdef PN532DEBUG
777 PN532DEBUGPRINT.println(F("Length check invalid"));
778 PN532DEBUGPRINT.println(length, HEX);
779 PN532DEBUGPRINT.println((~length) + 1, HEX);
780#endif
781 return false;
782 }
783 if (pn532_packetbuffer[5] == PN532_PN532TOHOST &&
784 pn532_packetbuffer[6] == PN532_RESPONSE_INLISTPASSIVETARGET) {
785 if (pn532_packetbuffer[7] != 1) {
786#ifdef PN532DEBUG
787 PN532DEBUGPRINT.println(F("Unhandled number of targets inlisted"));
788#endif
789 PN532DEBUGPRINT.println(F("Number of tags inlisted:"));
790 PN532DEBUGPRINT.println(pn532_packetbuffer[7]);
791 return false;
792 }
793
794 _inListedTag = pn532_packetbuffer[8];
795 PN532DEBUGPRINT.print(F("Tag number: "));
796 PN532DEBUGPRINT.println(_inListedTag);
797
798 return true;
799 } else {
800#ifdef PN532DEBUG
801 PN532DEBUGPRINT.print(F("Unexpected response to inlist passive host"));
802#endif
803 return false;
804 }
805 } else {
806#ifdef PN532DEBUG
807 PN532DEBUGPRINT.println(F("Preamble missing"));
808#endif
809 return false;
810 }
811
812 return true;
813}
814
815/***** Mifare Classic Functions ******/
816
817/**************************************************************************/
818/*!
819 @brief Indicates whether the specified block number is the first block
820 in the sector (block 0 relative to the current sector)
821 @param uiBlock Block number to test.
822 @return true if first block, false otherwise.
823*/
824/**************************************************************************/
825bool Adafruit_PN532::mifareclassic_IsFirstBlock(uint32_t uiBlock) {
826 // Test if we are in the small or big sectors
827 if (uiBlock < 128)
828 return ((uiBlock) % 4 == 0);
829 else
830 return ((uiBlock) % 16 == 0);
831}
832
833/**************************************************************************/
834/*!
835 @brief Indicates whether the specified block number is the sector
836 trailer.
837 @param uiBlock Block number to test.
838 @return true if sector trailer, false otherwise.
839*/
840/**************************************************************************/
841bool Adafruit_PN532::mifareclassic_IsTrailerBlock(uint32_t uiBlock) {
842 // Test if we are in the small or big sectors
843 if (uiBlock < 128)
844 return ((uiBlock + 1) % 4 == 0);
845 else
846 return ((uiBlock + 1) % 16 == 0);
847}
848
849/**************************************************************************/
850/*!
851 Tries to authenticate a block of memory on a MIFARE card using the
852 INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual
853 for more information on sending MIFARE and other commands.
854
855 @param uid Pointer to a byte array containing the card UID
856 @param uidLen The length (in bytes) of the card's UID (Should
857 be 4 for MIFARE Classic)
858 @param blockNumber The block number to authenticate. (0..63 for
859 1KB cards, and 0..255 for 4KB cards).
860 @param keyNumber Which key type to use during authentication
861 (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
862 @param keyData Pointer to a byte array containing the 6 byte
863 key value
864
865 @returns 1 if everything executed properly, 0 for an error
866*/
867/**************************************************************************/
868uint8_t Adafruit_PN532::mifareclassic_AuthenticateBlock(uint8_t *uid,
869 uint8_t uidLen,
870 uint32_t blockNumber,
871 uint8_t keyNumber,
872 uint8_t *keyData) {
873 // uint8_t len;
874 uint8_t i;
875
876 // Hang on to the key and uid data
877 memcpy(_key, keyData, 6);
878 memcpy(_uid, uid, uidLen);
879 _uidLen = uidLen;
880
881#ifdef MIFAREDEBUG
882 PN532DEBUGPRINT.print(F("Trying to authenticate card "));
883 Adafruit_PN532::PrintHex(_uid, _uidLen);
884 PN532DEBUGPRINT.print(F("Using authentication KEY "));
885 PN532DEBUGPRINT.print(keyNumber ? 'B' : 'A');
886 PN532DEBUGPRINT.print(F(": "));
887 Adafruit_PN532::PrintHex(_key, 6);
888#endif
889
890 // Prepare the authentication command //
891 pn532_packetbuffer[0] =
892 PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
893 pn532_packetbuffer[1] = 1; /* Max card numbers */
894 pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
895 pn532_packetbuffer[3] =
896 blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
897 memcpy(pn532_packetbuffer + 4, _key, 6);
898 for (i = 0; i < _uidLen; i++) {
899 pn532_packetbuffer[10 + i] = _uid[i]; /* 4 byte card ID */
900 }
901
902 if (!sendCommandCheckAck(pn532_packetbuffer, 10 + _uidLen))
903 return 0;
904
905 // Read the response packet
906 readdata(pn532_packetbuffer, 12);
907
908 // check if the response is valid and we are authenticated???
909 // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
910 // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00
911 // is not good
912 if (pn532_packetbuffer[7] != 0x00) {
913#ifdef PN532DEBUG
914 PN532DEBUGPRINT.print(F("Authentification failed: "));
915 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 12);
916#endif
917 return 0;
918 }
919
920 return 1;
921}
922
923/**************************************************************************/
924/*!
925 Tries to read an entire 16-byte data block at the specified block
926 address.
927
928 @param blockNumber The block number to authenticate. (0..63 for
929 1KB cards, and 0..255 for 4KB cards).
930 @param data Pointer to the byte array that will hold the
931 retrieved data (if any)
932
933 @returns 1 if everything executed properly, 0 for an error
934*/
935/**************************************************************************/
936uint8_t Adafruit_PN532::mifareclassic_ReadDataBlock(uint8_t blockNumber,
937 uint8_t *data) {
938#ifdef MIFAREDEBUG
939 PN532DEBUGPRINT.print(F("Trying to read 16 bytes from block "));
940 PN532DEBUGPRINT.println(blockNumber);
941#endif
942
943 /* Prepare the command */
944 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
945 pn532_packetbuffer[1] = 1; /* Card number */
946 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
947 pn532_packetbuffer[3] =
948 blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
949
950 /* Send the command */
951 if (!sendCommandCheckAck(pn532_packetbuffer, 4)) {
952#ifdef MIFAREDEBUG
953 PN532DEBUGPRINT.println(F("Failed to receive ACK for read command"));
954#endif
955 return 0;
956 }
957
958 /* Read the response packet */
959 readdata(pn532_packetbuffer, 26);
960
961 /* If byte 8 isn't 0x00 we probably have an error */
962 if (pn532_packetbuffer[7] != 0x00) {
963#ifdef MIFAREDEBUG
964 PN532DEBUGPRINT.println(F("Unexpected response"));
965 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
966#endif
967 return 0;
968 }
969
970 /* Copy the 16 data bytes to the output buffer */
971 /* Block content starts at byte 9 of a valid response */
972 memcpy(data, pn532_packetbuffer + 8, 16);
973
974/* Display data for debug if requested */
975#ifdef MIFAREDEBUG
976 PN532DEBUGPRINT.print(F("Block "));
977 PN532DEBUGPRINT.println(blockNumber);
978 Adafruit_PN532::PrintHexChar(data, 16);
979#endif
980
981 return 1;
982}
983
984/**************************************************************************/
985/*!
986 Tries to write an entire 16-byte data block at the specified block
987 address.
988
989 @param blockNumber The block number to authenticate. (0..63 for
990 1KB cards, and 0..255 for 4KB cards).
991 @param data The byte array that contains the data to write.
992
993 @returns 1 if everything executed properly, 0 for an error
994*/
995/**************************************************************************/
996uint8_t Adafruit_PN532::mifareclassic_WriteDataBlock(uint8_t blockNumber,
997 uint8_t *data) {
998#ifdef MIFAREDEBUG
999 PN532DEBUGPRINT.print(F("Trying to write 16 bytes to block "));
1000 PN532DEBUGPRINT.println(blockNumber);
1001#endif
1002
1003 /* Prepare the first command */
1004 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1005 pn532_packetbuffer[1] = 1; /* Card number */
1006 pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
1007 pn532_packetbuffer[3] =
1008 blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
1009 memcpy(pn532_packetbuffer + 4, data, 16); /* Data Payload */
1010
1011 /* Send the command */
1012 if (!sendCommandCheckAck(pn532_packetbuffer, 20)) {
1013#ifdef MIFAREDEBUG
1014 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1015#endif
1016 return 0;
1017 }
1018 delay(10);
1019
1020 /* Read the response packet */
1021 readdata(pn532_packetbuffer, 26);
1022
1023 return 1;
1024}
1025
1026/**************************************************************************/
1027/*!
1028 Formats a Mifare Classic card to store NDEF Records
1029
1030 @returns 1 if everything executed properly, 0 for an error
1031*/
1032/**************************************************************************/
1033uint8_t Adafruit_PN532::mifareclassic_FormatNDEF(void) {
1034 uint8_t sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1,
1035 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
1036 uint8_t sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1,
1037 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
1038 uint8_t sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77,
1039 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1040
1041 // Note 0xA0 0xA1 0xA2 0xA3 0xA4 0xA5 must be used for key A
1042 // for the MAD sector in NDEF records (sector 0)
1043
1044 // Write block 1 and 2 to the card
1045 if (!(mifareclassic_WriteDataBlock(1, sectorbuffer1)))
1046 return 0;
1047 if (!(mifareclassic_WriteDataBlock(2, sectorbuffer2)))
1048 return 0;
1049 // Write key A and access rights card
1050 if (!(mifareclassic_WriteDataBlock(3, sectorbuffer3)))
1051 return 0;
1052
1053 // Seems that everything was OK (?!)
1054 return 1;
1055}
1056
1057/**************************************************************************/
1058/*!
1059 Writes an NDEF URI Record to the specified sector (1..15)
1060
1061 Note that this function assumes that the Mifare Classic card is
1062 already formatted to work as an "NFC Forum Tag" and uses a MAD1
1063 file system. You can use the NXP TagWriter app on Android to
1064 properly format cards for this.
1065
1066 @param sectorNumber The sector that the URI record should be written
1067 to (can be 1..15 for a 1K card)
1068 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
1069 "http://www.", etc.)
1070 @param url The uri text to write (max 38 characters).
1071
1072 @returns 1 if everything executed properly, 0 for an error
1073*/
1074/**************************************************************************/
1075uint8_t Adafruit_PN532::mifareclassic_WriteNDEFURI(uint8_t sectorNumber,
1076 uint8_t uriIdentifier,
1077 const char *url) {
1078 // Figure out how long the string is
1079 uint8_t len = strlen(url);
1080
1081 // Make sure we're within a 1K limit for the sector number
1082 if ((sectorNumber < 1) || (sectorNumber > 15))
1083 return 0;
1084
1085 // Make sure the URI payload is between 1 and 38 chars
1086 if ((len < 1) || (len > 38))
1087 return 0;
1088
1089 // Note 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 must be used for key A
1090 // in NDEF records
1091
1092 // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
1093 uint8_t sectorbuffer1[16] = {0x00,
1094 0x00,
1095 0x03,
1096 (uint8_t)(len + 5),
1097 0xD1,
1098 0x01,
1099 (uint8_t)(len + 1),
1100 0x55,
1101 uriIdentifier,
1102 0x00,
1103 0x00,
1104 0x00,
1105 0x00,
1106 0x00,
1107 0x00,
1108 0x00};
1109 uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1111 uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1113 uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07,
1114 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1115 if (len <= 6) {
1116 // Unlikely we'll get a url this short, but why not ...
1117 memcpy(sectorbuffer1 + 9, url, len);
1118 sectorbuffer1[len + 9] = 0xFE;
1119 } else if (len == 7) {
1120 // 0xFE needs to be wrapped around to next block
1121 memcpy(sectorbuffer1 + 9, url, len);
1122 sectorbuffer2[0] = 0xFE;
1123 } else if ((len > 7) && (len <= 22)) {
1124 // Url fits in two blocks
1125 memcpy(sectorbuffer1 + 9, url, 7);
1126 memcpy(sectorbuffer2, url + 7, len - 7);
1127 sectorbuffer2[len - 7] = 0xFE;
1128 } else if (len == 23) {
1129 // 0xFE needs to be wrapped around to final block
1130 memcpy(sectorbuffer1 + 9, url, 7);
1131 memcpy(sectorbuffer2, url + 7, len - 7);
1132 sectorbuffer3[0] = 0xFE;
1133 } else {
1134 // Url fits in three blocks
1135 memcpy(sectorbuffer1 + 9, url, 7);
1136 memcpy(sectorbuffer2, url + 7, 16);
1137 memcpy(sectorbuffer3, url + 23, len - 24);
1138 sectorbuffer3[len - 22] = 0xFE;
1139 }
1140
1141 // Now write all three blocks back to the card
1142 if (!(mifareclassic_WriteDataBlock(sectorNumber * 4, sectorbuffer1)))
1143 return 0;
1144 if (!(mifareclassic_WriteDataBlock((sectorNumber * 4) + 1, sectorbuffer2)))
1145 return 0;
1146 if (!(mifareclassic_WriteDataBlock((sectorNumber * 4) + 2, sectorbuffer3)))
1147 return 0;
1148 if (!(mifareclassic_WriteDataBlock((sectorNumber * 4) + 3, sectorbuffer4)))
1149 return 0;
1150
1151 // Seems that everything was OK (?!)
1152 return 1;
1153}
1154
1155/***** Mifare Ultralight Functions ******/
1156
1157/**************************************************************************/
1158/*!
1159 @brief Tries to read an entire 4-byte page at the specified address.
1160
1161 @param page The page number (0..63 in most cases)
1162 @param buffer Pointer to the byte array that will hold the
1163 retrieved data (if any)
1164 @return 1 on success, 0 on error.
1165*/
1166/**************************************************************************/
1167uint8_t Adafruit_PN532::mifareultralight_ReadPage(uint8_t page,
1168 uint8_t *buffer) {
1169 if (page >= 64) {
1170#ifdef MIFAREDEBUG
1171 PN532DEBUGPRINT.println(F("Page value out of range"));
1172#endif
1173 return 0;
1174 }
1175
1176#ifdef MIFAREDEBUG
1177 PN532DEBUGPRINT.print(F("Reading page "));
1178 PN532DEBUGPRINT.println(page);
1179#endif
1180
1181 /* Prepare the command */
1182 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1183 pn532_packetbuffer[1] = 1; /* Card number */
1184 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
1185 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
1186
1187 /* Send the command */
1188 if (!sendCommandCheckAck(pn532_packetbuffer, 4)) {
1189#ifdef MIFAREDEBUG
1190 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1191#endif
1192 return 0;
1193 }
1194
1195 /* Read the response packet */
1196 readdata(pn532_packetbuffer, 26);
1197#ifdef MIFAREDEBUG
1198 PN532DEBUGPRINT.println(F("Received: "));
1199 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1200#endif
1201
1202 /* If byte 8 isn't 0x00 we probably have an error */
1203 if (pn532_packetbuffer[7] == 0x00) {
1204 /* Copy the 4 data bytes to the output buffer */
1205 /* Block content starts at byte 9 of a valid response */
1206 /* Note that the command actually reads 16 byte or 4 */
1207 /* pages at a time ... we simply discard the last 12 */
1208 /* bytes */
1209 memcpy(buffer, pn532_packetbuffer + 8, 4);
1210 } else {
1211#ifdef MIFAREDEBUG
1212 PN532DEBUGPRINT.println(F("Unexpected response reading block: "));
1213 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1214#endif
1215 return 0;
1216 }
1217
1218/* Display data for debug if requested */
1219#ifdef MIFAREDEBUG
1220 PN532DEBUGPRINT.print(F("Page "));
1221 PN532DEBUGPRINT.print(page);
1222 PN532DEBUGPRINT.println(F(":"));
1223 Adafruit_PN532::PrintHexChar(buffer, 4);
1224#endif
1225
1226 // Return OK signal
1227 return 1;
1228}
1229
1230/**************************************************************************/
1231/*!
1232 Tries to write an entire 4-byte page at the specified block
1233 address.
1234
1235 @param page The page number to write. (0..63 for most cases)
1236 @param data The byte array that contains the data to write.
1237 Should be exactly 4 bytes long.
1238
1239 @returns 1 if everything executed properly, 0 for an error
1240*/
1241/**************************************************************************/
1242uint8_t Adafruit_PN532::mifareultralight_WritePage(uint8_t page,
1243 uint8_t *data) {
1244
1245 if (page >= 64) {
1246#ifdef MIFAREDEBUG
1247 PN532DEBUGPRINT.println(F("Page value out of range"));
1248#endif
1249 // Return Failed Signal
1250 return 0;
1251 }
1252
1253#ifdef MIFAREDEBUG
1254 PN532DEBUGPRINT.print(F("Trying to write 4 byte page"));
1255 PN532DEBUGPRINT.println(page);
1256#endif
1257
1258 /* Prepare the first command */
1259 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1260 pn532_packetbuffer[1] = 1; /* Card number */
1261 pn532_packetbuffer[2] =
1262 MIFARE_ULTRALIGHT_CMD_WRITE; /* Mifare Ultralight Write command = 0xA2 */
1263 pn532_packetbuffer[3] = page; /* Page Number (0..63 for most cases) */
1264 memcpy(pn532_packetbuffer + 4, data, 4); /* Data Payload */
1265
1266 /* Send the command */
1267 if (!sendCommandCheckAck(pn532_packetbuffer, 8)) {
1268#ifdef MIFAREDEBUG
1269 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1270#endif
1271
1272 // Return Failed Signal
1273 return 0;
1274 }
1275 delay(10);
1276
1277 /* Read the response packet */
1278 readdata(pn532_packetbuffer, 26);
1279
1280 // Return OK Signal
1281 return 1;
1282}
1283
1284/***** NTAG2xx Functions ******/
1285
1286/**************************************************************************/
1287/*!
1288 @brief Tries to read an entire 4-byte page at the specified address.
1289
1290 @param page The page number (0..63 in most cases)
1291 @param buffer Pointer to the byte array that will hold the
1292 retrieved data (if any)
1293 @return 1 on success, 0 on error.
1294*/
1295/**************************************************************************/
1296uint8_t Adafruit_PN532::ntag2xx_ReadPage(uint8_t page, uint8_t *buffer) {
1297 // TAG Type PAGES USER START USER STOP
1298 // -------- ----- ---------- ---------
1299 // NTAG 203 42 4 39
1300 // NTAG 213 45 4 39
1301 // NTAG 215 135 4 129
1302 // NTAG 216 231 4 225
1303
1304 if (page >= 231) {
1305#ifdef MIFAREDEBUG
1306 PN532DEBUGPRINT.println(F("Page value out of range"));
1307#endif
1308 return 0;
1309 }
1310
1311#ifdef MIFAREDEBUG
1312 PN532DEBUGPRINT.print(F("Reading page "));
1313 PN532DEBUGPRINT.println(page);
1314#endif
1315
1316 /* Prepare the command */
1317 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1318 pn532_packetbuffer[1] = 1; /* Card number */
1319 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
1320 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
1321
1322 /* Send the command */
1323 if (!sendCommandCheckAck(pn532_packetbuffer, 4)) {
1324#ifdef MIFAREDEBUG
1325 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1326#endif
1327 return 0;
1328 }
1329
1330 /* Read the response packet */
1331 readdata(pn532_packetbuffer, 26);
1332#ifdef MIFAREDEBUG
1333 PN532DEBUGPRINT.println(F("Received: "));
1334 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1335#endif
1336
1337 /* If byte 8 isn't 0x00 we probably have an error */
1338 if (pn532_packetbuffer[7] == 0x00) {
1339 /* Copy the 4 data bytes to the output buffer */
1340 /* Block content starts at byte 9 of a valid response */
1341 /* Note that the command actually reads 16 byte or 4 */
1342 /* pages at a time ... we simply discard the last 12 */
1343 /* bytes */
1344 memcpy(buffer, pn532_packetbuffer + 8, 4);
1345 } else {
1346#ifdef MIFAREDEBUG
1347 PN532DEBUGPRINT.println(F("Unexpected response reading block: "));
1348 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1349#endif
1350 return 0;
1351 }
1352
1353/* Display data for debug if requested */
1354#ifdef MIFAREDEBUG
1355 PN532DEBUGPRINT.print(F("Page "));
1356 PN532DEBUGPRINT.print(page);
1357 PN532DEBUGPRINT.println(F(":"));
1358 Adafruit_PN532::PrintHexChar(buffer, 4);
1359#endif
1360
1361 // Return OK signal
1362 return 1;
1363}
1364
1365/**************************************************************************/
1366/*!
1367 Tries to write an entire 4-byte page at the specified block
1368 address.
1369
1370 @param page The page number to write. (0..63 for most cases)
1371 @param data The byte array that contains the data to write.
1372 Should be exactly 4 bytes long.
1373
1374 @returns 1 if everything executed properly, 0 for an error
1375*/
1376/**************************************************************************/
1377uint8_t Adafruit_PN532::ntag2xx_WritePage(uint8_t page, uint8_t *data) {
1378 // TAG Type PAGES USER START USER STOP
1379 // -------- ----- ---------- ---------
1380 // NTAG 203 42 4 39
1381 // NTAG 213 45 4 39
1382 // NTAG 215 135 4 129
1383 // NTAG 216 231 4 225
1384
1385 if ((page < 4) || (page > 225)) {
1386#ifdef MIFAREDEBUG
1387 PN532DEBUGPRINT.println(F("Page value out of range"));
1388#endif
1389 // Return Failed Signal
1390 return 0;
1391 }
1392
1393#ifdef MIFAREDEBUG
1394 PN532DEBUGPRINT.print(F("Trying to write 4 byte page"));
1395 PN532DEBUGPRINT.println(page);
1396#endif
1397
1398 /* Prepare the first command */
1399 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1400 pn532_packetbuffer[1] = 1; /* Card number */
1401 pn532_packetbuffer[2] =
1402 MIFARE_ULTRALIGHT_CMD_WRITE; /* Mifare Ultralight Write command = 0xA2 */
1403 pn532_packetbuffer[3] = page; /* Page Number (0..63 for most cases) */
1404 memcpy(pn532_packetbuffer + 4, data, 4); /* Data Payload */
1405
1406 /* Send the command */
1407 if (!sendCommandCheckAck(pn532_packetbuffer, 8)) {
1408#ifdef MIFAREDEBUG
1409 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1410#endif
1411
1412 // Return Failed Signal
1413 return 0;
1414 }
1415 delay(10);
1416
1417 /* Read the response packet */
1418 readdata(pn532_packetbuffer, 26);
1419
1420 // Return OK Signal
1421 return 1;
1422}
1423
1424/**************************************************************************/
1425/*!
1426 Writes an NDEF URI Record starting at the specified page (4..nn)
1427
1428 Note that this function assumes that the NTAG2xx card is
1429 already formatted to work as an "NFC Forum Tag".
1430
1431 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
1432 "http://www.", etc.)
1433 @param url The uri text to write (null-terminated string).
1434 @param dataLen The size of the data area for overflow checks.
1435
1436 @returns 1 if everything executed properly, 0 for an error
1437*/
1438/**************************************************************************/
1439uint8_t Adafruit_PN532::ntag2xx_WriteNDEFURI(uint8_t uriIdentifier, char *url,
1440 uint8_t dataLen) {
1441 uint8_t pageBuffer[4] = {0, 0, 0, 0};
1442
1443 // Remove NDEF record overhead from the URI data (pageHeader below)
1444 uint8_t wrapperSize = 12;
1445
1446 // Figure out how long the string is
1447 uint8_t len = strlen(url);
1448
1449 // Make sure the URI payload will fit in dataLen (include 0xFE trailer)
1450 if ((len < 1) || (len + 1 > (dataLen - wrapperSize)))
1451 return 0;
1452
1453 // Setup the record header
1454 // See NFCForum-TS-Type-2-Tag_1.1.pdf for details
1455 uint8_t pageHeader[12] = {
1456 /* NDEF Lock Control TLV (must be first and always present) */
1457 0x01, /* Tag Field (0x01 = Lock Control TLV) */
1458 0x03, /* Payload Length (always 3) */
1459 0xA0, /* The position inside the tag of the lock bytes (upper 4 = page
1460 address, lower 4 = byte offset) */
1461 0x10, /* Size in bits of the lock area */
1462 0x44, /* Size in bytes of a page and the number of bytes each lock bit can
1463 lock (4 bit + 4 bits) */
1464 /* NDEF Message TLV - URI Record */
1465 0x03, /* Tag Field (0x03 = NDEF Message) */
1466 (uint8_t)(len + 5), /* Payload Length (not including 0xFE trailer) */
1467 0xD1, /* NDEF Record Header (TNF=0x1:Well known record + SR + ME + MB) */
1468 0x01, /* Type Length for the record type indicator */
1469 (uint8_t)(len + 1), /* Payload len */
1470 0x55, /* Record Type Indicator (0x55 or 'U' = URI Record) */
1471 uriIdentifier /* URI Prefix (ex. 0x01 = "http://www.") */
1472 };
1473
1474 // Write 12 byte header (three pages of data starting at page 4)
1475 memcpy(pageBuffer, pageHeader, 4);
1476 if (!(ntag2xx_WritePage(4, pageBuffer)))
1477 return 0;
1478 memcpy(pageBuffer, pageHeader + 4, 4);
1479 if (!(ntag2xx_WritePage(5, pageBuffer)))
1480 return 0;
1481 memcpy(pageBuffer, pageHeader + 8, 4);
1482 if (!(ntag2xx_WritePage(6, pageBuffer)))
1483 return 0;
1484
1485 // Write URI (starting at page 7)
1486 uint8_t currentPage = 7;
1487 char *urlcopy = url;
1488 while (len) {
1489 if (len < 4) {
1490 memset(pageBuffer, 0, 4);
1491 memcpy(pageBuffer, urlcopy, len);
1492 pageBuffer[len] = 0xFE; // NDEF record footer
1493 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1494 return 0;
1495 // DONE!
1496 return 1;
1497 } else if (len == 4) {
1498 memcpy(pageBuffer, urlcopy, len);
1499 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1500 return 0;
1501 memset(pageBuffer, 0, 4);
1502 pageBuffer[0] = 0xFE; // NDEF record footer
1503 currentPage++;
1504 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1505 return 0;
1506 // DONE!
1507 return 1;
1508 } else {
1509 // More than one page of data left
1510 memcpy(pageBuffer, urlcopy, 4);
1511 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1512 return 0;
1513 currentPage++;
1514 urlcopy += 4;
1515 len -= 4;
1516 }
1517 }
1518
1519 // Seems that everything was OK (?!)
1520 return 1;
1521}
1522
1523/************** high level communication functions (handles both I2C and SPI) */
1524
1525/**************************************************************************/
1526/*!
1527 @brief Tries to read the SPI or I2C ACK signal
1528*/
1529/**************************************************************************/
1530bool Adafruit_PN532::readack() {
1531 uint8_t ackbuff[6];
1532
1533 if (spi_dev) {
1534 uint8_t cmd = PN532_SPI_DATAREAD;
1535 spi_dev->write_then_read(&cmd, 1, ackbuff, 6);
1536 } else if (i2c_dev || ser_dev) {
1537 readdata(ackbuff, 6);
1538 }
1539
1540 return (0 == memcmp((char *)ackbuff, (char *)pn532ack, 6));
1541}
1542
1543/**************************************************************************/
1544/*!
1545 @brief Return true if the PN532 is ready with a response.
1546*/
1547/**************************************************************************/
1548bool Adafruit_PN532::isready() {
1549 if (spi_dev) {
1550 // SPI ready check via Status Request
1551 uint8_t cmd = PN532_SPI_STATREAD;
1552 uint8_t reply;
1553 spi_dev->write_then_read(&cmd, 1, &reply, 1);
1554 return reply == PN532_SPI_READY;
1555 } else if (i2c_dev) {
1556 // I2C ready check via reading RDY byte
1557 uint8_t rdy[1];
1558 i2c_dev->read(rdy, 1);
1559 return rdy[0] == PN532_I2C_READY;
1560 } else if (ser_dev) {
1561 // Serial ready check based on non-zero read buffer
1562 return (ser_dev->available() != 0);
1563 } else if (_irq != -1) {
1564 uint8_t x = digitalRead(_irq);
1565 return x == 0;
1566 }
1567 return false;
1568}
1569
1570/**************************************************************************/
1571/*!
1572 @brief Waits until the PN532 is ready.
1573
1574 @param timeout Timeout before giving up
1575*/
1576/**************************************************************************/
1577bool Adafruit_PN532::waitready(uint16_t timeout) {
1578 uint16_t timer = 0;
1579 while (!isready()) {
1580 if (timeout != 0) {
1581 timer += 10;
1582 if (timer > timeout) {
1583#ifdef PN532DEBUG
1584 PN532DEBUGPRINT.println("TIMEOUT!");
1585#endif
1586 return false;
1587 }
1588 }
1589 delay(10);
1590 }
1591 return true;
1592}
1593
1594/**************************************************************************/
1595/*!
1596 @brief Reads n bytes of data from the PN532 via SPI or I2C.
1597
1598 @param buff Pointer to the buffer where data will be written
1599 @param n Number of bytes to be read
1600*/
1601/**************************************************************************/
1602void Adafruit_PN532::readdata(uint8_t *buff, uint8_t n) {
1603 if (spi_dev) {
1604 // SPI read
1605 uint8_t cmd = PN532_SPI_DATAREAD;
1606 spi_dev->write_then_read(&cmd, 1, buff, n);
1607 } else if (i2c_dev) {
1608 // I2C read
1609 uint8_t rbuff[n + 1]; // +1 for leading RDY byte
1610 i2c_dev->read(rbuff, n + 1);
1611 for (uint8_t i = 0; i < n; i++) {
1612 buff[i] = rbuff[i + 1];
1613 }
1614 } else if (ser_dev) {
1615 // Serial read
1616 ser_dev->readBytes(buff, n);
1617 }
1618#ifdef PN532DEBUG
1619 PN532DEBUGPRINT.print(F("Reading: "));
1620 for (uint8_t i = 0; i < n; i++) {
1621 PN532DEBUGPRINT.print(F(" 0x"));
1622 PN532DEBUGPRINT.print(buff[i], HEX);
1623 }
1624 PN532DEBUGPRINT.println();
1625#endif
1626}
1627
1628/**************************************************************************/
1629/*!
1630 @brief set the PN532 as iso14443a Target behaving as a SmartCard
1631 @return true on success, false otherwise.
1632 @note Author: Salvador Mendoza (salmg.net) new functions:
1633 -AsTarget
1634 -getDataTarget
1635 -setDataTarget
1636*/
1637/**************************************************************************/
1638uint8_t Adafruit_PN532::AsTarget() {
1639 pn532_packetbuffer[0] = 0x8C;
1640 uint8_t target[] = {
1641 0x8C, // INIT AS TARGET
1642 0x00, // MODE -> BITFIELD
1643 0x08, 0x00, // SENS_RES - MIFARE PARAMS
1644 0xdc, 0x44, 0x20, // NFCID1T
1645 0x60, // SEL_RES
1646 0x01, 0xfe, // NFCID2T MUST START WITH 01fe - FELICA PARAMS - POL_RES
1647 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xc0,
1648 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, // PAD
1649 0xff, 0xff, // SYSTEM CODE
1650 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44,
1651 0x33, 0x22, 0x11, 0x01, 0x00, // NFCID3t MAX 47 BYTES ATR_RES
1652 0x0d, 0x52, 0x46, 0x49, 0x44, 0x49, 0x4f,
1653 0x74, 0x20, 0x50, 0x4e, 0x35, 0x33, 0x32 // HISTORICAL BYTES
1654 };
1655 if (!sendCommandCheckAck(target, sizeof(target)))
1656 return false;
1657
1658 // read data packet
1659 readdata(pn532_packetbuffer, 8);
1660
1661 int offset = 6;
1662 return (pn532_packetbuffer[offset] == 0x15);
1663}
1664/**************************************************************************/
1665/*!
1666 @brief Retrieve response from the emulation mode
1667
1668 @param cmd = data
1669 @param cmdlen = data length
1670 @return true on success, false otherwise.
1671*/
1672/**************************************************************************/
1673uint8_t Adafruit_PN532::getDataTarget(uint8_t *cmd, uint8_t *cmdlen) {
1674 uint8_t length;
1675 pn532_packetbuffer[0] = 0x86;
1676 if (!sendCommandCheckAck(pn532_packetbuffer, 1, 1000)) {
1677 PN532DEBUGPRINT.println(F("Error en ack"));
1678 return false;
1679 }
1680
1681 // read data packet
1682 readdata(pn532_packetbuffer, 64);
1683 length = pn532_packetbuffer[3] - 3;
1684
1685 // if (length > *responseLength) {// Bug, should avoid it in the reading
1686 // target data
1687 // length = *responseLength; // silent truncation...
1688 //}
1689
1690 for (int i = 0; i < length; ++i) {
1691 cmd[i] = pn532_packetbuffer[8 + i];
1692 }
1693 *cmdlen = length;
1694 return true;
1695}
1696
1697/**************************************************************************/
1698/*!
1699 @brief Set data in PN532 in the emulation mode
1700
1701 @param cmd = data
1702 @param cmdlen = data length
1703 @return true on success, false otherwise.
1704*/
1705/**************************************************************************/
1706uint8_t Adafruit_PN532::setDataTarget(uint8_t *cmd, uint8_t cmdlen) {
1707 uint8_t length;
1708 // cmd1[0] = 0x8E; Must!
1709
1710 if (!sendCommandCheckAck(cmd, cmdlen))
1711 return false;
1712
1713 // read data packet
1714 readdata(pn532_packetbuffer, 8);
1715 length = pn532_packetbuffer[3] - 3;
1716 for (int i = 0; i < length; ++i) {
1717 cmd[i] = pn532_packetbuffer[8 + i];
1718 }
1719 // cmdl = 0
1720 cmdlen = length;
1721
1722 int offset = 6;
1723 return (pn532_packetbuffer[offset] == 0x15);
1724}
1725
1726/**************************************************************************/
1727/*!
1728 @brief Writes a command to the PN532, automatically inserting the
1729 preamble and required frame details (checksum, len, etc.)
1730
1731 @param cmd Pointer to the command buffer
1732 @param cmdlen Command length in bytes
1733*/
1734/**************************************************************************/
1735void Adafruit_PN532::writecommand(uint8_t *cmd, uint8_t cmdlen) {
1736 if (spi_dev) {
1737 // SPI command write.
1738 uint8_t checksum;
1739 uint8_t packet[9 + cmdlen];
1740 uint8_t *p = packet;
1741 cmdlen++;
1742
1743 p[0] = PN532_SPI_DATAWRITE;
1744 p++;
1745
1746 p[0] = PN532_PREAMBLE;
1747 p++;
1748 p[0] = PN532_STARTCODE1;
1749 p++;
1750 p[0] = PN532_STARTCODE2;
1751 p++;
1752 checksum = PN532_PREAMBLE + PN532_STARTCODE1 + PN532_STARTCODE2;
1753
1754 p[0] = cmdlen;
1755 p++;
1756 p[0] = ~cmdlen + 1;
1757 p++;
1758
1759 p[0] = PN532_HOSTTOPN532;
1760 p++;
1761 checksum += PN532_HOSTTOPN532;
1762
1763 for (uint8_t i = 0; i < cmdlen - 1; i++) {
1764 p[0] = cmd[i];
1765 p++;
1766 checksum += cmd[i];
1767 }
1768
1769 p[0] = ~checksum;
1770 p++;
1771 p[0] = PN532_POSTAMBLE;
1772 p++;
1773
1774#ifdef PN532DEBUG
1775 Serial.print("Sending : ");
1776 for (int i = 1; i < 8 + cmdlen; i++) {
1777 Serial.print("0x");
1778 Serial.print(packet[i], HEX);
1779 Serial.print(", ");
1780 }
1781 Serial.println();
1782#endif
1783
1784 spi_dev->write(packet, 8 + cmdlen);
1785 } else if (i2c_dev || ser_dev) {
1786 // I2C or Serial command write.
1787 uint8_t packet[8 + cmdlen];
1788 uint8_t LEN = cmdlen + 1;
1789
1790 packet[0] = PN532_PREAMBLE;
1791 packet[1] = PN532_STARTCODE1;
1792 packet[2] = PN532_STARTCODE2;
1793 packet[3] = LEN;
1794 packet[4] = ~LEN + 1;
1795 packet[5] = PN532_HOSTTOPN532;
1796 uint8_t sum = 0;
1797 for (uint8_t i = 0; i < cmdlen; i++) {
1798 packet[6 + i] = cmd[i];
1799 sum += cmd[i];
1800 }
1801 packet[6 + cmdlen] = ~(PN532_HOSTTOPN532 + sum) + 1;
1802 packet[7 + cmdlen] = PN532_POSTAMBLE;
1803
1804#ifdef PN532DEBUG
1805 Serial.print("Sending : ");
1806 for (int i = 1; i < 8 + cmdlen; i++) {
1807 Serial.print("0x");
1808 Serial.print(packet[i], HEX);
1809 Serial.print(", ");
1810 }
1811 Serial.println();
1812#endif
1813
1814 if (i2c_dev) {
1815 i2c_dev->write(packet, 8 + cmdlen);
1816 } else {
1817 ser_dev->write(packet, 8 + cmdlen);
1818 }
1819 }
1820}