Porting from Arduino Platform to mbed KL25Z. Original Source: https://github.com/adafruit/Adafruit-PN532

Dependencies:   mbed

Committer:
nebgnahz
Date:
Fri Sep 19 05:04:15 2014 +0000
Revision:
0:54bf4b21c7fa
Child:
2:96f420fa4a6e
Version 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nebgnahz 0:54bf4b21c7fa 1 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 2 /*!
nebgnahz 0:54bf4b21c7fa 3 @file Adafruit_PN532.cpp
nebgnahz 0:54bf4b21c7fa 4 @author Adafruit Industries
nebgnahz 0:54bf4b21c7fa 5 @license BSD (see license.txt)
nebgnahz 0:54bf4b21c7fa 6
nebgnahz 0:54bf4b21c7fa 7 SPI Driver for NXP's PN532 NFC/13.56MHz RFID Transceiver
nebgnahz 0:54bf4b21c7fa 8
nebgnahz 0:54bf4b21c7fa 9 This is a library for the Adafruit PN532 NFC/RFID breakout boards
nebgnahz 0:54bf4b21c7fa 10 This library works with the Adafruit NFC breakout
nebgnahz 0:54bf4b21c7fa 11 ----> https://www.adafruit.com/products/364
nebgnahz 0:54bf4b21c7fa 12
nebgnahz 0:54bf4b21c7fa 13 Check out the links above for our tutorials and wiring diagrams
nebgnahz 0:54bf4b21c7fa 14 These chips use SPI to communicate, 4 required to interface
nebgnahz 0:54bf4b21c7fa 15
nebgnahz 0:54bf4b21c7fa 16 Adafruit invests time and resources providing this open source code,
nebgnahz 0:54bf4b21c7fa 17 please support Adafruit and open-source hardware by purchasing
nebgnahz 0:54bf4b21c7fa 18 products from Adafruit!
nebgnahz 0:54bf4b21c7fa 19
nebgnahz 0:54bf4b21c7fa 20
nebgnahz 0:54bf4b21c7fa 21 @section HISTORY
nebgnahz 0:54bf4b21c7fa 22
nebgnahz 0:54bf4b21c7fa 23 v1.4 - Added setPassiveActivationRetries()
nebgnahz 0:54bf4b21c7fa 24
nebgnahz 0:54bf4b21c7fa 25 v1.2 - Added writeGPIO()
nebgnahz 0:54bf4b21c7fa 26 - Added readGPIO()
nebgnahz 0:54bf4b21c7fa 27
nebgnahz 0:54bf4b21c7fa 28 v1.1 - Changed readPassiveTargetID() to handle multiple UID sizes
nebgnahz 0:54bf4b21c7fa 29 - Added the following helper functions for text display
nebgnahz 0:54bf4b21c7fa 30 static void PrintHex(const uint8_t * data, const uint32_t numuint8_ts)
nebgnahz 0:54bf4b21c7fa 31 static void PrintHexChar(const uint8_t * pbtData, const uint32_t numuint8_ts)
nebgnahz 0:54bf4b21c7fa 32 - Added the following Mifare Classic functions:
nebgnahz 0:54bf4b21c7fa 33 bool mifareclassic_IsFirstBlock (uint32_t uiBlock)
nebgnahz 0:54bf4b21c7fa 34 bool mifareclassic_IsTrailerBlock (uint32_t uiBlock)
nebgnahz 0:54bf4b21c7fa 35 uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData)
nebgnahz 0:54bf4b21c7fa 36 uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data)
nebgnahz 0:54bf4b21c7fa 37 uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
nebgnahz 0:54bf4b21c7fa 38 - Added the following Mifare Ultalight functions:
nebgnahz 0:54bf4b21c7fa 39 uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
nebgnahz 0:54bf4b21c7fa 40 */
nebgnahz 0:54bf4b21c7fa 41 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 42
nebgnahz 0:54bf4b21c7fa 43 #include "Adafruit_PN532.h"
nebgnahz 0:54bf4b21c7fa 44
nebgnahz 0:54bf4b21c7fa 45 uint8_t pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
nebgnahz 0:54bf4b21c7fa 46 uint8_t pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
nebgnahz 0:54bf4b21c7fa 47
nebgnahz 0:54bf4b21c7fa 48 // Uncomment these lines to enable debug output for PN532(SPI) and/or MIFARE related code
nebgnahz 0:54bf4b21c7fa 49 // #define PN532DEBUG
nebgnahz 0:54bf4b21c7fa 50 // #define MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 51
nebgnahz 0:54bf4b21c7fa 52 Serial serial(USBTX, USBRX);
nebgnahz 0:54bf4b21c7fa 53 #define SERIAL_PRINT serial.printf
nebgnahz 0:54bf4b21c7fa 54
nebgnahz 0:54bf4b21c7fa 55 #define _BV(bit) (1 << (bit))
nebgnahz 0:54bf4b21c7fa 56 #define PN532_PACKBUFFSIZ 64
nebgnahz 0:54bf4b21c7fa 57 uint8_t pn532_packetbuffer[PN532_PACKBUFFSIZ];
nebgnahz 0:54bf4b21c7fa 58
nebgnahz 0:54bf4b21c7fa 59 void delay(int delayInMS) {
nebgnahz 0:54bf4b21c7fa 60 wait(1.0 * delayInMS / 1000);
nebgnahz 0:54bf4b21c7fa 61 }
nebgnahz 0:54bf4b21c7fa 62
nebgnahz 0:54bf4b21c7fa 63 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 64 /*!
nebgnahz 0:54bf4b21c7fa 65 @brief Instantiates a new PN532 class
nebgnahz 0:54bf4b21c7fa 66
nebgnahz 0:54bf4b21c7fa 67 @param clk SPI clock pin (SCK)
nebgnahz 0:54bf4b21c7fa 68 @param miso SPI MISO pin
nebgnahz 0:54bf4b21c7fa 69 @param mosi SPI MOSI pin
nebgnahz 0:54bf4b21c7fa 70 @param ss SPI chip select pin (CS/SSEL)
nebgnahz 0:54bf4b21c7fa 71 */
nebgnahz 0:54bf4b21c7fa 72 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 73 Adafruit_PN532::Adafruit_PN532(DigitalOut clk, DigitalIn miso,
nebgnahz 0:54bf4b21c7fa 74 DigitalOut mosi, DigitalOut ss)
nebgnahz 0:54bf4b21c7fa 75 : _clk(clk), _miso(miso), _mosi(mosi), _ss(ss) {}
nebgnahz 0:54bf4b21c7fa 76
nebgnahz 0:54bf4b21c7fa 77 Adafruit_PN532::Adafruit_PN532(PinName clk_pin, PinName miso_pin,
nebgnahz 0:54bf4b21c7fa 78 PinName mosi_pin, PinName ss_pin)
nebgnahz 0:54bf4b21c7fa 79 : _clk(DigitalOut(clk_pin)), _miso(DigitalIn(miso_pin)),
nebgnahz 0:54bf4b21c7fa 80 _mosi(DigitalOut(mosi_pin)), _ss(DigitalOut(ss_pin)) {}
nebgnahz 0:54bf4b21c7fa 81
nebgnahz 0:54bf4b21c7fa 82 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 83 /*!
nebgnahz 0:54bf4b21c7fa 84 @brief Setups the HW
nebgnahz 0:54bf4b21c7fa 85 */
nebgnahz 0:54bf4b21c7fa 86 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 87 void Adafruit_PN532::begin() {
nebgnahz 0:54bf4b21c7fa 88 _ss = 0;
nebgnahz 0:54bf4b21c7fa 89 delay(1000);
nebgnahz 0:54bf4b21c7fa 90
nebgnahz 0:54bf4b21c7fa 91 // not exactly sure why but we have to send a dummy command to get synced up
nebgnahz 0:54bf4b21c7fa 92 pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
nebgnahz 0:54bf4b21c7fa 93 sendCommandCheckAck(pn532_packetbuffer, 1);
nebgnahz 0:54bf4b21c7fa 94
nebgnahz 0:54bf4b21c7fa 95 // ignore response!
nebgnahz 0:54bf4b21c7fa 96 }
nebgnahz 0:54bf4b21c7fa 97
nebgnahz 0:54bf4b21c7fa 98 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 99 /*!
nebgnahz 0:54bf4b21c7fa 100 @brief Prints a hexadecimal value in plain characters
nebgnahz 0:54bf4b21c7fa 101
nebgnahz 0:54bf4b21c7fa 102 @param data Pointer to the uint8_t data
nebgnahz 0:54bf4b21c7fa 103 @param numuint8_ts Data length in uint8_ts
nebgnahz 0:54bf4b21c7fa 104 */
nebgnahz 0:54bf4b21c7fa 105 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 106 void Adafruit_PN532::PrintHex(const uint8_t * data, const uint32_t numuint8_ts)
nebgnahz 0:54bf4b21c7fa 107 {
nebgnahz 0:54bf4b21c7fa 108 uint32_t szPos;
nebgnahz 0:54bf4b21c7fa 109 for (szPos=0; szPos < numuint8_ts; szPos++)
nebgnahz 0:54bf4b21c7fa 110 {
nebgnahz 0:54bf4b21c7fa 111 SERIAL_PRINT("0x");
nebgnahz 0:54bf4b21c7fa 112 // Append leading 0 for small values
nebgnahz 0:54bf4b21c7fa 113 if (data[szPos] <= 0xF)
nebgnahz 0:54bf4b21c7fa 114 SERIAL_PRINT("0");
nebgnahz 0:54bf4b21c7fa 115 SERIAL_PRINT("%d", data[szPos]);
nebgnahz 0:54bf4b21c7fa 116 if ((numuint8_ts > 1) && (szPos != numuint8_ts - 1))
nebgnahz 0:54bf4b21c7fa 117 {
nebgnahz 0:54bf4b21c7fa 118 SERIAL_PRINT(" ");
nebgnahz 0:54bf4b21c7fa 119 }
nebgnahz 0:54bf4b21c7fa 120 }
nebgnahz 0:54bf4b21c7fa 121 SERIAL_PRINT("\n");
nebgnahz 0:54bf4b21c7fa 122 }
nebgnahz 0:54bf4b21c7fa 123
nebgnahz 0:54bf4b21c7fa 124 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 125 /*!
nebgnahz 0:54bf4b21c7fa 126 @brief Prints a hexadecimal value in plain characters, along with
nebgnahz 0:54bf4b21c7fa 127 the char equivalents in the following format
nebgnahz 0:54bf4b21c7fa 128
nebgnahz 0:54bf4b21c7fa 129 00 00 00 00 00 00 ......
nebgnahz 0:54bf4b21c7fa 130
nebgnahz 0:54bf4b21c7fa 131 @param data Pointer to the uint8_t data
nebgnahz 0:54bf4b21c7fa 132 @param numuint8_ts Data length in uint8_ts
nebgnahz 0:54bf4b21c7fa 133 */
nebgnahz 0:54bf4b21c7fa 134 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 135 void Adafruit_PN532::PrintHexChar(const uint8_t * data, const uint32_t numuint8_ts)
nebgnahz 0:54bf4b21c7fa 136 {
nebgnahz 0:54bf4b21c7fa 137 uint32_t szPos;
nebgnahz 0:54bf4b21c7fa 138 for (szPos=0; szPos < numuint8_ts; szPos++)
nebgnahz 0:54bf4b21c7fa 139 {
nebgnahz 0:54bf4b21c7fa 140 // Append leading 0 for small values
nebgnahz 0:54bf4b21c7fa 141 if (data[szPos] <= 0xF)
nebgnahz 0:54bf4b21c7fa 142 SERIAL_PRINT("0");
nebgnahz 0:54bf4b21c7fa 143 SERIAL_PRINT("%x", data[szPos]);
nebgnahz 0:54bf4b21c7fa 144 if ((numuint8_ts > 1) && (szPos != numuint8_ts - 1))
nebgnahz 0:54bf4b21c7fa 145 {
nebgnahz 0:54bf4b21c7fa 146 SERIAL_PRINT(" ");
nebgnahz 0:54bf4b21c7fa 147 }
nebgnahz 0:54bf4b21c7fa 148 }
nebgnahz 0:54bf4b21c7fa 149 SERIAL_PRINT(" ");
nebgnahz 0:54bf4b21c7fa 150 for (szPos=0; szPos < numuint8_ts; szPos++)
nebgnahz 0:54bf4b21c7fa 151 {
nebgnahz 0:54bf4b21c7fa 152 if (data[szPos] <= 0x1F)
nebgnahz 0:54bf4b21c7fa 153 SERIAL_PRINT(".");
nebgnahz 0:54bf4b21c7fa 154 else
nebgnahz 0:54bf4b21c7fa 155 SERIAL_PRINT("%c", data[szPos]);
nebgnahz 0:54bf4b21c7fa 156 }
nebgnahz 0:54bf4b21c7fa 157 SERIAL_PRINT("");
nebgnahz 0:54bf4b21c7fa 158 }
nebgnahz 0:54bf4b21c7fa 159
nebgnahz 0:54bf4b21c7fa 160 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 161 /*!
nebgnahz 0:54bf4b21c7fa 162 @brief Checks the firmware version of the PN5xx chip
nebgnahz 0:54bf4b21c7fa 163
nebgnahz 0:54bf4b21c7fa 164 @returns The chip's firmware version and ID
nebgnahz 0:54bf4b21c7fa 165 */
nebgnahz 0:54bf4b21c7fa 166 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 167 uint32_t Adafruit_PN532::getFirmwareVersion(void) {
nebgnahz 0:54bf4b21c7fa 168 uint32_t response;
nebgnahz 0:54bf4b21c7fa 169
nebgnahz 0:54bf4b21c7fa 170 pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
nebgnahz 0:54bf4b21c7fa 171
nebgnahz 0:54bf4b21c7fa 172 if (! sendCommandCheckAck(pn532_packetbuffer, 1))
nebgnahz 0:54bf4b21c7fa 173 return 0;
nebgnahz 0:54bf4b21c7fa 174
nebgnahz 0:54bf4b21c7fa 175 // read data packet
nebgnahz 0:54bf4b21c7fa 176 readspidata(pn532_packetbuffer, 12);
nebgnahz 0:54bf4b21c7fa 177
nebgnahz 0:54bf4b21c7fa 178 // check some basic stuff
nebgnahz 0:54bf4b21c7fa 179 if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6)) {
nebgnahz 0:54bf4b21c7fa 180 return 0;
nebgnahz 0:54bf4b21c7fa 181 }
nebgnahz 0:54bf4b21c7fa 182
nebgnahz 0:54bf4b21c7fa 183 response = pn532_packetbuffer[6];
nebgnahz 0:54bf4b21c7fa 184 response <<= 8;
nebgnahz 0:54bf4b21c7fa 185 response |= pn532_packetbuffer[7];
nebgnahz 0:54bf4b21c7fa 186 response <<= 8;
nebgnahz 0:54bf4b21c7fa 187 response |= pn532_packetbuffer[8];
nebgnahz 0:54bf4b21c7fa 188 response <<= 8;
nebgnahz 0:54bf4b21c7fa 189 response |= pn532_packetbuffer[9];
nebgnahz 0:54bf4b21c7fa 190
nebgnahz 0:54bf4b21c7fa 191 return response;
nebgnahz 0:54bf4b21c7fa 192 }
nebgnahz 0:54bf4b21c7fa 193
nebgnahz 0:54bf4b21c7fa 194
nebgnahz 0:54bf4b21c7fa 195 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 196 /*!
nebgnahz 0:54bf4b21c7fa 197 @brief Sends a command and waits a specified period for the ACK
nebgnahz 0:54bf4b21c7fa 198
nebgnahz 0:54bf4b21c7fa 199 @param cmd Pointer to the command buffer
nebgnahz 0:54bf4b21c7fa 200 @param cmdlen The size of the command in uint8_ts
nebgnahz 0:54bf4b21c7fa 201 @param timeout timeout before giving up
nebgnahz 0:54bf4b21c7fa 202
nebgnahz 0:54bf4b21c7fa 203 @returns 1 if everything is OK, 0 if timeout occured before an
nebgnahz 0:54bf4b21c7fa 204 ACK was recieved
nebgnahz 0:54bf4b21c7fa 205 */
nebgnahz 0:54bf4b21c7fa 206 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 207 // default timeout of one second
nebgnahz 0:54bf4b21c7fa 208 bool Adafruit_PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout) {
nebgnahz 0:54bf4b21c7fa 209 uint16_t timer = 0;
nebgnahz 0:54bf4b21c7fa 210
nebgnahz 0:54bf4b21c7fa 211 // write the command
nebgnahz 0:54bf4b21c7fa 212 spiwritecommand(cmd, cmdlen);
nebgnahz 0:54bf4b21c7fa 213
nebgnahz 0:54bf4b21c7fa 214 // Wait for chip to say its ready!
nebgnahz 0:54bf4b21c7fa 215 while (readspistatus() != PN532_SPI_READY) {
nebgnahz 0:54bf4b21c7fa 216 if (timeout != 0) {
nebgnahz 0:54bf4b21c7fa 217 timer+=10;
nebgnahz 0:54bf4b21c7fa 218 if (timer > timeout)
nebgnahz 0:54bf4b21c7fa 219 return false;
nebgnahz 0:54bf4b21c7fa 220 }
nebgnahz 0:54bf4b21c7fa 221 delay(10);
nebgnahz 0:54bf4b21c7fa 222 }
nebgnahz 0:54bf4b21c7fa 223
nebgnahz 0:54bf4b21c7fa 224 // read acknowledgement
nebgnahz 0:54bf4b21c7fa 225 if (!spi_readack()) {
nebgnahz 0:54bf4b21c7fa 226 return false;
nebgnahz 0:54bf4b21c7fa 227 }
nebgnahz 0:54bf4b21c7fa 228
nebgnahz 0:54bf4b21c7fa 229 timer = 0;
nebgnahz 0:54bf4b21c7fa 230 // Wait for chip to say its ready!
nebgnahz 0:54bf4b21c7fa 231 while (readspistatus() != PN532_SPI_READY) {
nebgnahz 0:54bf4b21c7fa 232 if (timeout != 0) {
nebgnahz 0:54bf4b21c7fa 233 timer+=10;
nebgnahz 0:54bf4b21c7fa 234 if (timer > timeout)
nebgnahz 0:54bf4b21c7fa 235 return false;
nebgnahz 0:54bf4b21c7fa 236 }
nebgnahz 0:54bf4b21c7fa 237 delay(10);
nebgnahz 0:54bf4b21c7fa 238 }
nebgnahz 0:54bf4b21c7fa 239
nebgnahz 0:54bf4b21c7fa 240 return true; // ack'd command
nebgnahz 0:54bf4b21c7fa 241 }
nebgnahz 0:54bf4b21c7fa 242
nebgnahz 0:54bf4b21c7fa 243 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 244 /*!
nebgnahz 0:54bf4b21c7fa 245 Writes an 8-bit value that sets the state of the PN532's GPIO pins
nebgnahz 0:54bf4b21c7fa 246
nebgnahz 0:54bf4b21c7fa 247 @warning This function is provided exclusively for board testing and
nebgnahz 0:54bf4b21c7fa 248 is dangerous since it will throw an error if any pin other
nebgnahz 0:54bf4b21c7fa 249 than the ones marked "Can be used as GPIO" are modified! All
nebgnahz 0:54bf4b21c7fa 250 pins that can not be used as GPIO should ALWAYS be left high
nebgnahz 0:54bf4b21c7fa 251 (value = 1) or the system will become unstable and a HW reset
nebgnahz 0:54bf4b21c7fa 252 will be required to recover the PN532.
nebgnahz 0:54bf4b21c7fa 253
nebgnahz 0:54bf4b21c7fa 254 pinState[0] = P30 Can be used as GPIO
nebgnahz 0:54bf4b21c7fa 255 pinState[1] = P31 Can be used as GPIO
nebgnahz 0:54bf4b21c7fa 256 pinState[2] = P32 *** RESERVED (Must be 1!) ***
nebgnahz 0:54bf4b21c7fa 257 pinState[3] = P33 Can be used as GPIO
nebgnahz 0:54bf4b21c7fa 258 pinState[4] = P34 *** RESERVED (Must be 1!) ***
nebgnahz 0:54bf4b21c7fa 259 pinState[5] = P35 Can be used as GPIO
nebgnahz 0:54bf4b21c7fa 260
nebgnahz 0:54bf4b21c7fa 261 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 262 */
nebgnahz 0:54bf4b21c7fa 263 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 264 bool Adafruit_PN532::writeGPIO(uint8_t pinstate) {
nebgnahz 0:54bf4b21c7fa 265 // Make sure pinstate does not try to toggle P32 or P34
nebgnahz 0:54bf4b21c7fa 266 pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
nebgnahz 0:54bf4b21c7fa 267
nebgnahz 0:54bf4b21c7fa 268 // Fill command buffer
nebgnahz 0:54bf4b21c7fa 269 pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
nebgnahz 0:54bf4b21c7fa 270 pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins
nebgnahz 0:54bf4b21c7fa 271 pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by SPI)
nebgnahz 0:54bf4b21c7fa 272
nebgnahz 0:54bf4b21c7fa 273 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 274 SERIAL_PRINT("Writing P3 GPIO: "); SERIAL_PRINTln(pn532_packetbuffer[1], HEX);
nebgnahz 0:54bf4b21c7fa 275 #endif
nebgnahz 0:54bf4b21c7fa 276
nebgnahz 0:54bf4b21c7fa 277 // Send the WRITEGPIO command (0x0E)
nebgnahz 0:54bf4b21c7fa 278 if (! sendCommandCheckAck(pn532_packetbuffer, 3))
nebgnahz 0:54bf4b21c7fa 279 return 0x0;
nebgnahz 0:54bf4b21c7fa 280
nebgnahz 0:54bf4b21c7fa 281 // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0F) DATACHECKSUM 00)
nebgnahz 0:54bf4b21c7fa 282 readspidata(pn532_packetbuffer, 8);
nebgnahz 0:54bf4b21c7fa 283
nebgnahz 0:54bf4b21c7fa 284 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 285 SERIAL_PRINT("Received: ");
nebgnahz 0:54bf4b21c7fa 286 PrintHex(pn532_packetbuffer, 8);
nebgnahz 0:54bf4b21c7fa 287 SERIAL_PRINTln("");
nebgnahz 0:54bf4b21c7fa 288 #endif
nebgnahz 0:54bf4b21c7fa 289
nebgnahz 0:54bf4b21c7fa 290 return (pn532_packetbuffer[5] == 0x0F);
nebgnahz 0:54bf4b21c7fa 291 }
nebgnahz 0:54bf4b21c7fa 292
nebgnahz 0:54bf4b21c7fa 293 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 294 /*!
nebgnahz 0:54bf4b21c7fa 295 Reads the state of the PN532's GPIO pins
nebgnahz 0:54bf4b21c7fa 296
nebgnahz 0:54bf4b21c7fa 297 @returns An 8-bit value containing the pin state where:
nebgnahz 0:54bf4b21c7fa 298
nebgnahz 0:54bf4b21c7fa 299 pinState[0] = P30
nebgnahz 0:54bf4b21c7fa 300 pinState[1] = P31
nebgnahz 0:54bf4b21c7fa 301 pinState[2] = P32
nebgnahz 0:54bf4b21c7fa 302 pinState[3] = P33
nebgnahz 0:54bf4b21c7fa 303 pinState[4] = P34
nebgnahz 0:54bf4b21c7fa 304 pinState[5] = P35
nebgnahz 0:54bf4b21c7fa 305 */
nebgnahz 0:54bf4b21c7fa 306 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 307 uint8_t Adafruit_PN532::readGPIO(void) {
nebgnahz 0:54bf4b21c7fa 308 pn532_packetbuffer[0] = PN532_COMMAND_READGPIO;
nebgnahz 0:54bf4b21c7fa 309
nebgnahz 0:54bf4b21c7fa 310 // Send the READGPIO command (0x0C)
nebgnahz 0:54bf4b21c7fa 311 if (! sendCommandCheckAck(pn532_packetbuffer, 1))
nebgnahz 0:54bf4b21c7fa 312 return 0x0;
nebgnahz 0:54bf4b21c7fa 313
nebgnahz 0:54bf4b21c7fa 314 // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0D) P3 P7 IO1 DATACHECKSUM 00)
nebgnahz 0:54bf4b21c7fa 315 readspidata(pn532_packetbuffer, 11);
nebgnahz 0:54bf4b21c7fa 316
nebgnahz 0:54bf4b21c7fa 317 /* READGPIO response should be in the following format:
nebgnahz 0:54bf4b21c7fa 318
nebgnahz 0:54bf4b21c7fa 319 uint8_t Description
nebgnahz 0:54bf4b21c7fa 320 ------------- ------------------------------------------
nebgnahz 0:54bf4b21c7fa 321 b0..5 Frame header and preamble
nebgnahz 0:54bf4b21c7fa 322 b6 P3 GPIO Pins
nebgnahz 0:54bf4b21c7fa 323 b7 P7 GPIO Pins (not used ... taken by SPI)
nebgnahz 0:54bf4b21c7fa 324 b8 Interface Mode Pins (not used ... bus select pins)
nebgnahz 0:54bf4b21c7fa 325 b9..10 checksum */
nebgnahz 0:54bf4b21c7fa 326
nebgnahz 0:54bf4b21c7fa 327 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 328 SERIAL_PRINT("Received: ");
nebgnahz 0:54bf4b21c7fa 329 PrintHex(pn532_packetbuffer, 11);
nebgnahz 0:54bf4b21c7fa 330 SERIAL_PRINTln("");
nebgnahz 0:54bf4b21c7fa 331 SERIAL_PRINT("P3 GPIO: 0x"); SERIAL_PRINTln(pn532_packetbuffer[6], HEX);
nebgnahz 0:54bf4b21c7fa 332 SERIAL_PRINT("P7 GPIO: 0x"); SERIAL_PRINTln(pn532_packetbuffer[7], HEX);
nebgnahz 0:54bf4b21c7fa 333 SERIAL_PRINT("IO GPIO: 0x"); SERIAL_PRINTln(pn532_packetbuffer[8], HEX);
nebgnahz 0:54bf4b21c7fa 334 // Note: You can use the IO GPIO value to detect the serial bus being used
nebgnahz 0:54bf4b21c7fa 335 switch(pn532_packetbuffer[8])
nebgnahz 0:54bf4b21c7fa 336 {
nebgnahz 0:54bf4b21c7fa 337 case 0x00: // Using UART
nebgnahz 0:54bf4b21c7fa 338 SERIAL_PRINTln("Using UART (IO = 0x00)");
nebgnahz 0:54bf4b21c7fa 339 break;
nebgnahz 0:54bf4b21c7fa 340 case 0x01: // Using I2C
nebgnahz 0:54bf4b21c7fa 341 SERIAL_PRINTln("Using I2C (IO = 0x01)");
nebgnahz 0:54bf4b21c7fa 342 break;
nebgnahz 0:54bf4b21c7fa 343 case 0x02: // Using SPI
nebgnahz 0:54bf4b21c7fa 344 SERIAL_PRINTln("Using SPI (IO = 0x02)");
nebgnahz 0:54bf4b21c7fa 345 break;
nebgnahz 0:54bf4b21c7fa 346 }
nebgnahz 0:54bf4b21c7fa 347 #endif
nebgnahz 0:54bf4b21c7fa 348
nebgnahz 0:54bf4b21c7fa 349 return pn532_packetbuffer[6];
nebgnahz 0:54bf4b21c7fa 350 }
nebgnahz 0:54bf4b21c7fa 351
nebgnahz 0:54bf4b21c7fa 352 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 353 /*!
nebgnahz 0:54bf4b21c7fa 354 @brief Configures the SAM (Secure Access Module)
nebgnahz 0:54bf4b21c7fa 355 */
nebgnahz 0:54bf4b21c7fa 356 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 357 bool Adafruit_PN532::SAMConfig(void) {
nebgnahz 0:54bf4b21c7fa 358 pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
nebgnahz 0:54bf4b21c7fa 359 pn532_packetbuffer[1] = 0x01; // normal mode;
nebgnahz 0:54bf4b21c7fa 360 pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
nebgnahz 0:54bf4b21c7fa 361 pn532_packetbuffer[3] = 0x01; // use IRQ pin!
nebgnahz 0:54bf4b21c7fa 362
nebgnahz 0:54bf4b21c7fa 363 if (! sendCommandCheckAck(pn532_packetbuffer, 4))
nebgnahz 0:54bf4b21c7fa 364 return false;
nebgnahz 0:54bf4b21c7fa 365
nebgnahz 0:54bf4b21c7fa 366 // read data packet
nebgnahz 0:54bf4b21c7fa 367 readspidata(pn532_packetbuffer, 8);
nebgnahz 0:54bf4b21c7fa 368
nebgnahz 0:54bf4b21c7fa 369 return (pn532_packetbuffer[5] == 0x15);
nebgnahz 0:54bf4b21c7fa 370 }
nebgnahz 0:54bf4b21c7fa 371
nebgnahz 0:54bf4b21c7fa 372 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 373 /*!
nebgnahz 0:54bf4b21c7fa 374 Sets the MxRtyPassiveActivation uint8_t of the RFConfiguration register
nebgnahz 0:54bf4b21c7fa 375
nebgnahz 0:54bf4b21c7fa 376 @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout
nebgnahz 0:54bf4b21c7fa 377 after mxRetries
nebgnahz 0:54bf4b21c7fa 378
nebgnahz 0:54bf4b21c7fa 379 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 380 */
nebgnahz 0:54bf4b21c7fa 381 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 382 bool Adafruit_PN532::setPassiveActivationRetries(uint8_t maxRetries) {
nebgnahz 0:54bf4b21c7fa 383 pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
nebgnahz 0:54bf4b21c7fa 384 pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
nebgnahz 0:54bf4b21c7fa 385 pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
nebgnahz 0:54bf4b21c7fa 386 pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
nebgnahz 0:54bf4b21c7fa 387 pn532_packetbuffer[4] = maxRetries;
nebgnahz 0:54bf4b21c7fa 388
nebgnahz 0:54bf4b21c7fa 389 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 390 SERIAL_PRINT("Setting MxRtyPassiveActivation to "); SERIAL_PRINT(maxRetries, DEC); SERIAL_PRINTln(" ");
nebgnahz 0:54bf4b21c7fa 391 #endif
nebgnahz 0:54bf4b21c7fa 392
nebgnahz 0:54bf4b21c7fa 393 if (! sendCommandCheckAck(pn532_packetbuffer, 5))
nebgnahz 0:54bf4b21c7fa 394 return 0x0; // no ACK
nebgnahz 0:54bf4b21c7fa 395
nebgnahz 0:54bf4b21c7fa 396 return 1;
nebgnahz 0:54bf4b21c7fa 397 }
nebgnahz 0:54bf4b21c7fa 398
nebgnahz 0:54bf4b21c7fa 399 /***** ISO14443A Commands ******/
nebgnahz 0:54bf4b21c7fa 400
nebgnahz 0:54bf4b21c7fa 401 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 402 /*!
nebgnahz 0:54bf4b21c7fa 403 Waits for an ISO14443A target to enter the field
nebgnahz 0:54bf4b21c7fa 404
nebgnahz 0:54bf4b21c7fa 405 @param cardBaudRate Baud rate of the card
nebgnahz 0:54bf4b21c7fa 406 @param uid Pointer to the array that will be populated
nebgnahz 0:54bf4b21c7fa 407 with the card's UID (up to 7 uint8_ts)
nebgnahz 0:54bf4b21c7fa 408 @param uidLength Pointer to the variable that will hold the
nebgnahz 0:54bf4b21c7fa 409 length of the card's UID.
nebgnahz 0:54bf4b21c7fa 410
nebgnahz 0:54bf4b21c7fa 411 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 412 */
nebgnahz 0:54bf4b21c7fa 413 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 414 bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, uint8_t * uidLength) {
nebgnahz 0:54bf4b21c7fa 415 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
nebgnahz 0:54bf4b21c7fa 416 pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
nebgnahz 0:54bf4b21c7fa 417 pn532_packetbuffer[2] = cardbaudrate;
nebgnahz 0:54bf4b21c7fa 418
nebgnahz 0:54bf4b21c7fa 419 if (! sendCommandCheckAck(pn532_packetbuffer, 3))
nebgnahz 0:54bf4b21c7fa 420 return 0x0; // no cards read
nebgnahz 0:54bf4b21c7fa 421
nebgnahz 0:54bf4b21c7fa 422 // read data packet
nebgnahz 0:54bf4b21c7fa 423 readspidata(pn532_packetbuffer, 20);
nebgnahz 0:54bf4b21c7fa 424 // check some basic stuff
nebgnahz 0:54bf4b21c7fa 425
nebgnahz 0:54bf4b21c7fa 426 /* ISO14443A card response should be in the following format:
nebgnahz 0:54bf4b21c7fa 427
nebgnahz 0:54bf4b21c7fa 428 uint8_t Description
nebgnahz 0:54bf4b21c7fa 429 ------------- ------------------------------------------
nebgnahz 0:54bf4b21c7fa 430 b0..6 Frame header and preamble
nebgnahz 0:54bf4b21c7fa 431 b7 Tags Found
nebgnahz 0:54bf4b21c7fa 432 b8 Tag Number (only one used in this example)
nebgnahz 0:54bf4b21c7fa 433 b9..10 SENS_RES
nebgnahz 0:54bf4b21c7fa 434 b11 SEL_RES
nebgnahz 0:54bf4b21c7fa 435 b12 NFCID Length
nebgnahz 0:54bf4b21c7fa 436 b13..NFCIDLen NFCID */
nebgnahz 0:54bf4b21c7fa 437
nebgnahz 0:54bf4b21c7fa 438 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 439 SERIAL_PRINT("Found "); SERIAL_PRINT(pn532_packetbuffer[7], DEC); SERIAL_PRINTln(" tags");
nebgnahz 0:54bf4b21c7fa 440 #endif
nebgnahz 0:54bf4b21c7fa 441 if (pn532_packetbuffer[7] != 1)
nebgnahz 0:54bf4b21c7fa 442 return 0;
nebgnahz 0:54bf4b21c7fa 443
nebgnahz 0:54bf4b21c7fa 444 uint16_t sens_res = pn532_packetbuffer[9];
nebgnahz 0:54bf4b21c7fa 445 sens_res <<= 8;
nebgnahz 0:54bf4b21c7fa 446 sens_res |= pn532_packetbuffer[10];
nebgnahz 0:54bf4b21c7fa 447 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 448 SERIAL_PRINT("ATQA: 0x"); SERIAL_PRINTln(sens_res, HEX);
nebgnahz 0:54bf4b21c7fa 449 SERIAL_PRINT("SAK: 0x"); SERIAL_PRINTln(pn532_packetbuffer[11], HEX);
nebgnahz 0:54bf4b21c7fa 450 #endif
nebgnahz 0:54bf4b21c7fa 451
nebgnahz 0:54bf4b21c7fa 452 /* Card appears to be Mifare Classic */
nebgnahz 0:54bf4b21c7fa 453 *uidLength = pn532_packetbuffer[12];
nebgnahz 0:54bf4b21c7fa 454 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 455 SERIAL_PRINT("UID:");
nebgnahz 0:54bf4b21c7fa 456 #endif
nebgnahz 0:54bf4b21c7fa 457 for (uint8_t i=0; i < pn532_packetbuffer[12]; i++)
nebgnahz 0:54bf4b21c7fa 458 {
nebgnahz 0:54bf4b21c7fa 459 uid[i] = pn532_packetbuffer[13+i];
nebgnahz 0:54bf4b21c7fa 460 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 461 SERIAL_PRINT(" 0x");SERIAL_PRINT(uid[i], HEX);
nebgnahz 0:54bf4b21c7fa 462 #endif
nebgnahz 0:54bf4b21c7fa 463 }
nebgnahz 0:54bf4b21c7fa 464 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 465 SERIAL_PRINTln();
nebgnahz 0:54bf4b21c7fa 466 #endif
nebgnahz 0:54bf4b21c7fa 467
nebgnahz 0:54bf4b21c7fa 468 return 1;
nebgnahz 0:54bf4b21c7fa 469 }
nebgnahz 0:54bf4b21c7fa 470
nebgnahz 0:54bf4b21c7fa 471
nebgnahz 0:54bf4b21c7fa 472 /***** Mifare Classic Functions ******/
nebgnahz 0:54bf4b21c7fa 473
nebgnahz 0:54bf4b21c7fa 474 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 475 /*!
nebgnahz 0:54bf4b21c7fa 476 Indicates whether the specified block number is the first block
nebgnahz 0:54bf4b21c7fa 477 in the sector (block 0 relative to the current sector)
nebgnahz 0:54bf4b21c7fa 478 */
nebgnahz 0:54bf4b21c7fa 479 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 480 bool Adafruit_PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock)
nebgnahz 0:54bf4b21c7fa 481 {
nebgnahz 0:54bf4b21c7fa 482 // Test if we are in the small or big sectors
nebgnahz 0:54bf4b21c7fa 483 if (uiBlock < 128)
nebgnahz 0:54bf4b21c7fa 484 return ((uiBlock) % 4 == 0);
nebgnahz 0:54bf4b21c7fa 485 else
nebgnahz 0:54bf4b21c7fa 486 return ((uiBlock) % 16 == 0);
nebgnahz 0:54bf4b21c7fa 487 }
nebgnahz 0:54bf4b21c7fa 488
nebgnahz 0:54bf4b21c7fa 489 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 490 /*!
nebgnahz 0:54bf4b21c7fa 491 Indicates whether the specified block number is the sector trailer
nebgnahz 0:54bf4b21c7fa 492 */
nebgnahz 0:54bf4b21c7fa 493 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 494 bool Adafruit_PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock)
nebgnahz 0:54bf4b21c7fa 495 {
nebgnahz 0:54bf4b21c7fa 496 // Test if we are in the small or big sectors
nebgnahz 0:54bf4b21c7fa 497 if (uiBlock < 128)
nebgnahz 0:54bf4b21c7fa 498 return ((uiBlock + 1) % 4 == 0);
nebgnahz 0:54bf4b21c7fa 499 else
nebgnahz 0:54bf4b21c7fa 500 return ((uiBlock + 1) % 16 == 0);
nebgnahz 0:54bf4b21c7fa 501 }
nebgnahz 0:54bf4b21c7fa 502
nebgnahz 0:54bf4b21c7fa 503 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 504 /*!
nebgnahz 0:54bf4b21c7fa 505 Tries to authenticate a block of memory on a MIFARE card using the
nebgnahz 0:54bf4b21c7fa 506 INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual
nebgnahz 0:54bf4b21c7fa 507 for more information on sending MIFARE and other commands.
nebgnahz 0:54bf4b21c7fa 508
nebgnahz 0:54bf4b21c7fa 509 @param uid Pointer to a uint8_t array containing the card UID
nebgnahz 0:54bf4b21c7fa 510 @param uidLen The length (in uint8_ts) of the card's UID (Should
nebgnahz 0:54bf4b21c7fa 511 be 4 for MIFARE Classic)
nebgnahz 0:54bf4b21c7fa 512 @param blockNumber The block number to authenticate. (0..63 for
nebgnahz 0:54bf4b21c7fa 513 1KB cards, and 0..255 for 4KB cards).
nebgnahz 0:54bf4b21c7fa 514 @param keyNumber Which key type to use during authentication
nebgnahz 0:54bf4b21c7fa 515 (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
nebgnahz 0:54bf4b21c7fa 516 @param keyData Pointer to a uint8_t array containing the 6 uint8_t
nebgnahz 0:54bf4b21c7fa 517 key value
nebgnahz 0:54bf4b21c7fa 518
nebgnahz 0:54bf4b21c7fa 519 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 520 */
nebgnahz 0:54bf4b21c7fa 521 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 522 uint8_t Adafruit_PN532::mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData)
nebgnahz 0:54bf4b21c7fa 523 {
nebgnahz 0:54bf4b21c7fa 524 uint8_t i;
nebgnahz 0:54bf4b21c7fa 525
nebgnahz 0:54bf4b21c7fa 526 // Hang on to the key and uid data
nebgnahz 0:54bf4b21c7fa 527 memcpy (_key, keyData, 6);
nebgnahz 0:54bf4b21c7fa 528 memcpy (_uid, uid, uidLen);
nebgnahz 0:54bf4b21c7fa 529 _uidLen = uidLen;
nebgnahz 0:54bf4b21c7fa 530
nebgnahz 0:54bf4b21c7fa 531 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 532 SERIAL_PRINT("Trying to authenticate card ");
nebgnahz 0:54bf4b21c7fa 533 Adafruit_PN532::PrintHex(_uid, _uidLen);
nebgnahz 0:54bf4b21c7fa 534 SERIAL_PRINT("Using authentication KEY ");SERIAL_PRINT(keyNumber ? 'B' : 'A');SERIAL_PRINT(": ");
nebgnahz 0:54bf4b21c7fa 535 Adafruit_PN532::PrintHex(_key, 6);
nebgnahz 0:54bf4b21c7fa 536 #endif
nebgnahz 0:54bf4b21c7fa 537
nebgnahz 0:54bf4b21c7fa 538 // Prepare the authentication command //
nebgnahz 0:54bf4b21c7fa 539 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
nebgnahz 0:54bf4b21c7fa 540 pn532_packetbuffer[1] = 1; /* Max card numbers */
nebgnahz 0:54bf4b21c7fa 541 pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
nebgnahz 0:54bf4b21c7fa 542 pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
nebgnahz 0:54bf4b21c7fa 543 memcpy (pn532_packetbuffer+4, _key, 6);
nebgnahz 0:54bf4b21c7fa 544 for (i = 0; i < _uidLen; i++)
nebgnahz 0:54bf4b21c7fa 545 {
nebgnahz 0:54bf4b21c7fa 546 pn532_packetbuffer[10+i] = _uid[i]; /* 4 uint8_t card ID */
nebgnahz 0:54bf4b21c7fa 547 }
nebgnahz 0:54bf4b21c7fa 548
nebgnahz 0:54bf4b21c7fa 549 if (! sendCommandCheckAck(pn532_packetbuffer, 10+_uidLen))
nebgnahz 0:54bf4b21c7fa 550 return 0;
nebgnahz 0:54bf4b21c7fa 551
nebgnahz 0:54bf4b21c7fa 552 // Read the response packet
nebgnahz 0:54bf4b21c7fa 553 readspidata(pn532_packetbuffer, 12);
nebgnahz 0:54bf4b21c7fa 554 // check if the response is valid and we are authenticated???
nebgnahz 0:54bf4b21c7fa 555 // for an auth success it should be uint8_ts 5-7: 0xD5 0x41 0x00
nebgnahz 0:54bf4b21c7fa 556 // Mifare auth error is technically uint8_t 7: 0x14 but anything other and 0x00 is not good
nebgnahz 0:54bf4b21c7fa 557 if (pn532_packetbuffer[7] != 0x00)
nebgnahz 0:54bf4b21c7fa 558 {
nebgnahz 0:54bf4b21c7fa 559 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 560 SERIAL_PRINT("Authentification failed: ");
nebgnahz 0:54bf4b21c7fa 561 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 12);
nebgnahz 0:54bf4b21c7fa 562 #endif
nebgnahz 0:54bf4b21c7fa 563 return 0;
nebgnahz 0:54bf4b21c7fa 564 }
nebgnahz 0:54bf4b21c7fa 565
nebgnahz 0:54bf4b21c7fa 566 return 1;
nebgnahz 0:54bf4b21c7fa 567 }
nebgnahz 0:54bf4b21c7fa 568
nebgnahz 0:54bf4b21c7fa 569 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 570 /*!
nebgnahz 0:54bf4b21c7fa 571 Tries to read an entire 16-uint8_t data block at the specified block
nebgnahz 0:54bf4b21c7fa 572 address.
nebgnahz 0:54bf4b21c7fa 573
nebgnahz 0:54bf4b21c7fa 574 @param blockNumber The block number to authenticate. (0..63 for
nebgnahz 0:54bf4b21c7fa 575 1KB cards, and 0..255 for 4KB cards).
nebgnahz 0:54bf4b21c7fa 576 @param data Pointer to the uint8_t array that will hold the
nebgnahz 0:54bf4b21c7fa 577 retrieved data (if any)
nebgnahz 0:54bf4b21c7fa 578
nebgnahz 0:54bf4b21c7fa 579 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 580 */
nebgnahz 0:54bf4b21c7fa 581 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 582 uint8_t Adafruit_PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data)
nebgnahz 0:54bf4b21c7fa 583 {
nebgnahz 0:54bf4b21c7fa 584 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 585 SERIAL_PRINT("Trying to read 16 uint8_ts from block ");SERIAL_PRINTln(blockNumber);
nebgnahz 0:54bf4b21c7fa 586 #endif
nebgnahz 0:54bf4b21c7fa 587
nebgnahz 0:54bf4b21c7fa 588 /* Prepare the command */
nebgnahz 0:54bf4b21c7fa 589 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nebgnahz 0:54bf4b21c7fa 590 pn532_packetbuffer[1] = 1; /* Card number */
nebgnahz 0:54bf4b21c7fa 591 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
nebgnahz 0:54bf4b21c7fa 592 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
nebgnahz 0:54bf4b21c7fa 593
nebgnahz 0:54bf4b21c7fa 594 /* Send the command */
nebgnahz 0:54bf4b21c7fa 595 if (! sendCommandCheckAck(pn532_packetbuffer, 4))
nebgnahz 0:54bf4b21c7fa 596 {
nebgnahz 0:54bf4b21c7fa 597 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 598 SERIAL_PRINTln("Failed to receive ACK for read command");
nebgnahz 0:54bf4b21c7fa 599 #endif
nebgnahz 0:54bf4b21c7fa 600 return 0;
nebgnahz 0:54bf4b21c7fa 601 }
nebgnahz 0:54bf4b21c7fa 602
nebgnahz 0:54bf4b21c7fa 603 /* Read the response packet */
nebgnahz 0:54bf4b21c7fa 604 readspidata(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 605
nebgnahz 0:54bf4b21c7fa 606 /* If uint8_t 8 isn't 0x00 we probably have an error */
nebgnahz 0:54bf4b21c7fa 607 if (pn532_packetbuffer[7] != 0x00)
nebgnahz 0:54bf4b21c7fa 608 {
nebgnahz 0:54bf4b21c7fa 609 //#ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 610 SERIAL_PRINT("Unexpected response");
nebgnahz 0:54bf4b21c7fa 611 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 612 //#endif
nebgnahz 0:54bf4b21c7fa 613 return 0;
nebgnahz 0:54bf4b21c7fa 614 }
nebgnahz 0:54bf4b21c7fa 615
nebgnahz 0:54bf4b21c7fa 616 /* Copy the 16 data uint8_ts to the output buffer */
nebgnahz 0:54bf4b21c7fa 617 /* Block content starts at uint8_t 9 of a valid response */
nebgnahz 0:54bf4b21c7fa 618 memcpy (data, pn532_packetbuffer+8, 16);
nebgnahz 0:54bf4b21c7fa 619
nebgnahz 0:54bf4b21c7fa 620 /* Display data for debug if requested */
nebgnahz 0:54bf4b21c7fa 621 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 622 SERIAL_PRINT("Block ");
nebgnahz 0:54bf4b21c7fa 623 SERIAL_PRINTln(blockNumber);
nebgnahz 0:54bf4b21c7fa 624 Adafruit_PN532::PrintHexChar(data, 16);
nebgnahz 0:54bf4b21c7fa 625 #endif
nebgnahz 0:54bf4b21c7fa 626
nebgnahz 0:54bf4b21c7fa 627 return 1;
nebgnahz 0:54bf4b21c7fa 628 }
nebgnahz 0:54bf4b21c7fa 629
nebgnahz 0:54bf4b21c7fa 630 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 631 /*!
nebgnahz 0:54bf4b21c7fa 632 Tries to write an entire 16-uint8_t data block at the specified block
nebgnahz 0:54bf4b21c7fa 633 address.
nebgnahz 0:54bf4b21c7fa 634
nebgnahz 0:54bf4b21c7fa 635 @param blockNumber The block number to authenticate. (0..63 for
nebgnahz 0:54bf4b21c7fa 636 1KB cards, and 0..255 for 4KB cards).
nebgnahz 0:54bf4b21c7fa 637 @param data The uint8_t array that contains the data to write.
nebgnahz 0:54bf4b21c7fa 638
nebgnahz 0:54bf4b21c7fa 639 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 640 */
nebgnahz 0:54bf4b21c7fa 641 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 642 uint8_t Adafruit_PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
nebgnahz 0:54bf4b21c7fa 643 {
nebgnahz 0:54bf4b21c7fa 644 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 645 SERIAL_PRINT("Trying to write 16 uint8_ts to block ");SERIAL_PRINTln(blockNumber);
nebgnahz 0:54bf4b21c7fa 646 #endif
nebgnahz 0:54bf4b21c7fa 647
nebgnahz 0:54bf4b21c7fa 648 /* Prepare the first command */
nebgnahz 0:54bf4b21c7fa 649 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nebgnahz 0:54bf4b21c7fa 650 pn532_packetbuffer[1] = 1; /* Card number */
nebgnahz 0:54bf4b21c7fa 651 pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
nebgnahz 0:54bf4b21c7fa 652 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
nebgnahz 0:54bf4b21c7fa 653 memcpy (pn532_packetbuffer+4, data, 16); /* Data Payload */
nebgnahz 0:54bf4b21c7fa 654
nebgnahz 0:54bf4b21c7fa 655 /* Send the command */
nebgnahz 0:54bf4b21c7fa 656 if (! sendCommandCheckAck(pn532_packetbuffer, 20))
nebgnahz 0:54bf4b21c7fa 657 {
nebgnahz 0:54bf4b21c7fa 658 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 659 SERIAL_PRINTln("Failed to receive ACK for write command");
nebgnahz 0:54bf4b21c7fa 660 #endif
nebgnahz 0:54bf4b21c7fa 661 return 0;
nebgnahz 0:54bf4b21c7fa 662 }
nebgnahz 0:54bf4b21c7fa 663 delay(10);
nebgnahz 0:54bf4b21c7fa 664
nebgnahz 0:54bf4b21c7fa 665 /* Read the response packet */
nebgnahz 0:54bf4b21c7fa 666 readspidata(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 667
nebgnahz 0:54bf4b21c7fa 668 return 1;
nebgnahz 0:54bf4b21c7fa 669 }
nebgnahz 0:54bf4b21c7fa 670
nebgnahz 0:54bf4b21c7fa 671 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 672 /*!
nebgnahz 0:54bf4b21c7fa 673 Formats a Mifare Classic card to store NDEF Records
nebgnahz 0:54bf4b21c7fa 674
nebgnahz 0:54bf4b21c7fa 675 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 676 */
nebgnahz 0:54bf4b21c7fa 677 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 678 uint8_t Adafruit_PN532::mifareclassic_FormatNDEF (void)
nebgnahz 0:54bf4b21c7fa 679 {
nebgnahz 0:54bf4b21c7fa 680 uint8_t sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
nebgnahz 0:54bf4b21c7fa 681 uint8_t sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
nebgnahz 0:54bf4b21c7fa 682 uint8_t sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
nebgnahz 0:54bf4b21c7fa 683
nebgnahz 0:54bf4b21c7fa 684 // Write block 1 and 2 to the card
nebgnahz 0:54bf4b21c7fa 685 if (!(mifareclassic_WriteDataBlock (1, sectorbuffer1)))
nebgnahz 0:54bf4b21c7fa 686 return 0;
nebgnahz 0:54bf4b21c7fa 687 if (!(mifareclassic_WriteDataBlock (2, sectorbuffer2)))
nebgnahz 0:54bf4b21c7fa 688 return 0;
nebgnahz 0:54bf4b21c7fa 689 // Write key A and access rights card
nebgnahz 0:54bf4b21c7fa 690 if (!(mifareclassic_WriteDataBlock (3, sectorbuffer3)))
nebgnahz 0:54bf4b21c7fa 691 return 0;
nebgnahz 0:54bf4b21c7fa 692
nebgnahz 0:54bf4b21c7fa 693 // Seems that everything was OK (?!)
nebgnahz 0:54bf4b21c7fa 694 return 1;
nebgnahz 0:54bf4b21c7fa 695 }
nebgnahz 0:54bf4b21c7fa 696
nebgnahz 0:54bf4b21c7fa 697 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 698 /*!
nebgnahz 0:54bf4b21c7fa 699 Writes an NDEF URI Record to the specified sector (1..15)
nebgnahz 0:54bf4b21c7fa 700
nebgnahz 0:54bf4b21c7fa 701 Note that this function assumes that the Mifare Classic card is
nebgnahz 0:54bf4b21c7fa 702 already formatted to work as an "NFC Forum Tag" and uses a MAD1
nebgnahz 0:54bf4b21c7fa 703 file system. You can use the NXP TagWriter app on Android to
nebgnahz 0:54bf4b21c7fa 704 properly format cards for this.
nebgnahz 0:54bf4b21c7fa 705
nebgnahz 0:54bf4b21c7fa 706 @param sectorNumber The sector that the URI record should be written
nebgnahz 0:54bf4b21c7fa 707 to (can be 1..15 for a 1K card)
nebgnahz 0:54bf4b21c7fa 708 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
nebgnahz 0:54bf4b21c7fa 709 "http://www.", etc.)
nebgnahz 0:54bf4b21c7fa 710 @param url The uri text to write (max 38 characters).
nebgnahz 0:54bf4b21c7fa 711
nebgnahz 0:54bf4b21c7fa 712 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 713 */
nebgnahz 0:54bf4b21c7fa 714 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 715 uint8_t Adafruit_PN532::mifareclassic_WriteNDEFURI (uint8_t sectorNumber, uint8_t uriIdentifier, const char * url)
nebgnahz 0:54bf4b21c7fa 716 {
nebgnahz 0:54bf4b21c7fa 717 // Figure out how long the string is
nebgnahz 0:54bf4b21c7fa 718 uint8_t len = strlen(url);
nebgnahz 0:54bf4b21c7fa 719
nebgnahz 0:54bf4b21c7fa 720 // Make sure we're within a 1K limit for the sector number
nebgnahz 0:54bf4b21c7fa 721 if ((sectorNumber < 1) || (sectorNumber > 15))
nebgnahz 0:54bf4b21c7fa 722 return 0;
nebgnahz 0:54bf4b21c7fa 723
nebgnahz 0:54bf4b21c7fa 724 // Make sure the URI payload is between 1 and 38 chars
nebgnahz 0:54bf4b21c7fa 725 if ((len < 1) || (len > 38))
nebgnahz 0:54bf4b21c7fa 726 return 0;
nebgnahz 0:54bf4b21c7fa 727
nebgnahz 0:54bf4b21c7fa 728 // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
nebgnahz 0:54bf4b21c7fa 729 uint8_t sectorbuffer1[16] = {0x00, 0x00, 0x03, len+5, 0xD1, 0x01, len+1, 0x55, uriIdentifier, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
nebgnahz 0:54bf4b21c7fa 730 uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
nebgnahz 0:54bf4b21c7fa 731 uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
nebgnahz 0:54bf4b21c7fa 732 uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
nebgnahz 0:54bf4b21c7fa 733 if (len <= 6)
nebgnahz 0:54bf4b21c7fa 734 {
nebgnahz 0:54bf4b21c7fa 735 // Unlikely we'll get a url this short, but why not ...
nebgnahz 0:54bf4b21c7fa 736 memcpy (sectorbuffer1+9, url, len);
nebgnahz 0:54bf4b21c7fa 737 sectorbuffer1[len+9] = 0xFE;
nebgnahz 0:54bf4b21c7fa 738 }
nebgnahz 0:54bf4b21c7fa 739 else if (len == 7)
nebgnahz 0:54bf4b21c7fa 740 {
nebgnahz 0:54bf4b21c7fa 741 // 0xFE needs to be wrapped around to next block
nebgnahz 0:54bf4b21c7fa 742 memcpy (sectorbuffer1+9, url, len);
nebgnahz 0:54bf4b21c7fa 743 sectorbuffer2[0] = 0xFE;
nebgnahz 0:54bf4b21c7fa 744 }
nebgnahz 0:54bf4b21c7fa 745 else if ((len > 7) || (len <= 22))
nebgnahz 0:54bf4b21c7fa 746 {
nebgnahz 0:54bf4b21c7fa 747 // Url fits in two blocks
nebgnahz 0:54bf4b21c7fa 748 memcpy (sectorbuffer1+9, url, 7);
nebgnahz 0:54bf4b21c7fa 749 memcpy (sectorbuffer2, url+7, len-7);
nebgnahz 0:54bf4b21c7fa 750 sectorbuffer2[len-7] = 0xFE;
nebgnahz 0:54bf4b21c7fa 751 }
nebgnahz 0:54bf4b21c7fa 752 else if (len == 23)
nebgnahz 0:54bf4b21c7fa 753 {
nebgnahz 0:54bf4b21c7fa 754 // 0xFE needs to be wrapped around to final block
nebgnahz 0:54bf4b21c7fa 755 memcpy (sectorbuffer1+9, url, 7);
nebgnahz 0:54bf4b21c7fa 756 memcpy (sectorbuffer2, url+7, len-7);
nebgnahz 0:54bf4b21c7fa 757 sectorbuffer3[0] = 0xFE;
nebgnahz 0:54bf4b21c7fa 758 }
nebgnahz 0:54bf4b21c7fa 759 else
nebgnahz 0:54bf4b21c7fa 760 {
nebgnahz 0:54bf4b21c7fa 761 // Url fits in three blocks
nebgnahz 0:54bf4b21c7fa 762 memcpy (sectorbuffer1+9, url, 7);
nebgnahz 0:54bf4b21c7fa 763 memcpy (sectorbuffer2, url+7, 16);
nebgnahz 0:54bf4b21c7fa 764 memcpy (sectorbuffer3, url+23, len-24);
nebgnahz 0:54bf4b21c7fa 765 sectorbuffer3[len-22] = 0xFE;
nebgnahz 0:54bf4b21c7fa 766 }
nebgnahz 0:54bf4b21c7fa 767
nebgnahz 0:54bf4b21c7fa 768 // Now write all three blocks back to the card
nebgnahz 0:54bf4b21c7fa 769 if (!(mifareclassic_WriteDataBlock (sectorNumber*4, sectorbuffer1)))
nebgnahz 0:54bf4b21c7fa 770 return 0;
nebgnahz 0:54bf4b21c7fa 771 if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+1, sectorbuffer2)))
nebgnahz 0:54bf4b21c7fa 772 return 0;
nebgnahz 0:54bf4b21c7fa 773 if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+2, sectorbuffer3)))
nebgnahz 0:54bf4b21c7fa 774 return 0;
nebgnahz 0:54bf4b21c7fa 775 if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+3, sectorbuffer4)))
nebgnahz 0:54bf4b21c7fa 776 return 0;
nebgnahz 0:54bf4b21c7fa 777
nebgnahz 0:54bf4b21c7fa 778 // Seems that everything was OK (?!)
nebgnahz 0:54bf4b21c7fa 779 return 1;
nebgnahz 0:54bf4b21c7fa 780 }
nebgnahz 0:54bf4b21c7fa 781
nebgnahz 0:54bf4b21c7fa 782 /***** Mifare Ultralight Functions ******/
nebgnahz 0:54bf4b21c7fa 783
nebgnahz 0:54bf4b21c7fa 784 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 785 /*!
nebgnahz 0:54bf4b21c7fa 786 Tries to read an entire 4-uint8_t page at the specified address.
nebgnahz 0:54bf4b21c7fa 787
nebgnahz 0:54bf4b21c7fa 788 @param page The page number (0..63 in most cases)
nebgnahz 0:54bf4b21c7fa 789 @param buffer Pointer to the uint8_t array that will hold the
nebgnahz 0:54bf4b21c7fa 790 retrieved data (if any)
nebgnahz 0:54bf4b21c7fa 791 */
nebgnahz 0:54bf4b21c7fa 792 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 793 uint8_t Adafruit_PN532::mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
nebgnahz 0:54bf4b21c7fa 794 {
nebgnahz 0:54bf4b21c7fa 795 if (page >= 64)
nebgnahz 0:54bf4b21c7fa 796 {
nebgnahz 0:54bf4b21c7fa 797 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 798 SERIAL_PRINTln("Page value out of range");
nebgnahz 0:54bf4b21c7fa 799 #endif
nebgnahz 0:54bf4b21c7fa 800 return 0;
nebgnahz 0:54bf4b21c7fa 801 }
nebgnahz 0:54bf4b21c7fa 802
nebgnahz 0:54bf4b21c7fa 803 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 804 SERIAL_PRINT("Reading page ");SERIAL_PRINTln(page);
nebgnahz 0:54bf4b21c7fa 805 #endif
nebgnahz 0:54bf4b21c7fa 806
nebgnahz 0:54bf4b21c7fa 807 /* Prepare the command */
nebgnahz 0:54bf4b21c7fa 808 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nebgnahz 0:54bf4b21c7fa 809 pn532_packetbuffer[1] = 1; /* Card number */
nebgnahz 0:54bf4b21c7fa 810 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
nebgnahz 0:54bf4b21c7fa 811 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
nebgnahz 0:54bf4b21c7fa 812
nebgnahz 0:54bf4b21c7fa 813 /* Send the command */
nebgnahz 0:54bf4b21c7fa 814 if (! sendCommandCheckAck(pn532_packetbuffer, 4))
nebgnahz 0:54bf4b21c7fa 815 {
nebgnahz 0:54bf4b21c7fa 816 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 817 SERIAL_PRINTln("Failed to receive ACK for write command");
nebgnahz 0:54bf4b21c7fa 818 #endif
nebgnahz 0:54bf4b21c7fa 819 return 0;
nebgnahz 0:54bf4b21c7fa 820 }
nebgnahz 0:54bf4b21c7fa 821
nebgnahz 0:54bf4b21c7fa 822 /* Read the response packet */
nebgnahz 0:54bf4b21c7fa 823 readspidata(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 824 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 825 SERIAL_PRINTln("Received: ");
nebgnahz 0:54bf4b21c7fa 826 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 827 #endif
nebgnahz 0:54bf4b21c7fa 828
nebgnahz 0:54bf4b21c7fa 829 /* If uint8_t 8 isn't 0x00 we probably have an error */
nebgnahz 0:54bf4b21c7fa 830 if (pn532_packetbuffer[7] == 0x00)
nebgnahz 0:54bf4b21c7fa 831 {
nebgnahz 0:54bf4b21c7fa 832 /* Copy the 4 data uint8_ts to the output buffer */
nebgnahz 0:54bf4b21c7fa 833 /* Block content starts at uint8_t 9 of a valid response */
nebgnahz 0:54bf4b21c7fa 834 /* Note that the command actually reads 16 uint8_t or 4 */
nebgnahz 0:54bf4b21c7fa 835 /* pages at a time ... we simply discard the last 12 */
nebgnahz 0:54bf4b21c7fa 836 /* uint8_ts */
nebgnahz 0:54bf4b21c7fa 837 memcpy (buffer, pn532_packetbuffer+8, 4);
nebgnahz 0:54bf4b21c7fa 838 }
nebgnahz 0:54bf4b21c7fa 839 else
nebgnahz 0:54bf4b21c7fa 840 {
nebgnahz 0:54bf4b21c7fa 841 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 842 SERIAL_PRINTln("Unexpected response reading block: ");
nebgnahz 0:54bf4b21c7fa 843 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 844 #endif
nebgnahz 0:54bf4b21c7fa 845 return 0;
nebgnahz 0:54bf4b21c7fa 846 }
nebgnahz 0:54bf4b21c7fa 847
nebgnahz 0:54bf4b21c7fa 848 /* Display data for debug if requested */
nebgnahz 0:54bf4b21c7fa 849 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 850 SERIAL_PRINT("Page ");SERIAL_PRINT(page);SERIAL_PRINTln(":");
nebgnahz 0:54bf4b21c7fa 851 Adafruit_PN532::PrintHexChar(buffer, 4);
nebgnahz 0:54bf4b21c7fa 852 #endif
nebgnahz 0:54bf4b21c7fa 853
nebgnahz 0:54bf4b21c7fa 854 // Return OK signal
nebgnahz 0:54bf4b21c7fa 855 return 1;
nebgnahz 0:54bf4b21c7fa 856 }
nebgnahz 0:54bf4b21c7fa 857
nebgnahz 0:54bf4b21c7fa 858
nebgnahz 0:54bf4b21c7fa 859
nebgnahz 0:54bf4b21c7fa 860 /************** high level SPI */
nebgnahz 0:54bf4b21c7fa 861
nebgnahz 0:54bf4b21c7fa 862
nebgnahz 0:54bf4b21c7fa 863 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 864 /*!
nebgnahz 0:54bf4b21c7fa 865 @brief Tries to read the SPI ACK signal
nebgnahz 0:54bf4b21c7fa 866 */
nebgnahz 0:54bf4b21c7fa 867 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 868 bool Adafruit_PN532::spi_readack() {
nebgnahz 0:54bf4b21c7fa 869 uint8_t ackbuff[6];
nebgnahz 0:54bf4b21c7fa 870
nebgnahz 0:54bf4b21c7fa 871 readspidata(ackbuff, 6);
nebgnahz 0:54bf4b21c7fa 872
nebgnahz 0:54bf4b21c7fa 873 return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
nebgnahz 0:54bf4b21c7fa 874 }
nebgnahz 0:54bf4b21c7fa 875
nebgnahz 0:54bf4b21c7fa 876 /************** mid level SPI */
nebgnahz 0:54bf4b21c7fa 877
nebgnahz 0:54bf4b21c7fa 878 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 879 /*!
nebgnahz 0:54bf4b21c7fa 880 @brief Reads the SPI status register (to know if the PN532 is ready)
nebgnahz 0:54bf4b21c7fa 881 */
nebgnahz 0:54bf4b21c7fa 882 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 883 uint8_t Adafruit_PN532::readspistatus(void) {
nebgnahz 0:54bf4b21c7fa 884 _ss = 0;
nebgnahz 0:54bf4b21c7fa 885 delay(2);
nebgnahz 0:54bf4b21c7fa 886 spiwrite(PN532_SPI_STATREAD);
nebgnahz 0:54bf4b21c7fa 887 // read uint8_t
nebgnahz 0:54bf4b21c7fa 888 uint8_t x = spiread();
nebgnahz 0:54bf4b21c7fa 889
nebgnahz 0:54bf4b21c7fa 890 _ss = 1;
nebgnahz 0:54bf4b21c7fa 891 return x;
nebgnahz 0:54bf4b21c7fa 892 }
nebgnahz 0:54bf4b21c7fa 893
nebgnahz 0:54bf4b21c7fa 894 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 895 /*!
nebgnahz 0:54bf4b21c7fa 896 @brief Reads n uint8_ts of data from the PN532 via SPI
nebgnahz 0:54bf4b21c7fa 897
nebgnahz 0:54bf4b21c7fa 898 @param buff Pointer to the buffer where data will be written
nebgnahz 0:54bf4b21c7fa 899 @param n Number of uint8_ts to be read
nebgnahz 0:54bf4b21c7fa 900 */
nebgnahz 0:54bf4b21c7fa 901 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 902 void Adafruit_PN532::readspidata(uint8_t* buff, uint8_t n) {
nebgnahz 0:54bf4b21c7fa 903 _ss = 0;
nebgnahz 0:54bf4b21c7fa 904 delay(2);
nebgnahz 0:54bf4b21c7fa 905 spiwrite(PN532_SPI_DATAREAD);
nebgnahz 0:54bf4b21c7fa 906
nebgnahz 0:54bf4b21c7fa 907 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 908 SERIAL_PRINT("Reading: ");
nebgnahz 0:54bf4b21c7fa 909 #endif
nebgnahz 0:54bf4b21c7fa 910 for (uint8_t i=0; i<n; i++) {
nebgnahz 0:54bf4b21c7fa 911 delay(1);
nebgnahz 0:54bf4b21c7fa 912 buff[i] = spiread();
nebgnahz 0:54bf4b21c7fa 913 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 914 SERIAL_PRINT(" 0x");
nebgnahz 0:54bf4b21c7fa 915 SERIAL_PRINT(buff[i], HEX);
nebgnahz 0:54bf4b21c7fa 916 #endif
nebgnahz 0:54bf4b21c7fa 917 }
nebgnahz 0:54bf4b21c7fa 918
nebgnahz 0:54bf4b21c7fa 919 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 920 SERIAL_PRINTln();
nebgnahz 0:54bf4b21c7fa 921 #endif
nebgnahz 0:54bf4b21c7fa 922
nebgnahz 0:54bf4b21c7fa 923 _ss = 1;
nebgnahz 0:54bf4b21c7fa 924 }
nebgnahz 0:54bf4b21c7fa 925
nebgnahz 0:54bf4b21c7fa 926 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 927 /*!
nebgnahz 0:54bf4b21c7fa 928 @brief Writes a command to the PN532, automatically inserting the
nebgnahz 0:54bf4b21c7fa 929 preamble and required frame details (checksum, len, etc.)
nebgnahz 0:54bf4b21c7fa 930
nebgnahz 0:54bf4b21c7fa 931 @param cmd Pointer to the command buffer
nebgnahz 0:54bf4b21c7fa 932 @param cmdlen Command length in uint8_ts
nebgnahz 0:54bf4b21c7fa 933 */
nebgnahz 0:54bf4b21c7fa 934 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 935 void Adafruit_PN532::spiwritecommand(uint8_t* cmd, uint8_t cmdlen) {
nebgnahz 0:54bf4b21c7fa 936 uint8_t checksum;
nebgnahz 0:54bf4b21c7fa 937
nebgnahz 0:54bf4b21c7fa 938 cmdlen++;
nebgnahz 0:54bf4b21c7fa 939
nebgnahz 0:54bf4b21c7fa 940 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 941 SERIAL_PRINT("\nSending: ");
nebgnahz 0:54bf4b21c7fa 942 #endif
nebgnahz 0:54bf4b21c7fa 943
nebgnahz 0:54bf4b21c7fa 944 _ss = 0;
nebgnahz 0:54bf4b21c7fa 945 delay(2); // or whatever the delay is for waking up the board
nebgnahz 0:54bf4b21c7fa 946 spiwrite(PN532_SPI_DATAWRITE);
nebgnahz 0:54bf4b21c7fa 947
nebgnahz 0:54bf4b21c7fa 948 checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2;
nebgnahz 0:54bf4b21c7fa 949 spiwrite(PN532_PREAMBLE);
nebgnahz 0:54bf4b21c7fa 950 spiwrite(PN532_PREAMBLE);
nebgnahz 0:54bf4b21c7fa 951 spiwrite(PN532_STARTCODE2);
nebgnahz 0:54bf4b21c7fa 952
nebgnahz 0:54bf4b21c7fa 953 spiwrite(cmdlen);
nebgnahz 0:54bf4b21c7fa 954 spiwrite(~cmdlen + 1);
nebgnahz 0:54bf4b21c7fa 955
nebgnahz 0:54bf4b21c7fa 956 spiwrite(PN532_HOSTTOPN532);
nebgnahz 0:54bf4b21c7fa 957 checksum += PN532_HOSTTOPN532;
nebgnahz 0:54bf4b21c7fa 958
nebgnahz 0:54bf4b21c7fa 959 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 960 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_PREAMBLE, HEX);
nebgnahz 0:54bf4b21c7fa 961 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_PREAMBLE, HEX);
nebgnahz 0:54bf4b21c7fa 962 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_STARTCODE2, HEX);
nebgnahz 0:54bf4b21c7fa 963 SERIAL_PRINT(" 0x"); SERIAL_PRINT(cmdlen, HEX);
nebgnahz 0:54bf4b21c7fa 964 SERIAL_PRINT(" 0x"); SERIAL_PRINT(~cmdlen + 1, HEX);
nebgnahz 0:54bf4b21c7fa 965 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_HOSTTOPN532, HEX);
nebgnahz 0:54bf4b21c7fa 966 #endif
nebgnahz 0:54bf4b21c7fa 967
nebgnahz 0:54bf4b21c7fa 968 for (uint8_t i=0; i<cmdlen-1; i++) {
nebgnahz 0:54bf4b21c7fa 969 spiwrite(cmd[i]);
nebgnahz 0:54bf4b21c7fa 970 checksum += cmd[i];
nebgnahz 0:54bf4b21c7fa 971 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 972 SERIAL_PRINT(" 0x"); SERIAL_PRINT(cmd[i], HEX);
nebgnahz 0:54bf4b21c7fa 973 #endif
nebgnahz 0:54bf4b21c7fa 974 }
nebgnahz 0:54bf4b21c7fa 975
nebgnahz 0:54bf4b21c7fa 976 spiwrite(~checksum);
nebgnahz 0:54bf4b21c7fa 977 spiwrite(PN532_POSTAMBLE);
nebgnahz 0:54bf4b21c7fa 978 _ss = 1;
nebgnahz 0:54bf4b21c7fa 979
nebgnahz 0:54bf4b21c7fa 980 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 981 SERIAL_PRINT(" 0x"); SERIAL_PRINT(~checksum, HEX);
nebgnahz 0:54bf4b21c7fa 982 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_POSTAMBLE, HEX);
nebgnahz 0:54bf4b21c7fa 983 SERIAL_PRINTln();
nebgnahz 0:54bf4b21c7fa 984 #endif
nebgnahz 0:54bf4b21c7fa 985 }
nebgnahz 0:54bf4b21c7fa 986 /************** low level SPI */
nebgnahz 0:54bf4b21c7fa 987
nebgnahz 0:54bf4b21c7fa 988 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 989 /*!
nebgnahz 0:54bf4b21c7fa 990 @brief Low-level SPI write wrapper
nebgnahz 0:54bf4b21c7fa 991
nebgnahz 0:54bf4b21c7fa 992 @param c 8-bit command to write to the SPI bus
nebgnahz 0:54bf4b21c7fa 993 */
nebgnahz 0:54bf4b21c7fa 994 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 995 void Adafruit_PN532::spiwrite(uint8_t c) {
nebgnahz 0:54bf4b21c7fa 996 int8_t i;
nebgnahz 0:54bf4b21c7fa 997 _clk = 1;
nebgnahz 0:54bf4b21c7fa 998
nebgnahz 0:54bf4b21c7fa 999 for (i=0; i<8; i++) {
nebgnahz 0:54bf4b21c7fa 1000 _clk = 0;
nebgnahz 0:54bf4b21c7fa 1001 if (c & _BV(i)) {
nebgnahz 0:54bf4b21c7fa 1002 _mosi = 1;
nebgnahz 0:54bf4b21c7fa 1003 } else {
nebgnahz 0:54bf4b21c7fa 1004 _mosi = 0;
nebgnahz 0:54bf4b21c7fa 1005 }
nebgnahz 0:54bf4b21c7fa 1006 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1007 }
nebgnahz 0:54bf4b21c7fa 1008 }
nebgnahz 0:54bf4b21c7fa 1009
nebgnahz 0:54bf4b21c7fa 1010 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 1011 /*!
nebgnahz 0:54bf4b21c7fa 1012 @brief Low-level SPI read wrapper
nebgnahz 0:54bf4b21c7fa 1013
nebgnahz 0:54bf4b21c7fa 1014 @returns The 8-bit value that was read from the SPI bus
nebgnahz 0:54bf4b21c7fa 1015 */
nebgnahz 0:54bf4b21c7fa 1016 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 1017 uint8_t Adafruit_PN532::spiread(void) {
nebgnahz 0:54bf4b21c7fa 1018 int8_t i, x;
nebgnahz 0:54bf4b21c7fa 1019 x = 0;
nebgnahz 0:54bf4b21c7fa 1020 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1021
nebgnahz 0:54bf4b21c7fa 1022 for (i=0; i<8; i++) {
nebgnahz 0:54bf4b21c7fa 1023 if (_miso.read()) {
nebgnahz 0:54bf4b21c7fa 1024 x |= _BV(i);
nebgnahz 0:54bf4b21c7fa 1025 }
nebgnahz 0:54bf4b21c7fa 1026 _clk = 0;
nebgnahz 0:54bf4b21c7fa 1027 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1028 }
nebgnahz 0:54bf4b21c7fa 1029 return x;
nebgnahz 0:54bf4b21c7fa 1030 }