Adafruit_PN532.cpp 59 KB

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