| 1 | /**************************************************************************/ |
| 2 | /*! |
| 3 | @file Adafruit_PN532.h |
| 4 | |
| 5 | v2.0 - Refactored to add I2C support from Adafruit_NFCShield_I2C library. |
| 6 | |
| 7 | v1.1 - Added full command list |
| 8 | - Added 'verbose' mode flag to constructor to toggle debug output |
| 9 | - Changed readPassiveTargetID() to return variable length values |
| 10 | */ |
| 11 | /**************************************************************************/ |
| 12 | |
| 13 | #ifndef ADAFRUIT_PN532_H |
| 14 | #define ADAFRUIT_PN532_H |
| 15 | |
| 16 | #include "Arduino.h" |
| 17 | |
| 18 | #include <Adafruit_I2CDevice.h> |
| 19 | #include <Adafruit_SPIDevice.h> |
| 20 | |
| 21 | #define PN532_PREAMBLE (0x00) ///< Command sequence start, byte 1/3 |
| 22 | #define PN532_STARTCODE1 (0x00) ///< Command sequence start, byte 2/3 |
| 23 | #define PN532_STARTCODE2 (0xFF) ///< Command sequence start, byte 3/3 |
| 24 | #define PN532_POSTAMBLE (0x00) ///< EOD |
| 25 | |
| 26 | #define PN532_HOSTTOPN532 (0xD4) ///< Host-to-PN532 |
| 27 | #define PN532_PN532TOHOST (0xD5) ///< PN532-to-host |
| 28 | |
| 29 | // PN532 Commands |
| 30 | #define PN532_COMMAND_DIAGNOSE (0x00) ///< Diagnose |
| 31 | #define PN532_COMMAND_GETFIRMWAREVERSION (0x02) ///< Get firmware version |
| 32 | #define PN532_COMMAND_GETGENERALSTATUS (0x04) ///< Get general status |
| 33 | #define PN532_COMMAND_READREGISTER (0x06) ///< Read register |
| 34 | #define PN532_COMMAND_WRITEREGISTER (0x08) ///< Write register |
| 35 | #define PN532_COMMAND_READGPIO (0x0C) ///< Read GPIO |
| 36 | #define PN532_COMMAND_WRITEGPIO (0x0E) ///< Write GPIO |
| 37 | #define PN532_COMMAND_SETSERIALBAUDRATE (0x10) ///< Set serial baud rate |
| 38 | #define PN532_COMMAND_SETPARAMETERS (0x12) ///< Set parameters |
| 39 | #define PN532_COMMAND_SAMCONFIGURATION (0x14) ///< SAM configuration |
| 40 | #define PN532_COMMAND_POWERDOWN (0x16) ///< Power down |
| 41 | #define PN532_COMMAND_RFCONFIGURATION (0x32) ///< RF config |
| 42 | #define PN532_COMMAND_RFREGULATIONTEST (0x58) ///< RF regulation test |
| 43 | #define PN532_COMMAND_INJUMPFORDEP (0x56) ///< Jump for DEP |
| 44 | #define PN532_COMMAND_INJUMPFORPSL (0x46) ///< Jump for PSL |
| 45 | #define PN532_COMMAND_INLISTPASSIVETARGET (0x4A) ///< List passive target |
| 46 | #define PN532_COMMAND_INATR (0x50) ///< ATR |
| 47 | #define PN532_COMMAND_INPSL (0x4E) ///< PSL |
| 48 | #define PN532_COMMAND_INDATAEXCHANGE (0x40) ///< Data exchange |
| 49 | #define PN532_COMMAND_INCOMMUNICATETHRU (0x42) ///< Communicate through |
| 50 | #define PN532_COMMAND_INDESELECT (0x44) ///< Deselect |
| 51 | #define PN532_COMMAND_INRELEASE (0x52) ///< Release |
| 52 | #define PN532_COMMAND_INSELECT (0x54) ///< Select |
| 53 | #define PN532_COMMAND_INAUTOPOLL (0x60) ///< Auto poll |
| 54 | #define PN532_COMMAND_TGINITASTARGET (0x8C) ///< Init as target |
| 55 | #define PN532_COMMAND_TGSETGENERALBYTES (0x92) ///< Set general bytes |
| 56 | #define PN532_COMMAND_TGGETDATA (0x86) ///< Get data |
| 57 | #define PN532_COMMAND_TGSETDATA (0x8E) ///< Set data |
| 58 | #define PN532_COMMAND_TGSETMETADATA (0x94) ///< Set metadata |
| 59 | #define PN532_COMMAND_TGGETINITIATORCOMMAND (0x88) ///< Get initiator command |
| 60 | #define PN532_COMMAND_TGRESPONSETOINITIATOR (0x90) ///< Response to initiator |
| 61 | #define PN532_COMMAND_TGGETTARGETSTATUS (0x8A) ///< Get target status |
| 62 | |
| 63 | #define PN532_RESPONSE_INDATAEXCHANGE (0x41) ///< Data exchange |
| 64 | #define PN532_RESPONSE_INLISTPASSIVETARGET (0x4B) ///< List passive target |
| 65 | |
| 66 | #define PN532_WAKEUP (0x55) ///< Wake |
| 67 | |
| 68 | #define PN532_SPI_STATREAD (0x02) ///< Stat read |
| 69 | #define PN532_SPI_DATAWRITE (0x01) ///< Data write |
| 70 | #define PN532_SPI_DATAREAD (0x03) ///< Data read |
| 71 | #define PN532_SPI_READY (0x01) ///< Ready |
| 72 | |
| 73 | //#define PN532_I2C_ADDRESS (0x48 >> 1) ///< Default I2C address |
| 74 | // My fucking clone board for some goddamn reason uses the address 0x28 |
| 75 | #define PN532_I2C_ADDRESS (0x28) |
| 76 | #define PN532_I2C_READBIT (0x01) ///< Read bit |
| 77 | #define PN532_I2C_BUSY (0x00) ///< Busy |
| 78 | #define PN532_I2C_READY (0x01) ///< Ready |
| 79 | #define PN532_I2C_READYTIMEOUT (20) ///< Ready timeout |
| 80 | |
| 81 | #define PN532_MIFARE_ISO14443A (0x00) ///< MiFare |
| 82 | |
| 83 | // Mifare Commands |
| 84 | #define MIFARE_CMD_AUTH_A (0x60) ///< Auth A |
| 85 | #define MIFARE_CMD_AUTH_B (0x61) ///< Auth B |
| 86 | #define MIFARE_CMD_READ (0x30) ///< Read |
| 87 | #define MIFARE_CMD_WRITE (0xA0) ///< Write |
| 88 | #define MIFARE_CMD_TRANSFER (0xB0) ///< Transfer |
| 89 | #define MIFARE_CMD_DECREMENT (0xC0) ///< Decrement |
| 90 | #define MIFARE_CMD_INCREMENT (0xC1) ///< Increment |
| 91 | #define MIFARE_CMD_STORE (0xC2) ///< Store |
| 92 | #define MIFARE_ULTRALIGHT_CMD_WRITE (0xA2) ///< Write (MiFare Ultralight) |
| 93 | |
| 94 | // Prefixes for NDEF Records (to identify record type) |
| 95 | #define NDEF_URIPREFIX_NONE (0x00) ///< No prefix |
| 96 | #define NDEF_URIPREFIX_HTTP_WWWDOT (0x01) ///< HTTP www. prefix |
| 97 | #define NDEF_URIPREFIX_HTTPS_WWWDOT (0x02) ///< HTTPS www. prefix |
| 98 | #define NDEF_URIPREFIX_HTTP (0x03) ///< HTTP prefix |
| 99 | #define NDEF_URIPREFIX_HTTPS (0x04) ///< HTTPS prefix |
| 100 | #define NDEF_URIPREFIX_TEL (0x05) ///< Tel prefix |
| 101 | #define NDEF_URIPREFIX_MAILTO (0x06) ///< Mailto prefix |
| 102 | #define NDEF_URIPREFIX_FTP_ANONAT (0x07) ///< FTP |
| 103 | #define NDEF_URIPREFIX_FTP_FTPDOT (0x08) ///< FTP dot |
| 104 | #define NDEF_URIPREFIX_FTPS (0x09) ///< FTPS |
| 105 | #define NDEF_URIPREFIX_SFTP (0x0A) ///< SFTP |
| 106 | #define NDEF_URIPREFIX_SMB (0x0B) ///< SMB |
| 107 | #define NDEF_URIPREFIX_NFS (0x0C) ///< NFS |
| 108 | #define NDEF_URIPREFIX_FTP (0x0D) ///< FTP |
| 109 | #define NDEF_URIPREFIX_DAV (0x0E) ///< DAV |
| 110 | #define NDEF_URIPREFIX_NEWS (0x0F) ///< NEWS |
| 111 | #define NDEF_URIPREFIX_TELNET (0x10) ///< Telnet prefix |
| 112 | #define NDEF_URIPREFIX_IMAP (0x11) ///< IMAP prefix |
| 113 | #define NDEF_URIPREFIX_RTSP (0x12) ///< RTSP |
| 114 | #define NDEF_URIPREFIX_URN (0x13) ///< URN |
| 115 | #define NDEF_URIPREFIX_POP (0x14) ///< POP |
| 116 | #define NDEF_URIPREFIX_SIP (0x15) ///< SIP |
| 117 | #define NDEF_URIPREFIX_SIPS (0x16) ///< SIPS |
| 118 | #define NDEF_URIPREFIX_TFTP (0x17) ///< TFPT |
| 119 | #define NDEF_URIPREFIX_BTSPP (0x18) ///< BTSPP |
| 120 | #define NDEF_URIPREFIX_BTL2CAP (0x19) ///< BTL2CAP |
| 121 | #define NDEF_URIPREFIX_BTGOEP (0x1A) ///< BTGOEP |
| 122 | #define NDEF_URIPREFIX_TCPOBEX (0x1B) ///< TCPOBEX |
| 123 | #define NDEF_URIPREFIX_IRDAOBEX (0x1C) ///< IRDAOBEX |
| 124 | #define NDEF_URIPREFIX_FILE (0x1D) ///< File |
| 125 | #define NDEF_URIPREFIX_URN_EPC_ID (0x1E) ///< URN EPC ID |
| 126 | #define NDEF_URIPREFIX_URN_EPC_TAG (0x1F) ///< URN EPC tag |
| 127 | #define NDEF_URIPREFIX_URN_EPC_PAT (0x20) ///< URN EPC pat |
| 128 | #define NDEF_URIPREFIX_URN_EPC_RAW (0x21) ///< URN EPC raw |
| 129 | #define NDEF_URIPREFIX_URN_EPC (0x22) ///< URN EPC |
| 130 | #define NDEF_URIPREFIX_URN_NFC (0x23) ///< URN NFC |
| 131 | |
| 132 | #define PN532_GPIO_VALIDATIONBIT (0x80) ///< GPIO validation bit |
| 133 | #define PN532_GPIO_P30 (0) ///< GPIO 30 |
| 134 | #define PN532_GPIO_P31 (1) ///< GPIO 31 |
| 135 | #define PN532_GPIO_P32 (2) ///< GPIO 32 |
| 136 | #define PN532_GPIO_P33 (3) ///< GPIO 33 |
| 137 | #define PN532_GPIO_P34 (4) ///< GPIO 34 |
| 138 | #define PN532_GPIO_P35 (5) ///< GPIO 35 |
| 139 | |
| 140 | /** |
| 141 | * @brief Class for working with Adafruit PN532 NFC/RFID breakout boards. |
| 142 | */ |
| 143 | class Adafruit_PN532 { |
| 144 | public: |
| 145 | Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi, |
| 146 | uint8_t ss); // Software SPI |
| 147 | Adafruit_PN532(uint8_t ss, SPIClass *theSPI = &SPI); // Hardware SPI |
| 148 | Adafruit_PN532(uint8_t irq, uint8_t reset, |
| 149 | TwoWire *theWire = &Wire); // Hardware I2C |
| 150 | Adafruit_PN532(uint8_t reset, HardwareSerial *theSer); // Hardware UART |
| 151 | bool begin(void); |
| 152 | |
| 153 | void reset(void); |
| 154 | void wakeup(void); |
| 155 | |
| 156 | // Generic PN532 functions |
| 157 | bool SAMConfig(void); |
| 158 | uint32_t getFirmwareVersion(void); |
| 159 | bool sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, |
| 160 | uint16_t timeout = 100); |
| 161 | bool writeGPIO(uint8_t pinstate); |
| 162 | uint8_t readGPIO(void); |
| 163 | bool setPassiveActivationRetries(uint8_t maxRetries); |
| 164 | |
| 165 | // ISO14443A functions |
| 166 | bool readPassiveTargetID( |
| 167 | uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, |
| 168 | uint16_t timeout = 0); // timeout 0 means no timeout - will block forever. |
| 169 | bool startPassiveTargetIDDetection(uint8_t cardbaudrate); |
| 170 | bool readDetectedPassiveTargetID(uint8_t *uid, uint8_t *uidLength); |
| 171 | bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, |
| 172 | uint8_t *responseLength); |
| 173 | bool inListPassiveTarget(); |
| 174 | uint8_t AsTarget(); |
| 175 | uint8_t getDataTarget(uint8_t *cmd, uint8_t *cmdlen); |
| 176 | uint8_t setDataTarget(uint8_t *cmd, uint8_t cmdlen); |
| 177 | |
| 178 | // Mifare Classic functions |
| 179 | bool mifareclassic_IsFirstBlock(uint32_t uiBlock); |
| 180 | bool mifareclassic_IsTrailerBlock(uint32_t uiBlock); |
| 181 | uint8_t mifareclassic_AuthenticateBlock(uint8_t *uid, uint8_t uidLen, |
| 182 | uint32_t blockNumber, |
| 183 | uint8_t keyNumber, uint8_t *keyData); |
| 184 | uint8_t mifareclassic_ReadDataBlock(uint8_t blockNumber, uint8_t *data); |
| 185 | uint8_t mifareclassic_WriteDataBlock(uint8_t blockNumber, uint8_t *data); |
| 186 | uint8_t mifareclassic_FormatNDEF(void); |
| 187 | uint8_t mifareclassic_WriteNDEFURI(uint8_t sectorNumber, |
| 188 | uint8_t uriIdentifier, const char *url); |
| 189 | |
| 190 | // Mifare Ultralight functions |
| 191 | uint8_t mifareultralight_ReadPage(uint8_t page, uint8_t *buffer); |
| 192 | uint8_t mifareultralight_WritePage(uint8_t page, uint8_t *data); |
| 193 | |
| 194 | // NTAG2xx functions |
| 195 | uint8_t ntag2xx_ReadPage(uint8_t page, uint8_t *buffer); |
| 196 | uint8_t ntag2xx_WritePage(uint8_t page, uint8_t *data); |
| 197 | uint8_t ntag2xx_WriteNDEFURI(uint8_t uriIdentifier, char *url, |
| 198 | uint8_t dataLen); |
| 199 | |
| 200 | // Help functions to display formatted text |
| 201 | static void PrintHex(const byte *data, const uint32_t numBytes); |
| 202 | static void PrintHexChar(const byte *pbtData, const uint32_t numBytes); |
| 203 | |
| 204 | private: |
| 205 | int8_t _irq = -1, _reset = -1, _cs = -1; |
| 206 | int8_t _uid[7]; // ISO14443A uid |
| 207 | int8_t _uidLen; // uid len |
| 208 | int8_t _key[6]; // Mifare Classic key |
| 209 | int8_t _inListedTag; // Tg number of inlisted tag. |
| 210 | |
| 211 | // Low level communication functions that handle both SPI and I2C. |
| 212 | void readdata(uint8_t *buff, uint8_t n); |
| 213 | void writecommand(uint8_t *cmd, uint8_t cmdlen); |
| 214 | bool isready(); |
| 215 | bool waitready(uint16_t timeout); |
| 216 | bool readack(); |
| 217 | |
| 218 | Adafruit_SPIDevice *spi_dev = NULL; |
| 219 | Adafruit_I2CDevice *i2c_dev = NULL; |
| 220 | HardwareSerial *ser_dev = NULL; |
| 221 | }; |
| 222 | |
| 223 | #endif |