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

Dependencies:   mbed

Committer:
shong2010
Date:
Mon Nov 03 05:48:29 2014 +0000
Revision:
2:96f420fa4a6e
Parent:
0:54bf4b21c7fa
RFID Prototype

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
shong2010 2:96f420fa4a6e 468 uint8_t bTestDeselect[2];
shong2010 2:96f420fa4a6e 469 bTestDeselect[0] = PN532_COMMAND_INDESELECT;
shong2010 2:96f420fa4a6e 470 bTestDeselect[1] = pn532_packetbuffer[8];
shong2010 2:96f420fa4a6e 471 sendCommandCheckAck(bTestDeselect,2);
shong2010 2:96f420fa4a6e 472
nebgnahz 0:54bf4b21c7fa 473 return 1;
nebgnahz 0:54bf4b21c7fa 474 }
nebgnahz 0:54bf4b21c7fa 475
nebgnahz 0:54bf4b21c7fa 476
nebgnahz 0:54bf4b21c7fa 477 /***** Mifare Classic Functions ******/
nebgnahz 0:54bf4b21c7fa 478
nebgnahz 0:54bf4b21c7fa 479 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 480 /*!
nebgnahz 0:54bf4b21c7fa 481 Indicates whether the specified block number is the first block
nebgnahz 0:54bf4b21c7fa 482 in the sector (block 0 relative to the current sector)
nebgnahz 0:54bf4b21c7fa 483 */
nebgnahz 0:54bf4b21c7fa 484 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 485 bool Adafruit_PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock)
nebgnahz 0:54bf4b21c7fa 486 {
nebgnahz 0:54bf4b21c7fa 487 // Test if we are in the small or big sectors
nebgnahz 0:54bf4b21c7fa 488 if (uiBlock < 128)
nebgnahz 0:54bf4b21c7fa 489 return ((uiBlock) % 4 == 0);
nebgnahz 0:54bf4b21c7fa 490 else
nebgnahz 0:54bf4b21c7fa 491 return ((uiBlock) % 16 == 0);
nebgnahz 0:54bf4b21c7fa 492 }
nebgnahz 0:54bf4b21c7fa 493
nebgnahz 0:54bf4b21c7fa 494 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 495 /*!
nebgnahz 0:54bf4b21c7fa 496 Indicates whether the specified block number is the sector trailer
nebgnahz 0:54bf4b21c7fa 497 */
nebgnahz 0:54bf4b21c7fa 498 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 499 bool Adafruit_PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock)
nebgnahz 0:54bf4b21c7fa 500 {
nebgnahz 0:54bf4b21c7fa 501 // Test if we are in the small or big sectors
nebgnahz 0:54bf4b21c7fa 502 if (uiBlock < 128)
nebgnahz 0:54bf4b21c7fa 503 return ((uiBlock + 1) % 4 == 0);
nebgnahz 0:54bf4b21c7fa 504 else
nebgnahz 0:54bf4b21c7fa 505 return ((uiBlock + 1) % 16 == 0);
nebgnahz 0:54bf4b21c7fa 506 }
nebgnahz 0:54bf4b21c7fa 507
nebgnahz 0:54bf4b21c7fa 508 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 509 /*!
nebgnahz 0:54bf4b21c7fa 510 Tries to authenticate a block of memory on a MIFARE card using the
nebgnahz 0:54bf4b21c7fa 511 INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual
nebgnahz 0:54bf4b21c7fa 512 for more information on sending MIFARE and other commands.
nebgnahz 0:54bf4b21c7fa 513
nebgnahz 0:54bf4b21c7fa 514 @param uid Pointer to a uint8_t array containing the card UID
nebgnahz 0:54bf4b21c7fa 515 @param uidLen The length (in uint8_ts) of the card's UID (Should
nebgnahz 0:54bf4b21c7fa 516 be 4 for MIFARE Classic)
nebgnahz 0:54bf4b21c7fa 517 @param blockNumber The block number to authenticate. (0..63 for
nebgnahz 0:54bf4b21c7fa 518 1KB cards, and 0..255 for 4KB cards).
nebgnahz 0:54bf4b21c7fa 519 @param keyNumber Which key type to use during authentication
nebgnahz 0:54bf4b21c7fa 520 (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
nebgnahz 0:54bf4b21c7fa 521 @param keyData Pointer to a uint8_t array containing the 6 uint8_t
nebgnahz 0:54bf4b21c7fa 522 key value
nebgnahz 0:54bf4b21c7fa 523
nebgnahz 0:54bf4b21c7fa 524 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 525 */
nebgnahz 0:54bf4b21c7fa 526 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 527 uint8_t Adafruit_PN532::mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData)
nebgnahz 0:54bf4b21c7fa 528 {
nebgnahz 0:54bf4b21c7fa 529 uint8_t i;
nebgnahz 0:54bf4b21c7fa 530
nebgnahz 0:54bf4b21c7fa 531 // Hang on to the key and uid data
nebgnahz 0:54bf4b21c7fa 532 memcpy (_key, keyData, 6);
nebgnahz 0:54bf4b21c7fa 533 memcpy (_uid, uid, uidLen);
nebgnahz 0:54bf4b21c7fa 534 _uidLen = uidLen;
nebgnahz 0:54bf4b21c7fa 535
nebgnahz 0:54bf4b21c7fa 536 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 537 SERIAL_PRINT("Trying to authenticate card ");
nebgnahz 0:54bf4b21c7fa 538 Adafruit_PN532::PrintHex(_uid, _uidLen);
nebgnahz 0:54bf4b21c7fa 539 SERIAL_PRINT("Using authentication KEY ");SERIAL_PRINT(keyNumber ? 'B' : 'A');SERIAL_PRINT(": ");
nebgnahz 0:54bf4b21c7fa 540 Adafruit_PN532::PrintHex(_key, 6);
nebgnahz 0:54bf4b21c7fa 541 #endif
nebgnahz 0:54bf4b21c7fa 542
nebgnahz 0:54bf4b21c7fa 543 // Prepare the authentication command //
nebgnahz 0:54bf4b21c7fa 544 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
nebgnahz 0:54bf4b21c7fa 545 pn532_packetbuffer[1] = 1; /* Max card numbers */
nebgnahz 0:54bf4b21c7fa 546 pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
nebgnahz 0:54bf4b21c7fa 547 pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
nebgnahz 0:54bf4b21c7fa 548 memcpy (pn532_packetbuffer+4, _key, 6);
nebgnahz 0:54bf4b21c7fa 549 for (i = 0; i < _uidLen; i++)
nebgnahz 0:54bf4b21c7fa 550 {
nebgnahz 0:54bf4b21c7fa 551 pn532_packetbuffer[10+i] = _uid[i]; /* 4 uint8_t card ID */
nebgnahz 0:54bf4b21c7fa 552 }
nebgnahz 0:54bf4b21c7fa 553
nebgnahz 0:54bf4b21c7fa 554 if (! sendCommandCheckAck(pn532_packetbuffer, 10+_uidLen))
nebgnahz 0:54bf4b21c7fa 555 return 0;
nebgnahz 0:54bf4b21c7fa 556
nebgnahz 0:54bf4b21c7fa 557 // Read the response packet
nebgnahz 0:54bf4b21c7fa 558 readspidata(pn532_packetbuffer, 12);
nebgnahz 0:54bf4b21c7fa 559 // check if the response is valid and we are authenticated???
nebgnahz 0:54bf4b21c7fa 560 // for an auth success it should be uint8_ts 5-7: 0xD5 0x41 0x00
nebgnahz 0:54bf4b21c7fa 561 // Mifare auth error is technically uint8_t 7: 0x14 but anything other and 0x00 is not good
nebgnahz 0:54bf4b21c7fa 562 if (pn532_packetbuffer[7] != 0x00)
nebgnahz 0:54bf4b21c7fa 563 {
nebgnahz 0:54bf4b21c7fa 564 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 565 SERIAL_PRINT("Authentification failed: ");
nebgnahz 0:54bf4b21c7fa 566 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 12);
nebgnahz 0:54bf4b21c7fa 567 #endif
nebgnahz 0:54bf4b21c7fa 568 return 0;
nebgnahz 0:54bf4b21c7fa 569 }
nebgnahz 0:54bf4b21c7fa 570
nebgnahz 0:54bf4b21c7fa 571 return 1;
nebgnahz 0:54bf4b21c7fa 572 }
nebgnahz 0:54bf4b21c7fa 573
nebgnahz 0:54bf4b21c7fa 574 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 575 /*!
nebgnahz 0:54bf4b21c7fa 576 Tries to read an entire 16-uint8_t data block at the specified block
nebgnahz 0:54bf4b21c7fa 577 address.
nebgnahz 0:54bf4b21c7fa 578
nebgnahz 0:54bf4b21c7fa 579 @param blockNumber The block number to authenticate. (0..63 for
nebgnahz 0:54bf4b21c7fa 580 1KB cards, and 0..255 for 4KB cards).
nebgnahz 0:54bf4b21c7fa 581 @param data Pointer to the uint8_t array that will hold the
nebgnahz 0:54bf4b21c7fa 582 retrieved data (if any)
nebgnahz 0:54bf4b21c7fa 583
nebgnahz 0:54bf4b21c7fa 584 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 585 */
nebgnahz 0:54bf4b21c7fa 586 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 587 uint8_t Adafruit_PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data)
nebgnahz 0:54bf4b21c7fa 588 {
nebgnahz 0:54bf4b21c7fa 589 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 590 SERIAL_PRINT("Trying to read 16 uint8_ts from block ");SERIAL_PRINTln(blockNumber);
nebgnahz 0:54bf4b21c7fa 591 #endif
nebgnahz 0:54bf4b21c7fa 592
nebgnahz 0:54bf4b21c7fa 593 /* Prepare the command */
nebgnahz 0:54bf4b21c7fa 594 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nebgnahz 0:54bf4b21c7fa 595 pn532_packetbuffer[1] = 1; /* Card number */
nebgnahz 0:54bf4b21c7fa 596 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
nebgnahz 0:54bf4b21c7fa 597 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
nebgnahz 0:54bf4b21c7fa 598
nebgnahz 0:54bf4b21c7fa 599 /* Send the command */
nebgnahz 0:54bf4b21c7fa 600 if (! sendCommandCheckAck(pn532_packetbuffer, 4))
nebgnahz 0:54bf4b21c7fa 601 {
nebgnahz 0:54bf4b21c7fa 602 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 603 SERIAL_PRINTln("Failed to receive ACK for read command");
nebgnahz 0:54bf4b21c7fa 604 #endif
nebgnahz 0:54bf4b21c7fa 605 return 0;
nebgnahz 0:54bf4b21c7fa 606 }
nebgnahz 0:54bf4b21c7fa 607
nebgnahz 0:54bf4b21c7fa 608 /* Read the response packet */
nebgnahz 0:54bf4b21c7fa 609 readspidata(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 610
nebgnahz 0:54bf4b21c7fa 611 /* If uint8_t 8 isn't 0x00 we probably have an error */
nebgnahz 0:54bf4b21c7fa 612 if (pn532_packetbuffer[7] != 0x00)
nebgnahz 0:54bf4b21c7fa 613 {
nebgnahz 0:54bf4b21c7fa 614 //#ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 615 SERIAL_PRINT("Unexpected response");
nebgnahz 0:54bf4b21c7fa 616 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 617 //#endif
nebgnahz 0:54bf4b21c7fa 618 return 0;
nebgnahz 0:54bf4b21c7fa 619 }
nebgnahz 0:54bf4b21c7fa 620
nebgnahz 0:54bf4b21c7fa 621 /* Copy the 16 data uint8_ts to the output buffer */
nebgnahz 0:54bf4b21c7fa 622 /* Block content starts at uint8_t 9 of a valid response */
nebgnahz 0:54bf4b21c7fa 623 memcpy (data, pn532_packetbuffer+8, 16);
nebgnahz 0:54bf4b21c7fa 624
nebgnahz 0:54bf4b21c7fa 625 /* Display data for debug if requested */
nebgnahz 0:54bf4b21c7fa 626 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 627 SERIAL_PRINT("Block ");
nebgnahz 0:54bf4b21c7fa 628 SERIAL_PRINTln(blockNumber);
nebgnahz 0:54bf4b21c7fa 629 Adafruit_PN532::PrintHexChar(data, 16);
nebgnahz 0:54bf4b21c7fa 630 #endif
nebgnahz 0:54bf4b21c7fa 631
nebgnahz 0:54bf4b21c7fa 632 return 1;
nebgnahz 0:54bf4b21c7fa 633 }
nebgnahz 0:54bf4b21c7fa 634
nebgnahz 0:54bf4b21c7fa 635 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 636 /*!
nebgnahz 0:54bf4b21c7fa 637 Tries to write an entire 16-uint8_t data block at the specified block
nebgnahz 0:54bf4b21c7fa 638 address.
nebgnahz 0:54bf4b21c7fa 639
nebgnahz 0:54bf4b21c7fa 640 @param blockNumber The block number to authenticate. (0..63 for
nebgnahz 0:54bf4b21c7fa 641 1KB cards, and 0..255 for 4KB cards).
nebgnahz 0:54bf4b21c7fa 642 @param data The uint8_t array that contains the data to write.
nebgnahz 0:54bf4b21c7fa 643
nebgnahz 0:54bf4b21c7fa 644 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 645 */
nebgnahz 0:54bf4b21c7fa 646 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 647 uint8_t Adafruit_PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
nebgnahz 0:54bf4b21c7fa 648 {
nebgnahz 0:54bf4b21c7fa 649 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 650 SERIAL_PRINT("Trying to write 16 uint8_ts to block ");SERIAL_PRINTln(blockNumber);
nebgnahz 0:54bf4b21c7fa 651 #endif
nebgnahz 0:54bf4b21c7fa 652
nebgnahz 0:54bf4b21c7fa 653 /* Prepare the first command */
nebgnahz 0:54bf4b21c7fa 654 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nebgnahz 0:54bf4b21c7fa 655 pn532_packetbuffer[1] = 1; /* Card number */
nebgnahz 0:54bf4b21c7fa 656 pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
nebgnahz 0:54bf4b21c7fa 657 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
nebgnahz 0:54bf4b21c7fa 658 memcpy (pn532_packetbuffer+4, data, 16); /* Data Payload */
nebgnahz 0:54bf4b21c7fa 659
nebgnahz 0:54bf4b21c7fa 660 /* Send the command */
nebgnahz 0:54bf4b21c7fa 661 if (! sendCommandCheckAck(pn532_packetbuffer, 20))
nebgnahz 0:54bf4b21c7fa 662 {
nebgnahz 0:54bf4b21c7fa 663 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 664 SERIAL_PRINTln("Failed to receive ACK for write command");
nebgnahz 0:54bf4b21c7fa 665 #endif
nebgnahz 0:54bf4b21c7fa 666 return 0;
nebgnahz 0:54bf4b21c7fa 667 }
nebgnahz 0:54bf4b21c7fa 668 delay(10);
nebgnahz 0:54bf4b21c7fa 669
nebgnahz 0:54bf4b21c7fa 670 /* Read the response packet */
nebgnahz 0:54bf4b21c7fa 671 readspidata(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 672
nebgnahz 0:54bf4b21c7fa 673 return 1;
nebgnahz 0:54bf4b21c7fa 674 }
nebgnahz 0:54bf4b21c7fa 675
nebgnahz 0:54bf4b21c7fa 676 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 677 /*!
nebgnahz 0:54bf4b21c7fa 678 Formats a Mifare Classic card to store NDEF Records
nebgnahz 0:54bf4b21c7fa 679
nebgnahz 0:54bf4b21c7fa 680 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 681 */
nebgnahz 0:54bf4b21c7fa 682 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 683 uint8_t Adafruit_PN532::mifareclassic_FormatNDEF (void)
nebgnahz 0:54bf4b21c7fa 684 {
nebgnahz 0:54bf4b21c7fa 685 uint8_t sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
nebgnahz 0:54bf4b21c7fa 686 uint8_t sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
nebgnahz 0:54bf4b21c7fa 687 uint8_t sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
nebgnahz 0:54bf4b21c7fa 688
nebgnahz 0:54bf4b21c7fa 689 // Write block 1 and 2 to the card
nebgnahz 0:54bf4b21c7fa 690 if (!(mifareclassic_WriteDataBlock (1, sectorbuffer1)))
nebgnahz 0:54bf4b21c7fa 691 return 0;
nebgnahz 0:54bf4b21c7fa 692 if (!(mifareclassic_WriteDataBlock (2, sectorbuffer2)))
nebgnahz 0:54bf4b21c7fa 693 return 0;
nebgnahz 0:54bf4b21c7fa 694 // Write key A and access rights card
nebgnahz 0:54bf4b21c7fa 695 if (!(mifareclassic_WriteDataBlock (3, sectorbuffer3)))
nebgnahz 0:54bf4b21c7fa 696 return 0;
nebgnahz 0:54bf4b21c7fa 697
nebgnahz 0:54bf4b21c7fa 698 // Seems that everything was OK (?!)
nebgnahz 0:54bf4b21c7fa 699 return 1;
nebgnahz 0:54bf4b21c7fa 700 }
nebgnahz 0:54bf4b21c7fa 701
nebgnahz 0:54bf4b21c7fa 702 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 703 /*!
nebgnahz 0:54bf4b21c7fa 704 Writes an NDEF URI Record to the specified sector (1..15)
nebgnahz 0:54bf4b21c7fa 705
nebgnahz 0:54bf4b21c7fa 706 Note that this function assumes that the Mifare Classic card is
nebgnahz 0:54bf4b21c7fa 707 already formatted to work as an "NFC Forum Tag" and uses a MAD1
nebgnahz 0:54bf4b21c7fa 708 file system. You can use the NXP TagWriter app on Android to
nebgnahz 0:54bf4b21c7fa 709 properly format cards for this.
nebgnahz 0:54bf4b21c7fa 710
nebgnahz 0:54bf4b21c7fa 711 @param sectorNumber The sector that the URI record should be written
nebgnahz 0:54bf4b21c7fa 712 to (can be 1..15 for a 1K card)
nebgnahz 0:54bf4b21c7fa 713 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
nebgnahz 0:54bf4b21c7fa 714 "http://www.", etc.)
nebgnahz 0:54bf4b21c7fa 715 @param url The uri text to write (max 38 characters).
nebgnahz 0:54bf4b21c7fa 716
nebgnahz 0:54bf4b21c7fa 717 @returns 1 if everything executed properly, 0 for an error
nebgnahz 0:54bf4b21c7fa 718 */
nebgnahz 0:54bf4b21c7fa 719 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 720 uint8_t Adafruit_PN532::mifareclassic_WriteNDEFURI (uint8_t sectorNumber, uint8_t uriIdentifier, const char * url)
nebgnahz 0:54bf4b21c7fa 721 {
nebgnahz 0:54bf4b21c7fa 722 // Figure out how long the string is
nebgnahz 0:54bf4b21c7fa 723 uint8_t len = strlen(url);
nebgnahz 0:54bf4b21c7fa 724
nebgnahz 0:54bf4b21c7fa 725 // Make sure we're within a 1K limit for the sector number
nebgnahz 0:54bf4b21c7fa 726 if ((sectorNumber < 1) || (sectorNumber > 15))
nebgnahz 0:54bf4b21c7fa 727 return 0;
nebgnahz 0:54bf4b21c7fa 728
nebgnahz 0:54bf4b21c7fa 729 // Make sure the URI payload is between 1 and 38 chars
nebgnahz 0:54bf4b21c7fa 730 if ((len < 1) || (len > 38))
nebgnahz 0:54bf4b21c7fa 731 return 0;
nebgnahz 0:54bf4b21c7fa 732
nebgnahz 0:54bf4b21c7fa 733 // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
nebgnahz 0:54bf4b21c7fa 734 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 735 uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
nebgnahz 0:54bf4b21c7fa 736 uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
nebgnahz 0:54bf4b21c7fa 737 uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
nebgnahz 0:54bf4b21c7fa 738 if (len <= 6)
nebgnahz 0:54bf4b21c7fa 739 {
nebgnahz 0:54bf4b21c7fa 740 // Unlikely we'll get a url this short, but why not ...
nebgnahz 0:54bf4b21c7fa 741 memcpy (sectorbuffer1+9, url, len);
nebgnahz 0:54bf4b21c7fa 742 sectorbuffer1[len+9] = 0xFE;
nebgnahz 0:54bf4b21c7fa 743 }
nebgnahz 0:54bf4b21c7fa 744 else if (len == 7)
nebgnahz 0:54bf4b21c7fa 745 {
nebgnahz 0:54bf4b21c7fa 746 // 0xFE needs to be wrapped around to next block
nebgnahz 0:54bf4b21c7fa 747 memcpy (sectorbuffer1+9, url, len);
nebgnahz 0:54bf4b21c7fa 748 sectorbuffer2[0] = 0xFE;
nebgnahz 0:54bf4b21c7fa 749 }
nebgnahz 0:54bf4b21c7fa 750 else if ((len > 7) || (len <= 22))
nebgnahz 0:54bf4b21c7fa 751 {
nebgnahz 0:54bf4b21c7fa 752 // Url fits in two blocks
nebgnahz 0:54bf4b21c7fa 753 memcpy (sectorbuffer1+9, url, 7);
nebgnahz 0:54bf4b21c7fa 754 memcpy (sectorbuffer2, url+7, len-7);
nebgnahz 0:54bf4b21c7fa 755 sectorbuffer2[len-7] = 0xFE;
nebgnahz 0:54bf4b21c7fa 756 }
nebgnahz 0:54bf4b21c7fa 757 else if (len == 23)
nebgnahz 0:54bf4b21c7fa 758 {
nebgnahz 0:54bf4b21c7fa 759 // 0xFE needs to be wrapped around to final block
nebgnahz 0:54bf4b21c7fa 760 memcpy (sectorbuffer1+9, url, 7);
nebgnahz 0:54bf4b21c7fa 761 memcpy (sectorbuffer2, url+7, len-7);
nebgnahz 0:54bf4b21c7fa 762 sectorbuffer3[0] = 0xFE;
nebgnahz 0:54bf4b21c7fa 763 }
nebgnahz 0:54bf4b21c7fa 764 else
nebgnahz 0:54bf4b21c7fa 765 {
nebgnahz 0:54bf4b21c7fa 766 // Url fits in three blocks
nebgnahz 0:54bf4b21c7fa 767 memcpy (sectorbuffer1+9, url, 7);
nebgnahz 0:54bf4b21c7fa 768 memcpy (sectorbuffer2, url+7, 16);
nebgnahz 0:54bf4b21c7fa 769 memcpy (sectorbuffer3, url+23, len-24);
nebgnahz 0:54bf4b21c7fa 770 sectorbuffer3[len-22] = 0xFE;
nebgnahz 0:54bf4b21c7fa 771 }
nebgnahz 0:54bf4b21c7fa 772
nebgnahz 0:54bf4b21c7fa 773 // Now write all three blocks back to the card
nebgnahz 0:54bf4b21c7fa 774 if (!(mifareclassic_WriteDataBlock (sectorNumber*4, sectorbuffer1)))
nebgnahz 0:54bf4b21c7fa 775 return 0;
nebgnahz 0:54bf4b21c7fa 776 if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+1, sectorbuffer2)))
nebgnahz 0:54bf4b21c7fa 777 return 0;
nebgnahz 0:54bf4b21c7fa 778 if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+2, sectorbuffer3)))
nebgnahz 0:54bf4b21c7fa 779 return 0;
nebgnahz 0:54bf4b21c7fa 780 if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+3, sectorbuffer4)))
nebgnahz 0:54bf4b21c7fa 781 return 0;
nebgnahz 0:54bf4b21c7fa 782
nebgnahz 0:54bf4b21c7fa 783 // Seems that everything was OK (?!)
nebgnahz 0:54bf4b21c7fa 784 return 1;
nebgnahz 0:54bf4b21c7fa 785 }
nebgnahz 0:54bf4b21c7fa 786
nebgnahz 0:54bf4b21c7fa 787 /***** Mifare Ultralight Functions ******/
nebgnahz 0:54bf4b21c7fa 788
nebgnahz 0:54bf4b21c7fa 789 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 790 /*!
nebgnahz 0:54bf4b21c7fa 791 Tries to read an entire 4-uint8_t page at the specified address.
nebgnahz 0:54bf4b21c7fa 792
nebgnahz 0:54bf4b21c7fa 793 @param page The page number (0..63 in most cases)
nebgnahz 0:54bf4b21c7fa 794 @param buffer Pointer to the uint8_t array that will hold the
nebgnahz 0:54bf4b21c7fa 795 retrieved data (if any)
nebgnahz 0:54bf4b21c7fa 796 */
nebgnahz 0:54bf4b21c7fa 797 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 798 uint8_t Adafruit_PN532::mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
nebgnahz 0:54bf4b21c7fa 799 {
nebgnahz 0:54bf4b21c7fa 800 if (page >= 64)
nebgnahz 0:54bf4b21c7fa 801 {
nebgnahz 0:54bf4b21c7fa 802 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 803 SERIAL_PRINTln("Page value out of range");
nebgnahz 0:54bf4b21c7fa 804 #endif
nebgnahz 0:54bf4b21c7fa 805 return 0;
nebgnahz 0:54bf4b21c7fa 806 }
nebgnahz 0:54bf4b21c7fa 807
nebgnahz 0:54bf4b21c7fa 808 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 809 SERIAL_PRINT("Reading page ");SERIAL_PRINTln(page);
nebgnahz 0:54bf4b21c7fa 810 #endif
nebgnahz 0:54bf4b21c7fa 811
nebgnahz 0:54bf4b21c7fa 812 /* Prepare the command */
nebgnahz 0:54bf4b21c7fa 813 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nebgnahz 0:54bf4b21c7fa 814 pn532_packetbuffer[1] = 1; /* Card number */
nebgnahz 0:54bf4b21c7fa 815 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
nebgnahz 0:54bf4b21c7fa 816 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
nebgnahz 0:54bf4b21c7fa 817
nebgnahz 0:54bf4b21c7fa 818 /* Send the command */
nebgnahz 0:54bf4b21c7fa 819 if (! sendCommandCheckAck(pn532_packetbuffer, 4))
nebgnahz 0:54bf4b21c7fa 820 {
nebgnahz 0:54bf4b21c7fa 821 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 822 SERIAL_PRINTln("Failed to receive ACK for write command");
nebgnahz 0:54bf4b21c7fa 823 #endif
nebgnahz 0:54bf4b21c7fa 824 return 0;
nebgnahz 0:54bf4b21c7fa 825 }
nebgnahz 0:54bf4b21c7fa 826
nebgnahz 0:54bf4b21c7fa 827 /* Read the response packet */
nebgnahz 0:54bf4b21c7fa 828 readspidata(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 829 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 830 SERIAL_PRINTln("Received: ");
nebgnahz 0:54bf4b21c7fa 831 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 832 #endif
nebgnahz 0:54bf4b21c7fa 833
nebgnahz 0:54bf4b21c7fa 834 /* If uint8_t 8 isn't 0x00 we probably have an error */
nebgnahz 0:54bf4b21c7fa 835 if (pn532_packetbuffer[7] == 0x00)
nebgnahz 0:54bf4b21c7fa 836 {
nebgnahz 0:54bf4b21c7fa 837 /* Copy the 4 data uint8_ts to the output buffer */
nebgnahz 0:54bf4b21c7fa 838 /* Block content starts at uint8_t 9 of a valid response */
nebgnahz 0:54bf4b21c7fa 839 /* Note that the command actually reads 16 uint8_t or 4 */
nebgnahz 0:54bf4b21c7fa 840 /* pages at a time ... we simply discard the last 12 */
nebgnahz 0:54bf4b21c7fa 841 /* uint8_ts */
nebgnahz 0:54bf4b21c7fa 842 memcpy (buffer, pn532_packetbuffer+8, 4);
nebgnahz 0:54bf4b21c7fa 843 }
nebgnahz 0:54bf4b21c7fa 844 else
nebgnahz 0:54bf4b21c7fa 845 {
nebgnahz 0:54bf4b21c7fa 846 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 847 SERIAL_PRINTln("Unexpected response reading block: ");
nebgnahz 0:54bf4b21c7fa 848 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
nebgnahz 0:54bf4b21c7fa 849 #endif
nebgnahz 0:54bf4b21c7fa 850 return 0;
nebgnahz 0:54bf4b21c7fa 851 }
nebgnahz 0:54bf4b21c7fa 852
nebgnahz 0:54bf4b21c7fa 853 /* Display data for debug if requested */
nebgnahz 0:54bf4b21c7fa 854 #ifdef MIFAREDEBUG
nebgnahz 0:54bf4b21c7fa 855 SERIAL_PRINT("Page ");SERIAL_PRINT(page);SERIAL_PRINTln(":");
nebgnahz 0:54bf4b21c7fa 856 Adafruit_PN532::PrintHexChar(buffer, 4);
nebgnahz 0:54bf4b21c7fa 857 #endif
nebgnahz 0:54bf4b21c7fa 858
nebgnahz 0:54bf4b21c7fa 859 // Return OK signal
nebgnahz 0:54bf4b21c7fa 860 return 1;
nebgnahz 0:54bf4b21c7fa 861 }
nebgnahz 0:54bf4b21c7fa 862
nebgnahz 0:54bf4b21c7fa 863
nebgnahz 0:54bf4b21c7fa 864
nebgnahz 0:54bf4b21c7fa 865 /************** high level SPI */
nebgnahz 0:54bf4b21c7fa 866
nebgnahz 0:54bf4b21c7fa 867
nebgnahz 0:54bf4b21c7fa 868 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 869 /*!
nebgnahz 0:54bf4b21c7fa 870 @brief Tries to read the SPI ACK signal
nebgnahz 0:54bf4b21c7fa 871 */
nebgnahz 0:54bf4b21c7fa 872 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 873 bool Adafruit_PN532::spi_readack() {
nebgnahz 0:54bf4b21c7fa 874 uint8_t ackbuff[6];
nebgnahz 0:54bf4b21c7fa 875
nebgnahz 0:54bf4b21c7fa 876 readspidata(ackbuff, 6);
nebgnahz 0:54bf4b21c7fa 877
nebgnahz 0:54bf4b21c7fa 878 return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
nebgnahz 0:54bf4b21c7fa 879 }
nebgnahz 0:54bf4b21c7fa 880
nebgnahz 0:54bf4b21c7fa 881 /************** mid level SPI */
nebgnahz 0:54bf4b21c7fa 882
nebgnahz 0:54bf4b21c7fa 883 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 884 /*!
nebgnahz 0:54bf4b21c7fa 885 @brief Reads the SPI status register (to know if the PN532 is ready)
nebgnahz 0:54bf4b21c7fa 886 */
nebgnahz 0:54bf4b21c7fa 887 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 888 uint8_t Adafruit_PN532::readspistatus(void) {
nebgnahz 0:54bf4b21c7fa 889 _ss = 0;
nebgnahz 0:54bf4b21c7fa 890 delay(2);
nebgnahz 0:54bf4b21c7fa 891 spiwrite(PN532_SPI_STATREAD);
nebgnahz 0:54bf4b21c7fa 892 // read uint8_t
nebgnahz 0:54bf4b21c7fa 893 uint8_t x = spiread();
nebgnahz 0:54bf4b21c7fa 894
nebgnahz 0:54bf4b21c7fa 895 _ss = 1;
nebgnahz 0:54bf4b21c7fa 896 return x;
nebgnahz 0:54bf4b21c7fa 897 }
nebgnahz 0:54bf4b21c7fa 898
nebgnahz 0:54bf4b21c7fa 899 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 900 /*!
nebgnahz 0:54bf4b21c7fa 901 @brief Reads n uint8_ts of data from the PN532 via SPI
nebgnahz 0:54bf4b21c7fa 902
nebgnahz 0:54bf4b21c7fa 903 @param buff Pointer to the buffer where data will be written
nebgnahz 0:54bf4b21c7fa 904 @param n Number of uint8_ts to be read
nebgnahz 0:54bf4b21c7fa 905 */
nebgnahz 0:54bf4b21c7fa 906 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 907 void Adafruit_PN532::readspidata(uint8_t* buff, uint8_t n) {
nebgnahz 0:54bf4b21c7fa 908 _ss = 0;
nebgnahz 0:54bf4b21c7fa 909 delay(2);
nebgnahz 0:54bf4b21c7fa 910 spiwrite(PN532_SPI_DATAREAD);
nebgnahz 0:54bf4b21c7fa 911
nebgnahz 0:54bf4b21c7fa 912 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 913 SERIAL_PRINT("Reading: ");
nebgnahz 0:54bf4b21c7fa 914 #endif
nebgnahz 0:54bf4b21c7fa 915 for (uint8_t i=0; i<n; i++) {
nebgnahz 0:54bf4b21c7fa 916 delay(1);
nebgnahz 0:54bf4b21c7fa 917 buff[i] = spiread();
nebgnahz 0:54bf4b21c7fa 918 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 919 SERIAL_PRINT(" 0x");
nebgnahz 0:54bf4b21c7fa 920 SERIAL_PRINT(buff[i], HEX);
nebgnahz 0:54bf4b21c7fa 921 #endif
nebgnahz 0:54bf4b21c7fa 922 }
nebgnahz 0:54bf4b21c7fa 923
nebgnahz 0:54bf4b21c7fa 924 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 925 SERIAL_PRINTln();
nebgnahz 0:54bf4b21c7fa 926 #endif
nebgnahz 0:54bf4b21c7fa 927
nebgnahz 0:54bf4b21c7fa 928 _ss = 1;
nebgnahz 0:54bf4b21c7fa 929 }
nebgnahz 0:54bf4b21c7fa 930
nebgnahz 0:54bf4b21c7fa 931 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 932 /*!
nebgnahz 0:54bf4b21c7fa 933 @brief Writes a command to the PN532, automatically inserting the
nebgnahz 0:54bf4b21c7fa 934 preamble and required frame details (checksum, len, etc.)
nebgnahz 0:54bf4b21c7fa 935
nebgnahz 0:54bf4b21c7fa 936 @param cmd Pointer to the command buffer
nebgnahz 0:54bf4b21c7fa 937 @param cmdlen Command length in uint8_ts
nebgnahz 0:54bf4b21c7fa 938 */
nebgnahz 0:54bf4b21c7fa 939 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 940 void Adafruit_PN532::spiwritecommand(uint8_t* cmd, uint8_t cmdlen) {
nebgnahz 0:54bf4b21c7fa 941 uint8_t checksum;
nebgnahz 0:54bf4b21c7fa 942
nebgnahz 0:54bf4b21c7fa 943 cmdlen++;
nebgnahz 0:54bf4b21c7fa 944
nebgnahz 0:54bf4b21c7fa 945 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 946 SERIAL_PRINT("\nSending: ");
nebgnahz 0:54bf4b21c7fa 947 #endif
nebgnahz 0:54bf4b21c7fa 948
nebgnahz 0:54bf4b21c7fa 949 _ss = 0;
nebgnahz 0:54bf4b21c7fa 950 delay(2); // or whatever the delay is for waking up the board
nebgnahz 0:54bf4b21c7fa 951 spiwrite(PN532_SPI_DATAWRITE);
nebgnahz 0:54bf4b21c7fa 952
nebgnahz 0:54bf4b21c7fa 953 checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2;
nebgnahz 0:54bf4b21c7fa 954 spiwrite(PN532_PREAMBLE);
nebgnahz 0:54bf4b21c7fa 955 spiwrite(PN532_PREAMBLE);
nebgnahz 0:54bf4b21c7fa 956 spiwrite(PN532_STARTCODE2);
nebgnahz 0:54bf4b21c7fa 957
nebgnahz 0:54bf4b21c7fa 958 spiwrite(cmdlen);
nebgnahz 0:54bf4b21c7fa 959 spiwrite(~cmdlen + 1);
nebgnahz 0:54bf4b21c7fa 960
nebgnahz 0:54bf4b21c7fa 961 spiwrite(PN532_HOSTTOPN532);
nebgnahz 0:54bf4b21c7fa 962 checksum += PN532_HOSTTOPN532;
nebgnahz 0:54bf4b21c7fa 963
nebgnahz 0:54bf4b21c7fa 964 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 965 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_PREAMBLE, HEX);
nebgnahz 0:54bf4b21c7fa 966 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_PREAMBLE, HEX);
nebgnahz 0:54bf4b21c7fa 967 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_STARTCODE2, HEX);
nebgnahz 0:54bf4b21c7fa 968 SERIAL_PRINT(" 0x"); SERIAL_PRINT(cmdlen, HEX);
nebgnahz 0:54bf4b21c7fa 969 SERIAL_PRINT(" 0x"); SERIAL_PRINT(~cmdlen + 1, HEX);
nebgnahz 0:54bf4b21c7fa 970 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_HOSTTOPN532, HEX);
nebgnahz 0:54bf4b21c7fa 971 #endif
nebgnahz 0:54bf4b21c7fa 972
nebgnahz 0:54bf4b21c7fa 973 for (uint8_t i=0; i<cmdlen-1; i++) {
nebgnahz 0:54bf4b21c7fa 974 spiwrite(cmd[i]);
nebgnahz 0:54bf4b21c7fa 975 checksum += cmd[i];
nebgnahz 0:54bf4b21c7fa 976 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 977 SERIAL_PRINT(" 0x"); SERIAL_PRINT(cmd[i], HEX);
nebgnahz 0:54bf4b21c7fa 978 #endif
nebgnahz 0:54bf4b21c7fa 979 }
nebgnahz 0:54bf4b21c7fa 980
nebgnahz 0:54bf4b21c7fa 981 spiwrite(~checksum);
nebgnahz 0:54bf4b21c7fa 982 spiwrite(PN532_POSTAMBLE);
nebgnahz 0:54bf4b21c7fa 983 _ss = 1;
nebgnahz 0:54bf4b21c7fa 984
nebgnahz 0:54bf4b21c7fa 985 #ifdef PN532DEBUG
nebgnahz 0:54bf4b21c7fa 986 SERIAL_PRINT(" 0x"); SERIAL_PRINT(~checksum, HEX);
nebgnahz 0:54bf4b21c7fa 987 SERIAL_PRINT(" 0x"); SERIAL_PRINT(PN532_POSTAMBLE, HEX);
nebgnahz 0:54bf4b21c7fa 988 SERIAL_PRINTln();
nebgnahz 0:54bf4b21c7fa 989 #endif
nebgnahz 0:54bf4b21c7fa 990 }
nebgnahz 0:54bf4b21c7fa 991 /************** low level SPI */
nebgnahz 0:54bf4b21c7fa 992
nebgnahz 0:54bf4b21c7fa 993 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 994 /*!
nebgnahz 0:54bf4b21c7fa 995 @brief Low-level SPI write wrapper
nebgnahz 0:54bf4b21c7fa 996
nebgnahz 0:54bf4b21c7fa 997 @param c 8-bit command to write to the SPI bus
nebgnahz 0:54bf4b21c7fa 998 */
nebgnahz 0:54bf4b21c7fa 999 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 1000 void Adafruit_PN532::spiwrite(uint8_t c) {
nebgnahz 0:54bf4b21c7fa 1001 int8_t i;
nebgnahz 0:54bf4b21c7fa 1002 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1003
nebgnahz 0:54bf4b21c7fa 1004 for (i=0; i<8; i++) {
nebgnahz 0:54bf4b21c7fa 1005 _clk = 0;
nebgnahz 0:54bf4b21c7fa 1006 if (c & _BV(i)) {
nebgnahz 0:54bf4b21c7fa 1007 _mosi = 1;
nebgnahz 0:54bf4b21c7fa 1008 } else {
nebgnahz 0:54bf4b21c7fa 1009 _mosi = 0;
nebgnahz 0:54bf4b21c7fa 1010 }
nebgnahz 0:54bf4b21c7fa 1011 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1012 }
nebgnahz 0:54bf4b21c7fa 1013 }
nebgnahz 0:54bf4b21c7fa 1014
nebgnahz 0:54bf4b21c7fa 1015 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 1016 /*!
nebgnahz 0:54bf4b21c7fa 1017 @brief Low-level SPI read wrapper
nebgnahz 0:54bf4b21c7fa 1018
nebgnahz 0:54bf4b21c7fa 1019 @returns The 8-bit value that was read from the SPI bus
nebgnahz 0:54bf4b21c7fa 1020 */
nebgnahz 0:54bf4b21c7fa 1021 /**************************************************************************/
nebgnahz 0:54bf4b21c7fa 1022 uint8_t Adafruit_PN532::spiread(void) {
nebgnahz 0:54bf4b21c7fa 1023 int8_t i, x;
nebgnahz 0:54bf4b21c7fa 1024 x = 0;
nebgnahz 0:54bf4b21c7fa 1025 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1026
nebgnahz 0:54bf4b21c7fa 1027 for (i=0; i<8; i++) {
nebgnahz 0:54bf4b21c7fa 1028 if (_miso.read()) {
nebgnahz 0:54bf4b21c7fa 1029 x |= _BV(i);
nebgnahz 0:54bf4b21c7fa 1030 }
nebgnahz 0:54bf4b21c7fa 1031 _clk = 0;
nebgnahz 0:54bf4b21c7fa 1032 _clk = 1;
nebgnahz 0:54bf4b21c7fa 1033 }
nebgnahz 0:54bf4b21c7fa 1034 return x;
nebgnahz 0:54bf4b21c7fa 1035 }