Test example

Dependencies:   mbed

Fork of readMifare by Interactive Device Design

Committer:
mjovanov1
Date:
Thu Mar 17 10:37:47 2016 +0000
Revision:
11:5e52e43e2977
Parent:
8:cd4d5da8efdf
Chained read;

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