PN532

Dependents:   PN532_GPIO PN532_ReadUid EX_encoder_PID_QianYuyangV4

Fork of LibPN532 by dotnfc Tang

Committer:
zhangyx
Date:
Mon Jan 15 17:12:41 2018 +0000
Revision:
3:685e0bf1409d
Parent:
2:d8e57d5776b3
disable debug message

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dotnfc 0:db8030e71f55 1 /**************************************************************************/
dotnfc 0:db8030e71f55 2 /*!
dotnfc 0:db8030e71f55 3 @file PN532.cpp
dotnfc 0:db8030e71f55 4 @author Adafruit Industries & Seeed Studio
dotnfc 0:db8030e71f55 5 @license BSD
dotnfc 0:db8030e71f55 6 */
dotnfc 0:db8030e71f55 7 /**************************************************************************/
dotnfc 0:db8030e71f55 8
dotnfc 0:db8030e71f55 9 #include "Arduino.h"
dotnfc 0:db8030e71f55 10 #include "PN532.h"
dotnfc 0:db8030e71f55 11 #include "PN532_debug.h"
dotnfc 0:db8030e71f55 12 #include <string.h>
dotnfc 0:db8030e71f55 13
dotnfc 0:db8030e71f55 14 #define HAL(func) (_interface->func)
dotnfc 0:db8030e71f55 15
dotnfc 0:db8030e71f55 16 PN532::PN532(PN532Interface &interface)
dotnfc 0:db8030e71f55 17 {
dotnfc 0:db8030e71f55 18 _interface = &interface;
dotnfc 0:db8030e71f55 19 }
dotnfc 0:db8030e71f55 20
dotnfc 0:db8030e71f55 21 /**************************************************************************/
dotnfc 0:db8030e71f55 22 /*!
dotnfc 0:db8030e71f55 23 @brief Setups the HW
dotnfc 0:db8030e71f55 24 */
dotnfc 0:db8030e71f55 25 /**************************************************************************/
dotnfc 0:db8030e71f55 26 void PN532::begin()
dotnfc 0:db8030e71f55 27 {
dotnfc 0:db8030e71f55 28 HAL(begin)();
dotnfc 0:db8030e71f55 29 HAL(wakeup)();
dotnfc 0:db8030e71f55 30 }
dotnfc 0:db8030e71f55 31
dotnfc 0:db8030e71f55 32 /**************************************************************************/
dotnfc 0:db8030e71f55 33 /*!
dotnfc 0:db8030e71f55 34 @brief Prints a hexadecimal value in plain characters
dotnfc 0:db8030e71f55 35
dotnfc 0:db8030e71f55 36 @param data Pointer to the uint8_t data
dotnfc 0:db8030e71f55 37 @param numBytes Data length in bytes
dotnfc 0:db8030e71f55 38 */
dotnfc 0:db8030e71f55 39 /**************************************************************************/
dotnfc 0:db8030e71f55 40 void PN532::PrintHex(const uint8_t *data, const uint32_t numBytes)
dotnfc 0:db8030e71f55 41 {
dotnfc 0:db8030e71f55 42 #ifdef ARDUINO
dotnfc 0:db8030e71f55 43 for (uint8_t i = 0; i < numBytes; i++) {
dotnfc 0:db8030e71f55 44 if (data[i] < 0x10) {
dotnfc 0:db8030e71f55 45 Serial.print(" 0");
dotnfc 0:db8030e71f55 46 } else {
dotnfc 0:db8030e71f55 47 Serial.print(' ');
dotnfc 0:db8030e71f55 48 }
dotnfc 0:db8030e71f55 49 Serial.print(data[i], HEX);
dotnfc 0:db8030e71f55 50 }
dotnfc 0:db8030e71f55 51 Serial.println("");
dotnfc 0:db8030e71f55 52 #else
dotnfc 0:db8030e71f55 53 for (uint8_t i = 0; i < numBytes; i++) {
dotnfc 0:db8030e71f55 54 printf(" %2X", data[i]);
dotnfc 0:db8030e71f55 55 }
dotnfc 0:db8030e71f55 56 printf("\n");
dotnfc 0:db8030e71f55 57 #endif
dotnfc 0:db8030e71f55 58 }
dotnfc 0:db8030e71f55 59
dotnfc 0:db8030e71f55 60 /**************************************************************************/
dotnfc 0:db8030e71f55 61 /*!
dotnfc 0:db8030e71f55 62 @brief Prints a hexadecimal value in plain characters, along with
dotnfc 0:db8030e71f55 63 the char equivalents in the following format
dotnfc 0:db8030e71f55 64
dotnfc 0:db8030e71f55 65 00 00 00 00 00 00 ......
dotnfc 0:db8030e71f55 66
dotnfc 0:db8030e71f55 67 @param data Pointer to the data
dotnfc 0:db8030e71f55 68 @param numBytes Data length in bytes
dotnfc 0:db8030e71f55 69 */
dotnfc 0:db8030e71f55 70 /**************************************************************************/
dotnfc 0:db8030e71f55 71 void PN532::PrintHexChar(const uint8_t *data, const uint32_t numBytes)
dotnfc 0:db8030e71f55 72 {
dotnfc 0:db8030e71f55 73 #ifdef ARDUINO
dotnfc 0:db8030e71f55 74 for (uint8_t i = 0; i < numBytes; i++) {
dotnfc 0:db8030e71f55 75 if (data[i] < 0x10) {
dotnfc 0:db8030e71f55 76 Serial.print(" 0");
dotnfc 0:db8030e71f55 77 } else {
dotnfc 0:db8030e71f55 78 Serial.print(' ');
dotnfc 0:db8030e71f55 79 }
dotnfc 0:db8030e71f55 80 Serial.print(data[i], HEX);
dotnfc 0:db8030e71f55 81 }
dotnfc 0:db8030e71f55 82 Serial.print(" ");
dotnfc 0:db8030e71f55 83 for (uint8_t i = 0; i < numBytes; i++) {
dotnfc 0:db8030e71f55 84 char c = data[i];
dotnfc 0:db8030e71f55 85 if (c <= 0x1f || c > 0x7f) {
dotnfc 0:db8030e71f55 86 Serial.print('.');
dotnfc 0:db8030e71f55 87 } else {
dotnfc 0:db8030e71f55 88 Serial.print(c);
dotnfc 0:db8030e71f55 89 }
dotnfc 0:db8030e71f55 90 }
dotnfc 0:db8030e71f55 91 Serial.println("");
dotnfc 0:db8030e71f55 92 #else
dotnfc 0:db8030e71f55 93 for (uint8_t i = 0; i < numBytes; i++) {
dotnfc 0:db8030e71f55 94 printf(" %2X", data[i]);
dotnfc 0:db8030e71f55 95 }
dotnfc 0:db8030e71f55 96 printf(" ");
dotnfc 0:db8030e71f55 97 for (uint8_t i = 0; i < numBytes; i++) {
dotnfc 0:db8030e71f55 98 char c = data[i];
dotnfc 0:db8030e71f55 99 if (c <= 0x1f || c > 0x7f) {
dotnfc 0:db8030e71f55 100 printf(".");
dotnfc 0:db8030e71f55 101 } else {
dotnfc 0:db8030e71f55 102 printf("%c", c);
dotnfc 0:db8030e71f55 103 }
dotnfc 0:db8030e71f55 104 printf("\n");
dotnfc 0:db8030e71f55 105 }
dotnfc 0:db8030e71f55 106 #endif
dotnfc 0:db8030e71f55 107 }
dotnfc 0:db8030e71f55 108
dotnfc 0:db8030e71f55 109 /**************************************************************************/
dotnfc 0:db8030e71f55 110 /*!
dotnfc 0:db8030e71f55 111 @brief Checks the firmware version of the PN5xx chip
dotnfc 0:db8030e71f55 112
dotnfc 0:db8030e71f55 113 @returns The chip's firmware version and ID
dotnfc 0:db8030e71f55 114 */
dotnfc 0:db8030e71f55 115 /**************************************************************************/
dotnfc 0:db8030e71f55 116 uint32_t PN532::getFirmwareVersion(void)
dotnfc 0:db8030e71f55 117 {
dotnfc 0:db8030e71f55 118 uint32_t response;
dotnfc 0:db8030e71f55 119
dotnfc 0:db8030e71f55 120 pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
dotnfc 0:db8030e71f55 121
dotnfc 0:db8030e71f55 122 if (HAL(writeCommand)(pn532_packetbuffer, 1)) {
dotnfc 0:db8030e71f55 123 return 0;
dotnfc 0:db8030e71f55 124 }
dotnfc 0:db8030e71f55 125
dotnfc 0:db8030e71f55 126 // read data packet
dotnfc 0:db8030e71f55 127 int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
dotnfc 0:db8030e71f55 128 if (0 > status) {
dotnfc 0:db8030e71f55 129 return 0;
dotnfc 0:db8030e71f55 130 }
dotnfc 0:db8030e71f55 131
dotnfc 0:db8030e71f55 132 response = pn532_packetbuffer[0];
dotnfc 0:db8030e71f55 133 response <<= 8;
dotnfc 0:db8030e71f55 134 response |= pn532_packetbuffer[1];
dotnfc 0:db8030e71f55 135 response <<= 8;
dotnfc 0:db8030e71f55 136 response |= pn532_packetbuffer[2];
dotnfc 0:db8030e71f55 137 response <<= 8;
dotnfc 0:db8030e71f55 138 response |= pn532_packetbuffer[3];
dotnfc 0:db8030e71f55 139
dotnfc 0:db8030e71f55 140 return response;
dotnfc 0:db8030e71f55 141 }
dotnfc 0:db8030e71f55 142
dotnfc 0:db8030e71f55 143
dotnfc 0:db8030e71f55 144 /**************************************************************************/
dotnfc 0:db8030e71f55 145 /*!
dotnfc 0:db8030e71f55 146 Writes an 8-bit value that sets the state of the PN532's GPIO pins
dotnfc 0:db8030e71f55 147
dotnfc 0:db8030e71f55 148 @warning This function is provided exclusively for board testing and
dotnfc 0:db8030e71f55 149 is dangerous since it will throw an error if any pin other
dotnfc 0:db8030e71f55 150 than the ones marked "Can be used as GPIO" are modified! All
dotnfc 0:db8030e71f55 151 pins that can not be used as GPIO should ALWAYS be left high
dotnfc 0:db8030e71f55 152 (value = 1) or the system will become unstable and a HW reset
dotnfc 0:db8030e71f55 153 will be required to recover the PN532.
dotnfc 0:db8030e71f55 154
dotnfc 0:db8030e71f55 155 pinState[0] = P30 Can be used as GPIO
dotnfc 0:db8030e71f55 156 pinState[1] = P31 Can be used as GPIO
dotnfc 0:db8030e71f55 157 pinState[2] = P32 *** RESERVED (Must be 1!) ***
dotnfc 0:db8030e71f55 158 pinState[3] = P33 Can be used as GPIO
dotnfc 0:db8030e71f55 159 pinState[4] = P34 *** RESERVED (Must be 1!) ***
dotnfc 0:db8030e71f55 160 pinState[5] = P35 Can be used as GPIO
dotnfc 0:db8030e71f55 161
dotnfc 0:db8030e71f55 162 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 163 */
dotnfc 0:db8030e71f55 164 /**************************************************************************/
zhangyx 2:d8e57d5776b3 165 bool PN532::writeGPIOP3(uint8_t pinstate)
dotnfc 0:db8030e71f55 166 {
dotnfc 0:db8030e71f55 167 // Make sure pinstate does not try to toggle P32 or P34
dotnfc 0:db8030e71f55 168 pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
dotnfc 0:db8030e71f55 169
dotnfc 0:db8030e71f55 170 // Fill command buffer
dotnfc 0:db8030e71f55 171 pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
dotnfc 0:db8030e71f55 172 pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins
dotnfc 0:db8030e71f55 173 pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by I2C)
dotnfc 0:db8030e71f55 174
dotnfc 0:db8030e71f55 175 DMSG("Writing P3 GPIO: ");
dotnfc 0:db8030e71f55 176 DMSG_HEX(pn532_packetbuffer[1]);
dotnfc 0:db8030e71f55 177 DMSG("\n");
dotnfc 0:db8030e71f55 178
dotnfc 0:db8030e71f55 179 // Send the WRITEGPIO command (0x0E)
dotnfc 0:db8030e71f55 180 if (HAL(writeCommand)(pn532_packetbuffer, 3))
dotnfc 0:db8030e71f55 181 return 0;
dotnfc 0:db8030e71f55 182
dotnfc 0:db8030e71f55 183 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
dotnfc 0:db8030e71f55 184 }
dotnfc 0:db8030e71f55 185
zhangyx 2:d8e57d5776b3 186 bool PN532::writeGPIOP7(uint8_t pinstate)
zhangyx 2:d8e57d5776b3 187 {
zhangyx 2:d8e57d5776b3 188 pinstate &= (1 << PN532_GPIO_P70) | (1 << PN532_GPIO_P71) | (1 << PN532_GPIO_P72);
zhangyx 2:d8e57d5776b3 189
zhangyx 2:d8e57d5776b3 190 // Fill command buffer
zhangyx 2:d8e57d5776b3 191 pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
zhangyx 2:d8e57d5776b3 192 pn532_packetbuffer[1] = 0x00; // P3 Pins are not changed
zhangyx 2:d8e57d5776b3 193 pn532_packetbuffer[2] = PN532_GPIO_VALIDATIONBIT | pinstate; // P7 Pins
zhangyx 2:d8e57d5776b3 194
zhangyx 2:d8e57d5776b3 195 DMSG("Writing P7 GPIO: ");
zhangyx 2:d8e57d5776b3 196 DMSG_HEX(pn532_packetbuffer[1]);
zhangyx 2:d8e57d5776b3 197 DMSG("\n");
zhangyx 2:d8e57d5776b3 198
zhangyx 2:d8e57d5776b3 199 // Send the WRITEGPIO command (0x0E)
zhangyx 2:d8e57d5776b3 200 if (HAL(writeCommand)(pn532_packetbuffer, 3))
zhangyx 2:d8e57d5776b3 201 return 0;
zhangyx 2:d8e57d5776b3 202
zhangyx 2:d8e57d5776b3 203 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
zhangyx 2:d8e57d5776b3 204 }
zhangyx 2:d8e57d5776b3 205
dotnfc 0:db8030e71f55 206 /**************************************************************************/
dotnfc 0:db8030e71f55 207 /*!
dotnfc 0:db8030e71f55 208 Reads the state of the PN532's GPIO pins
dotnfc 0:db8030e71f55 209
dotnfc 0:db8030e71f55 210 @returns An 8-bit value containing the pin state where:
dotnfc 0:db8030e71f55 211
dotnfc 0:db8030e71f55 212 pinState[0] = P30
dotnfc 0:db8030e71f55 213 pinState[1] = P31
dotnfc 0:db8030e71f55 214 pinState[2] = P32
dotnfc 0:db8030e71f55 215 pinState[3] = P33
dotnfc 0:db8030e71f55 216 pinState[4] = P34
dotnfc 0:db8030e71f55 217 pinState[5] = P35
dotnfc 0:db8030e71f55 218 */
dotnfc 0:db8030e71f55 219 /**************************************************************************/
dotnfc 0:db8030e71f55 220 uint8_t PN532::readGPIO(void)
dotnfc 0:db8030e71f55 221 {
dotnfc 0:db8030e71f55 222 pn532_packetbuffer[0] = PN532_COMMAND_READGPIO;
dotnfc 0:db8030e71f55 223
dotnfc 0:db8030e71f55 224 // Send the READGPIO command (0x0C)
dotnfc 0:db8030e71f55 225 if (HAL(writeCommand)(pn532_packetbuffer, 1))
dotnfc 0:db8030e71f55 226 return 0x0;
dotnfc 0:db8030e71f55 227
dotnfc 0:db8030e71f55 228 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
dotnfc 0:db8030e71f55 229
dotnfc 0:db8030e71f55 230 /* READGPIO response without prefix and suffix should be in the following format:
dotnfc 0:db8030e71f55 231
dotnfc 0:db8030e71f55 232 byte Description
dotnfc 0:db8030e71f55 233 ------------- ------------------------------------------
dotnfc 0:db8030e71f55 234 b0 P3 GPIO Pins
dotnfc 0:db8030e71f55 235 b1 P7 GPIO Pins (not used ... taken by I2C)
dotnfc 0:db8030e71f55 236 b2 Interface Mode Pins (not used ... bus select pins)
dotnfc 0:db8030e71f55 237 */
dotnfc 0:db8030e71f55 238
dotnfc 0:db8030e71f55 239
dotnfc 0:db8030e71f55 240 DMSG("P3 GPIO: "); DMSG_HEX(pn532_packetbuffer[7]);
dotnfc 0:db8030e71f55 241 DMSG("P7 GPIO: "); DMSG_HEX(pn532_packetbuffer[8]);
dotnfc 0:db8030e71f55 242 DMSG("I0I1 GPIO: "); DMSG_HEX(pn532_packetbuffer[9]);
dotnfc 0:db8030e71f55 243 DMSG("\n");
dotnfc 0:db8030e71f55 244
dotnfc 0:db8030e71f55 245 return pn532_packetbuffer[0];
dotnfc 0:db8030e71f55 246 }
dotnfc 0:db8030e71f55 247
dotnfc 0:db8030e71f55 248 /**************************************************************************/
dotnfc 0:db8030e71f55 249 /*!
dotnfc 0:db8030e71f55 250 @brief Configures the SAM (Secure Access Module)
dotnfc 0:db8030e71f55 251 */
dotnfc 0:db8030e71f55 252 /**************************************************************************/
dotnfc 0:db8030e71f55 253 bool PN532::SAMConfig(void)
dotnfc 0:db8030e71f55 254 {
dotnfc 0:db8030e71f55 255 pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
dotnfc 0:db8030e71f55 256 pn532_packetbuffer[1] = 0x01; // normal mode;
dotnfc 0:db8030e71f55 257 pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
dotnfc 0:db8030e71f55 258 pn532_packetbuffer[3] = 0x01; // use IRQ pin!
dotnfc 0:db8030e71f55 259
dotnfc 0:db8030e71f55 260 DMSG("SAMConfig\n");
dotnfc 0:db8030e71f55 261
dotnfc 0:db8030e71f55 262 if (HAL(writeCommand)(pn532_packetbuffer, 4))
dotnfc 0:db8030e71f55 263 return false;
dotnfc 0:db8030e71f55 264
dotnfc 0:db8030e71f55 265 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
dotnfc 0:db8030e71f55 266 }
dotnfc 0:db8030e71f55 267
dotnfc 0:db8030e71f55 268 /**************************************************************************/
dotnfc 0:db8030e71f55 269 /*!
dotnfc 0:db8030e71f55 270 Sets the MxRtyPassiveActivation uint8_t of the RFConfiguration register
dotnfc 0:db8030e71f55 271
dotnfc 0:db8030e71f55 272 @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout
dotnfc 0:db8030e71f55 273 after mxRetries
dotnfc 0:db8030e71f55 274
dotnfc 0:db8030e71f55 275 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 276 */
dotnfc 0:db8030e71f55 277 /**************************************************************************/
dotnfc 0:db8030e71f55 278 bool PN532::setPassiveActivationRetries(uint8_t maxRetries)
dotnfc 0:db8030e71f55 279 {
dotnfc 0:db8030e71f55 280 pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
dotnfc 0:db8030e71f55 281 pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
dotnfc 0:db8030e71f55 282 pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
dotnfc 0:db8030e71f55 283 pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
dotnfc 0:db8030e71f55 284 pn532_packetbuffer[4] = maxRetries;
dotnfc 0:db8030e71f55 285
dotnfc 0:db8030e71f55 286 if (HAL(writeCommand)(pn532_packetbuffer, 5))
dotnfc 0:db8030e71f55 287 return 0x0; // no ACK
dotnfc 0:db8030e71f55 288
dotnfc 0:db8030e71f55 289 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
dotnfc 0:db8030e71f55 290 }
dotnfc 0:db8030e71f55 291
dotnfc 0:db8030e71f55 292 /***** ISO14443A Commands ******/
dotnfc 0:db8030e71f55 293
dotnfc 0:db8030e71f55 294 /**************************************************************************/
dotnfc 0:db8030e71f55 295 /*!
dotnfc 0:db8030e71f55 296 Waits for an ISO14443A target to enter the field
dotnfc 0:db8030e71f55 297
dotnfc 0:db8030e71f55 298 @param cardBaudRate Baud rate of the card
dotnfc 0:db8030e71f55 299 @param uid Pointer to the array that will be populated
dotnfc 0:db8030e71f55 300 with the card's UID (up to 7 bytes)
dotnfc 0:db8030e71f55 301 @param uidLength Pointer to the variable that will hold the
dotnfc 0:db8030e71f55 302 length of the card's UID.
dotnfc 0:db8030e71f55 303 @param timeout The number of tries before timing out
dotnfc 0:db8030e71f55 304 @param inlist If set to true, the card will be inlisted
dotnfc 0:db8030e71f55 305
dotnfc 0:db8030e71f55 306 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 307 */
dotnfc 0:db8030e71f55 308 /**************************************************************************/
dotnfc 0:db8030e71f55 309 bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout, bool inlist)
dotnfc 0:db8030e71f55 310 {
dotnfc 0:db8030e71f55 311 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
dotnfc 0:db8030e71f55 312 pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
dotnfc 0:db8030e71f55 313 pn532_packetbuffer[2] = cardbaudrate;
dotnfc 0:db8030e71f55 314
dotnfc 0:db8030e71f55 315 if (HAL(writeCommand)(pn532_packetbuffer, 3)) {
dotnfc 0:db8030e71f55 316 return 0x0; // command failed
dotnfc 0:db8030e71f55 317 }
dotnfc 0:db8030e71f55 318
dotnfc 0:db8030e71f55 319 // read data packet
dotnfc 0:db8030e71f55 320 if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
dotnfc 0:db8030e71f55 321 return 0x0;
dotnfc 0:db8030e71f55 322 }
dotnfc 0:db8030e71f55 323
dotnfc 0:db8030e71f55 324 // check some basic stuff
dotnfc 0:db8030e71f55 325 /* ISO14443A card response should be in the following format:
dotnfc 0:db8030e71f55 326
dotnfc 0:db8030e71f55 327 byte Description
dotnfc 0:db8030e71f55 328 ------------- ------------------------------------------
dotnfc 0:db8030e71f55 329 b0 Tags Found
dotnfc 0:db8030e71f55 330 b1 Tag Number (only one used in this example)
dotnfc 0:db8030e71f55 331 b2..3 SENS_RES
dotnfc 0:db8030e71f55 332 b4 SEL_RES
dotnfc 0:db8030e71f55 333 b5 NFCID Length
dotnfc 0:db8030e71f55 334 b6..NFCIDLen NFCID
dotnfc 0:db8030e71f55 335 */
dotnfc 0:db8030e71f55 336
dotnfc 0:db8030e71f55 337 if (pn532_packetbuffer[0] != 1)
dotnfc 0:db8030e71f55 338 return 0;
dotnfc 0:db8030e71f55 339
dotnfc 0:db8030e71f55 340 uint16_t sens_res = pn532_packetbuffer[2];
dotnfc 0:db8030e71f55 341 sens_res <<= 8;
dotnfc 0:db8030e71f55 342 sens_res |= pn532_packetbuffer[3];
dotnfc 0:db8030e71f55 343
dotnfc 0:db8030e71f55 344 DMSG("ATQA: 0x"); DMSG_HEX(sens_res);
dotnfc 0:db8030e71f55 345 DMSG("\n");
dotnfc 0:db8030e71f55 346 DMSG("SAK: 0x"); DMSG_HEX(pn532_packetbuffer[4]);
dotnfc 0:db8030e71f55 347 DMSG("\n");
dotnfc 0:db8030e71f55 348
dotnfc 0:db8030e71f55 349 /* Card appears to be Mifare Classic */
dotnfc 0:db8030e71f55 350 *uidLength = pn532_packetbuffer[5];
dotnfc 0:db8030e71f55 351
dotnfc 0:db8030e71f55 352 for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) {
dotnfc 0:db8030e71f55 353 uid[i] = pn532_packetbuffer[6 + i];
dotnfc 0:db8030e71f55 354 }
dotnfc 0:db8030e71f55 355
dotnfc 0:db8030e71f55 356 if (inlist) {
dotnfc 0:db8030e71f55 357 inListedTag = pn532_packetbuffer[1];
dotnfc 0:db8030e71f55 358 }
dotnfc 0:db8030e71f55 359
dotnfc 0:db8030e71f55 360 return 1;
dotnfc 0:db8030e71f55 361 }
dotnfc 0:db8030e71f55 362
dotnfc 0:db8030e71f55 363
dotnfc 0:db8030e71f55 364 /***** Mifare Classic Functions ******/
dotnfc 0:db8030e71f55 365
dotnfc 0:db8030e71f55 366 /**************************************************************************/
dotnfc 0:db8030e71f55 367 /*!
dotnfc 0:db8030e71f55 368 Indicates whether the specified block number is the first block
dotnfc 0:db8030e71f55 369 in the sector (block 0 relative to the current sector)
dotnfc 0:db8030e71f55 370 */
dotnfc 0:db8030e71f55 371 /**************************************************************************/
dotnfc 0:db8030e71f55 372 bool PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock)
dotnfc 0:db8030e71f55 373 {
dotnfc 0:db8030e71f55 374 // Test if we are in the small or big sectors
dotnfc 0:db8030e71f55 375 if (uiBlock < 128)
dotnfc 0:db8030e71f55 376 return ((uiBlock) % 4 == 0);
dotnfc 0:db8030e71f55 377 else
dotnfc 0:db8030e71f55 378 return ((uiBlock) % 16 == 0);
dotnfc 0:db8030e71f55 379 }
dotnfc 0:db8030e71f55 380
dotnfc 0:db8030e71f55 381 /**************************************************************************/
dotnfc 0:db8030e71f55 382 /*!
dotnfc 0:db8030e71f55 383 Indicates whether the specified block number is the sector trailer
dotnfc 0:db8030e71f55 384 */
dotnfc 0:db8030e71f55 385 /**************************************************************************/
dotnfc 0:db8030e71f55 386 bool PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock)
dotnfc 0:db8030e71f55 387 {
dotnfc 0:db8030e71f55 388 // Test if we are in the small or big sectors
dotnfc 0:db8030e71f55 389 if (uiBlock < 128)
dotnfc 0:db8030e71f55 390 return ((uiBlock + 1) % 4 == 0);
dotnfc 0:db8030e71f55 391 else
dotnfc 0:db8030e71f55 392 return ((uiBlock + 1) % 16 == 0);
dotnfc 0:db8030e71f55 393 }
dotnfc 0:db8030e71f55 394
dotnfc 0:db8030e71f55 395 /**************************************************************************/
dotnfc 0:db8030e71f55 396 /*!
dotnfc 0:db8030e71f55 397 Tries to authenticate a block of memory on a MIFARE card using the
dotnfc 0:db8030e71f55 398 INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual
dotnfc 0:db8030e71f55 399 for more information on sending MIFARE and other commands.
dotnfc 0:db8030e71f55 400
dotnfc 0:db8030e71f55 401 @param uid Pointer to a byte array containing the card UID
dotnfc 0:db8030e71f55 402 @param uidLen The length (in bytes) of the card's UID (Should
dotnfc 0:db8030e71f55 403 be 4 for MIFARE Classic)
dotnfc 0:db8030e71f55 404 @param blockNumber The block number to authenticate. (0..63 for
dotnfc 0:db8030e71f55 405 1KB cards, and 0..255 for 4KB cards).
dotnfc 0:db8030e71f55 406 @param keyNumber Which key type to use during authentication
dotnfc 0:db8030e71f55 407 (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
dotnfc 0:db8030e71f55 408 @param keyData Pointer to a byte array containing the 6 bytes
dotnfc 0:db8030e71f55 409 key value
dotnfc 0:db8030e71f55 410
dotnfc 0:db8030e71f55 411 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 412 */
dotnfc 0:db8030e71f55 413 /**************************************************************************/
dotnfc 0:db8030e71f55 414 uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData)
dotnfc 0:db8030e71f55 415 {
dotnfc 0:db8030e71f55 416 uint8_t i;
dotnfc 0:db8030e71f55 417
dotnfc 0:db8030e71f55 418 // Hang on to the key and uid data
dotnfc 0:db8030e71f55 419 memcpy (_key, keyData, 6);
dotnfc 0:db8030e71f55 420 memcpy (_uid, uid, uidLen);
dotnfc 0:db8030e71f55 421 _uidLen = uidLen;
dotnfc 0:db8030e71f55 422
dotnfc 0:db8030e71f55 423 // Prepare the authentication command //
dotnfc 0:db8030e71f55 424 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
dotnfc 0:db8030e71f55 425 pn532_packetbuffer[1] = 1; /* Max card numbers */
dotnfc 0:db8030e71f55 426 pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
dotnfc 0:db8030e71f55 427 pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
dotnfc 0:db8030e71f55 428 memcpy (pn532_packetbuffer + 4, _key, 6);
dotnfc 0:db8030e71f55 429 for (i = 0; i < _uidLen; i++) {
dotnfc 0:db8030e71f55 430 pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */
dotnfc 0:db8030e71f55 431 }
dotnfc 0:db8030e71f55 432
dotnfc 0:db8030e71f55 433 if (HAL(writeCommand)(pn532_packetbuffer, 10 + _uidLen))
dotnfc 0:db8030e71f55 434 return 0;
dotnfc 0:db8030e71f55 435
dotnfc 0:db8030e71f55 436 // Read the response packet
dotnfc 0:db8030e71f55 437 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
dotnfc 0:db8030e71f55 438
dotnfc 0:db8030e71f55 439 // Check if the response is valid and we are authenticated???
dotnfc 0:db8030e71f55 440 // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
dotnfc 0:db8030e71f55 441 // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good
dotnfc 0:db8030e71f55 442 if (pn532_packetbuffer[0] != 0x00) {
dotnfc 0:db8030e71f55 443 DMSG("Authentification failed\n");
dotnfc 0:db8030e71f55 444 return 0;
dotnfc 0:db8030e71f55 445 }
dotnfc 0:db8030e71f55 446
dotnfc 0:db8030e71f55 447 return 1;
dotnfc 0:db8030e71f55 448 }
dotnfc 0:db8030e71f55 449
dotnfc 0:db8030e71f55 450 /**************************************************************************/
dotnfc 0:db8030e71f55 451 /*!
dotnfc 0:db8030e71f55 452 Tries to read an entire 16-bytes data block at the specified block
dotnfc 0:db8030e71f55 453 address.
dotnfc 0:db8030e71f55 454
dotnfc 0:db8030e71f55 455 @param blockNumber The block number to authenticate. (0..63 for
dotnfc 0:db8030e71f55 456 1KB cards, and 0..255 for 4KB cards).
dotnfc 0:db8030e71f55 457 @param data Pointer to the byte array that will hold the
dotnfc 0:db8030e71f55 458 retrieved data (if any)
dotnfc 0:db8030e71f55 459
dotnfc 0:db8030e71f55 460 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 461 */
dotnfc 0:db8030e71f55 462 /**************************************************************************/
dotnfc 0:db8030e71f55 463 uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
dotnfc 0:db8030e71f55 464 {
dotnfc 0:db8030e71f55 465 DMSG("Trying to read 16 bytes from block ");
dotnfc 0:db8030e71f55 466 DMSG_INT(blockNumber);
dotnfc 0:db8030e71f55 467
dotnfc 0:db8030e71f55 468 /* Prepare the command */
dotnfc 0:db8030e71f55 469 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
dotnfc 0:db8030e71f55 470 pn532_packetbuffer[1] = 1; /* Card number */
dotnfc 0:db8030e71f55 471 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
dotnfc 0:db8030e71f55 472 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
dotnfc 0:db8030e71f55 473
dotnfc 0:db8030e71f55 474 /* Send the command */
dotnfc 0:db8030e71f55 475 if (HAL(writeCommand)(pn532_packetbuffer, 4)) {
dotnfc 0:db8030e71f55 476 return 0;
dotnfc 0:db8030e71f55 477 }
dotnfc 0:db8030e71f55 478
dotnfc 0:db8030e71f55 479 /* Read the response packet */
dotnfc 0:db8030e71f55 480 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
dotnfc 0:db8030e71f55 481
dotnfc 0:db8030e71f55 482 /* If byte 8 isn't 0x00 we probably have an error */
dotnfc 0:db8030e71f55 483 if (pn532_packetbuffer[0] != 0x00) {
dotnfc 0:db8030e71f55 484 return 0;
dotnfc 0:db8030e71f55 485 }
dotnfc 0:db8030e71f55 486
dotnfc 0:db8030e71f55 487 /* Copy the 16 data bytes to the output buffer */
dotnfc 0:db8030e71f55 488 /* Block content starts at byte 9 of a valid response */
dotnfc 0:db8030e71f55 489 memcpy (data, pn532_packetbuffer + 1, 16);
dotnfc 0:db8030e71f55 490
dotnfc 0:db8030e71f55 491 return 1;
dotnfc 0:db8030e71f55 492 }
dotnfc 0:db8030e71f55 493
dotnfc 0:db8030e71f55 494 /**************************************************************************/
dotnfc 0:db8030e71f55 495 /*!
dotnfc 0:db8030e71f55 496 Tries to write an entire 16-bytes data block at the specified block
dotnfc 0:db8030e71f55 497 address.
dotnfc 0:db8030e71f55 498
dotnfc 0:db8030e71f55 499 @param blockNumber The block number to authenticate. (0..63 for
dotnfc 0:db8030e71f55 500 1KB cards, and 0..255 for 4KB cards).
dotnfc 0:db8030e71f55 501 @param data The byte array that contains the data to write.
dotnfc 0:db8030e71f55 502
dotnfc 0:db8030e71f55 503 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 504 */
dotnfc 0:db8030e71f55 505 /**************************************************************************/
dotnfc 0:db8030e71f55 506 uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data)
dotnfc 0:db8030e71f55 507 {
dotnfc 0:db8030e71f55 508 /* Prepare the first command */
dotnfc 0:db8030e71f55 509 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
dotnfc 0:db8030e71f55 510 pn532_packetbuffer[1] = 1; /* Card number */
dotnfc 0:db8030e71f55 511 pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
dotnfc 0:db8030e71f55 512 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
dotnfc 0:db8030e71f55 513 memcpy (pn532_packetbuffer + 4, data, 16); /* Data Payload */
dotnfc 0:db8030e71f55 514
dotnfc 0:db8030e71f55 515 /* Send the command */
dotnfc 0:db8030e71f55 516 if (HAL(writeCommand)(pn532_packetbuffer, 20)) {
dotnfc 0:db8030e71f55 517 return 0;
dotnfc 0:db8030e71f55 518 }
dotnfc 0:db8030e71f55 519
dotnfc 0:db8030e71f55 520 /* Read the response packet */
dotnfc 0:db8030e71f55 521 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
dotnfc 0:db8030e71f55 522 }
dotnfc 0:db8030e71f55 523
dotnfc 0:db8030e71f55 524 /**************************************************************************/
dotnfc 0:db8030e71f55 525 /*!
dotnfc 0:db8030e71f55 526 Formats a Mifare Classic card to store NDEF Records
dotnfc 0:db8030e71f55 527
dotnfc 0:db8030e71f55 528 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 529 */
dotnfc 0:db8030e71f55 530 /**************************************************************************/
dotnfc 0:db8030e71f55 531 uint8_t PN532::mifareclassic_FormatNDEF (void)
dotnfc 0:db8030e71f55 532 {
dotnfc 0:db8030e71f55 533 uint8_t sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
dotnfc 0:db8030e71f55 534 uint8_t sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
dotnfc 0:db8030e71f55 535 uint8_t sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
dotnfc 0:db8030e71f55 536
dotnfc 0:db8030e71f55 537 // Note 0xA0 0xA1 0xA2 0xA3 0xA4 0xA5 must be used for key A
dotnfc 0:db8030e71f55 538 // for the MAD sector in NDEF records (sector 0)
dotnfc 0:db8030e71f55 539
dotnfc 0:db8030e71f55 540 // Write block 1 and 2 to the card
dotnfc 0:db8030e71f55 541 if (!(mifareclassic_WriteDataBlock (1, sectorbuffer1)))
dotnfc 0:db8030e71f55 542 return 0;
dotnfc 0:db8030e71f55 543 if (!(mifareclassic_WriteDataBlock (2, sectorbuffer2)))
dotnfc 0:db8030e71f55 544 return 0;
dotnfc 0:db8030e71f55 545 // Write key A and access rights card
dotnfc 0:db8030e71f55 546 if (!(mifareclassic_WriteDataBlock (3, sectorbuffer3)))
dotnfc 0:db8030e71f55 547 return 0;
dotnfc 0:db8030e71f55 548
dotnfc 0:db8030e71f55 549 // Seems that everything was OK (?!)
dotnfc 0:db8030e71f55 550 return 1;
dotnfc 0:db8030e71f55 551 }
dotnfc 0:db8030e71f55 552
dotnfc 0:db8030e71f55 553 /**************************************************************************/
dotnfc 0:db8030e71f55 554 /*!
dotnfc 0:db8030e71f55 555 Writes an NDEF URI Record to the specified sector (1..15)
dotnfc 0:db8030e71f55 556
dotnfc 0:db8030e71f55 557 Note that this function assumes that the Mifare Classic card is
dotnfc 0:db8030e71f55 558 already formatted to work as an "NFC Forum Tag" and uses a MAD1
dotnfc 0:db8030e71f55 559 file system. You can use the NXP TagWriter app on Android to
dotnfc 0:db8030e71f55 560 properly format cards for this.
dotnfc 0:db8030e71f55 561
dotnfc 0:db8030e71f55 562 @param sectorNumber The sector that the URI record should be written
dotnfc 0:db8030e71f55 563 to (can be 1..15 for a 1K card)
dotnfc 0:db8030e71f55 564 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
dotnfc 0:db8030e71f55 565 "http://www.", etc.)
dotnfc 0:db8030e71f55 566 @param url The uri text to write (max 38 characters).
dotnfc 0:db8030e71f55 567
dotnfc 0:db8030e71f55 568 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 569 */
dotnfc 0:db8030e71f55 570 /**************************************************************************/
dotnfc 0:db8030e71f55 571 uint8_t PN532::mifareclassic_WriteNDEFURI (uint8_t sectorNumber, uint8_t uriIdentifier, const char *url)
dotnfc 0:db8030e71f55 572 {
dotnfc 0:db8030e71f55 573 // Figure out how long the string is
dotnfc 0:db8030e71f55 574 uint8_t len = strlen(url);
dotnfc 0:db8030e71f55 575
dotnfc 0:db8030e71f55 576 // Make sure we're within a 1K limit for the sector number
dotnfc 0:db8030e71f55 577 if ((sectorNumber < 1) || (sectorNumber > 15))
dotnfc 0:db8030e71f55 578 return 0;
dotnfc 0:db8030e71f55 579
dotnfc 0:db8030e71f55 580 // Make sure the URI payload is between 1 and 38 chars
dotnfc 0:db8030e71f55 581 if ((len < 1) || (len > 38))
dotnfc 0:db8030e71f55 582 return 0;
dotnfc 0:db8030e71f55 583
dotnfc 0:db8030e71f55 584 // Note 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 must be used for key A
dotnfc 0:db8030e71f55 585 // in NDEF records
dotnfc 0:db8030e71f55 586
dotnfc 0:db8030e71f55 587 // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
dotnfc 0:db8030e71f55 588 uint8_t sectorbuffer1[16] = {0x00, 0x00, 0x03, len + 5, 0xD1, 0x01, len + 1, 0x55, uriIdentifier, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
dotnfc 0:db8030e71f55 589 uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
dotnfc 0:db8030e71f55 590 uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
dotnfc 0:db8030e71f55 591 uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
dotnfc 0:db8030e71f55 592 if (len <= 6) {
dotnfc 0:db8030e71f55 593 // Unlikely we'll get a url this short, but why not ...
dotnfc 0:db8030e71f55 594 memcpy (sectorbuffer1 + 9, url, len);
dotnfc 0:db8030e71f55 595 sectorbuffer1[len + 9] = 0xFE;
dotnfc 0:db8030e71f55 596 } else if (len == 7) {
dotnfc 0:db8030e71f55 597 // 0xFE needs to be wrapped around to next block
dotnfc 0:db8030e71f55 598 memcpy (sectorbuffer1 + 9, url, len);
dotnfc 0:db8030e71f55 599 sectorbuffer2[0] = 0xFE;
dotnfc 0:db8030e71f55 600 } else if ((len > 7) || (len <= 22)) {
dotnfc 0:db8030e71f55 601 // Url fits in two blocks
dotnfc 0:db8030e71f55 602 memcpy (sectorbuffer1 + 9, url, 7);
dotnfc 0:db8030e71f55 603 memcpy (sectorbuffer2, url + 7, len - 7);
dotnfc 0:db8030e71f55 604 sectorbuffer2[len - 7] = 0xFE;
dotnfc 0:db8030e71f55 605 } else if (len == 23) {
dotnfc 0:db8030e71f55 606 // 0xFE needs to be wrapped around to final block
dotnfc 0:db8030e71f55 607 memcpy (sectorbuffer1 + 9, url, 7);
dotnfc 0:db8030e71f55 608 memcpy (sectorbuffer2, url + 7, len - 7);
dotnfc 0:db8030e71f55 609 sectorbuffer3[0] = 0xFE;
dotnfc 0:db8030e71f55 610 } else {
dotnfc 0:db8030e71f55 611 // Url fits in three blocks
dotnfc 0:db8030e71f55 612 memcpy (sectorbuffer1 + 9, url, 7);
dotnfc 0:db8030e71f55 613 memcpy (sectorbuffer2, url + 7, 16);
dotnfc 0:db8030e71f55 614 memcpy (sectorbuffer3, url + 23, len - 24);
dotnfc 0:db8030e71f55 615 sectorbuffer3[len - 22] = 0xFE;
dotnfc 0:db8030e71f55 616 }
dotnfc 0:db8030e71f55 617
dotnfc 0:db8030e71f55 618 // Now write all three blocks back to the card
dotnfc 0:db8030e71f55 619 if (!(mifareclassic_WriteDataBlock (sectorNumber * 4, sectorbuffer1)))
dotnfc 0:db8030e71f55 620 return 0;
dotnfc 0:db8030e71f55 621 if (!(mifareclassic_WriteDataBlock ((sectorNumber * 4) + 1, sectorbuffer2)))
dotnfc 0:db8030e71f55 622 return 0;
dotnfc 0:db8030e71f55 623 if (!(mifareclassic_WriteDataBlock ((sectorNumber * 4) + 2, sectorbuffer3)))
dotnfc 0:db8030e71f55 624 return 0;
dotnfc 0:db8030e71f55 625 if (!(mifareclassic_WriteDataBlock ((sectorNumber * 4) + 3, sectorbuffer4)))
dotnfc 0:db8030e71f55 626 return 0;
dotnfc 0:db8030e71f55 627
dotnfc 0:db8030e71f55 628 // Seems that everything was OK (?!)
dotnfc 0:db8030e71f55 629 return 1;
dotnfc 0:db8030e71f55 630 }
dotnfc 0:db8030e71f55 631
dotnfc 0:db8030e71f55 632 /***** Mifare Ultralight Functions ******/
dotnfc 0:db8030e71f55 633
dotnfc 0:db8030e71f55 634 /**************************************************************************/
dotnfc 0:db8030e71f55 635 /*!
dotnfc 0:db8030e71f55 636 Tries to read an entire 4-bytes page at the specified address.
dotnfc 0:db8030e71f55 637
dotnfc 0:db8030e71f55 638 @param page The page number (0..63 in most cases)
dotnfc 0:db8030e71f55 639 @param buffer Pointer to the byte array that will hold the
dotnfc 0:db8030e71f55 640 retrieved data (if any)
dotnfc 0:db8030e71f55 641 */
dotnfc 0:db8030e71f55 642 /**************************************************************************/
dotnfc 0:db8030e71f55 643 uint8_t PN532::mifareultralight_ReadPage (uint8_t page, uint8_t *buffer)
dotnfc 0:db8030e71f55 644 {
dotnfc 0:db8030e71f55 645 if (page >= 64) {
dotnfc 0:db8030e71f55 646 DMSG("Page value out of range\n");
dotnfc 0:db8030e71f55 647 return 0;
dotnfc 0:db8030e71f55 648 }
dotnfc 0:db8030e71f55 649
dotnfc 0:db8030e71f55 650 /* Prepare the command */
dotnfc 0:db8030e71f55 651 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
dotnfc 0:db8030e71f55 652 pn532_packetbuffer[1] = 1; /* Card number */
dotnfc 0:db8030e71f55 653 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
dotnfc 0:db8030e71f55 654 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
dotnfc 0:db8030e71f55 655
dotnfc 0:db8030e71f55 656 /* Send the command */
dotnfc 0:db8030e71f55 657 if (HAL(writeCommand)(pn532_packetbuffer, 4)) {
dotnfc 0:db8030e71f55 658 return 0;
dotnfc 0:db8030e71f55 659 }
dotnfc 0:db8030e71f55 660
dotnfc 0:db8030e71f55 661 /* Read the response packet */
dotnfc 0:db8030e71f55 662 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
dotnfc 0:db8030e71f55 663
dotnfc 0:db8030e71f55 664 /* If byte 8 isn't 0x00 we probably have an error */
dotnfc 0:db8030e71f55 665 if (pn532_packetbuffer[0] == 0x00) {
dotnfc 0:db8030e71f55 666 /* Copy the 4 data bytes to the output buffer */
dotnfc 0:db8030e71f55 667 /* Block content starts at byte 9 of a valid response */
dotnfc 0:db8030e71f55 668 /* Note that the command actually reads 16 bytes or 4 */
dotnfc 0:db8030e71f55 669 /* pages at a time ... we simply discard the last 12 */
dotnfc 0:db8030e71f55 670 /* bytes */
dotnfc 0:db8030e71f55 671 memcpy (buffer, pn532_packetbuffer + 1, 4);
dotnfc 0:db8030e71f55 672 } else {
dotnfc 0:db8030e71f55 673 return 0;
dotnfc 0:db8030e71f55 674 }
dotnfc 0:db8030e71f55 675
dotnfc 0:db8030e71f55 676 // Return OK signal
dotnfc 0:db8030e71f55 677 return 1;
dotnfc 0:db8030e71f55 678 }
dotnfc 0:db8030e71f55 679
dotnfc 0:db8030e71f55 680 /**************************************************************************/
dotnfc 0:db8030e71f55 681 /*!
dotnfc 0:db8030e71f55 682 Tries to write an entire 4-bytes data buffer at the specified page
dotnfc 0:db8030e71f55 683 address.
dotnfc 0:db8030e71f55 684
dotnfc 0:db8030e71f55 685 @param page The page number to write into. (0..63).
dotnfc 0:db8030e71f55 686 @param buffer The byte array that contains the data to write.
dotnfc 0:db8030e71f55 687
dotnfc 0:db8030e71f55 688 @returns 1 if everything executed properly, 0 for an error
dotnfc 0:db8030e71f55 689 */
dotnfc 0:db8030e71f55 690 /**************************************************************************/
dotnfc 0:db8030e71f55 691 uint8_t PN532::mifareultralight_WritePage (uint8_t page, uint8_t *buffer)
dotnfc 0:db8030e71f55 692 {
dotnfc 0:db8030e71f55 693 /* Prepare the first command */
dotnfc 0:db8030e71f55 694 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
dotnfc 0:db8030e71f55 695 pn532_packetbuffer[1] = 1; /* Card number */
dotnfc 0:db8030e71f55 696 pn532_packetbuffer[2] = MIFARE_CMD_WRITE_ULTRALIGHT; /* Mifare UL Write cmd = 0xA2 */
dotnfc 0:db8030e71f55 697 pn532_packetbuffer[3] = page; /* page Number (0..63) */
dotnfc 0:db8030e71f55 698 memcpy (pn532_packetbuffer + 4, buffer, 4); /* Data Payload */
dotnfc 0:db8030e71f55 699
dotnfc 0:db8030e71f55 700 /* Send the command */
dotnfc 0:db8030e71f55 701 if (HAL(writeCommand)(pn532_packetbuffer, 8)) {
dotnfc 0:db8030e71f55 702 return 0;
dotnfc 0:db8030e71f55 703 }
dotnfc 0:db8030e71f55 704
dotnfc 0:db8030e71f55 705 /* Read the response packet */
dotnfc 0:db8030e71f55 706 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
dotnfc 0:db8030e71f55 707 }
dotnfc 0:db8030e71f55 708
dotnfc 0:db8030e71f55 709 /**************************************************************************/
dotnfc 0:db8030e71f55 710 /*!
dotnfc 0:db8030e71f55 711 @brief Exchanges an APDU with the currently inlisted peer
dotnfc 0:db8030e71f55 712
dotnfc 0:db8030e71f55 713 @param send Pointer to data to send
dotnfc 0:db8030e71f55 714 @param sendLength Length of the data to send
dotnfc 0:db8030e71f55 715 @param response Pointer to response data
dotnfc 0:db8030e71f55 716 @param responseLength Pointer to the response data length
dotnfc 0:db8030e71f55 717 */
dotnfc 0:db8030e71f55 718 /**************************************************************************/
dotnfc 0:db8030e71f55 719 bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength)
dotnfc 0:db8030e71f55 720 {
dotnfc 0:db8030e71f55 721 uint8_t i;
dotnfc 0:db8030e71f55 722
dotnfc 0:db8030e71f55 723 pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
dotnfc 0:db8030e71f55 724 pn532_packetbuffer[1] = inListedTag;
dotnfc 0:db8030e71f55 725
dotnfc 0:db8030e71f55 726 if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) {
dotnfc 0:db8030e71f55 727 return false;
dotnfc 0:db8030e71f55 728 }
dotnfc 0:db8030e71f55 729
dotnfc 0:db8030e71f55 730 int16_t status = HAL(readResponse)(response, *responseLength, 1000);
dotnfc 0:db8030e71f55 731 if (status < 0) {
dotnfc 0:db8030e71f55 732 return false;
dotnfc 0:db8030e71f55 733 }
dotnfc 0:db8030e71f55 734
dotnfc 0:db8030e71f55 735 if ((response[0] & 0x3f) != 0) {
dotnfc 0:db8030e71f55 736 DMSG("Status code indicates an error\n");
dotnfc 0:db8030e71f55 737 return false;
dotnfc 0:db8030e71f55 738 }
dotnfc 0:db8030e71f55 739
dotnfc 0:db8030e71f55 740 uint8_t length = status;
dotnfc 0:db8030e71f55 741 length -= 1;
dotnfc 0:db8030e71f55 742
dotnfc 0:db8030e71f55 743 if (length > *responseLength) {
dotnfc 0:db8030e71f55 744 length = *responseLength; // silent truncation...
dotnfc 0:db8030e71f55 745 }
dotnfc 0:db8030e71f55 746
dotnfc 0:db8030e71f55 747 for (uint8_t i = 0; i < length; i++) {
dotnfc 0:db8030e71f55 748 response[i] = response[i + 1];
dotnfc 0:db8030e71f55 749 }
dotnfc 0:db8030e71f55 750 *responseLength = length;
dotnfc 0:db8030e71f55 751
dotnfc 0:db8030e71f55 752 return true;
dotnfc 0:db8030e71f55 753 }
dotnfc 0:db8030e71f55 754
dotnfc 0:db8030e71f55 755 /**************************************************************************/
dotnfc 0:db8030e71f55 756 /*!
dotnfc 0:db8030e71f55 757 @brief 'InLists' a passive target. PN532 acting as reader/initiator,
dotnfc 0:db8030e71f55 758 peer acting as card/responder.
dotnfc 0:db8030e71f55 759 */
dotnfc 0:db8030e71f55 760 /**************************************************************************/
dotnfc 0:db8030e71f55 761 bool PN532::inListPassiveTarget()
dotnfc 0:db8030e71f55 762 {
dotnfc 0:db8030e71f55 763 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
dotnfc 0:db8030e71f55 764 pn532_packetbuffer[1] = 1;
dotnfc 0:db8030e71f55 765 pn532_packetbuffer[2] = 0;
dotnfc 0:db8030e71f55 766
dotnfc 0:db8030e71f55 767 DMSG("inList passive target\n");
dotnfc 0:db8030e71f55 768
dotnfc 0:db8030e71f55 769 if (HAL(writeCommand)(pn532_packetbuffer, 3)) {
dotnfc 0:db8030e71f55 770 return false;
dotnfc 0:db8030e71f55 771 }
dotnfc 0:db8030e71f55 772
dotnfc 0:db8030e71f55 773 int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 30000);
dotnfc 0:db8030e71f55 774 if (status < 0) {
dotnfc 0:db8030e71f55 775 return false;
dotnfc 0:db8030e71f55 776 }
dotnfc 0:db8030e71f55 777
dotnfc 0:db8030e71f55 778 if (pn532_packetbuffer[0] != 1) {
dotnfc 0:db8030e71f55 779 return false;
dotnfc 0:db8030e71f55 780 }
dotnfc 0:db8030e71f55 781
dotnfc 0:db8030e71f55 782 inListedTag = pn532_packetbuffer[1];
dotnfc 0:db8030e71f55 783
dotnfc 0:db8030e71f55 784 return true;
dotnfc 0:db8030e71f55 785 }
dotnfc 0:db8030e71f55 786
dotnfc 0:db8030e71f55 787 int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout){
dotnfc 0:db8030e71f55 788
dotnfc 0:db8030e71f55 789 int8_t status = HAL(writeCommand)(command, len);
dotnfc 0:db8030e71f55 790 if (status < 0) {
dotnfc 0:db8030e71f55 791 return -1;
dotnfc 0:db8030e71f55 792 }
dotnfc 0:db8030e71f55 793
dotnfc 0:db8030e71f55 794 status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout);
dotnfc 0:db8030e71f55 795 if (status > 0) {
dotnfc 0:db8030e71f55 796 return 1;
dotnfc 0:db8030e71f55 797 } else if (PN532_TIMEOUT == status) {
dotnfc 0:db8030e71f55 798 return 0;
dotnfc 0:db8030e71f55 799 } else {
dotnfc 0:db8030e71f55 800 return -2;
dotnfc 0:db8030e71f55 801 }
dotnfc 0:db8030e71f55 802 }
dotnfc 0:db8030e71f55 803
dotnfc 0:db8030e71f55 804 /**
dotnfc 0:db8030e71f55 805 * Peer to Peer
dotnfc 0:db8030e71f55 806 */
dotnfc 0:db8030e71f55 807 int8_t PN532::tgInitAsTarget(uint16_t timeout)
dotnfc 0:db8030e71f55 808 {
dotnfc 0:db8030e71f55 809 const uint8_t command[] = {
dotnfc 0:db8030e71f55 810 PN532_COMMAND_TGINITASTARGET,
dotnfc 0:db8030e71f55 811 0,
dotnfc 0:db8030e71f55 812 0x00, 0x00, //SENS_RES
dotnfc 0:db8030e71f55 813 0x00, 0x00, 0x00, //NFCID1
dotnfc 0:db8030e71f55 814 0x40, //SEL_RES
dotnfc 0:db8030e71f55 815
dotnfc 0:db8030e71f55 816 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, // POL_RES
dotnfc 0:db8030e71f55 817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
dotnfc 0:db8030e71f55 818 0xFF, 0xFF,
dotnfc 0:db8030e71f55 819
dotnfc 0:db8030e71f55 820 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value
dotnfc 0:db8030e71f55 821
dotnfc 0:db8030e71f55 822 0x0a, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x02, 0x02, 0x00, 0x80, // LLCP magic number, version parameter and MIUX
dotnfc 0:db8030e71f55 823 0x00
dotnfc 0:db8030e71f55 824 };
dotnfc 0:db8030e71f55 825 return tgInitAsTarget(command, sizeof(command), timeout);
dotnfc 0:db8030e71f55 826 }
dotnfc 0:db8030e71f55 827
dotnfc 0:db8030e71f55 828 int16_t PN532::tgGetData(uint8_t *buf, uint8_t len)
dotnfc 0:db8030e71f55 829 {
dotnfc 0:db8030e71f55 830 buf[0] = PN532_COMMAND_TGGETDATA;
dotnfc 0:db8030e71f55 831
dotnfc 0:db8030e71f55 832 if (HAL(writeCommand)(buf, 1)) {
dotnfc 0:db8030e71f55 833 return -1;
dotnfc 0:db8030e71f55 834 }
dotnfc 0:db8030e71f55 835
dotnfc 0:db8030e71f55 836 int16_t status = HAL(readResponse)(buf, len, 3000);
dotnfc 0:db8030e71f55 837 if (0 >= status) {
dotnfc 0:db8030e71f55 838 return status;
dotnfc 0:db8030e71f55 839 }
dotnfc 0:db8030e71f55 840
dotnfc 0:db8030e71f55 841 uint16_t length = status - 1;
dotnfc 0:db8030e71f55 842
dotnfc 0:db8030e71f55 843
dotnfc 0:db8030e71f55 844 if (buf[0] != 0) {
dotnfc 0:db8030e71f55 845 DMSG("status is not ok\n");
dotnfc 0:db8030e71f55 846 return -5;
dotnfc 0:db8030e71f55 847 }
dotnfc 0:db8030e71f55 848
dotnfc 0:db8030e71f55 849 for (uint8_t i = 0; i < length; i++) {
dotnfc 0:db8030e71f55 850 buf[i] = buf[i + 1];
dotnfc 0:db8030e71f55 851 }
dotnfc 0:db8030e71f55 852
dotnfc 0:db8030e71f55 853 return length;
dotnfc 0:db8030e71f55 854 }
dotnfc 0:db8030e71f55 855
dotnfc 0:db8030e71f55 856 bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
dotnfc 0:db8030e71f55 857 {
dotnfc 0:db8030e71f55 858 if (hlen > (sizeof(pn532_packetbuffer) - 1)) {
dotnfc 0:db8030e71f55 859 if ((body != 0) || (header == pn532_packetbuffer)) {
dotnfc 0:db8030e71f55 860 DMSG("tgSetData:buffer too small\n");
dotnfc 0:db8030e71f55 861 return false;
dotnfc 0:db8030e71f55 862 }
dotnfc 0:db8030e71f55 863
dotnfc 0:db8030e71f55 864 pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
dotnfc 0:db8030e71f55 865 if (HAL(writeCommand)(pn532_packetbuffer, 1, header, hlen)) {
dotnfc 0:db8030e71f55 866 return false;
dotnfc 0:db8030e71f55 867 }
dotnfc 0:db8030e71f55 868 } else {
dotnfc 0:db8030e71f55 869 for (int8_t i = hlen - 1; i >= 0; i--){
dotnfc 0:db8030e71f55 870 pn532_packetbuffer[i + 1] = header[i];
dotnfc 0:db8030e71f55 871 }
dotnfc 0:db8030e71f55 872 pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
dotnfc 0:db8030e71f55 873
dotnfc 0:db8030e71f55 874 if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) {
dotnfc 0:db8030e71f55 875 return false;
dotnfc 0:db8030e71f55 876 }
dotnfc 0:db8030e71f55 877 }
dotnfc 0:db8030e71f55 878
dotnfc 0:db8030e71f55 879 if (0 > HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000)) {
dotnfc 0:db8030e71f55 880 return false;
dotnfc 0:db8030e71f55 881 }
dotnfc 0:db8030e71f55 882
dotnfc 0:db8030e71f55 883 if (0 != pn532_packetbuffer[0]) {
dotnfc 0:db8030e71f55 884 return false;
dotnfc 0:db8030e71f55 885 }
dotnfc 0:db8030e71f55 886
dotnfc 0:db8030e71f55 887 return true;
dotnfc 0:db8030e71f55 888 }
dotnfc 0:db8030e71f55 889
dotnfc 0:db8030e71f55 890 int16_t PN532::inRelease(const uint8_t relevantTarget){
dotnfc 0:db8030e71f55 891
dotnfc 0:db8030e71f55 892 pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
dotnfc 0:db8030e71f55 893 pn532_packetbuffer[1] = relevantTarget;
dotnfc 0:db8030e71f55 894
dotnfc 0:db8030e71f55 895 if (HAL(writeCommand)(pn532_packetbuffer, 2)) {
dotnfc 0:db8030e71f55 896 return 0;
dotnfc 0:db8030e71f55 897 }
dotnfc 0:db8030e71f55 898
dotnfc 0:db8030e71f55 899 // read data packet
dotnfc 0:db8030e71f55 900 return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
dotnfc 0:db8030e71f55 901 }
dotnfc 0:db8030e71f55 902
dotnfc 0:db8030e71f55 903