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