1 /* 2 * Author: Jon Trulson <jtrulson@ics.com> 3 * Copyright (c) 2015 Intel Corporation. 4 * 5 * This code is heavily based on the Adafruit-PN532 library at 6 * https://github.com/adafruit/Adafruit-PN532, which is licensed under 7 * the BSD license. See upm/src/pn532/license.txt 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining 10 * a copy of this software and associated documentation files (the 11 * "Software"), to deal in the Software without restriction, including 12 * without limitation the rights to use, copy, modify, merge, publish, 13 * distribute, sublicense, and/or sell copies of the Software, and to 14 * permit persons to whom the Software is furnished to do so, subject to 15 * the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be 18 * included in all copies or substantial portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 */ 28 29 30 #pragma once 31 32 #include <string.h> 33 #include <string> 34 #include <mraa/common.hpp> 35 #include <mraa/i2c.hpp> 36 37 #include <mraa/gpio.hpp> 38 39 #define PN532_I2C_BUS 0 40 #define PN532_DEFAULT_I2C_ADDR (0x48 >> 1) 41 42 #define PN532_PREAMBLE (0x00) 43 #define PN532_STARTCODE1 (0x00) 44 #define PN532_STARTCODE2 (0xFF) 45 #define PN532_POSTAMBLE (0x00) 46 47 #define PN532_HOSTTOPN532 (0xD4) 48 #define PN532_PN532TOHOST (0xD5) 49 50 namespace upm { 51 52 /** 53 * @brief PN532 NFC/RFID reader/writer 54 * @defgroup pn532 libupm-pn532 55 * @ingroup adafruit i2c rfid 56 */ 57 58 /** 59 * @library pn532 60 * @sensor pn532 61 * @comname PN532 NFC/RFID reader/writer 62 * @type rfid 63 * @man adafruit 64 * @web http://www.adafruit.com/products/364 65 * @con i2c 66 * 67 * @brief API for the PN532 based NFC/RFID reader/writer 68 * 69 * Identify a card and print out basic info 70 * @snippet pn532.cxx Interesting 71 * Add a URI to an already NDEF formatted ultralight or NTAG2XX tag 72 * @snippet pn532-writeurl.cxx Interesting 73 */ 74 class PN532 { 75 public: 76 77 /** 78 * PN532 commands 79 */ 80 typedef enum { 81 CMD_DIAGNOSE = 0x00, 82 CMD_GETFIRMWAREVERSION = 0x02, 83 CMD_GETGENERALSTATUS = 0x04, 84 CMD_READREGISTER = 0x06, 85 CMD_WRITEREGISTER = 0x08, 86 CMD_READGPIO = 0x0C, 87 CMD_WRITEGPIO = 0x0E, 88 CMD_SETSERIALBAUDRATE = 0x10, 89 CMD_SETPARAMETERS = 0x12, 90 CMD_SAMCONFIGURATION = 0x14, 91 CMD_POWERDOWN = 0x16, 92 CMD_RFCONFIGURATION = 0x32, 93 CMD_RFREGULATIONTEST = 0x58, 94 CMD_INJUMPFORDEP = 0x56, 95 CMD_INJUMPFORPSL = 0x46, 96 CMD_INLISTPASSIVETARGET = 0x4A, 97 CMD_INATR = 0x50, 98 CMD_INPSL = 0x4E, 99 CMD_INDATAEXCHANGE = 0x40, 100 CMD_INCOMMUNICATETHRU = 0x42, 101 CMD_INDESELECT = 0x44, 102 CMD_INRELEASE = 0x52, 103 CMD_INSELECT = 0x54, 104 CMD_INAUTOPOLL = 0x60, 105 CMD_TGINITASTARGET = 0x8C, 106 CMD_TGSETGENERALBYTES = 0x92, 107 CMD_TGGETDATA = 0x86, 108 CMD_TGSETDATA = 0x8E, 109 CMD_TGSETMETADATA = 0x94, 110 CMD_TGGETINITIATORCOMMAND = 0x88, 111 CMD_TGRESPONSETOINITIATOR = 0x90, 112 CMD_TGGETTARGETSTATUS = 0x8A 113 } PN532_CMD_T; 114 115 /** 116 * Response bytes 117 */ 118 typedef enum { 119 RSP_INDATAEXCHANGE = 0x41, 120 RSP_INLISTPASSIVETARGET = 0x4B 121 } PN532_RSP_T; 122 123 /** 124 * MIFARE commands 125 */ 126 typedef enum { 127 MIFARE_CMD_AUTH_A = 0x60, 128 MIFARE_CMD_AUTH_B = 0x61, 129 MIFARE_CMD_READ = 0x30, 130 MIFARE_CMD_WRITE = 0xA0, 131 MIFARE_CMD_TRANSFER = 0xB0, 132 MIFARE_CMD_DECREMENT = 0xC0, 133 MIFARE_CMD_INCREMENT = 0xC1, 134 MIFARE_CMD_STORE = 0xC2, 135 MIFARE_ULTRALIGHT_CMD_WRITE = 0xA2 136 } MIFARE_CMD_T; 137 138 /** 139 * NDEF prefixes 140 */ 141 typedef enum { 142 NDEF_URIPREFIX_NONE = 0x00, 143 NDEF_URIPREFIX_HTTP_WWWDOT = 0x01, 144 NDEF_URIPREFIX_HTTPS_WWWDOT = 0x02, 145 NDEF_URIPREFIX_HTTP = 0x03, 146 NDEF_URIPREFIX_HTTPS = 0x04, 147 NDEF_URIPREFIX_TEL = 0x05, 148 NDEF_URIPREFIX_MAILTO = 0x06, 149 NDEF_URIPREFIX_FTP_ANONAT = 0x07, 150 NDEF_URIPREFIX_FTP_FTPDOT = 0x08, 151 NDEF_URIPREFIX_FTPS = 0x09, 152 NDEF_URIPREFIX_SFTP = 0x0A, 153 NDEF_URIPREFIX_SMB = 0x0B, 154 NDEF_URIPREFIX_NFS = 0x0C, 155 NDEF_URIPREFIX_FTP = 0x0D, 156 NDEF_URIPREFIX_DAV = 0x0E, 157 NDEF_URIPREFIX_NEWS = 0x0F, 158 NDEF_URIPREFIX_TELNET = 0x10, 159 NDEF_URIPREFIX_IMAP = 0x11, 160 NDEF_URIPREFIX_RTSP = 0x12, 161 NDEF_URIPREFIX_URN = 0x13, 162 NDEF_URIPREFIX_POP = 0x14, 163 NDEF_URIPREFIX_SIP = 0x15, 164 NDEF_URIPREFIX_SIPS = 0x16, 165 NDEF_URIPREFIX_TFTP = 0x17, 166 NDEF_URIPREFIX_BTSPP = 0x18, 167 NDEF_URIPREFIX_BTL2CAP = 0x19, 168 NDEF_URIPREFIX_BTGOEP = 0x1A, 169 NDEF_URIPREFIX_TCPOBEX = 0x1B, 170 NDEF_URIPREFIX_IRDAOBEX = 0x1C, 171 NDEF_URIPREFIX_FILE = 0x1D, 172 NDEF_URIPREFIX_URN_EPC_ID = 0x1E, 173 NDEF_URIPREFIX_URN_EPC_TAG = 0x1F, 174 NDEF_URIPREFIX_URN_EPC_PAT = 0x20, 175 NDEF_URIPREFIX_URN_EPC_RAW = 0x21, 176 NDEF_URIPREFIX_URN_EPC = 0x22, 177 NDEF_URIPREFIX_URN_NFC = 0x23 178 } NDEF_URI_T; 179 180 /** 181 * Card baud rates 182 */ 183 typedef enum { 184 BAUD_MIFARE_ISO14443A = 0x00 // 106 Kbit/s 185 } BAUD_T; 186 187 188 /** 189 * Tag types 190 */ 191 typedef enum { 192 TAG_TYPE_UNKNOWN = 0, 193 TAG_TYPE_MIFARE_CLASSIC = 1, 194 TAG_TYPE_NFC2 = 2 /* ultralight or NTAG2XX */ 195 } TAG_TYPE_T; 196 197 /** 198 * pn532 constructor 199 * 200 * @param irq pin to use for IRQ 201 * @param reset reset pin 202 * @param bus i2c bus to use 203 * @param address the address for this device 204 */ 205 PN532(int irq, int reset, int bus=PN532_I2C_BUS, 206 uint8_t address=PN532_DEFAULT_I2C_ADDR); 207 208 /** 209 * PN532 Destructor 210 */ 211 ~PN532(); 212 213 /** 214 * set up initial values and start operation 215 * 216 * @return true if successful 217 */ 218 bool init(); 219 220 /** 221 * Checks the firmware version of the PN5xx chip 222 * 223 * @return the chip's firmware version and ID 224 */ 225 uint32_t getFirmwareVersion(); 226 227 /** 228 * sends a command and waits a specified period for the ACK 229 * 230 * @param cmd Pointer to the command buffer 231 * @param cmdlen the size of the command in bytes 232 * @param timeout timeout before giving up (in ms) 233 * 234 * @return true if everything is OK, false if timeout occured 235 * before an ACK was recieved 236 */ 237 bool sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, 238 uint16_t timeout=1000); 239 240 /** 241 * configures the SAM (Secure Access Module) 242 * 243 * @return true if successfully configured 244 */ 245 bool SAMConfig(void); 246 247 /** 248 * sets the MxRtyPassiveActivation byte of the RFConfiguration 249 * register. By default the pn532 will retry indefinitely. 250 * 251 * @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout 252 * after maxRetries. 0x00 means try once, with no retries on failure. 253 * 254 * @return true if everything executed properly, false for an error 255 */ 256 bool setPassiveActivationRetries(uint8_t maxRetries); 257 258 /** 259 * waits for an ISO14443A target to enter the field 260 * 261 * @param cardbaudbate baud rate of the card, one of the BAUD_T values 262 * @param uid Pointer to the array that will be populated with the 263 * cards UID, up to 7 bytes 264 * @param uidLength Pointer to the variable that will hold the 265 * length of the card's UID. 266 * @param timeout the number of milliseconds to wait 267 * 268 * @return true if everything executed properly, false for an error 269 */ 270 bool readPassiveTargetID(BAUD_T cardbaudrate, uint8_t * uid, 271 uint8_t * uidLength, uint16_t timeout); 272 273 /** 274 * exchanges an APDU (Application Protocol Data Unit) with the 275 * currently inlisted peer 276 * 277 * @param send Pointer to data to send 278 * @param sendLength Length of the data to send 279 * @param response Pointer to response data 280 * @param responseLength Pointer to the response data length 281 * 282 * @return true if everything executed properly, false for an error 283 */ 284 bool inDataExchange(uint8_t * send, uint8_t sendLength, 285 uint8_t * response, uint8_t * responseLength); 286 287 /** 288 * 'InLists' a passive target. PN532 acting as reader/initiator, 289 * peer acting as card/responder. 290 * 291 * @return true if everything executed properly, false for an error 292 */ 293 bool inListPassiveTarget(); 294 295 /** 296 * Indicates whether the specified block number is the first block 297 * in the sector (block 0 relative to the current sector) 298 * 299 * @return true if it's the first block, false otherwise 300 */ 301 bool mifareclassic_IsFirstBlock (uint32_t uiBlock); 302 303 /** 304 * indicates whether the specified block number is the sector trailer 305 * 306 * @return true if it's the trailer block, false otherwise 307 */ 308 bool mifareclassic_IsTrailerBlock (uint32_t uiBlock); 309 310 /** 311 * tries to authenticate a block of memory on a MIFARE card using the 312 * INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual 313 * for more information on sending MIFARE and other commands. 314 * 315 * @param uid Pointer to a byte array containing the card UID 316 * @param uidLen The length (in bytes) of the card's UID (Should 317 * be 4 for MIFARE Classic) 318 * @param blockNumber The block number to authenticate. (0..63 for 319 * 1KB cards, and 0..255 for 4KB cards). 320 * @param keyNumber Which key type to use during authentication 321 * (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B) 322 * @param keyData Pointer to a byte array containing the 6 byte 323 * key value 324 * 325 * @return true if everything executed properly, false for an error 326 */ 327 bool mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, 328 uint32_t blockNumber, 329 uint8_t keyNumber, 330 uint8_t * keyData); 331 332 /** 333 * tries to read an entire 16-byte data block at the specified block 334 * address. 335 * 336 * @param blockNumber The block number to read (0..63 for 337 * 1KB cards, and 0..255 for 4KB cards). 338 * @param data Pointer to the byte array that will hold the 339 * retrieved data (if any) 340 * 341 * @return true if everything executed properly, false for an error 342 */ 343 bool mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data); 344 345 /** 346 * tries to write an entire 16-byte data block at the specified block 347 * address. 348 * 349 * @param blockNumber The block number to write. (0..63 for 350 * 1KB cards, and 0..255 for 4KB cards). 351 * @param data The byte array that contains the data to write. 352 * 353 * @returns true if everything executed properly, false for an error 354 */ 355 bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data); 356 357 /** 358 * formats a Mifare Classic card to store NDEF Records 359 * 360 * @return true if everything executed properly, false for an error 361 */ 362 bool mifareclassic_FormatNDEF (void); 363 364 /** 365 * writes an NDEF URI Record to the specified sector (1..15) 366 * 367 * Note that this function assumes that the Mifare Classic card is 368 * already formatted to work as an "NFC Forum Tag" and uses a MAD1 369 * file system. You can use the NXP TagWriter app on Android to 370 * properly format cards for this. 371 * 372 * @param sectorNumber The sector that the URI record should be written 373 * to (can be 1..15 for a 1K card) 374 * @param uriIdentifier The uri identifier code (one of the NDEF_URI_T 375 * values 376 * @param url the uri text to write (max 38 characters). 377 * 378 * @return true if everything executed properly, false for an error 379 */ 380 bool mifareclassic_WriteNDEFURI (uint8_t sectorNumber, 381 NDEF_URI_T uriIdentifier, 382 const char * url); 383 384 /** 385 * read an entire 4-byte page at the specified address 386 * 387 * @param page The page number (0..63 in most cases) 388 * @param buffer Pointer to the byte array that will hold the 389 * retrieved data (if any) 390 * 391 * @return true if everything executed properly, false for an error 392 */ 393 bool ntag2xx_ReadPage (uint8_t page, uint8_t * buffer); 394 395 /** 396 * write an entire 4-byte page at the specified block address 397 * 398 * @param page The page number to write. (0..63 for most cases) 399 * @param data The byte array that contains the data to write. 400 * Should be exactly 4 bytes long. 401 * 402 * @return true if everything executed properly, false for an error 403 */ 404 bool ntag2xx_WritePage (uint8_t page, uint8_t * data); 405 406 /** 407 * writes an NDEF URI Record starting at the specified page (4..nn) 408 * 409 * Note that this function assumes that the NTAG2xx card is 410 * already formatted to work as an "NFC Forum Tag". 411 * 412 * @param uriIdentifier The uri identifier code (one of the NDEF_URI_T 413 * values 414 * @param url The uri text to write (null-terminated string). 415 * @param dataLen The size of the data area for overflow checks. 416 * 417 * @return true if everything executed properly, false for an error 418 */ 419 bool ntag2xx_WriteNDEFURI (NDEF_URI_T uriIdentifier, char * url, 420 uint8_t dataLen); 421 422 /** 423 * return the ATQA (Answer to Request Acknowlege) value. This 424 * value is only valid after a successfull call to 425 * readPassiveTargetID() 426 * 427 * @return ATQA value 428 */ getATQA()429 uint16_t getATQA() { return m_ATQA; }; 430 431 /** 432 * return the SAK (Select Acknowlege) value. This 433 * value is only valid after a successfull call to 434 * readPassiveTargetID() 435 * 436 * @return SAK value 437 */ getSAK()438 uint8_t getSAK() { return m_SAK; }; 439 440 /** 441 * provide public access to the class's MRAA i2C context for 442 * direct user access 443 * 444 * @return a reference to the class i2c context 445 */ i2cContext()446 mraa::I2c& i2cContext() { return m_i2c; }; 447 448 /** 449 * enable or disable debugging output for pn532 related operations 450 * 451 * @param enable true to enabloe debug output, false to disable 452 */ pn532Debug(bool enable)453 void pn532Debug(bool enable) { m_pn532Debug = enable; }; 454 455 /** 456 * enable or disable debugging output for mifare related operations 457 * 458 * @param enable true to enabloe debug output, false to disable 459 */ 460 mifareDebug(bool enable)461 void mifareDebug(bool enable) { m_mifareDebug = enable; }; 462 463 /** 464 * try to determine the tag type 465 * 466 * @return one of the TAG_TYPE_T values 467 */ 468 TAG_TYPE_T tagType(); 469 470 protected: 471 mraa::I2c m_i2c; 472 mraa::Gpio m_gpioIRQ; 473 mraa::Gpio m_gpioReset; 474 475 bool readAck(); 476 bool isReady(); 477 bool waitForReady(uint16_t timeout); 478 void readData(uint8_t* buff, uint8_t n); 479 void writeCommand(uint8_t* cmd, uint8_t cmdlen); 480 481 private: 482 static void dataReadyISR(void *ctx); 483 bool m_isrInstalled; 484 volatile bool m_irqRcvd; 485 486 uint8_t m_addr; 487 488 uint8_t m_uid[7]; // ISO14443A uid 489 uint8_t m_uidLen; // uid len 490 uint8_t m_key[6]; // Mifare Classic key 491 uint8_t m_inListedTag; // Tg number of inlisted tag. 492 493 uint16_t m_ATQA; // ATQA (Answer to Request Acknowlege - ISO14443) 494 // for currently inlisted card 495 uint8_t m_SAK; // SAK (Select Acknowlege) 496 // for currently inlisted card 497 498 // debugables 499 bool m_pn532Debug; 500 bool m_mifareDebug; 501 }; 502 } 503 504 505