├── examples
├── apduToBlackBerry
│ ├── BlackBerry7
│ │ ├── res
│ │ │ └── img
│ │ │ │ └── icon.png
│ │ ├── .classpath
│ │ ├── .settings
│ │ │ └── org.eclipse.jdt.core.prefs
│ │ ├── .project
│ │ ├── build.xml
│ │ ├── src
│ │ │ └── mypackage
│ │ │ │ ├── MyApp.java
│ │ │ │ ├── ColorMixer.java
│ │ │ │ └── MyScreen.java
│ │ └── BlackBerry_App_Descriptor.xml
│ └── apduToBlackBerry.pde
├── iso14443a_uid
│ └── iso14443a_uid.pde
├── readMifareClassic
│ └── readMifareClassic.pde
├── ntag2xx_read
│ └── ntag2xx_read.pde
├── ntag2xx_erase
│ └── ntag2xx_erase.pde
├── readMifare
│ └── readMifare.pde
├── mifareclassic_updatendef
│ └── mifareclassic_updatendef.pde
├── mifareclassic_formatndef
│ └── mifareclassic_formatndef.pde
├── mifareclassic_memdump
│ └── mifareclassic_memdump.pde
├── ntag2xx_updatendef
│ └── ntag2xx_updatendef.pde
├── mifareclassic_ndeftoclassic
│ └── mifareclassic_ndeftoclassic.pde
└── ApplePay_Troyka_ACS
│ └── ApplePay_Troyka_ACS.ino
├── library.properties
├── README.txt
├── .github
├── PULL_REQUEST_TEMPLATE.md
└── ISSUE_TEMPLATE.md
├── license.txt
├── README.md
├── Adafruit_PN532.h
└── Adafruit_PN532.cpp
/examples/apduToBlackBerry/BlackBerry7/res/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhovner/Adafruit-PN532/HEAD/examples/apduToBlackBerry/BlackBerry7/res/img/icon.png
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=Adafruit PN532
2 | version=1.0.2
3 | author=Adafruit
4 | maintainer=Adafruit
5 | sentence=Arduino library for SPI and I2C access to the PN532 RFID/Near Field Communication chip
6 | paragraph=Arduino library for SPI and I2C access to the PN532 RFID/Near Field Communication chip
7 | category=Communication
8 | url=https://github.com/adafruit/Adafruit-PN532
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Fri Jun 22 00:02:13 EDT 2012
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.4
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore
12 | org.eclipse.jdt.core.compiler.source=1.3
13 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TargetEmulation
4 |
5 |
6 |
7 |
8 |
9 | net.rim.ejde.internal.builder.BlackBerryPreprocessBuilder
10 |
11 |
12 |
13 |
14 | net.rim.ejde.internal.builder.BlackBerryResourcesBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 |
25 | net.rim.ejde.BlackBerryPreProcessNature
26 | net.rim.ejde.BlackBerryProjectCoreNature
27 | org.eclipse.jdt.core.javanature
28 |
29 |
30 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | This is a library for the Adafruit PN532 NFC/RFID breakout boards
2 | This library works with the Adafruit NFC breakout
3 | ----> https://www.adafruit.com/products/364
4 |
5 | Check out the links above for our tutorials and wiring diagrams
6 | These chips use I2C or SPI to communicate.
7 |
8 | Adafruit invests time and resources providing this open source code,
9 | please support Adafruit and open-source hardware by purchasing
10 | products from Adafruit!
11 |
12 | Written by Limor Fried/Ladyada & Kevin Townsend for Adafruit Industries.
13 | BSD license, check license.txt for more information
14 | All text above must be included in any redistribution
15 |
16 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_PN532. Check that the Adafruit_PN532 folder contains Adafruit_PN532.cpp and Adafruit_PN532.h
17 |
18 | Place the Adafruit_PN532 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.
19 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/build.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code!
2 | Before you open the request please review the following guidelines and tips to
3 | help it be more easily integrated:
4 |
5 | - **Describe the scope of your change--i.e. what the change does and what parts
6 | of the code were modified.** This will help us understand any risks of integrating
7 | the code.
8 |
9 | - **Describe any known limitations with your change.** For example if the change
10 | doesn't apply to a supported platform of the library please mention it.
11 |
12 | - **Please run any tests or examples that can exercise your modified code.** We
13 | strive to not break users of the code and running tests/examples helps with this
14 | process.
15 |
16 | Thank you again for contributing! We will try to test and integrate the change
17 | as soon as we can, but be aware we have many GitHub repositories to manage and
18 | can't immediately respond to every request. There is no need to bump or check in
19 | on a pull request (it will clutter the discussion of the request).
20 |
21 | Also don't be worried if the request is closed or not integrated--sometimes the
22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the
23 | priorities of the pull request. Don't fret, the open source community thrives on
24 | forks and GitHub makes it easy to keep your changes in a forked repo.
25 |
26 | After reviewing the guidelines above you can delete this text from the pull request.
27 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Software License Agreement (BSD License)
2 |
3 | Copyright (c) 2012, Adafruit Industries
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 | 1. Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of the copyright holders nor the
14 | names of its contributors may be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/src/mypackage/MyApp.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2011, 2012, 2013 Research In Motion Limited.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | **/
16 | package mypackage;
17 |
18 | import net.rim.device.api.ui.UiApplication;
19 |
20 | /**
21 | * This class extends the UiApplication class, providing a
22 | * graphical user interface.
23 | */
24 | public class MyApp extends UiApplication
25 | {
26 | /**
27 | * Entry point for application
28 | * @param args Command line arguments (not used)
29 | */
30 | public static void main(String[] args)
31 | {
32 | // Create a new instance of the application and make the currently
33 | // running thread the application's event dispatch thread.
34 | MyApp theApp = new MyApp();
35 | theApp.enterEventDispatcher();
36 | }
37 |
38 |
39 | /**
40 | * Creates a new MyApp object
41 | */
42 | public MyApp()
43 | {
44 | // Push a screen onto the UI stack for rendering.
45 | pushScreen(new MyScreen());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/BlackBerry_App_Descriptor.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Thank you for opening an issue on an Adafruit Arduino library repository. To
2 | improve the speed of resolution please review the following guidelines and
3 | common troubleshooting steps below before creating the issue:
4 |
5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why
7 | something isn't working as expected. In many cases the problem is a common issue
8 | that you will more quickly receive help from the forum community. GitHub issues
9 | are meant for known defects in the code. If you don't know if there is a defect
10 | in the code then start with troubleshooting on the forum first.
11 |
12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully
13 | check all of the steps and commands to run have been followed. Consult the
14 | forum if you're unsure or have questions about steps in a guide/tutorial.
15 |
16 | - **For Arduino projects check these very common issues to ensure they don't apply**:
17 |
18 | - For uploading sketches or communicating with the board make sure you're using
19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
20 | very hard to tell the difference between a data and charge cable! Try using the
21 | cable with other devices or swapping to another cable to confirm it is not
22 | the problem.
23 |
24 | - **Be sure you are supplying adequate power to the board.** Check the specs of
25 | your board and plug in an external power supply. In many cases just
26 | plugging a board into your computer is not enough to power it and other
27 | peripherals.
28 |
29 | - **Double check all soldering joints and connections.** Flakey connections
30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
31 |
32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't
33 | guarantee a clone board will have the same functionality and work as expected
34 | with this code and don't support them.
35 |
36 | If you're sure this issue is a defect in the code and checked the steps above
37 | please fill in the following fields to provide enough troubleshooting information.
38 | You may delete the guideline and text above to just leave the following details:
39 |
40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
41 |
42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
43 | VERSION HERE**
44 |
45 | - List the steps to reproduce the problem below (if possible attach a sketch or
46 | copy the sketch code in too): **LIST REPRO STEPS BELOW**
47 |
--------------------------------------------------------------------------------
/examples/iso14443a_uid/iso14443a_uid.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file iso14443a_uid.pde
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | This example will attempt to connect to an ISO14443A
8 | card or tag and retrieve some basic information about it
9 | that can be used to determine what type of card it is.
10 |
11 | Note that you need the baud rate to be 115200 because we need to print
12 | out the data and read from the card at the same time!
13 |
14 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
15 | This library works with the Adafruit NFC breakout
16 | ----> https://www.adafruit.com/products/364
17 |
18 | Check out the links above for our tutorials and wiring diagrams
19 | These chips use SPI or I2C to communicate.
20 |
21 | Adafruit invests time and resources providing this open source code,
22 | please support Adafruit and open-source hardware by purchasing
23 | products from Adafruit!
24 |
25 | */
26 | /**************************************************************************/
27 | #include
28 | #include
29 | #include
30 |
31 | // If using the breakout with SPI, define the pins for SPI communication.
32 | #define PN532_SCK (2)
33 | #define PN532_MOSI (3)
34 | #define PN532_SS (4)
35 | #define PN532_MISO (5)
36 |
37 | // If using the breakout or shield with I2C, define just the pins connected
38 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
39 | #define PN532_IRQ (2)
40 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
41 |
42 | // Uncomment just _one_ line below depending on how your breakout or shield
43 | // is connected to the Arduino:
44 |
45 | // Use this line for a breakout with a SPI connection:
46 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
47 |
48 | // Use this line for a breakout with a hardware SPI connection. Note that
49 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
50 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
51 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
52 | //Adafruit_PN532 nfc(PN532_SS);
53 |
54 | // Or use this line for a breakout or shield with an I2C connection:
55 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
56 |
57 | #if defined(ARDUINO_ARCH_SAMD)
58 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
59 | // also change #define in Adafruit_PN532.cpp library file
60 | #define Serial SerialUSB
61 | #endif
62 |
63 | void setup(void) {
64 | #ifndef ESP8266
65 | while (!Serial); // for Leonardo/Micro/Zero
66 | #endif
67 | Serial.begin(115200);
68 | Serial.println("Hello!");
69 |
70 | nfc.begin();
71 |
72 | uint32_t versiondata = nfc.getFirmwareVersion();
73 | if (! versiondata) {
74 | Serial.print("Didn't find PN53x board");
75 | while (1); // halt
76 | }
77 |
78 | // Got ok data, print it out!
79 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
80 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
81 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
82 |
83 | // Set the max number of retry attempts to read from a card
84 | // This prevents us from waiting forever for a card, which is
85 | // the default behaviour of the PN532.
86 | nfc.setPassiveActivationRetries(0xFF);
87 |
88 | // configure board to read RFID tags
89 | nfc.SAMConfig();
90 |
91 | Serial.println("Waiting for an ISO14443A card");
92 | }
93 |
94 | void loop(void) {
95 | boolean success;
96 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
97 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
98 |
99 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found
100 | // 'uid' will be populated with the UID, and uidLength will indicate
101 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
102 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
103 |
104 | if (success) {
105 | Serial.println("Found a card!");
106 | Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
107 | Serial.print("UID Value: ");
108 | for (uint8_t i=0; i < uidLength; i++)
109 | {
110 | Serial.print(" 0x");Serial.print(uid[i], HEX);
111 | }
112 | Serial.println("");
113 | // Wait 1 second before continuing
114 | delay(1000);
115 | }
116 | else
117 | {
118 | // PN532 probably timed out waiting for a card
119 | Serial.println("Timed out waiting for a card");
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/examples/readMifareClassic/readMifareClassic.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file readMifareClassic.pde
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | This example will wait for any ISO14443A card or tag, and
8 | depending on the size of the UID will attempt to read from it.
9 |
10 | If the card has a 4-byte UID it is probably a Mifare
11 | Classic card, and the following steps are taken:
12 |
13 | Reads the 4 byte (32 bit) ID of a MiFare Classic card.
14 | Since the classic cards have only 32 bit identifiers you can stick
15 | them in a single variable and use that to compare card ID's as a
16 | number. This doesn't work for ultralight cards that have longer 7
17 | byte IDs!
18 |
19 | Note that you need the baud rate to be 115200 because we need to
20 | print out the data and read from the card at the same time!
21 |
22 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
23 | This library works with the Adafruit NFC breakout
24 | ----> https://www.adafruit.com/products/364
25 |
26 | Check out the links above for our tutorials and wiring diagrams
27 | These chips use SPI to communicate, 4 required to interface
28 |
29 | Adafruit invests time and resources providing this open source code,
30 | please support Adafruit and open-source hardware by purchasing
31 | products from Adafruit!
32 | */
33 | /**************************************************************************/
34 | #include
35 | #include
36 | #include
37 |
38 | // If using the breakout with SPI, define the pins for SPI communication.
39 | #define PN532_SCK (2)
40 | #define PN532_MOSI (3)
41 | #define PN532_SS (4)
42 | #define PN532_MISO (5)
43 |
44 | // If using the breakout or shield with I2C, define just the pins connected
45 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
46 | #define PN532_IRQ (2)
47 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
48 |
49 | // Uncomment just _one_ line below depending on how your breakout or shield
50 | // is connected to the Arduino:
51 |
52 | // Use this line for a breakout with a SPI connection:
53 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
54 |
55 | // Use this line for a breakout with a hardware SPI connection. Note that
56 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
57 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
58 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
59 | //Adafruit_PN532 nfc(PN532_SS);
60 |
61 | // Or use this line for a breakout or shield with an I2C connection:
62 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
63 |
64 | #if defined(ARDUINO_ARCH_SAMD)
65 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
66 | // also change #define in Adafruit_PN532.cpp library file
67 | #define Serial SerialUSB
68 | #endif
69 |
70 | void setup(void) {
71 | #ifndef ESP8266
72 | while (!Serial); // for Leonardo/Micro/Zero
73 | #endif
74 | Serial.begin(115200);
75 | Serial.println("Hello!");
76 |
77 | nfc.begin();
78 |
79 | uint32_t versiondata = nfc.getFirmwareVersion();
80 | if (! versiondata) {
81 | Serial.print("Didn't find PN53x board");
82 | while (1); // halt
83 | }
84 | // Got ok data, print it out!
85 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
86 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
87 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
88 |
89 | // configure board to read RFID tags
90 | nfc.SAMConfig();
91 |
92 | Serial.println("Waiting for an ISO14443A Card ...");
93 | }
94 |
95 |
96 | void loop(void) {
97 | uint8_t success;
98 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
99 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
100 |
101 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found
102 | // 'uid' will be populated with the UID, and uidLength will indicate
103 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
104 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
105 |
106 | if (success) {
107 | // Display some basic information about the card
108 | Serial.println("Found an ISO14443A card");
109 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
110 | Serial.print(" UID Value: ");
111 | nfc.PrintHex(uid, uidLength);
112 |
113 | if (uidLength == 4)
114 | {
115 | // We probably have a Mifare Classic card ...
116 | uint32_t cardid = uid[0];
117 | cardid <<= 8;
118 | cardid |= uid[1];
119 | cardid <<= 8;
120 | cardid |= uid[2];
121 | cardid <<= 8;
122 | cardid |= uid[3];
123 | Serial.print("Seems to be a Mifare Classic card #");
124 | Serial.println(cardid);
125 | }
126 | Serial.println("");
127 | }
128 | }
129 |
130 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/src/mypackage/ColorMixer.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2011, 2012, 2013 Research In Motion Limited.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | **/
16 | package mypackage;
17 |
18 | import net.rim.device.api.ui.Field;
19 | import net.rim.device.api.ui.Graphics;
20 | import net.rim.device.api.ui.TouchEvent;
21 |
22 | public class ColorMixer extends Field {
23 | private static final int[] colors = new int[] { 0xff0000, 0xff00, 0xff };
24 | private int barGap = 5;
25 |
26 | private int barHeight = 64;
27 | private int color;
28 | private MyScreen owner;
29 |
30 | private double r, g, b;
31 |
32 | public ColorMixer(MyScreen owner) {
33 | this.owner = owner;
34 | }
35 |
36 | protected void layout(int width, int height) {
37 | setExtent(640, barHeight * 3 + barGap * 2);
38 | }
39 |
40 | protected void paint(Graphics graphics) {
41 | int barWidth = getWidth() - barHeight * 3 - barGap * 3;
42 | double[] values = new double[] { r, g, b };
43 |
44 | // Draw color sliders
45 | for (int i = 0; i < 3; ++i) {
46 | int top = i * (barHeight + barGap);
47 | int toDraw = (int) (values[i] * barWidth + 0.5);
48 | graphics.setColor(0);
49 | graphics.fillRect(toDraw, top, barWidth - toDraw, barHeight);
50 |
51 | graphics.setColor(colors[i]);
52 | graphics.fillRect(0, top, toDraw, barHeight);
53 |
54 | graphics.setColor(0x7f7f7f);
55 | graphics.drawRect(0, top, barWidth, barHeight);
56 | }
57 |
58 | // Draw mixed down color
59 | int boxWidth = barHeight * 3 + barGap * 2;
60 | graphics.setColor(color);
61 | graphics.fillRect(getWidth() - 1 - boxWidth, 0, boxWidth, boxWidth);
62 |
63 | graphics.setColor(0x7f7f7f);
64 | graphics.drawRect(getWidth() - 1 - boxWidth, 0, boxWidth, boxWidth);
65 | }
66 |
67 | public void setColor(int color) {
68 | if (color != this.color) {
69 | this.color = color;
70 | r = ((color >> 16) & 0xff) / 255.0;
71 | g = ((color >> 8) & 0xff) / 255.0;
72 | b = (color & 0xff) / 255.0;
73 | invalidate();
74 | }
75 | }
76 |
77 | private void setPart(int which, double value) {
78 | double source = which == 0 ? r : which == 1 ? g : b;
79 | if (value == source) {
80 | return;
81 | }
82 | int bv = (int) (value * 255 + 0.5);
83 | bv &= 0xff;
84 | if (which == 0) {
85 | r = value;
86 | color &= 0xffff;
87 | color |= bv << 16;
88 | } else if (which == 1) {
89 | g = value;
90 | color &= 0xff00ff;
91 | color |= bv << 8;
92 | } else {
93 | b = value;
94 | color &= 0xffff00;
95 | color |= bv;
96 | }
97 | owner.setColor(color);
98 | invalidate();
99 | }
100 |
101 | private int touchTarget = -1;
102 |
103 | protected boolean touchEvent(TouchEvent message) {
104 | int event = message.getEvent();
105 |
106 | int x = message.getX(1);
107 | int y = message.getY(1);
108 |
109 | int barWidth = getWidth() - barHeight * 3 - barGap * 3;
110 |
111 | if (event == TouchEvent.UP) {
112 | touchTarget = -1;
113 | return false;
114 | } else if (event == TouchEvent.DOWN) {
115 | if (y < -5 || y > getWidth() + 5) {
116 | return false;
117 | }
118 |
119 | if (x <= barWidth) {
120 | for (int i = 0; i < 3; ++i) {
121 | if (y < 0) {
122 | break;
123 | }
124 | if (y < barHeight) {
125 | touchTarget = i;
126 | break;
127 | }
128 | y -= barHeight;
129 | y -= barGap;
130 | }
131 | } else {
132 | return false;
133 | }
134 | }
135 |
136 | if (touchTarget == -1) {
137 | return false;
138 | }
139 |
140 | double newValue = 1.0 * x / barWidth;
141 | if (newValue < 0) {
142 | newValue = 0;
143 | }
144 | if (newValue > 1) {
145 | newValue = 1;
146 | }
147 |
148 | setPart(touchTarget, newValue);
149 |
150 | return true;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/apduToBlackBerry.pde:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2011, 2012, 2013 Research In Motion Limited.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | **/
16 | #include
17 | #include
18 | #include
19 |
20 | // If using the breakout with SPI, define the pins for SPI communication.
21 | #define PN532_SCK (2)
22 | #define PN532_MOSI (3)
23 | #define PN532_SS (4)
24 | #define PN532_MISO (5)
25 |
26 | // If using the breakout or shield with I2C, define just the pins connected
27 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
28 | #define PN532_IRQ (2)
29 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
30 |
31 | // Uncomment just _one_ line below depending on how your breakout or shield
32 | // is connected to the Arduino:
33 |
34 | // Use this line for a breakout with a SPI connection:
35 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
36 |
37 | // Use this line for a breakout with a hardware SPI connection. Note that
38 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
39 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
40 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
41 | //Adafruit_PN532 nfc(PN532_SS);
42 |
43 | // Or use this line for a breakout or shield with an I2C connection:
44 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
45 |
46 | // PWM LED will be on the following PINs.
47 | #define R_PIN (9)
48 | #define G_PIN (10)
49 | #define B_PIN (11)
50 |
51 | // Initial values of RGB.
52 | uint8_t r = 0x00;
53 | uint8_t g = 0x00;
54 | uint8_t b = 0x7f;
55 |
56 | /**
57 | * Write the current color to the output pins.
58 | */
59 | void showColor() {
60 | analogWrite(R_PIN,r);
61 | analogWrite(G_PIN,g);
62 | analogWrite(B_PIN,b);
63 | }
64 |
65 | #if defined(ARDUINO_ARCH_SAMD)
66 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
67 | // also change #define in Adafruit_PN532.cpp library file
68 | #define Serial SerialUSB
69 | #endif
70 |
71 | void setup() {
72 | #ifndef ESP8266
73 | while (!Serial); // for Leonardo/Micro/Zero
74 | #endif
75 | Serial.begin(115200);
76 |
77 | pinMode(R_PIN,OUTPUT);
78 | pinMode(G_PIN,OUTPUT);
79 | pinMode(B_PIN,OUTPUT);
80 | showColor();
81 |
82 | nfc.begin();
83 |
84 | uint32_t versiondata = nfc.getFirmwareVersion();
85 | if (! versiondata) {
86 | Serial.println("Did not find the shield - locking up");
87 | while (true) {
88 | }
89 | }
90 |
91 | Serial.print("Found chip PN5");
92 | Serial.println((versiondata>>24) & 0xFF, HEX);
93 | Serial.print("Firmware ver. ");
94 | Serial.print((versiondata>>16) & 0xFF, DEC);
95 | Serial.print('.');
96 | Serial.println((versiondata>>8) & 0xFF, DEC);
97 |
98 | // configure board to read RFID tags
99 | nfc.SAMConfig();
100 |
101 | nfc.begin();
102 | }
103 |
104 | uint8_t message[4];
105 |
106 | void loop(void) {
107 | uint8_t i;
108 |
109 | // Serial.println("Listening...");
110 | if (nfc.inListPassiveTarget()) {
111 | // Serial.println("Something's there...");
112 | while(true) {
113 | message[0] = 1;
114 | message[1] = r;
115 | message[2] = g;
116 | message[3] = b;
117 | uint8_t responseLength = sizeof(message);
118 | if (nfc.inDataExchange(message,sizeof(message),message,&responseLength)) {
119 | uint8_t command = message[0];
120 | switch(command) {
121 | case 0:
122 | // NOP
123 | break;
124 | case 1:
125 | if (responseLength==4) {
126 | r = message[1];
127 | g = message[2];
128 | b = message[3];
129 | showColor();
130 | //Serial.print("Read a color: ");
131 | //for (i=0; i<3; ++i) {
132 | // Serial.print(message[i+1],HEX);
133 | // Serial.print(' ');
134 | //}
135 | //Serial.println();
136 | }
137 | else {
138 | //Serial.println("Doesn't seem to be a color...");
139 | }
140 | break;
141 | default:
142 | //Serial.print("Unknown command ");
143 | //Serial.println(message[0]);
144 | ;
145 | }
146 | delay(10);
147 | }
148 | else {
149 | //Serial.println("It's gone...");
150 | break;
151 | }
152 | }
153 | }
154 | else {
155 | //Serial.print("Trying again...");
156 | }
157 | }
158 |
159 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Changelog
2 | What changed in genuine Adafrauit PN532 library
3 |
4 | * **_inListedTag** -- tag number for `inDataExchange` method. Defined as `0x1` because `0x0` returns error.
5 | * **PN532_PACKBUFFSIZ** -- increased from 64 to 255 to read long responses from EMV cards.
6 | * **New example** -- Access Control reader based on PayWave/PayPass/ApplePay and Troyka cards (very dumb demo)
7 |
8 | ## Note for 7 byte UID Mifare Classic cards (Mifare Plus in legacy mode)
9 | For 7 byte UID Mifare's only last 4 byte should be used for authenticate sectors.
10 | This library have bug in examples that passes all 7 bytes to authenticate command.
11 |
12 | ### PN532 Command example
13 |
14 | If you have UID `0x04 0x33 0x18 0xEA 0x70 0x32 0x80`
15 |
16 | and want to authenticate block 4 (sector 1), then full PN532 command will be:
17 |
18 | `0xD4 0x40 0x01 0x60 0x04 0xA7 0x3F 0x5D 0xC1 0xD3 0x33 0xEA 0x70 0x32 0x80`
19 | (without PREAMBLE/POSTAMBLE and checksums)
20 |
21 | Command structure:
22 |
23 | * `0xD4` — **TFI** from host controller to PN532
24 | * `0x40` — **InDataExchange** command
25 | * `0x01` — **Tg** byte number of target (card)
26 | * `0x60` — **Mifare command** authenticate with key A
27 | * `0xA7 0x3F 0x5D 0xC1 0xD3 0x33` — **Mifare Key A** for authenticated sector
28 | * `0xEA 0x70 0x32 0x80` — **Last 4 bytes of UID**
29 |
30 |
31 | ### PN532 Response example
32 | Successfully authenticated response: `0x00 0x00 0xFF 0x03 0xFD 0xD5 0x41 0x00`
33 |
34 | If you pass all 7 bytes UID to auth command, you will get `syntax error` response from PN532.
35 | This library is incorrectry handle `syntax error` response from pn532.
36 |
37 | Syntax error respone: `0x00 0x00 0xFF 0x01 0xFF 0x7F 0x81 0x00`
38 |
39 |
40 |
41 |
42 |
43 |
44 | ---
45 |
46 | Source document: https://www.nxp.com/docs/en/user-guide/141520.pdf
47 |
48 | # 6.2 PN532 Host controller communication protocol
49 |
50 | Communication between the host controller and the PN532 is performed through frames, in a half-duplex mode.
51 | Four different types of frames are used in one or both directions (host controller to the PN532 and PN532 to the host controller).
52 |
53 |
54 | ## 6.2.1.1 Normal information frame
55 |
56 | Information frames are used to convey:
57 | * Commands from the host controller to the PN532,
58 | * And responses to these commands from the PN532 to the host controller.
59 |
60 | ### The structure of this frame is the following:
61 |
62 | 
63 |
64 |
65 | * **PREAMBLE** — 1 byte (0x00)
66 | * **START CODE** — 2 bytes (0x00 and 0xFF)
67 | * **LEN** — 1 byte indicating the number of bytes in the data field (TFI and PD0 to PDn)
68 | * **LCS** — 1 Packet Length Checksum LCS byte that satisfies the relation: Lower byte of [LEN + LCS] = 0x00
69 | * **TFI** — 1 byte frame identifier, the value of this byte depends on the way of the message:
70 | - **D4h** in case of a frame from the host controller to the PN532
71 | - **D5h** in case of a frame from the PN532 to the host controller
72 | * **DATA** — LEN-1 bytes of Packet Data Information The first byte PD0 is the Command Code
73 | * **DCS** — 1 Data Checksum DCS byte that satisfies the relation: Lower byte of [TFI + PD0 + PD1 + ... + PDn + DCS] = 0x00
74 | * **POSTAMBLE** — 1 byte (0x00)
75 |
76 | The amount of data that can be exchanged using this frame structure is limited to 255 bytes (including TFI).
77 |
78 | ## 6.2.1.2 Extended information frame
79 |
80 | The information frame has an extended definition allowing exchanging more data between the host controller and the PN532.
81 | In the firmware implementation of the PN532, the maximum length of the packet data is limited to 264 bytes (265 bytes with TFI included).
82 |
83 | ### The structure of this frame is the following:
84 | 
85 |
86 | The normal LEN and LCS fields are fixed to the 0xFF value, which is normally considered as erroneous frame, due to the fact that the checksum does not fit.
87 | The real length is then coded in the two following bytes LENM (MSByte) and LENL (LSByte) with:
88 |
89 | **LENGTH** = **LEN**M x 256 + **LENL** coding the number of bytes in the data field (TFI and PD0 to PDn)
90 | * **LCS** — 1 Packet Length Checksum LCS byte that satisfies the relation: Lower byte of [LENM + LENL + LCS] = 0x00
91 | * **DATA** — LENGTH-1 bytes of Packet Data Information The first byte PD0 is the Command Code.
92 |
93 | The host controller, for sending frame whose length is less than 255 bytes, can also use this type of frame.
94 | But, the PN532 always uses the suitable type of frame, depending on the length (Normal Information Frame for frame <= 255 bytes and Extended Information Frame for frame > 255 bytes).
95 |
96 |
97 | ## 6.2.1.3 ACK frame
98 | The specific ACK frame is used for the synchronization of the packets and also for the abort mechanism.
99 | This frame may be used either from the host controller to the PN532 or from the PN532 to the host controller to indicate that the previous frame has been successfully received.
100 |
101 | ### ACK frame:
102 | 
103 |
104 | ## 6.2.1.4 NACK frame
105 | The specific NACK frame is used for the synchronization of the packets.
106 | This frame is used only from the host controller to the PN532 to indicate that the previous response frame has not been successfully received, then asking for the retransmission of the last response frame from the PN532 to the host controller.
107 |
108 | ### NACK frame:
109 | 
110 |
111 | ## 6.2.1.5 Error frame
112 | The syntax error frame is used to inform the host controller that the PN532 has detected an error at the application level.
113 |
114 | ### Error frame:
115 | 
116 |
117 | ## 6.2.1.6 Preamble and Postamble
118 | These two specific fields of the frames are described in the previous paragraphs as single byte, which the value is 0x00.
119 | In fact, these fields can be composed with an undetermined number of bytes.
120 |
121 |
122 |
--------------------------------------------------------------------------------
/examples/apduToBlackBerry/BlackBerry7/src/mypackage/MyScreen.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright (c) 2011, 2012, 2013 Research In Motion Limited.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | **/
16 | package mypackage;
17 |
18 | import net.rim.device.api.io.nfc.NFCException;
19 | import net.rim.device.api.io.nfc.emulation.VirtualISO14443Part4TargetCallback;
20 | import net.rim.device.api.io.nfc.emulation.VirtualISO14443Part4TypeATarget;
21 | import net.rim.device.api.ui.Field;
22 | import net.rim.device.api.ui.FieldChangeListener;
23 | import net.rim.device.api.ui.component.CheckboxField;
24 | import net.rim.device.api.ui.component.LabelField;
25 | import net.rim.device.api.ui.container.MainScreen;
26 | import net.rim.device.api.ui.decor.BackgroundFactory;
27 |
28 | /**
29 | * A class extending the MainScreen class, which provides default standard
30 | * behavior for BlackBerry GUI applications.
31 | */
32 | public final class MyScreen extends MainScreen implements
33 | VirtualISO14443Part4TargetCallback, FieldChangeListener {
34 |
35 | private int color = 0x7f7f7f;
36 |
37 | private boolean colorQueued = false;
38 | private CheckboxField colorQueueLocked;
39 | private VirtualISO14443Part4TypeATarget emulated;
40 | private ColorMixer mixer;
41 |
42 | private LabelField status;
43 |
44 | /**
45 | * Creates a new MyScreen object
46 | */
47 | public MyScreen() {
48 | // Set the displayed title of the screen
49 | setTitle("Colour Control Setter");
50 | setBackground(BackgroundFactory.createSolidBackground(0x3f3f3f));
51 |
52 | add(new LabelField(""));
53 | add(colorQueueLocked = new CheckboxField("Lock Color", false));
54 | colorQueueLocked.setChangeListener(this);
55 |
56 | add(mixer = new ColorMixer(this));
57 | mixer.setColor(0x7f7f7f);
58 |
59 | add(status = new LabelField(""));
60 |
61 | try {
62 | emulated = new VirtualISO14443Part4TypeATarget(this, "10451045",
63 | null);
64 | log("created");
65 | emulated.startEmulation();
66 | log("emulating");
67 | } catch (NFCException e) {
68 | log("Failed to listen");
69 | status.setText(e.getClass().getName() + " " + e.getMessage());
70 | e.printStackTrace();
71 | }
72 | }
73 |
74 | // private TextField textField;
75 |
76 | public void fieldChanged(Field field, int context) {
77 | if (colorQueueLocked.getChecked()) {
78 | setColor(color);
79 | } else {
80 | colorQueued = false;
81 | status.setText("");
82 | }
83 | }
84 |
85 | private boolean isColorQueueLocked() {
86 | return colorQueueLocked.getChecked();
87 | }
88 |
89 | protected void log(String message) {
90 | System.out.println("SUPERDUPER: " + message);
91 | // textField.setText(textField.getText() + "\n" + message);
92 | }
93 |
94 | public void onVirtualTargetEvent(int targetEvent) {
95 | log("Target event: " + targetEvent);
96 | }
97 |
98 | public byte[] processCommand(byte[] command) {
99 | byte[] toReturn = processCommandInternal(command);
100 | String message = "[" + toString(command) + "," + toString(toReturn)
101 | + "]";
102 | // status.setText(message);
103 | // log(message);
104 | return toReturn;
105 | }
106 |
107 | private byte[] processCommandInternal(byte[] command) {
108 | if (command == null) {
109 | return new byte[0];
110 | }
111 | int messageType = command[0] & 0xff;
112 | switch (messageType) {
113 | case 1:
114 | if (command.length == 4) {
115 | int colorIn = (command[1] & 0xff) << 16;
116 | colorIn |= (command[2] & 0xff) << 8;
117 | colorIn |= (command[3] & 0xff);
118 |
119 | if (colorIn != color) {
120 | if (colorQueued) {
121 |
122 | byte[] toReturn = new byte[4];
123 | toReturn[0] = 1;
124 | toReturn[1] = (byte) (color >> 16);
125 | toReturn[2] = (byte) (color >> 8);
126 | toReturn[3] = (byte) color;
127 |
128 | if (!isColorQueueLocked()) {
129 | colorQueued = false;
130 | status.setText("");
131 | }
132 |
133 | return toReturn;
134 | } else {
135 | this.color = colorIn;
136 | mixer.setColor(colorIn);
137 | }
138 | }
139 | }
140 | break;
141 | }
142 | return new byte[] { 0 };
143 | }
144 |
145 | public void setColor(int color) {
146 | colorQueued = true;
147 | this.color = color;
148 | status.setText("#" + toHex(color));
149 | }
150 |
151 | private String toHex(int i) {
152 | String toReturn = "000000" + Integer.toString(i, 16);
153 | return toReturn.substring(toReturn.length() - 6);
154 | }
155 |
156 | private String toString(byte[] command) {
157 | String toReturn = "";
158 | for (int i = 0; i < command.length; ++i) {
159 | toReturn += Integer.toString(command[i] & 0xff, 16) + " ";
160 | }
161 | return toReturn;
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/examples/ntag2xx_read/ntag2xx_read.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file readntag203.pde
4 | @author KTOWN (Adafruit Industries)
5 | @license BSD (see license.txt)
6 |
7 | This example will wait for any NTAG203 or NTAG213 card or tag,
8 | and will attempt to read from it.
9 |
10 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
11 | This library works with the Adafruit NFC breakout
12 | ----> https://www.adafruit.com/products/364
13 |
14 | Check out the links above for our tutorials and wiring diagrams
15 | These chips use SPI or I2C to communicate.
16 |
17 | Adafruit invests time and resources providing this open source code,
18 | please support Adafruit and open-source hardware by purchasing
19 | products from Adafruit!
20 | */
21 | /**************************************************************************/
22 | #include
23 | #include
24 | #include
25 |
26 | // If using the breakout with SPI, define the pins for SPI communication.
27 | #define PN532_SCK (2)
28 | #define PN532_MOSI (3)
29 | #define PN532_SS (4)
30 | #define PN532_MISO (5)
31 |
32 | // If using the breakout or shield with I2C, define just the pins connected
33 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
34 | #define PN532_IRQ (2)
35 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
36 |
37 | // Uncomment just _one_ line below depending on how your breakout or shield
38 | // is connected to the Arduino:
39 |
40 | // Use this line for a breakout with a software SPI connection (recommended):
41 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
42 |
43 | // Use this line for a breakout with a hardware SPI connection. Note that
44 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
45 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
46 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
47 | //Adafruit_PN532 nfc(PN532_SS);
48 |
49 | // Or use this line for a breakout or shield with an I2C connection:
50 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
51 |
52 | #if defined(ARDUINO_ARCH_SAMD)
53 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
54 | // also change #define in Adafruit_PN532.cpp library file
55 | #define Serial SerialUSB
56 | #endif
57 |
58 | void setup(void) {
59 | #ifndef ESP8266
60 | while (!Serial); // for Leonardo/Micro/Zero
61 | #endif
62 | Serial.begin(115200);
63 | Serial.println("Hello!");
64 |
65 | nfc.begin();
66 |
67 | uint32_t versiondata = nfc.getFirmwareVersion();
68 | if (! versiondata) {
69 | Serial.print("Didn't find PN53x board");
70 | while (1); // halt
71 | }
72 | // Got ok data, print it out!
73 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
74 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
75 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
76 |
77 | // configure board to read RFID tags
78 | nfc.SAMConfig();
79 |
80 | Serial.println("Waiting for an ISO14443A Card ...");
81 | }
82 |
83 | void loop(void) {
84 | uint8_t success;
85 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
86 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
87 |
88 | // Wait for an NTAG203 card. When one is found 'uid' will be populated with
89 | // the UID, and uidLength will indicate the size of the UUID (normally 7)
90 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
91 |
92 | if (success) {
93 | // Display some basic information about the card
94 | Serial.println("Found an ISO14443A card");
95 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
96 | Serial.print(" UID Value: ");
97 | nfc.PrintHex(uid, uidLength);
98 | Serial.println("");
99 |
100 | if (uidLength == 7)
101 | {
102 | uint8_t data[32];
103 |
104 | // We probably have an NTAG2xx card (though it could be Ultralight as well)
105 | Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
106 |
107 | // NTAG2x3 cards have 39*4 bytes of user pages (156 user bytes),
108 | // starting at page 4 ... larger cards just add pages to the end of
109 | // this range:
110 |
111 | // See: http://www.nxp.com/documents/short_data_sheet/NTAG203_SDS.pdf
112 |
113 | // TAG Type PAGES USER START USER STOP
114 | // -------- ----- ---------- ---------
115 | // NTAG 203 42 4 39
116 | // NTAG 213 45 4 39
117 | // NTAG 215 135 4 129
118 | // NTAG 216 231 4 225
119 |
120 | for (uint8_t i = 0; i < 42; i++)
121 | {
122 | success = nfc.ntag2xx_ReadPage(i, data);
123 |
124 | // Display the current page number
125 | Serial.print("PAGE ");
126 | if (i < 10)
127 | {
128 | Serial.print("0");
129 | Serial.print(i);
130 | }
131 | else
132 | {
133 | Serial.print(i);
134 | }
135 | Serial.print(": ");
136 |
137 | // Display the results, depending on 'success'
138 | if (success)
139 | {
140 | // Dump the page data
141 | nfc.PrintHexChar(data, 4);
142 | }
143 | else
144 | {
145 | Serial.println("Unable to read the requested page!");
146 | }
147 | }
148 | }
149 | else
150 | {
151 | Serial.println("This doesn't seem to be an NTAG203 tag (UUID length != 7 bytes)!");
152 | }
153 |
154 | // Wait a bit before trying again
155 | Serial.println("\n\nSend a character to scan another tag!");
156 | Serial.flush();
157 | while (!Serial.available());
158 | while (Serial.available()) {
159 | Serial.read();
160 | }
161 | Serial.flush();
162 | }
163 | }
164 |
165 |
--------------------------------------------------------------------------------
/examples/ntag2xx_erase/ntag2xx_erase.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file ntag2xx_erase.pde
4 | @author KTOWN (Adafruit Industries)
5 | @license BSD (see license.txt)
6 |
7 | This example will wait for any NTAG203 or NTAG213 card or tag,
8 | and will attempt to erase the user data section of the card (setting
9 | all user bytes to 0x00)
10 |
11 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
12 | This library works with the Adafruit NFC breakout
13 | ----> https://www.adafruit.com/products/364
14 |
15 | Check out the links above for our tutorials and wiring diagrams
16 | These chips use SPI or I2C to communicate.
17 |
18 | Adafruit invests time and resources providing this open source code,
19 | please support Adafruit and open-source hardware by purchasing
20 | products from Adafruit!
21 | */
22 | /**************************************************************************/
23 | #include
24 | #include
25 | #include
26 |
27 | // If using the breakout with SPI, define the pins for SPI communication.
28 | #define PN532_SCK (2)
29 | #define PN532_MOSI (3)
30 | #define PN532_SS (4)
31 | #define PN532_MISO (5)
32 |
33 | // If using the breakout or shield with I2C, define just the pins connected
34 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
35 | #define PN532_IRQ (2)
36 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
37 |
38 | // Uncomment just _one_ line below depending on how your breakout or shield
39 | // is connected to the Arduino:
40 |
41 | // Use this line for a breakout with a software SPI connection (recommended):
42 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
43 |
44 | // Use this line for a breakout with a hardware SPI connection. Note that
45 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
46 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
47 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
48 | //Adafruit_PN532 nfc(PN532_SS);
49 |
50 | // Or use this line for a breakout or shield with an I2C connection:
51 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
52 |
53 | #if defined(ARDUINO_ARCH_SAMD)
54 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
55 | // also change #define in Adafruit_PN532.cpp library file
56 | #define Serial SerialUSB
57 | #endif
58 |
59 | void setup(void) {
60 | #ifndef ESP8266
61 | while (!Serial); // for Leonardo/Micro/Zero
62 | #endif
63 | Serial.begin(115200);
64 | Serial.println("Hello!");
65 |
66 | nfc.begin();
67 |
68 | uint32_t versiondata = nfc.getFirmwareVersion();
69 | if (! versiondata) {
70 | Serial.print("Didn't find PN53x board");
71 | while (1); // halt
72 | }
73 | // Got ok data, print it out!
74 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
75 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
76 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
77 |
78 | // configure board to read RFID tags
79 | nfc.SAMConfig();
80 |
81 | Serial.println("Waiting for an ISO14443A Card ...");
82 | }
83 |
84 | void loop(void) {
85 | uint8_t success;
86 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
87 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
88 |
89 | // Wait for an NTAG203 card. When one is found 'uid' will be populated with
90 | // the UID, and uidLength will indicate the size of the UUID (normally 7)
91 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
92 |
93 | if (success) {
94 | // Display some basic information about the card
95 | Serial.println("Found an ISO14443A card");
96 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
97 | Serial.print(" UID Value: ");
98 | nfc.PrintHex(uid, uidLength);
99 | Serial.println("");
100 |
101 | if (uidLength == 7)
102 | {
103 | uint8_t data[32];
104 |
105 | // We probably have an NTAG2xx card (though it could be Ultralight as well)
106 | Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
107 |
108 | // NTAG2x3 cards have 39*4 bytes of user pages (156 user bytes),
109 | // starting at page 4 ... larger cards just add pages to the end of
110 | // this range:
111 |
112 | // See: http://www.nxp.com/documents/short_data_sheet/NTAG203_SDS.pdf
113 |
114 | // TAG Type PAGES USER START USER STOP
115 | // -------- ----- ---------- ---------
116 | // NTAG 203 42 4 39
117 | // NTAG 213 45 4 39
118 | // NTAG 215 135 4 129
119 | // NTAG 216 231 4 225
120 |
121 | Serial.println("");
122 | Serial.println("Writing 0x00 0x00 0x00 0x00 to pages 4..29");
123 | Serial.println("");
124 | for (uint8_t i = 4; i < 39; i++)
125 | {
126 | memset(data, 0, 4);
127 | success = nfc.ntag2xx_WritePage(i, data);
128 |
129 | // Display the current page number
130 | Serial.print("Page ");
131 | if (i < 10)
132 | {
133 | Serial.print("0");
134 | Serial.print(i);
135 | }
136 | else
137 | {
138 | Serial.print(i);
139 | }
140 | Serial.print(": ");
141 |
142 | // Display the results, depending on 'success'
143 | if (success)
144 | {
145 | Serial.println("Erased");
146 | }
147 | else
148 | {
149 | Serial.println("Unable to write to the requested page!");
150 | }
151 | }
152 | }
153 | else
154 | {
155 | Serial.println("This doesn't seem to be an NTAG203 tag (UUID length != 7 bytes)!");
156 | }
157 |
158 | // Wait a bit before trying again
159 | Serial.println("\n\nSend a character to scan another tag!");
160 | Serial.flush();
161 | while (!Serial.available());
162 | while (Serial.available()) {
163 | Serial.read();
164 | }
165 | Serial.flush();
166 | }
167 | }
168 |
169 |
--------------------------------------------------------------------------------
/examples/readMifare/readMifare.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file readMifare.pde
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | This example will wait for any ISO14443A card or tag, and
8 | depending on the size of the UID will attempt to read from it.
9 |
10 | If the card has a 4-byte UID it is probably a Mifare
11 | Classic card, and the following steps are taken:
12 |
13 | - Authenticate block 4 (the first block of Sector 1) using
14 | the default KEYA of 0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
15 | - If authentication succeeds, we can then read any of the
16 | 4 blocks in that sector (though only block 4 is read here)
17 |
18 | If the card has a 7-byte UID it is probably a Mifare
19 | Ultralight card, and the 4 byte pages can be read directly.
20 | Page 4 is read by default since this is the first 'general-
21 | purpose' page on the tags.
22 |
23 |
24 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
25 | This library works with the Adafruit NFC breakout
26 | ----> https://www.adafruit.com/products/364
27 |
28 | Check out the links above for our tutorials and wiring diagrams
29 | These chips use SPI or I2C to communicate.
30 |
31 | Adafruit invests time and resources providing this open source code,
32 | please support Adafruit and open-source hardware by purchasing
33 | products from Adafruit!
34 |
35 | */
36 | /**************************************************************************/
37 | #include
38 | #include
39 | #include
40 |
41 | // If using the breakout with SPI, define the pins for SPI communication.
42 | #define PN532_SCK (2)
43 | #define PN532_MOSI (3)
44 | #define PN532_SS (4)
45 | #define PN532_MISO (5)
46 |
47 | // If using the breakout or shield with I2C, define just the pins connected
48 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
49 | #define PN532_IRQ (2)
50 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
51 |
52 | // Uncomment just _one_ line below depending on how your breakout or shield
53 | // is connected to the Arduino:
54 |
55 | // Use this line for a breakout with a software SPI connection (recommended):
56 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
57 |
58 | // Use this line for a breakout with a hardware SPI connection. Note that
59 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
60 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
61 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
62 | //Adafruit_PN532 nfc(PN532_SS);
63 |
64 | // Or use this line for a breakout or shield with an I2C connection:
65 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
66 |
67 | #if defined(ARDUINO_ARCH_SAMD)
68 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
69 | // also change #define in Adafruit_PN532.cpp library file
70 | #define Serial SerialUSB
71 | #endif
72 |
73 | void setup(void) {
74 | #ifndef ESP8266
75 | while (!Serial); // for Leonardo/Micro/Zero
76 | #endif
77 | Serial.begin(115200);
78 | Serial.println("Hello!");
79 |
80 | nfc.begin();
81 |
82 | uint32_t versiondata = nfc.getFirmwareVersion();
83 | if (! versiondata) {
84 | Serial.print("Didn't find PN53x board");
85 | while (1); // halt
86 | }
87 | // Got ok data, print it out!
88 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
89 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
90 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
91 |
92 | // configure board to read RFID tags
93 | nfc.SAMConfig();
94 |
95 | Serial.println("Waiting for an ISO14443A Card ...");
96 | }
97 |
98 |
99 | void loop(void) {
100 | uint8_t success;
101 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
102 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
103 |
104 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found
105 | // 'uid' will be populated with the UID, and uidLength will indicate
106 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
107 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
108 |
109 | if (success) {
110 | // Display some basic information about the card
111 | Serial.println("Found an ISO14443A card");
112 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
113 | Serial.print(" UID Value: ");
114 | nfc.PrintHex(uid, uidLength);
115 | Serial.println("");
116 |
117 | if (uidLength == 4)
118 | {
119 | // We probably have a Mifare Classic card ...
120 | Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
121 |
122 | // Now we need to try to authenticate it for read/write access
123 | // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
124 | Serial.println("Trying to authenticate block 4 with default KEYA value");
125 | uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
126 |
127 | // Start with block 4 (the first block of sector 1) since sector 0
128 | // contains the manufacturer data and it's probably better just
129 | // to leave it alone unless you know what you're doing
130 | success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
131 |
132 | if (success)
133 | {
134 | Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
135 | uint8_t data[16];
136 |
137 | // If you want to write something to block 4 to test with, uncomment
138 | // the following line and this text should be read back in a minute
139 | //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data);
140 | // success = nfc.mifareclassic_WriteDataBlock (4, data);
141 |
142 | // Try to read the contents of block 4
143 | success = nfc.mifareclassic_ReadDataBlock(4, data);
144 |
145 | if (success)
146 | {
147 | // Data seems to have been read ... spit it out
148 | Serial.println("Reading Block 4:");
149 | nfc.PrintHexChar(data, 16);
150 | Serial.println("");
151 |
152 | // Wait a bit before reading the card again
153 | delay(1000);
154 | }
155 | else
156 | {
157 | Serial.println("Ooops ... unable to read the requested block. Try another key?");
158 | }
159 | }
160 | else
161 | {
162 | Serial.println("Ooops ... authentication failed: Try another key?");
163 | }
164 | }
165 |
166 | if (uidLength == 7)
167 | {
168 | // We probably have a Mifare Ultralight card ...
169 | Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");
170 |
171 | // Try to read the first general-purpose user page (#4)
172 | Serial.println("Reading page 4");
173 | uint8_t data[32];
174 | success = nfc.mifareultralight_ReadPage (4, data);
175 | if (success)
176 | {
177 | // Data seems to have been read ... spit it out
178 | nfc.PrintHexChar(data, 4);
179 | Serial.println("");
180 |
181 | // Wait a bit before reading the card again
182 | delay(1000);
183 | }
184 | else
185 | {
186 | Serial.println("Ooops ... unable to read the requested page!?");
187 | }
188 | }
189 | }
190 | }
191 |
192 |
--------------------------------------------------------------------------------
/examples/mifareclassic_updatendef/mifareclassic_updatendef.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file mifareclassic_updatendef.pde
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | Updates a sector that is already formatted for NDEF (using
8 | mifareclassic_formatndef.pde for example), inserting a new url
9 |
10 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
11 | This library works with the Adafruit NFC Shield
12 | ----> https://www.adafruit.com/products/789
13 |
14 | Check out the links above for our tutorials and wiring diagrams
15 | These chips use SPI or I2C to communicate
16 |
17 | Adafruit invests time and resources providing this open source code,
18 | please support Adafruit and open-source hardware by purchasing
19 | products from Adafruit!
20 |
21 | */
22 | /**************************************************************************/
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | // If using the breakout with SPI, define the pins for SPI communication.
29 | #define PN532_SCK (2)
30 | #define PN532_MOSI (3)
31 | #define PN532_SS (4)
32 | #define PN532_MISO (5)
33 |
34 | // If using the breakout or shield with I2C, define just the pins connected
35 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
36 | #define PN532_IRQ (2)
37 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
38 |
39 | // Uncomment just _one_ line below depending on how your breakout or shield
40 | // is connected to the Arduino:
41 |
42 | // Use this line for a breakout with a SPI connection:
43 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
44 |
45 | // Use this line for a breakout with a hardware SPI connection. Note that
46 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
47 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
48 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
49 | //Adafruit_PN532 nfc(PN532_SS);
50 |
51 | // Or use this line for a breakout or shield with an I2C connection:
52 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
53 |
54 | /*
55 | We can encode many different kinds of pointers to the card,
56 | from a URL, to an Email address, to a phone number, and many more
57 | check the library header .h file to see the large # of supported
58 | prefixes!
59 | */
60 | // For a http://www. url:
61 | const char * url = "adafruit.com/blog/";
62 | uint8_t ndefprefix = NDEF_URIPREFIX_HTTP_WWWDOT;
63 |
64 | // for an email address
65 | //const char * url = "mail@example.com";
66 | //uint8_t ndefprefix = NDEF_URIPREFIX_MAILTO;
67 |
68 | // for a phone number
69 | //const char * url = "+1 212 555 1212";
70 | //uint8_t ndefprefix = NDEF_URIPREFIX_TEL;
71 |
72 | #if defined(ARDUINO_ARCH_SAMD)
73 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
74 | // also change #define in Adafruit_PN532.cpp library file
75 | #define Serial SerialUSB
76 | #endif
77 |
78 | void setup(void) {
79 | #ifndef ESP8266
80 | while (!Serial); // for Leonardo/Micro/Zero
81 | #endif
82 | Serial.begin(115200);
83 | Serial.println("Looking for PN532...");
84 |
85 | nfc.begin();
86 |
87 | uint32_t versiondata = nfc.getFirmwareVersion();
88 | if (! versiondata) {
89 | Serial.print("Didn't find PN53x board");
90 | while (1); // halt
91 | }
92 |
93 | // Got ok data, print it out!
94 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
95 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
96 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
97 |
98 | // configure board to read RFID tags
99 | nfc.SAMConfig();
100 | }
101 |
102 | void loop(void) {
103 | uint8_t success; // Flag to check if there was an error with the PN532
104 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
105 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
106 | bool authenticated = false; // Flag to indicate if the sector is authenticated
107 |
108 | // Use the default NDEF keys (these would have have set by mifareclassic_formatndef.pde!)
109 | uint8_t keya[6] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 };
110 | uint8_t keyb[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };
111 |
112 | Serial.println("Place your NDEF formatted Mifare Classic card on the reader to update the");
113 | Serial.println("NDEF record and press any key to continue ...");
114 | // Wait for user input before proceeding
115 | while (!Serial.available());
116 | // a key was pressed1
117 | while (Serial.available()) Serial.read();
118 |
119 | // Wait for an ISO14443A type card (Mifare, etc.). When one is found
120 | // 'uid' will be populated with the UID, and uidLength will indicate
121 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
122 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
123 |
124 | if (success)
125 | {
126 | // Display some basic information about the card
127 | Serial.println("Found an ISO14443A card");
128 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
129 | Serial.print(" UID Value: ");
130 | nfc.PrintHex(uid, uidLength);
131 | Serial.println("");
132 |
133 | // Make sure this is a Mifare Classic card
134 | if (uidLength != 4)
135 | {
136 | Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
137 | return;
138 | }
139 |
140 | // We probably have a Mifare Classic card ...
141 | Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
142 |
143 | // Check if this is an NDEF card (using first block of sector 1 from mifareclassic_formatndef.pde)
144 | // Must authenticate on the first key using 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7
145 | success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 4, 0, keyb);
146 | if (!success)
147 | {
148 | Serial.println("Unable to authenticate block 4 ... is this card NDEF formatted?");
149 | return;
150 | }
151 |
152 | Serial.println("Authentication succeeded (seems to be an NDEF/NFC Forum tag) ...");
153 |
154 | // Authenticated seems to have worked
155 | // Try to write an NDEF record to sector 1
156 | // Use 0x01 for the URI Identifier Code to prepend "http://www."
157 | // to the url (and save some space). For information on URI ID Codes
158 | // see http://www.ladyada.net/wiki/private/articlestaging/nfc/ndef
159 | if (strlen(url) > 38)
160 | {
161 | // The length is also checked in the WriteNDEFURI function, but lets
162 | // warn users here just in case they change the value and it's bigger
163 | // than it should be
164 | Serial.println("URI is too long ... must be less than 38 characters!");
165 | return;
166 | }
167 |
168 | Serial.println("Updating sector 1 with URI as NDEF Message");
169 |
170 | // URI is within size limits ... write it to the card and report success/failure
171 | success = nfc.mifareclassic_WriteNDEFURI(1, ndefprefix, url);
172 | if (success)
173 | {
174 | Serial.println("NDEF URI Record written to sector 1");
175 | Serial.println("");
176 | }
177 | else
178 | {
179 | Serial.println("NDEF Record creation failed! :(");
180 | }
181 | }
182 |
183 | // Wait a bit before trying again
184 | Serial.println("\n\nDone!");
185 | delay(1000);
186 | Serial.flush();
187 | while(Serial.available()) Serial.read();
188 | }
189 |
--------------------------------------------------------------------------------
/examples/mifareclassic_formatndef/mifareclassic_formatndef.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file mifareclassic_formatndef.pde
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | This example attempts to format a clean Mifare Classic 1K card as
8 | an NFC Forum tag (to store NDEF messages that can be read by any
9 | NFC enabled Android phone, etc.)
10 |
11 | Note that you need the baud rate to be 115200 because we need to print
12 | out the data and read from the card at the same time!
13 |
14 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
15 | This library works with the Adafruit NFC Shield
16 | ----> https://www.adafruit.com/products/789
17 |
18 | Check out the links above for our tutorials and wiring diagrams
19 | These chips use SPI or I2C to communicate
20 |
21 | Adafruit invests time and resources providing this open source code,
22 | please support Adafruit and open-source hardware by purchasing
23 | products from Adafruit!
24 |
25 | */
26 | /**************************************************************************/
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | // If using the breakout with SPI, define the pins for SPI communication.
33 | #define PN532_SCK (2)
34 | #define PN532_MOSI (3)
35 | #define PN532_SS (4)
36 | #define PN532_MISO (5)
37 |
38 | // If using the breakout or shield with I2C, define just the pins connected
39 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
40 | #define PN532_IRQ (2)
41 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
42 |
43 | // Uncomment just _one_ line below depending on how your breakout or shield
44 | // is connected to the Arduino:
45 |
46 | // Use this line for a breakout with a SPI connection:
47 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
48 |
49 | // Use this line for a breakout with a hardware SPI connection. Note that
50 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
51 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
52 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
53 | //Adafruit_PN532 nfc(PN532_SS);
54 |
55 | // Or use this line for a breakout or shield with an I2C connection:
56 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
57 |
58 | /*
59 | We can encode many different kinds of pointers to the card,
60 | from a URL, to an Email address, to a phone number, and many more
61 | check the library header .h file to see the large # of supported
62 | prefixes!
63 | */
64 | // For a http://www. url:
65 | const char * url = "adafruit.com";
66 | uint8_t ndefprefix = NDEF_URIPREFIX_HTTP_WWWDOT;
67 |
68 | // for an email address
69 | //const char * url = "mail@example.com";
70 | //uint8_t ndefprefix = NDEF_URIPREFIX_MAILTO;
71 |
72 | // for a phone number
73 | //const char * url = "+1 212 555 1212";
74 | //uint8_t ndefprefix = NDEF_URIPREFIX_TEL;
75 |
76 |
77 | void setup(void) {
78 | #ifndef ESP8266
79 | while (!Serial); // for Leonardo/Micro/Zero
80 | #endif
81 | Serial.begin(115200);
82 | Serial.println("Looking for PN532...");
83 |
84 | nfc.begin();
85 |
86 | uint32_t versiondata = nfc.getFirmwareVersion();
87 | if (! versiondata) {
88 | Serial.print("Didn't find PN53x board");
89 | while (1); // halt
90 | }
91 |
92 | // Got ok data, print it out!
93 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
94 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
95 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
96 |
97 | // configure board to read RFID tags
98 | nfc.SAMConfig();
99 | }
100 |
101 | void loop(void) {
102 | uint8_t success; // Flag to check if there was an error with the PN532
103 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
104 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
105 | bool authenticated = false; // Flag to indicate if the sector is authenticated
106 |
107 | // Use the default key
108 | uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
109 |
110 | Serial.println("");
111 | Serial.println("PLEASE NOTE: Formatting your card for NDEF records will change the");
112 | Serial.println("authentication keys. To reformat your NDEF tag as a clean Mifare");
113 | Serial.println("Classic tag, use the mifareclassic_ndeftoclassic example!");
114 | Serial.println("");
115 | Serial.println("Place your Mifare Classic card on the reader to format with NDEF");
116 | Serial.println("and press any key to continue ...");
117 | // Wait for user input before proceeding
118 | while (!Serial.available());
119 | // a key was pressed1
120 | while (Serial.available()) Serial.read();
121 |
122 | // Wait for an ISO14443A type card (Mifare, etc.). When one is found
123 | // 'uid' will be populated with the UID, and uidLength will indicate
124 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
125 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
126 |
127 | if (success)
128 | {
129 | // Display some basic information about the card
130 | Serial.println("Found an ISO14443A card");
131 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
132 | Serial.print(" UID Value: ");
133 | nfc.PrintHex(uid, uidLength);
134 | Serial.println("");
135 |
136 | // Make sure this is a Mifare Classic card
137 | if (uidLength != 4)
138 | {
139 | Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
140 | return;
141 | }
142 |
143 | // We probably have a Mifare Classic card ...
144 | Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
145 |
146 | // Try to format the card for NDEF data
147 | success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 0, 0, keya);
148 | if (!success)
149 | {
150 | Serial.println("Unable to authenticate block 0 to enable card formatting!");
151 | return;
152 | }
153 | success = nfc.mifareclassic_FormatNDEF();
154 | if (!success)
155 | {
156 | Serial.println("Unable to format the card for NDEF");
157 | return;
158 | }
159 |
160 | Serial.println("Card has been formatted for NDEF data using MAD1");
161 |
162 | // Try to authenticate block 4 (first block of sector 1) using our key
163 | success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 4, 0, keya);
164 |
165 | // Make sure the authentification process didn't fail
166 | if (!success)
167 | {
168 | Serial.println("Authentication failed.");
169 | return;
170 | }
171 |
172 | // Try to write a URL
173 | Serial.println("Writing URI to sector 1 as an NDEF Message");
174 |
175 | // Authenticated seems to have worked
176 | // Try to write an NDEF record to sector 1
177 | // Use 0x01 for the URI Identifier Code to prepend "http://www."
178 | // to the url (and save some space). For information on URI ID Codes
179 | // see http://www.ladyada.net/wiki/private/articlestaging/nfc/ndef
180 | if (strlen(url) > 38)
181 | {
182 | // The length is also checked in the WriteNDEFURI function, but lets
183 | // warn users here just in case they change the value and it's bigger
184 | // than it should be
185 | Serial.println("URI is too long ... must be less than 38 characters long");
186 | return;
187 | }
188 |
189 | // URI is within size limits ... write it to the card and report success/failure
190 | success = nfc.mifareclassic_WriteNDEFURI(1, ndefprefix, url);
191 | if (success)
192 | {
193 | Serial.println("NDEF URI Record written to sector 1");
194 | }
195 | else
196 | {
197 | Serial.println("NDEF Record creation failed! :(");
198 | }
199 | }
200 |
201 | // Wait a bit before trying again
202 | Serial.println("\n\nDone!");
203 | delay(1000);
204 | Serial.flush();
205 | while(Serial.available()) Serial.read();
206 | }
207 |
--------------------------------------------------------------------------------
/examples/mifareclassic_memdump/mifareclassic_memdump.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file mifareclassic_memdump.pde
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | This example attempts to dump the contents of a Mifare Classic 1K card
8 |
9 | Note that you need the baud rate to be 115200 because we need to print
10 | out the data and read from the card at the same time!
11 |
12 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
13 | This library works with the Adafruit NFC breakout
14 | ----> https://www.adafruit.com/products/364
15 |
16 | Check out the links above for our tutorials and wiring diagrams
17 | These chips use SPI or I2C to communicate
18 |
19 | Adafruit invests time and resources providing this open source code,
20 | please support Adafruit and open-source hardware by purchasing
21 | products from Adafruit!
22 |
23 | */
24 | /**************************************************************************/
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | // If using the breakout with SPI, define the pins for SPI communication.
31 | #define PN532_SCK (2)
32 | #define PN532_MOSI (3)
33 | #define PN532_SS (4)
34 | #define PN532_MISO (5)
35 |
36 | // If using the breakout or shield with I2C, define just the pins connected
37 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
38 | #define PN532_IRQ (2)
39 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
40 |
41 | // Uncomment just _one_ line below depending on how your breakout or shield
42 | // is connected to the Arduino:
43 |
44 | // Use this line for a breakout with a SPI connection:
45 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
46 |
47 | // Use this line for a breakout with a hardware SPI connection. Note that
48 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
49 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
50 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
51 | //Adafruit_PN532 nfc(PN532_SS);
52 |
53 | // Or use this line for a breakout or shield with an I2C connection:
54 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
55 |
56 | #if defined(ARDUINO_ARCH_SAMD)
57 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
58 | // also change #define in Adafruit_PN532.cpp library file
59 | #define Serial SerialUSB
60 | #endif
61 |
62 | void setup(void) {
63 | #ifndef ESP8266
64 | while (!Serial); // for Leonardo/Micro/Zero
65 | #endif
66 | // has to be fast to dump the entire memory contents!
67 | Serial.begin(115200);
68 | Serial.println("Looking for PN532...");
69 |
70 | nfc.begin();
71 |
72 | uint32_t versiondata = nfc.getFirmwareVersion();
73 | if (! versiondata) {
74 | Serial.print("Didn't find PN53x board");
75 | while (1); // halt
76 | }
77 | // Got ok data, print it out!
78 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
79 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
80 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
81 |
82 | // configure board to read RFID tags
83 | nfc.SAMConfig();
84 |
85 | Serial.println("Waiting for an ISO14443A Card ...");
86 | }
87 |
88 |
89 | void loop(void) {
90 | uint8_t success; // Flag to check if there was an error with the PN532
91 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
92 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
93 | uint8_t currentblock; // Counter to keep track of which block we're on
94 | bool authenticated = false; // Flag to indicate if the sector is authenticated
95 | uint8_t data[16]; // Array to store block data during reads
96 |
97 | // Keyb on NDEF and Mifare Classic should be the same
98 | uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
99 |
100 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found
101 | // 'uid' will be populated with the UID, and uidLength will indicate
102 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
103 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
104 |
105 | if (success) {
106 | // Display some basic information about the card
107 | Serial.println("Found an ISO14443A card");
108 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
109 | Serial.print(" UID Value: ");
110 | nfc.PrintHex(uid, uidLength);
111 | Serial.println("");
112 |
113 | if (uidLength == 4)
114 | {
115 | // We probably have a Mifare Classic card ...
116 | Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
117 |
118 | // Now we try to go through all 16 sectors (each having 4 blocks)
119 | // authenticating each sector, and then dumping the blocks
120 | for (currentblock = 0; currentblock < 64; currentblock++)
121 | {
122 | // Check if this is a new block so that we can reauthenticate
123 | if (nfc.mifareclassic_IsFirstBlock(currentblock)) authenticated = false;
124 |
125 | // If the sector hasn't been authenticated, do so first
126 | if (!authenticated)
127 | {
128 | // Starting of a new sector ... try to to authenticate
129 | Serial.print("------------------------Sector ");Serial.print(currentblock/4, DEC);Serial.println("-------------------------");
130 | if (currentblock == 0)
131 | {
132 | // This will be 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF for Mifare Classic (non-NDEF!)
133 | // or 0xA0 0xA1 0xA2 0xA3 0xA4 0xA5 for NDEF formatted cards using key a,
134 | // but keyb should be the same for both (0xFF 0xFF 0xFF 0xFF 0xFF 0xFF)
135 | success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, currentblock, 1, keyuniversal);
136 | }
137 | else
138 | {
139 | // This will be 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF for Mifare Classic (non-NDEF!)
140 | // or 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 for NDEF formatted cards using key a,
141 | // but keyb should be the same for both (0xFF 0xFF 0xFF 0xFF 0xFF 0xFF)
142 | success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, currentblock, 1, keyuniversal);
143 | }
144 | if (success)
145 | {
146 | authenticated = true;
147 | }
148 | else
149 | {
150 | Serial.println("Authentication error");
151 | }
152 | }
153 | // If we're still not authenticated just skip the block
154 | if (!authenticated)
155 | {
156 | Serial.print("Block ");Serial.print(currentblock, DEC);Serial.println(" unable to authenticate");
157 | }
158 | else
159 | {
160 | // Authenticated ... we should be able to read the block now
161 | // Dump the data into the 'data' array
162 | success = nfc.mifareclassic_ReadDataBlock(currentblock, data);
163 | if (success)
164 | {
165 | // Read successful
166 | Serial.print("Block ");Serial.print(currentblock, DEC);
167 | if (currentblock < 10)
168 | {
169 | Serial.print(" ");
170 | }
171 | else
172 | {
173 | Serial.print(" ");
174 | }
175 | // Dump the raw data
176 | nfc.PrintHexChar(data, 16);
177 | }
178 | else
179 | {
180 | // Oops ... something happened
181 | Serial.print("Block ");Serial.print(currentblock, DEC);
182 | Serial.println(" unable to read this block");
183 | }
184 | }
185 | }
186 | }
187 | else
188 | {
189 | Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
190 | }
191 | }
192 | // Wait a bit before trying again
193 | Serial.println("\n\nSend a character to run the mem dumper again!");
194 | Serial.flush();
195 | while (!Serial.available());
196 | while (Serial.available()) {
197 | Serial.read();
198 | }
199 | Serial.flush();
200 | }
201 |
--------------------------------------------------------------------------------
/examples/ntag2xx_updatendef/ntag2xx_updatendef.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file ntag2xx_updatendef.pde
4 | @author KTOWN (Adafruit Industries)
5 | @license BSD (see license.txt)
6 |
7 | This example will wait for any NTAG203 or NTAG213 card or tag,
8 | and will attempt to add or update an NDEF URI at the start of the
9 | tag's memory.
10 |
11 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
12 | This library works with the Adafruit NFC breakout
13 | ----> https://www.adafruit.com/products/364
14 |
15 | Check out the links above for our tutorials and wiring diagrams
16 | These chips use SPI or I2C to communicate.
17 |
18 | Adafruit invests time and resources providing this open source code,
19 | please support Adafruit and open-source hardware by purchasing
20 | products from Adafruit!
21 | */
22 | /**************************************************************************/
23 | #include
24 | #include
25 | #include
26 |
27 | // If using the breakout with SPI, define the pins for SPI communication.
28 | #define PN532_SCK (2)
29 | #define PN532_MOSI (3)
30 | #define PN532_SS (4)
31 | #define PN532_MISO (5)
32 |
33 | // If using the breakout or shield with I2C, define just the pins connected
34 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
35 | #define PN532_IRQ (2)
36 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
37 |
38 | // Uncomment just _one_ line below depending on how your breakout or shield
39 | // is connected to the Arduino:
40 |
41 | // Use this line for a breakout with a software SPI connection (recommended):
42 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
43 |
44 | // Use this line for a breakout with a hardware SPI connection. Note that
45 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
46 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
47 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
48 | //Adafruit_PN532 nfc(PN532_SS);
49 |
50 | // Or use this line for a breakout or shield with an I2C connection:
51 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
52 |
53 | /*
54 | We can encode many different kinds of pointers to the card,
55 | from a URL, to an Email address, to a phone number, and many more
56 | check the library header .h file to see the large # of supported
57 | prefixes!
58 | */
59 | // For a http://www. url:
60 | char * url = "adafruit.com/blog/";
61 | uint8_t ndefprefix = NDEF_URIPREFIX_HTTP_WWWDOT;
62 |
63 | // for an email address
64 | //char * url = "mail@example.com";
65 | //uint8_t ndefprefix = NDEF_URIPREFIX_MAILTO;
66 |
67 | // for a phone number
68 | //char * url = "+1 212 555 1212";
69 | //uint8_t ndefprefix = NDEF_URIPREFIX_TEL;
70 |
71 | #if defined(ARDUINO_ARCH_SAMD)
72 | // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
73 | // also change #define in Adafruit_PN532.cpp library file
74 | #define Serial SerialUSB
75 | #endif
76 |
77 | void setup(void) {
78 | #ifndef ESP8266
79 | while (!Serial); // for Leonardo/Micro/Zero
80 | #endif
81 | Serial.begin(115200);
82 | Serial.println("Hello!");
83 |
84 | nfc.begin();
85 |
86 | uint32_t versiondata = nfc.getFirmwareVersion();
87 | if (! versiondata) {
88 | Serial.print("Didn't find PN53x board");
89 | while (1); // halt
90 | }
91 | // Got ok data, print it out!
92 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
93 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
94 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
95 |
96 | // configure board to read RFID tags
97 | nfc.SAMConfig();
98 | }
99 |
100 | void loop(void)
101 | {
102 | uint8_t success;
103 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
104 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
105 | uint8_t dataLength;
106 |
107 | // Require some user feedback before running this example!
108 | Serial.println("\r\nPlace your NDEF formatted NTAG2xx tag on the reader to update the");
109 | Serial.println("NDEF record and press any key to continue ...\r\n");
110 | // Wait for user input before proceeding
111 | while (!Serial.available());
112 | // a key was pressed1
113 | while (Serial.available()) Serial.read();
114 |
115 | // 1.) Wait for an NTAG203 card. When one is found 'uid' will be populated with
116 | // the UID, and uidLength will indicate the size of the UID (normally 7)
117 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
118 |
119 | // It seems we found a valid ISO14443A Tag!
120 | if (success)
121 | {
122 | // 2.) Display some basic information about the card
123 | Serial.println("Found an ISO14443A card");
124 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
125 | Serial.print(" UID Value: ");
126 | nfc.PrintHex(uid, uidLength);
127 | Serial.println("");
128 |
129 | if (uidLength != 7)
130 | {
131 | Serial.println("This doesn't seem to be an NTAG203 tag (UUID length != 7 bytes)!");
132 | }
133 | else
134 | {
135 | uint8_t data[32];
136 |
137 | // We probably have an NTAG2xx card (though it could be Ultralight as well)
138 | Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
139 |
140 | // NTAG2x3 cards have 39*4 bytes of user pages (156 user bytes),
141 | // starting at page 4 ... larger cards just add pages to the end of
142 | // this range:
143 |
144 | // See: http://www.nxp.com/documents/short_data_sheet/NTAG203_SDS.pdf
145 |
146 | // TAG Type PAGES USER START USER STOP
147 | // -------- ----- ---------- ---------
148 | // NTAG 203 42 4 39
149 | // NTAG 213 45 4 39
150 | // NTAG 215 135 4 129
151 | // NTAG 216 231 4 225
152 |
153 |
154 | // 3.) Check if the NDEF Capability Container (CC) bits are already set
155 | // in OTP memory (page 3)
156 | memset(data, 0, 4);
157 | success = nfc.ntag2xx_ReadPage(3, data);
158 | if (!success)
159 | {
160 | Serial.println("Unable to read the Capability Container (page 3)");
161 | return;
162 | }
163 | else
164 | {
165 | // If the tag has already been formatted as NDEF, byte 0 should be:
166 | // Byte 0 = Magic Number (0xE1)
167 | // Byte 1 = NDEF Version (Should be 0x10)
168 | // Byte 2 = Data Area Size (value * 8 bytes)
169 | // Byte 3 = Read/Write Access (0x00 for full read and write)
170 | if (!((data[0] == 0xE1) && (data[1] == 0x10)))
171 | {
172 | Serial.println("This doesn't seem to be an NDEF formatted tag.");
173 | Serial.println("Page 3 should start with 0xE1 0x10.");
174 | }
175 | else
176 | {
177 | // 4.) Determine and display the data area size
178 | dataLength = data[2]*8;
179 | Serial.print("Tag is NDEF formatted. Data area size = ");
180 | Serial.print(dataLength);
181 | Serial.println(" bytes");
182 |
183 | // 5.) Erase the old data area
184 | Serial.print("Erasing previous data area ");
185 | for (uint8_t i = 4; i < (dataLength/4)+4; i++)
186 | {
187 | memset(data, 0, 4);
188 | success = nfc.ntag2xx_WritePage(i, data);
189 | Serial.print(".");
190 | if (!success)
191 | {
192 | Serial.println(" ERROR!");
193 | return;
194 | }
195 | }
196 | Serial.println(" DONE!");
197 |
198 | // 6.) Try to add a new NDEF URI record
199 | Serial.print("Writing URI as NDEF Record ... ");
200 | success = nfc.ntag2xx_WriteNDEFURI(ndefprefix, url, dataLength);
201 | if (success)
202 | {
203 | Serial.println("DONE!");
204 | }
205 | else
206 | {
207 | Serial.println("ERROR! (URI length?)");
208 | }
209 |
210 | } // CC contents NDEF record check
211 | } // CC page read check
212 | } // UUID length check
213 |
214 | // Wait a bit before trying again
215 | Serial.flush();
216 | while (!Serial.available());
217 | while (Serial.available()) {
218 | Serial.read();
219 | }
220 | Serial.flush();
221 | } // Start waiting for a new ISO14443A tag
222 | }
--------------------------------------------------------------------------------
/examples/mifareclassic_ndeftoclassic/mifareclassic_ndeftoclassic.pde:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file mifareclassic_ndeftoclassic.pde
4 | @author KTOWN (Adafruit Industries)
5 | @license BSD (see license.txt)
6 |
7 | This examples attempts to take a Mifare Classic 1K card that has been
8 | formatted for NDEF messages using mifareclassic_formatndef, and resets
9 | the authentication keys back to the Mifare Classic defaults
10 |
11 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
12 | This library works with the Adafruit NFC Shield
13 | ----> https://www.adafruit.com/products/789
14 |
15 | Check out the links above for our tutorials and wiring diagrams
16 | These chips use SPI or I2C to communicate
17 |
18 | Adafruit invests time and resources providing this open source code,
19 | please support Adafruit and open-source hardware by purchasing
20 | products from Adafruit!
21 |
22 | */
23 | /**************************************************************************/
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | // If using the breakout with SPI, define the pins for SPI communication.
30 | #define PN532_SCK (2)
31 | #define PN532_MOSI (3)
32 | #define PN532_SS (4)
33 | #define PN532_MISO (5)
34 |
35 | // If using the breakout or shield with I2C, define just the pins connected
36 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield!
37 | #define PN532_IRQ (2)
38 | #define PN532_RESET (3) // Not connected by default on the NFC Shield
39 |
40 | // Uncomment just _one_ line below depending on how your breakout or shield
41 | // is connected to the Arduino:
42 |
43 | // Use this line for a breakout with a SPI connection:
44 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
45 |
46 | // Use this line for a breakout with a hardware SPI connection. Note that
47 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
48 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
49 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
50 | //Adafruit_PN532 nfc(PN532_SS);
51 |
52 | // Or use this line for a breakout or shield with an I2C connection:
53 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
54 |
55 | #define NR_SHORTSECTOR (32) // Number of short sectors on Mifare 1K/4K
56 | #define NR_LONGSECTOR (8) // Number of long sectors on Mifare 4K
57 | #define NR_BLOCK_OF_SHORTSECTOR (4) // Number of blocks in a short sector
58 | #define NR_BLOCK_OF_LONGSECTOR (16) // Number of blocks in a long sector
59 |
60 | // Determine the sector trailer block based on sector number
61 | #define BLOCK_NUMBER_OF_SECTOR_TRAILER(sector) (((sector)>24) & 0xFF, HEX);
96 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
97 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
98 |
99 | // configure board to read RFID tags
100 | nfc.SAMConfig();
101 | }
102 |
103 | void loop(void) {
104 | uint8_t success; // Flag to check if there was an error with the PN532
105 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
106 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
107 | bool authenticated = false; // Flag to indicate if the sector is authenticated
108 | uint8_t blockBuffer[16]; // Buffer to store block contents
109 | uint8_t blankAccessBits[3] = { 0xff, 0x07, 0x80 };
110 | uint8_t idx = 0;
111 | uint8_t numOfSector = 16; // Assume Mifare Classic 1K for now (16 4-block sectors)
112 |
113 | Serial.println("Place your NDEF formatted Mifare Classic 1K card on the reader");
114 | Serial.println("and press any key to continue ...");
115 |
116 | // Wait for user input before proceeding
117 | while (!Serial.available());
118 | while (Serial.available()) Serial.read();
119 |
120 | // Wait for an ISO14443A type card (Mifare, etc.). When one is found
121 | // 'uid' will be populated with the UID, and uidLength will indicate
122 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
123 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
124 |
125 | if (success)
126 | {
127 | // We seem to have a tag ...
128 | // Display some basic information about it
129 | Serial.println("Found an ISO14443A card/tag");
130 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
131 | Serial.print(" UID Value: ");
132 | nfc.PrintHex(uid, uidLength);
133 | Serial.println("");
134 |
135 | // Make sure this is a Mifare Classic card
136 | if (uidLength != 4)
137 | {
138 | Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
139 | return;
140 | }
141 |
142 | Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
143 | Serial.println("");
144 | Serial.println("Reformatting card for Mifare Classic (please don't touch it!) ... ");
145 |
146 | // Now run through the card sector by sector
147 | for (idx = 0; idx < numOfSector; idx++)
148 | {
149 | // Step 1: Authenticate the current sector using key B 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
150 | success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), 1, (uint8_t *)KEY_DEFAULT_KEYAB);
151 | if (!success)
152 | {
153 | Serial.print("Authentication failed for sector "); Serial.println(numOfSector);
154 | return;
155 | }
156 |
157 | // Step 2: Write to the other blocks
158 | if (idx == 16)
159 | {
160 | memset(blockBuffer, 0, sizeof(blockBuffer));
161 | if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)))
162 | {
163 | Serial.print("Unable to write to sector "); Serial.println(numOfSector);
164 | return;
165 | }
166 | }
167 | if ((idx == 0) || (idx == 16))
168 | {
169 | memset(blockBuffer, 0, sizeof(blockBuffer));
170 | if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)))
171 | {
172 | Serial.print("Unable to write to sector "); Serial.println(numOfSector);
173 | return;
174 | }
175 | }
176 | else
177 | {
178 | memset(blockBuffer, 0, sizeof(blockBuffer));
179 | if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)))
180 | {
181 | Serial.print("Unable to write to sector "); Serial.println(numOfSector);
182 | return;
183 | }
184 | if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)))
185 | {
186 | Serial.print("Unable to write to sector "); Serial.println(numOfSector);
187 | return;
188 | }
189 | }
190 | memset(blockBuffer, 0, sizeof(blockBuffer));
191 | if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 1, blockBuffer)))
192 | {
193 | Serial.print("Unable to write to sector "); Serial.println(numOfSector);
194 | return;
195 | }
196 |
197 | // Step 3: Reset both keys to 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
198 | memcpy(blockBuffer, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
199 | memcpy(blockBuffer + 6, blankAccessBits, sizeof(blankAccessBits));
200 | blockBuffer[9] = 0x69;
201 | memcpy(blockBuffer + 10, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
202 |
203 | // Step 4: Write the trailer block
204 | if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)), blockBuffer)))
205 | {
206 | Serial.print("Unable to write trailer block of sector "); Serial.println(numOfSector);
207 | return;
208 | }
209 | }
210 | }
211 |
212 | // Wait a bit before trying again
213 | Serial.println("\n\nDone!");
214 | delay(1000);
215 | Serial.flush();
216 | while(Serial.available()) Serial.read();
217 | }
--------------------------------------------------------------------------------
/Adafruit_PN532.h:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file Adafruit_PN532.h
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 |
8 | This is a library for the Adafruit PN532 NFC/RFID breakout boards
9 | This library works with the Adafruit NFC breakout
10 | ----> https://www.adafruit.com/products/364
11 |
12 | Check out the links above for our tutorials and wiring diagrams
13 | These chips use SPI or I2C to communicate.
14 |
15 | Adafruit invests time and resources providing this open source code,
16 | please support Adafruit and open-source hardware by purchasing
17 | products from Adafruit!
18 |
19 | @section HISTORY
20 |
21 | v2.0 - Refactored to add I2C support from Adafruit_NFCShield_I2C library.
22 |
23 | v1.1 - Added full command list
24 | - Added 'verbose' mode flag to constructor to toggle debug output
25 | - Changed readPassiveTargetID() to return variable length values
26 |
27 | */
28 | /**************************************************************************/
29 |
30 | #ifndef ADAFRUIT_PN532_H
31 | #define ADAFRUIT_PN532_H
32 |
33 | #if ARDUINO >= 100
34 | #include "Arduino.h"
35 | #else
36 | #include "WProgram.h"
37 | #endif
38 |
39 | #define PN532_PREAMBLE (0x00)
40 | #define PN532_STARTCODE1 (0x00)
41 | #define PN532_STARTCODE2 (0xFF)
42 | #define PN532_POSTAMBLE (0x00)
43 |
44 | #define PN532_HOSTTOPN532 (0xD4)
45 | #define PN532_PN532TOHOST (0xD5)
46 |
47 | // PN532 Commands
48 | #define PN532_COMMAND_DIAGNOSE (0x00)
49 | #define PN532_COMMAND_GETFIRMWAREVERSION (0x02)
50 | #define PN532_COMMAND_GETGENERALSTATUS (0x04)
51 | #define PN532_COMMAND_READREGISTER (0x06)
52 | #define PN532_COMMAND_WRITEREGISTER (0x08)
53 | #define PN532_COMMAND_READGPIO (0x0C)
54 | #define PN532_COMMAND_WRITEGPIO (0x0E)
55 | #define PN532_COMMAND_SETSERIALBAUDRATE (0x10)
56 | #define PN532_COMMAND_SETPARAMETERS (0x12)
57 | #define PN532_COMMAND_SAMCONFIGURATION (0x14)
58 | #define PN532_COMMAND_POWERDOWN (0x16)
59 | #define PN532_COMMAND_RFCONFIGURATION (0x32)
60 | #define PN532_COMMAND_RFREGULATIONTEST (0x58)
61 | #define PN532_COMMAND_INJUMPFORDEP (0x56)
62 | #define PN532_COMMAND_INJUMPFORPSL (0x46)
63 | #define PN532_COMMAND_INLISTPASSIVETARGET (0x4A)
64 | #define PN532_COMMAND_INATR (0x50)
65 | #define PN532_COMMAND_INPSL (0x4E)
66 | #define PN532_COMMAND_INDATAEXCHANGE (0x40)
67 | #define PN532_COMMAND_INCOMMUNICATETHRU (0x42)
68 | #define PN532_COMMAND_INDESELECT (0x44)
69 | #define PN532_COMMAND_INRELEASE (0x52)
70 | #define PN532_COMMAND_INSELECT (0x54)
71 | #define PN532_COMMAND_INAUTOPOLL (0x60)
72 | #define PN532_COMMAND_TGINITASTARGET (0x8C)
73 | #define PN532_COMMAND_TGSETGENERALBYTES (0x92)
74 | #define PN532_COMMAND_TGGETDATA (0x86)
75 | #define PN532_COMMAND_TGSETDATA (0x8E)
76 | #define PN532_COMMAND_TGSETMETADATA (0x94)
77 | #define PN532_COMMAND_TGGETINITIATORCOMMAND (0x88)
78 | #define PN532_COMMAND_TGRESPONSETOINITIATOR (0x90)
79 | #define PN532_COMMAND_TGGETTARGETSTATUS (0x8A)
80 |
81 | #define PN532_RESPONSE_INDATAEXCHANGE (0x41)
82 | #define PN532_RESPONSE_INLISTPASSIVETARGET (0x4B)
83 |
84 | #define PN532_WAKEUP (0x55)
85 |
86 | #define PN532_SPI_STATREAD (0x02)
87 | #define PN532_SPI_DATAWRITE (0x01)
88 | #define PN532_SPI_DATAREAD (0x03)
89 | #define PN532_SPI_READY (0x01)
90 |
91 | #define PN532_I2C_ADDRESS (0x48 >> 1)
92 | #define PN532_I2C_READBIT (0x01)
93 | #define PN532_I2C_BUSY (0x00)
94 | #define PN532_I2C_READY (0x01)
95 | #define PN532_I2C_READYTIMEOUT (20)
96 |
97 | #define PN532_MIFARE_ISO14443A (0x00)
98 |
99 | // Mifare Commands
100 | #define MIFARE_CMD_AUTH_A (0x60)
101 | #define MIFARE_CMD_AUTH_B (0x61)
102 | #define MIFARE_CMD_READ (0x30)
103 | #define MIFARE_CMD_WRITE (0xA0)
104 | #define MIFARE_CMD_TRANSFER (0xB0)
105 | #define MIFARE_CMD_DECREMENT (0xC0)
106 | #define MIFARE_CMD_INCREMENT (0xC1)
107 | #define MIFARE_CMD_STORE (0xC2)
108 | #define MIFARE_ULTRALIGHT_CMD_WRITE (0xA2)
109 |
110 | // Prefixes for NDEF Records (to identify record type)
111 | #define NDEF_URIPREFIX_NONE (0x00)
112 | #define NDEF_URIPREFIX_HTTP_WWWDOT (0x01)
113 | #define NDEF_URIPREFIX_HTTPS_WWWDOT (0x02)
114 | #define NDEF_URIPREFIX_HTTP (0x03)
115 | #define NDEF_URIPREFIX_HTTPS (0x04)
116 | #define NDEF_URIPREFIX_TEL (0x05)
117 | #define NDEF_URIPREFIX_MAILTO (0x06)
118 | #define NDEF_URIPREFIX_FTP_ANONAT (0x07)
119 | #define NDEF_URIPREFIX_FTP_FTPDOT (0x08)
120 | #define NDEF_URIPREFIX_FTPS (0x09)
121 | #define NDEF_URIPREFIX_SFTP (0x0A)
122 | #define NDEF_URIPREFIX_SMB (0x0B)
123 | #define NDEF_URIPREFIX_NFS (0x0C)
124 | #define NDEF_URIPREFIX_FTP (0x0D)
125 | #define NDEF_URIPREFIX_DAV (0x0E)
126 | #define NDEF_URIPREFIX_NEWS (0x0F)
127 | #define NDEF_URIPREFIX_TELNET (0x10)
128 | #define NDEF_URIPREFIX_IMAP (0x11)
129 | #define NDEF_URIPREFIX_RTSP (0x12)
130 | #define NDEF_URIPREFIX_URN (0x13)
131 | #define NDEF_URIPREFIX_POP (0x14)
132 | #define NDEF_URIPREFIX_SIP (0x15)
133 | #define NDEF_URIPREFIX_SIPS (0x16)
134 | #define NDEF_URIPREFIX_TFTP (0x17)
135 | #define NDEF_URIPREFIX_BTSPP (0x18)
136 | #define NDEF_URIPREFIX_BTL2CAP (0x19)
137 | #define NDEF_URIPREFIX_BTGOEP (0x1A)
138 | #define NDEF_URIPREFIX_TCPOBEX (0x1B)
139 | #define NDEF_URIPREFIX_IRDAOBEX (0x1C)
140 | #define NDEF_URIPREFIX_FILE (0x1D)
141 | #define NDEF_URIPREFIX_URN_EPC_ID (0x1E)
142 | #define NDEF_URIPREFIX_URN_EPC_TAG (0x1F)
143 | #define NDEF_URIPREFIX_URN_EPC_PAT (0x20)
144 | #define NDEF_URIPREFIX_URN_EPC_RAW (0x21)
145 | #define NDEF_URIPREFIX_URN_EPC (0x22)
146 | #define NDEF_URIPREFIX_URN_NFC (0x23)
147 |
148 | #define PN532_GPIO_VALIDATIONBIT (0x80)
149 | #define PN532_GPIO_P30 (0)
150 | #define PN532_GPIO_P31 (1)
151 | #define PN532_GPIO_P32 (2)
152 | #define PN532_GPIO_P33 (3)
153 | #define PN532_GPIO_P34 (4)
154 | #define PN532_GPIO_P35 (5)
155 |
156 | class Adafruit_PN532{
157 | public:
158 | Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss); // Software SPI
159 | Adafruit_PN532(uint8_t irq, uint8_t reset); // Hardware I2C
160 | Adafruit_PN532(uint8_t ss); // Hardware SPI
161 | void begin(void);
162 |
163 | // Generic PN532 functions
164 | bool SAMConfig(void);
165 | uint32_t getFirmwareVersion(void);
166 | bool sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout = 1000);
167 | bool writeGPIO(uint8_t pinstate);
168 | uint8_t readGPIO(void);
169 | bool setPassiveActivationRetries(uint8_t maxRetries);
170 |
171 | // ISO14443A functions
172 | bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, uint8_t * uidLength, uint16_t timeout = 0); //timeout 0 means no timeout - will block forever.
173 | bool inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint8_t * responseLength);
174 | bool inListPassiveTarget();
175 |
176 | // Mifare Classic functions
177 | bool mifareclassic_IsFirstBlock (uint32_t uiBlock);
178 | bool mifareclassic_IsTrailerBlock (uint32_t uiBlock);
179 | uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData);
180 | uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data);
181 | uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data);
182 | uint8_t mifareclassic_FormatNDEF (void);
183 | uint8_t mifareclassic_WriteNDEFURI (uint8_t sectorNumber, uint8_t uriIdentifier, const char * url);
184 |
185 | // Mifare Ultralight functions
186 | uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t * buffer);
187 | uint8_t mifareultralight_WritePage (uint8_t page, uint8_t * data);
188 |
189 | // NTAG2xx functions
190 | uint8_t ntag2xx_ReadPage (uint8_t page, uint8_t * buffer);
191 | uint8_t ntag2xx_WritePage (uint8_t page, uint8_t * data);
192 | uint8_t ntag2xx_WriteNDEFURI (uint8_t uriIdentifier, char * url, uint8_t dataLen);
193 |
194 | // Help functions to display formatted text
195 | static void PrintHex(const byte * data, const uint32_t numBytes);
196 | static void PrintHexChar(const byte * pbtData, const uint32_t numBytes);
197 |
198 | private:
199 | uint8_t _ss, _clk, _mosi, _miso;
200 | uint8_t _irq, _reset;
201 | uint8_t _uid[7]; // ISO14443A uid
202 | uint8_t _uidLen; // uid len
203 | uint8_t _key[6]; // Mifare Classic key
204 | uint8_t _inListedTag = 0x1 ; // Tg number of inlisted tag. Undefined tag nubmer (0x00) returns error.
205 | bool _usingSPI; // True if using SPI, false if using I2C.
206 | bool _hardwareSPI; // True is using hardware SPI, false if using software SPI.
207 |
208 | // Low level communication functions that handle both SPI and I2C.
209 | void readdata(uint8_t* buff, uint8_t n);
210 | void writecommand(uint8_t* cmd, uint8_t cmdlen);
211 | bool isready();
212 | bool waitready(uint16_t timeout);
213 | bool readack();
214 |
215 | // SPI-specific functions.
216 | void spi_write(uint8_t c);
217 | uint8_t spi_read(void);
218 |
219 | // Note there are i2c_read and i2c_write inline functions defined in the .cpp file.
220 | };
221 |
222 | #endif
223 |
--------------------------------------------------------------------------------
/examples/ApplePay_Troyka_ACS/ApplePay_Troyka_ACS.ino:
--------------------------------------------------------------------------------
1 | //Access Control Reader based on ApplePay (EMV) and Troyka cards
2 |
3 |
4 | #include
5 |
6 | // If using the breakout with SPI, define the pins for SPI communication.
7 | #define PN532_SCK (2)
8 | #define PN532_MOSI (3)
9 | #define PN532_SS (4)
10 | #define PN532_MISO (5)
11 |
12 | // Use this line for a breakout with a software SPI connection (recommended):
13 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
14 |
15 |
16 | //EMV card global vars
17 | static const uint8_t aid_marker[] = {0x4F, 0x07};
18 | static const uint8_t pan_marker[] = {0x5A, 0x08};
19 |
20 |
21 |
22 | void setup(void) {
23 | Serial.begin(115200);
24 | Serial.println("Hello!");
25 |
26 | nfc.begin();
27 |
28 | uint32_t versiondata = nfc.getFirmwareVersion();
29 | if (! versiondata) {
30 | Serial.print("Didn't find PN53x board");
31 | while (1); // halt
32 | }
33 | // Got ok data, print it out!
34 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
35 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
36 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
37 |
38 | // configure board to read RFID tags
39 | nfc.SAMConfig();
40 |
41 | Serial.println("Waiting for an ISO14443A Card ...");
42 | }
43 |
44 | // dumb_memmem
45 | static char* dumb_memmem(const char* haystack, int hlen, const char* needle, int nlen) {
46 | // naive implementation
47 | if (nlen > hlen) return 0;
48 | int i;
49 | for (i=0; i 20) {
62 | void * searchresult = dumb_memmem(haystack, hlen, pan_marker, 2);
63 | if (searchresult) {
64 | memcpy(outbuff, searchresult + 2, 8);
65 | //Serial.print("Full PAN: ");
66 | //nfc.PrintHex(outbuff, 8);
67 | return 1;
68 | }
69 | return 0;
70 |
71 | } // end of if
72 | return 0;
73 | } //end of pan_search
74 |
75 |
76 |
77 | // Get Troyka serial from data block
78 | char * gettroykaserial(char * blockdata)
79 | {
80 |
81 | uint32_t serial_temp;
82 | char troykaserial[11];
83 |
84 |
85 | // Parse Troyka 10 digits serial number (not UID) that printed on card
86 | // located from 3 byte up to 4 lower bits of 3 byte
87 | memcpy(&serial_temp, &(blockdata[3]), 4);
88 |
89 | // Covert MSB to LSB byte order
90 | serial_temp = ((serial_temp>>24)&0xf0) | // move half from byte 3 to byte 0
91 | ((serial_temp<<8)&0xff0000) | // move byte 1 to byte 2
92 | ((serial_temp>>8)&0xff00) | // move byte 2 to byte 1
93 | ((serial_temp<<24)&0xff000000); // byte 0 to byte 3
94 |
95 | // Shift to half byte to the right
96 | serial_temp = serial_temp >> 4;
97 |
98 | // Add zero's padding from the left if necessary
99 | sprintf(troykaserial, "%010lu", serial_temp);
100 |
101 | Serial.print("Troyka Serial: ");
102 | Serial.println(troykaserial);
103 |
104 | return troykaserial;
105 | }
106 |
107 |
108 | void loop(void) {
109 | uint8_t success;
110 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
111 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
112 |
113 |
114 | // Troyka
115 | uint8_t TroykaKeyA[6] = { 0xA7, 0x3F, 0x5D, 0xC1, 0xD3, 0x33 }; // Key А from 8 sector Troyka card
116 | uint8_t KeyTypeA = 0;
117 | uint8_t KeyTypeB = 1;
118 | uint8_t TroykaBlockAddr = 32; // Sector 8, block 0 (block number 32)
119 |
120 | // EMV card
121 | bool apdusuccess;
122 | uint8_t apdu[255];
123 | uint8_t berBuffer[255];
124 | uint8_t berLength = 255;
125 | uint8_t aid[7];
126 | void *searchresult;
127 | uint8_t pan[8] = {0x00};
128 | uint8_t pan_found = 0;
129 | char temp[3];
130 | char * cardID;
131 |
132 |
133 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found
134 | // 'uid' will be populated with the UID, and uidLength will indicate length
135 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
136 |
137 | if (success) {
138 | // Display some basic information about the card
139 | Serial.println("");
140 | Serial.println("");
141 | Serial.println("Found an ISO14443A card");
142 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
143 | Serial.print(" UID Value: ");
144 | nfc.PrintHex(uid, uidLength);
145 | Serial.println("");
146 |
147 | if (uid)
148 | {
149 |
150 | if (uidLength == 7)
151 | {
152 | // If 7 bytes UID, we probably have a Troyka card
153 | // TODO: check ATS for detect mifare plus instead of UID length
154 | Serial.println("Seems to be a Troyka card (7 byte UID). Lets try authenticate it as Mifare Classic");
155 |
156 | success = nfc.mifareclassic_AuthenticateBlock(uid+3, uidLength - 3, TroykaBlockAddr, KeyTypeA, TroykaKeyA);
157 |
158 | if (success)
159 | {
160 | Serial.println("Sector 8 (Blocks 32..35) has been authenticated");
161 | uint8_t data[16];
162 |
163 | // Try to read content of block 32 (sector 8 block 0)
164 | success = nfc.mifareclassic_ReadDataBlock(TroykaBlockAddr, data);
165 |
166 | // Extract Troyka serial from block data
167 | cardID = gettroykaserial(data);
168 | Serial.println("-----------------------");
169 | Serial.print("Card ID: ");
170 | Serial.println(cardID);
171 |
172 | delay(2000);
173 | } // end of if (success)
174 |
175 | else
176 | {
177 | // If authentication failed, probably it's not mifare card
178 | // tryes to check for EMV card
179 | Serial.println("Failed to authenticate card as Mifare. Try to check for EMV card");
180 |
181 | delay(2000);
182 | }
183 | } // end of if (uidLength == 7)
184 |
185 | else if (uidLength == 4)
186 | {
187 | // If 4 bytes UID, we probably have a EMV card
188 | Serial.println("Seems to be a EMV card (4 byte UID). Lets try to read PAN nubmer");
189 |
190 | // Reading PSE file for AID number
191 | uint8_t apdu[] = {0x00, 0xA4, 0x04, 0x00, 0x0e, 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00};
192 | apdusuccess = nfc.inDataExchange(apdu, sizeof(apdu), berBuffer, &berLength);
193 |
194 | if (apdusuccess)
195 | {
196 | if (berLength > 10) {
197 | searchresult = dumb_memmem(berBuffer, berLength, aid_marker, 2);
198 | if (searchresult) {
199 | memcpy(&aid, searchresult + 2, 7);
200 | //Serial.print("AID: ");
201 | //nfc.PrintHex(aid, 7);
202 | }
203 | }
204 |
205 |
206 | // Now start application on card (AID)
207 | uint8_t startAID[] = {0x00, 0xa4, 0x04, 0x00, 0x07, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
208 | memcpy(&startAID[5], &aid, 7);
209 | //Serial.print("StartAID is: "); nfc.PrintHex(startAID, sizeof(startAID));
210 | berLength = 255;
211 | apdusuccess = nfc.inDataExchange(startAID, sizeof(startAID), berBuffer, &berLength);
212 |
213 |
214 | memset(pan, 0x00, 8);
215 | pan_found = 0;
216 | // Looking for PAN
217 | //uint8_t apdu1[] = {0x00, 0xb2, 0x01, 0x0c, 0x00};
218 | //berLength = 255;
219 | //apdusuccess = nfc.inDataExchange(apdu1, sizeof(apdu1), berBuffer, &berLength);
220 | //Serial.print("berBuffer1 is: "); nfc.PrintHex(berBuffer, berLength);
221 | //pan_found = pan_search(berBuffer, berLength, pan);
222 | //if (pan_found) Serial.println("Pan found"); else Serial.println("Pan not found");
223 |
224 | //uint8_t apdu2[] = {0x00, 0xb2, 0x02, 0x0c, 0x00};
225 | //berLength = 255;
226 | //apdusuccess = nfc.inDataExchange(apdu2, sizeof(apdu2), berBuffer, &berLength);
227 | //Serial.print("berBuffer3 is: "); nfc.PrintHex(berBuffer, berLength);
228 | //if (!pan_found)
229 | //pan_found = pan_search(berBuffer, berLength, pan);
230 | //if (pan_found) Serial.println("Pan found"); else Serial.println("Pan not found");
231 |
232 | uint8_t apdu3[] = {0x00, 0xb2, 0x01, 0x14, 0x00};
233 | berLength = 255;
234 | apdusuccess = nfc.inDataExchange(apdu3, sizeof(apdu3), berBuffer, &berLength);
235 | //Serial.print("berBuffer4 is: "); nfc.PrintHex(berBuffer, berLength);
236 | if (!pan_found)
237 | pan_found = pan_search(berBuffer, berLength, pan);
238 | //if (pan_found) Serial.println("Pan found"); else Serial.println("Pan not found");
239 |
240 | uint8_t apdu4[] = {0x00, 0xb2, 0x02, 0x14, 0x00};
241 | uint8_t berLength = 255;
242 | apdusuccess = nfc.inDataExchange(apdu4, sizeof(apdu4), berBuffer, &berLength);
243 | //Serial.print("berBuffer5 is: "); nfc.PrintHex(berBuffer, berLength);
244 | if (!pan_found)
245 | pan_found = pan_search(berBuffer, berLength, pan);
246 | //if (pan_found) Serial.println("Pan found"); else Serial.println("Pan not found");
247 |
248 | if (pan_found) {
249 | Serial.println("-----------------------");
250 | Serial.print("Сard ID: ");
251 | for (int i = 3; i < 8; i++) {
252 | sprintf(temp, "%02x", pan[i]);
253 | Serial.print(temp);
254 | }
255 | }
256 | }
257 |
258 |
259 | }
260 |
261 | else
262 | {
263 | Serial.print("Abnormal UID Length: ");
264 | nfc.PrintHex(uid, uidLength);
265 | }
266 |
267 | } // end of if (uid)
268 |
269 | else
270 | {
271 | // Failed to read card
272 | Serial.println("Failed to read card. Retry after 2 seconds.");
273 | delay(2000);
274 | }
275 | }
276 | }
277 |
278 |
--------------------------------------------------------------------------------
/Adafruit_PN532.cpp:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file Adafruit_PN532.cpp
4 | @author Adafruit Industries
5 | @license BSD (see license.txt)
6 |
7 | Driver for NXP's PN532 NFC/13.56MHz RFID Transceiver
8 |
9 | This is a library for the Adafruit PN532 NFC/RFID breakout boards
10 | This library works with the Adafruit NFC breakout
11 | ----> https://www.adafruit.com/products/364
12 |
13 | Check out the links above for our tutorials and wiring diagrams
14 | These chips use SPI or I2C to communicate.
15 |
16 | Adafruit invests time and resources providing this open source code,
17 | please support Adafruit and open-source hardware by purchasing
18 | products from Adafruit!
19 |
20 | @section HISTORY
21 |
22 | v2.1 - Added NTAG2xx helper functions
23 |
24 | v2.0 - Refactored to add I2C support from Adafruit_NFCShield_I2C library.
25 |
26 | v1.4 - Added setPassiveActivationRetries()
27 |
28 | v1.2 - Added writeGPIO()
29 | - Added readGPIO()
30 |
31 | v1.1 - Changed readPassiveTargetID() to handle multiple UID sizes
32 | - Added the following helper functions for text display
33 | static void PrintHex(const byte * data, const uint32_t numBytes)
34 | static void PrintHexChar(const byte * pbtData, const uint32_t numBytes)
35 | - Added the following Mifare Classic functions:
36 | bool mifareclassic_IsFirstBlock (uint32_t uiBlock)
37 | bool mifareclassic_IsTrailerBlock (uint32_t uiBlock)
38 | uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData)
39 | uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data)
40 | uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
41 | - Added the following Mifare Ultalight functions:
42 | uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
43 | */
44 | /**************************************************************************/
45 | #if ARDUINO >= 100
46 | #include "Arduino.h"
47 | #else
48 | #include "WProgram.h"
49 | #endif
50 |
51 | #include
52 | #if defined(__AVR__) || defined(__i386__) || defined(ARDUINO_ARCH_SAMD) || defined(ESP8266) || defined(ARDUINO_ARCH_STM32)
53 | #define WIRE Wire
54 | #else // Arduino Due
55 | #define WIRE Wire1
56 | #endif
57 |
58 | #include
59 |
60 | #include "Adafruit_PN532.h"
61 |
62 | byte pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
63 | byte pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
64 |
65 | // Uncomment these lines to enable debug output for PN532(SPI) and/or MIFARE related code
66 | // #define PN532DEBUG
67 | // #define MIFAREDEBUG
68 |
69 | // If using Native Port on Arduino Zero or Due define as SerialUSB
70 | #define PN532DEBUGPRINT Serial
71 | //#define PN532DEBUGPRINT SerialUSB
72 |
73 | // Hardware SPI-specific configuration:
74 | #ifdef SPI_HAS_TRANSACTION
75 | #define PN532_SPI_SETTING SPISettings(1000000, LSBFIRST, SPI_MODE0)
76 | #else
77 | #define PN532_SPI_CLOCKDIV SPI_CLOCK_DIV16
78 | #endif
79 |
80 | #define PN532_PACKBUFFSIZ 255
81 | byte pn532_packetbuffer[PN532_PACKBUFFSIZ];
82 |
83 | #ifndef _BV
84 | #define _BV(bit) (1<<(bit))
85 | #endif
86 |
87 | /**************************************************************************/
88 | /*!
89 | @brief Sends a single byte via I2C
90 |
91 | @param x The byte to send
92 | */
93 | /**************************************************************************/
94 | static inline void i2c_send(uint8_t x)
95 | {
96 | #if ARDUINO >= 100
97 | WIRE.write((uint8_t)x);
98 | #else
99 | WIRE.send(x);
100 | #endif
101 | }
102 |
103 | /**************************************************************************/
104 | /*!
105 | @brief Reads a single byte via I2C
106 | */
107 | /**************************************************************************/
108 | static inline uint8_t i2c_recv(void)
109 | {
110 | #if ARDUINO >= 100
111 | return WIRE.read();
112 | #else
113 | return WIRE.receive();
114 | #endif
115 | }
116 |
117 | /**************************************************************************/
118 | /*!
119 | @brief Instantiates a new PN532 class using software SPI.
120 |
121 | @param clk SPI clock pin (SCK)
122 | @param miso SPI MISO pin
123 | @param mosi SPI MOSI pin
124 | @param ss SPI chip select pin (CS/SSEL)
125 | */
126 | /**************************************************************************/
127 | Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss):
128 | _clk(clk),
129 | _miso(miso),
130 | _mosi(mosi),
131 | _ss(ss),
132 | _irq(0),
133 | _reset(0),
134 | _usingSPI(true),
135 | _hardwareSPI(false)
136 | {
137 | pinMode(_ss, OUTPUT);
138 | pinMode(_clk, OUTPUT);
139 | pinMode(_mosi, OUTPUT);
140 | pinMode(_miso, INPUT);
141 | }
142 |
143 | /**************************************************************************/
144 | /*!
145 | @brief Instantiates a new PN532 class using I2C.
146 |
147 | @param irq Location of the IRQ pin
148 | @param reset Location of the RSTPD_N pin
149 | */
150 | /**************************************************************************/
151 | Adafruit_PN532::Adafruit_PN532(uint8_t irq, uint8_t reset):
152 | _clk(0),
153 | _miso(0),
154 | _mosi(0),
155 | _ss(0),
156 | _irq(irq),
157 | _reset(reset),
158 | _usingSPI(false),
159 | _hardwareSPI(false)
160 | {
161 | pinMode(_irq, INPUT);
162 | pinMode(_reset, OUTPUT);
163 | }
164 |
165 | /**************************************************************************/
166 | /*!
167 | @brief Instantiates a new PN532 class using hardware SPI.
168 |
169 | @param ss SPI chip select pin (CS/SSEL)
170 | */
171 | /**************************************************************************/
172 | Adafruit_PN532::Adafruit_PN532(uint8_t ss):
173 | _clk(0),
174 | _miso(0),
175 | _mosi(0),
176 | _ss(ss),
177 | _irq(0),
178 | _reset(0),
179 | _usingSPI(true),
180 | _hardwareSPI(true)
181 | {
182 | pinMode(_ss, OUTPUT);
183 | }
184 |
185 | /**************************************************************************/
186 | /*!
187 | @brief Setups the HW
188 | */
189 | /**************************************************************************/
190 | void Adafruit_PN532::begin() {
191 | if (_usingSPI) {
192 | // SPI initialization
193 | if (_hardwareSPI) {
194 | SPI.begin();
195 |
196 | #ifdef SPI_HAS_TRANSACTION
197 | SPI.beginTransaction(PN532_SPI_SETTING);
198 | #else
199 | SPI.setDataMode(SPI_MODE0);
200 | SPI.setBitOrder(LSBFIRST);
201 | SPI.setClockDivider(PN532_SPI_CLOCKDIV);
202 | #endif
203 | }
204 | digitalWrite(_ss, LOW);
205 |
206 | delay(1000);
207 |
208 | // not exactly sure why but we have to send a dummy command to get synced up
209 | pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
210 | sendCommandCheckAck(pn532_packetbuffer, 1);
211 |
212 | // ignore response!
213 |
214 | digitalWrite(_ss, HIGH);
215 | #ifdef SPI_HAS_TRANSACTION
216 | if (_hardwareSPI) SPI.endTransaction();
217 | #endif
218 | }
219 | else {
220 | // I2C initialization.
221 | WIRE.begin();
222 |
223 | // Reset the PN532
224 | digitalWrite(_reset, HIGH);
225 | digitalWrite(_reset, LOW);
226 | delay(400);
227 | digitalWrite(_reset, HIGH);
228 | delay(10); // Small delay required before taking other actions after reset.
229 | // See timing diagram on page 209 of the datasheet, section 12.23.
230 | }
231 | }
232 |
233 | /**************************************************************************/
234 | /*!
235 | @brief Prints a hexadecimal value in plain characters
236 |
237 | @param data Pointer to the byte data
238 | @param numBytes Data length in bytes
239 | */
240 | /**************************************************************************/
241 | void Adafruit_PN532::PrintHex(const byte * data, const uint32_t numBytes)
242 | {
243 | uint32_t szPos;
244 | for (szPos=0; szPos < numBytes; szPos++)
245 | {
246 | PN532DEBUGPRINT.print(F("0x"));
247 | // Append leading 0 for small values
248 | if (data[szPos] <= 0xF)
249 | PN532DEBUGPRINT.print(F("0"));
250 | PN532DEBUGPRINT.print(data[szPos]&0xff, HEX);
251 | if ((numBytes > 1) && (szPos != numBytes - 1))
252 | {
253 | PN532DEBUGPRINT.print(F(" "));
254 | }
255 | }
256 | PN532DEBUGPRINT.println();
257 | }
258 |
259 | /**************************************************************************/
260 | /*!
261 | @brief Prints a hexadecimal value in plain characters, along with
262 | the char equivalents in the following format
263 |
264 | 00 00 00 00 00 00 ......
265 |
266 | @param data Pointer to the byte data
267 | @param numBytes Data length in bytes
268 | */
269 | /**************************************************************************/
270 | void Adafruit_PN532::PrintHexChar(const byte * data, const uint32_t numBytes)
271 | {
272 | uint32_t szPos;
273 | for (szPos=0; szPos < numBytes; szPos++)
274 | {
275 | // Append leading 0 for small values
276 | if (data[szPos] <= 0xF)
277 | PN532DEBUGPRINT.print(F("0"));
278 | PN532DEBUGPRINT.print(data[szPos], HEX);
279 | if ((numBytes > 1) && (szPos != numBytes - 1))
280 | {
281 | PN532DEBUGPRINT.print(F(" "));
282 | }
283 | }
284 | PN532DEBUGPRINT.print(F(" "));
285 | for (szPos=0; szPos < numBytes; szPos++)
286 | {
287 | if (data[szPos] <= 0x1F)
288 | PN532DEBUGPRINT.print(F("."));
289 | else
290 | PN532DEBUGPRINT.print((char)data[szPos]);
291 | }
292 | PN532DEBUGPRINT.println();
293 | }
294 |
295 | /**************************************************************************/
296 | /*!
297 | @brief Checks the firmware version of the PN5xx chip
298 |
299 | @returns The chip's firmware version and ID
300 | */
301 | /**************************************************************************/
302 | uint32_t Adafruit_PN532::getFirmwareVersion(void) {
303 | uint32_t response;
304 |
305 | pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
306 |
307 | if (! sendCommandCheckAck(pn532_packetbuffer, 1)) {
308 | return 0;
309 | }
310 |
311 | // read data packet
312 | readdata(pn532_packetbuffer, 12);
313 |
314 | // check some basic stuff
315 | if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6)) {
316 | #ifdef PN532DEBUG
317 | PN532DEBUGPRINT.println(F("Firmware doesn't match!"));
318 | #endif
319 | return 0;
320 | }
321 |
322 | int offset = _usingSPI ? 6 : 7; // Skip a response byte when using I2C to ignore extra data.
323 | response = pn532_packetbuffer[offset++];
324 | response <<= 8;
325 | response |= pn532_packetbuffer[offset++];
326 | response <<= 8;
327 | response |= pn532_packetbuffer[offset++];
328 | response <<= 8;
329 | response |= pn532_packetbuffer[offset++];
330 |
331 | return response;
332 | }
333 |
334 |
335 | /**************************************************************************/
336 | /*!
337 | @brief Sends a command and waits a specified period for the ACK
338 |
339 | @param cmd Pointer to the command buffer
340 | @param cmdlen The size of the command in bytes
341 | @param timeout timeout before giving up
342 |
343 | @returns 1 if everything is OK, 0 if timeout occured before an
344 | ACK was recieved
345 | */
346 | /**************************************************************************/
347 | // default timeout of one second
348 | bool Adafruit_PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout) {
349 | uint16_t timer = 0;
350 |
351 | // write the command
352 | writecommand(cmd, cmdlen);
353 |
354 | // Wait for chip to say its ready!
355 | if (!waitready(timeout)) {
356 | return false;
357 | }
358 |
359 | #ifdef PN532DEBUG
360 | if (!_usingSPI) {
361 | PN532DEBUGPRINT.println(F("IRQ received"));
362 | }
363 | #endif
364 |
365 | // read acknowledgement
366 | if (!readack()) {
367 | #ifdef PN532DEBUG
368 | PN532DEBUGPRINT.println(F("No ACK frame received!"));
369 | #endif
370 | return false;
371 | }
372 |
373 | // For SPI only wait for the chip to be ready again.
374 | // This is unnecessary with I2C.
375 | if (_usingSPI) {
376 | if (!waitready(timeout)) {
377 | return false;
378 | }
379 | }
380 |
381 | return true; // ack'd command
382 | }
383 |
384 | /**************************************************************************/
385 | /*!
386 | Writes an 8-bit value that sets the state of the PN532's GPIO pins
387 |
388 | @warning This function is provided exclusively for board testing and
389 | is dangerous since it will throw an error if any pin other
390 | than the ones marked "Can be used as GPIO" are modified! All
391 | pins that can not be used as GPIO should ALWAYS be left high
392 | (value = 1) or the system will become unstable and a HW reset
393 | will be required to recover the PN532.
394 |
395 | pinState[0] = P30 Can be used as GPIO
396 | pinState[1] = P31 Can be used as GPIO
397 | pinState[2] = P32 *** RESERVED (Must be 1!) ***
398 | pinState[3] = P33 Can be used as GPIO
399 | pinState[4] = P34 *** RESERVED (Must be 1!) ***
400 | pinState[5] = P35 Can be used as GPIO
401 |
402 | @returns 1 if everything executed properly, 0 for an error
403 | */
404 | /**************************************************************************/
405 | bool Adafruit_PN532::writeGPIO(uint8_t pinstate) {
406 | uint8_t errorbit;
407 |
408 | // Make sure pinstate does not try to toggle P32 or P34
409 | pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
410 |
411 | // Fill command buffer
412 | pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
413 | pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins
414 | pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by SPI)
415 |
416 | #ifdef PN532DEBUG
417 | PN532DEBUGPRINT.print(F("Writing P3 GPIO: ")); PN532DEBUGPRINT.println(pn532_packetbuffer[1], HEX);
418 | #endif
419 |
420 | // Send the WRITEGPIO command (0x0E)
421 | if (! sendCommandCheckAck(pn532_packetbuffer, 3))
422 | return 0x0;
423 |
424 | // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0F) DATACHECKSUM 00)
425 | readdata(pn532_packetbuffer, 8);
426 |
427 | #ifdef PN532DEBUG
428 | PN532DEBUGPRINT.print(F("Received: "));
429 | PrintHex(pn532_packetbuffer, 8);
430 | PN532DEBUGPRINT.println();
431 | #endif
432 |
433 | int offset = _usingSPI ? 5 : 6;
434 | return (pn532_packetbuffer[offset] == 0x0F);
435 | }
436 |
437 | /**************************************************************************/
438 | /*!
439 | Reads the state of the PN532's GPIO pins
440 |
441 | @returns An 8-bit value containing the pin state where:
442 |
443 | pinState[0] = P30
444 | pinState[1] = P31
445 | pinState[2] = P32
446 | pinState[3] = P33
447 | pinState[4] = P34
448 | pinState[5] = P35
449 | */
450 | /**************************************************************************/
451 | uint8_t Adafruit_PN532::readGPIO(void) {
452 | pn532_packetbuffer[0] = PN532_COMMAND_READGPIO;
453 |
454 | // Send the READGPIO command (0x0C)
455 | if (! sendCommandCheckAck(pn532_packetbuffer, 1))
456 | return 0x0;
457 |
458 | // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0D) P3 P7 IO1 DATACHECKSUM 00)
459 | readdata(pn532_packetbuffer, 11);
460 |
461 | /* READGPIO response should be in the following format:
462 |
463 | byte Description
464 | ------------- ------------------------------------------
465 | b0..5 Frame header and preamble (with I2C there is an extra 0x00)
466 | b6 P3 GPIO Pins
467 | b7 P7 GPIO Pins (not used ... taken by SPI)
468 | b8 Interface Mode Pins (not used ... bus select pins)
469 | b9..10 checksum */
470 |
471 | int p3offset = _usingSPI ? 6 : 7;
472 |
473 | #ifdef PN532DEBUG
474 | PN532DEBUGPRINT.print(F("Received: "));
475 | PrintHex(pn532_packetbuffer, 11);
476 | PN532DEBUGPRINT.println();
477 | PN532DEBUGPRINT.print(F("P3 GPIO: 0x")); PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset], HEX);
478 | PN532DEBUGPRINT.print(F("P7 GPIO: 0x")); PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset+1], HEX);
479 | PN532DEBUGPRINT.print(F("IO GPIO: 0x")); PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset+2], HEX);
480 | // Note: You can use the IO GPIO value to detect the serial bus being used
481 | switch(pn532_packetbuffer[p3offset+2])
482 | {
483 | case 0x00: // Using UART
484 | PN532DEBUGPRINT.println(F("Using UART (IO = 0x00)"));
485 | break;
486 | case 0x01: // Using I2C
487 | PN532DEBUGPRINT.println(F("Using I2C (IO = 0x01)"));
488 | break;
489 | case 0x02: // Using SPI
490 | PN532DEBUGPRINT.println(F("Using SPI (IO = 0x02)"));
491 | break;
492 | }
493 | #endif
494 |
495 | return pn532_packetbuffer[p3offset];
496 | }
497 |
498 | /**************************************************************************/
499 | /*!
500 | @brief Configures the SAM (Secure Access Module)
501 | */
502 | /**************************************************************************/
503 | bool Adafruit_PN532::SAMConfig(void) {
504 | pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
505 | pn532_packetbuffer[1] = 0x01; // normal mode;
506 | pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
507 | pn532_packetbuffer[3] = 0x01; // use IRQ pin!
508 |
509 | if (! sendCommandCheckAck(pn532_packetbuffer, 4))
510 | return false;
511 |
512 | // read data packet
513 | readdata(pn532_packetbuffer, 8);
514 |
515 | int offset = _usingSPI ? 5 : 6;
516 | return (pn532_packetbuffer[offset] == 0x15);
517 | }
518 |
519 | /**************************************************************************/
520 | /*!
521 | Sets the MxRtyPassiveActivation byte of the RFConfiguration register
522 |
523 | @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout
524 | after mxRetries
525 |
526 | @returns 1 if everything executed properly, 0 for an error
527 | */
528 | /**************************************************************************/
529 | bool Adafruit_PN532::setPassiveActivationRetries(uint8_t maxRetries) {
530 | pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
531 | pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
532 | pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
533 | pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
534 | pn532_packetbuffer[4] = maxRetries;
535 |
536 | #ifdef MIFAREDEBUG
537 | PN532DEBUGPRINT.print(F("Setting MxRtyPassiveActivation to ")); PN532DEBUGPRINT.print(maxRetries, DEC); PN532DEBUGPRINT.println(F(" "));
538 | #endif
539 |
540 | if (! sendCommandCheckAck(pn532_packetbuffer, 5))
541 | return 0x0; // no ACK
542 |
543 | return 1;
544 | }
545 |
546 | /***** ISO14443A Commands ******/
547 |
548 | /**************************************************************************/
549 | /*!
550 | Waits for an ISO14443A target to enter the field
551 |
552 | @param cardBaudRate Baud rate of the card
553 | @param uid Pointer to the array that will be populated
554 | with the card's UID (up to 7 bytes)
555 | @param uidLength Pointer to the variable that will hold the
556 | length of the card's UID.
557 |
558 | @returns 1 if everything executed properly, 0 for an error
559 | */
560 | /**************************************************************************/
561 | bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, uint8_t * uidLength, uint16_t timeout) {
562 | pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
563 | pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
564 | pn532_packetbuffer[2] = cardbaudrate;
565 |
566 | if (!sendCommandCheckAck(pn532_packetbuffer, 3, timeout))
567 | {
568 | #ifdef PN532DEBUG
569 | PN532DEBUGPRINT.println(F("No card(s) read"));
570 | #endif
571 | return 0x0; // no cards read
572 | }
573 |
574 | // wait for a card to enter the field (only possible with I2C)
575 | if (!_usingSPI) {
576 | #ifdef PN532DEBUG
577 | PN532DEBUGPRINT.println(F("Waiting for IRQ (indicates card presence)"));
578 | #endif
579 | if (!waitready(timeout)) {
580 | #ifdef PN532DEBUG
581 | PN532DEBUGPRINT.println(F("IRQ Timeout"));
582 | #endif
583 | return 0x0;
584 | }
585 | }
586 |
587 | // read data packet
588 | readdata(pn532_packetbuffer, 20);
589 | // check some basic stuff
590 |
591 | /* ISO14443A card response should be in the following format:
592 |
593 | byte Description
594 | ------------- ------------------------------------------
595 | b0..6 Frame header and preamble
596 | b7 Tags Found
597 | b8 Tag Number (only one used in this example)
598 | b9..10 SENS_RES
599 | b11 SEL_RES
600 | b12 NFCID Length
601 | b13..NFCIDLen NFCID */
602 |
603 | #ifdef MIFAREDEBUG
604 | PN532DEBUGPRINT.print(F("Found ")); PN532DEBUGPRINT.print(pn532_packetbuffer[7], DEC); PN532DEBUGPRINT.println(F(" tags"));
605 | #endif
606 | if (pn532_packetbuffer[7] != 1)
607 | return 0;
608 |
609 | uint16_t sens_res = pn532_packetbuffer[9];
610 | sens_res <<= 8;
611 | sens_res |= pn532_packetbuffer[10];
612 | #ifdef MIFAREDEBUG
613 | PN532DEBUGPRINT.print(F("ATQA: 0x")); PN532DEBUGPRINT.println(sens_res, HEX);
614 | PN532DEBUGPRINT.print(F("SAK: 0x")); PN532DEBUGPRINT.println(pn532_packetbuffer[11], HEX);
615 | #endif
616 |
617 | /* Card appears to be Mifare Classic */
618 | *uidLength = pn532_packetbuffer[12];
619 | #ifdef MIFAREDEBUG
620 | PN532DEBUGPRINT.print(F("UID:"));
621 | #endif
622 | for (uint8_t i=0; i < pn532_packetbuffer[12]; i++)
623 | {
624 | uid[i] = pn532_packetbuffer[13+i];
625 | #ifdef MIFAREDEBUG
626 | PN532DEBUGPRINT.print(F(" 0x"));PN532DEBUGPRINT.print(uid[i], HEX);
627 | #endif
628 | }
629 | #ifdef MIFAREDEBUG
630 | PN532DEBUGPRINT.println();
631 | #endif
632 |
633 | return 1;
634 | }
635 |
636 | /**************************************************************************/
637 | /*!
638 | @brief Exchanges an APDU with the currently inlisted peer
639 |
640 | @param send Pointer to data to send
641 | @param sendLength Length of the data to send
642 | @param response Pointer to response data
643 | @param responseLength Pointer to the response data length
644 | */
645 | /**************************************************************************/
646 | bool Adafruit_PN532::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint8_t * responseLength) {
647 | if (sendLength > PN532_PACKBUFFSIZ-2) {
648 | #ifdef PN532DEBUG
649 | PN532DEBUGPRINT.println(F("APDU length too long for packet buffer"));
650 | #endif
651 | return false;
652 | }
653 | uint8_t i;
654 |
655 | pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
656 | pn532_packetbuffer[1] = _inListedTag;
657 | for (i=0; i *responseLength) {
698 | length = *responseLength; // silent truncation...
699 | }
700 |
701 | for (i=0; i 15))
1046 | return 0;
1047 |
1048 | // Make sure the URI payload is between 1 and 38 chars
1049 | if ((len < 1) || (len > 38))
1050 | return 0;
1051 |
1052 | // Note 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 must be used for key A
1053 | // in NDEF records
1054 |
1055 | // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
1056 | uint8_t sectorbuffer1[16] = {0x00, 0x00, 0x03, len+5, 0xD1, 0x01, len+1, 0x55, uriIdentifier, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1057 | uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1058 | uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1059 | uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1060 | if (len <= 6)
1061 | {
1062 | // Unlikely we'll get a url this short, but why not ...
1063 | memcpy (sectorbuffer1+9, url, len);
1064 | sectorbuffer1[len+9] = 0xFE;
1065 | }
1066 | else if (len == 7)
1067 | {
1068 | // 0xFE needs to be wrapped around to next block
1069 | memcpy (sectorbuffer1+9, url, len);
1070 | sectorbuffer2[0] = 0xFE;
1071 | }
1072 | else if ((len > 7) && (len <= 22))
1073 | {
1074 | // Url fits in two blocks
1075 | memcpy (sectorbuffer1+9, url, 7);
1076 | memcpy (sectorbuffer2, url+7, len-7);
1077 | sectorbuffer2[len-7] = 0xFE;
1078 | }
1079 | else if (len == 23)
1080 | {
1081 | // 0xFE needs to be wrapped around to final block
1082 | memcpy (sectorbuffer1+9, url, 7);
1083 | memcpy (sectorbuffer2, url+7, len-7);
1084 | sectorbuffer3[0] = 0xFE;
1085 | }
1086 | else
1087 | {
1088 | // Url fits in three blocks
1089 | memcpy (sectorbuffer1+9, url, 7);
1090 | memcpy (sectorbuffer2, url+7, 16);
1091 | memcpy (sectorbuffer3, url+23, len-24);
1092 | sectorbuffer3[len-22] = 0xFE;
1093 | }
1094 |
1095 | // Now write all three blocks back to the card
1096 | if (!(mifareclassic_WriteDataBlock (sectorNumber*4, sectorbuffer1)))
1097 | return 0;
1098 | if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+1, sectorbuffer2)))
1099 | return 0;
1100 | if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+2, sectorbuffer3)))
1101 | return 0;
1102 | if (!(mifareclassic_WriteDataBlock ((sectorNumber*4)+3, sectorbuffer4)))
1103 | return 0;
1104 |
1105 | // Seems that everything was OK (?!)
1106 | return 1;
1107 | }
1108 |
1109 | /***** Mifare Ultralight Functions ******/
1110 |
1111 | /**************************************************************************/
1112 | /*!
1113 | Tries to read an entire 4-byte page at the specified address.
1114 |
1115 | @param page The page number (0..63 in most cases)
1116 | @param buffer Pointer to the byte array that will hold the
1117 | retrieved data (if any)
1118 | */
1119 | /**************************************************************************/
1120 | uint8_t Adafruit_PN532::mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
1121 | {
1122 | if (page >= 64)
1123 | {
1124 | #ifdef MIFAREDEBUG
1125 | PN532DEBUGPRINT.println(F("Page value out of range"));
1126 | #endif
1127 | return 0;
1128 | }
1129 |
1130 | #ifdef MIFAREDEBUG
1131 | PN532DEBUGPRINT.print(F("Reading page "));PN532DEBUGPRINT.println(page);
1132 | #endif
1133 |
1134 | /* Prepare the command */
1135 | pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1136 | pn532_packetbuffer[1] = 1; /* Card number */
1137 | pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
1138 | pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
1139 |
1140 | /* Send the command */
1141 | if (! sendCommandCheckAck(pn532_packetbuffer, 4))
1142 | {
1143 | #ifdef MIFAREDEBUG
1144 | PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1145 | #endif
1146 | return 0;
1147 | }
1148 |
1149 | /* Read the response packet */
1150 | readdata(pn532_packetbuffer, 26);
1151 | #ifdef MIFAREDEBUG
1152 | PN532DEBUGPRINT.println(F("Received: "));
1153 | Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1154 | #endif
1155 |
1156 | /* If byte 8 isn't 0x00 we probably have an error */
1157 | if (pn532_packetbuffer[7] == 0x00)
1158 | {
1159 | /* Copy the 4 data bytes to the output buffer */
1160 | /* Block content starts at byte 9 of a valid response */
1161 | /* Note that the command actually reads 16 byte or 4 */
1162 | /* pages at a time ... we simply discard the last 12 */
1163 | /* bytes */
1164 | memcpy (buffer, pn532_packetbuffer+8, 4);
1165 | }
1166 | else
1167 | {
1168 | #ifdef MIFAREDEBUG
1169 | PN532DEBUGPRINT.println(F("Unexpected response reading block: "));
1170 | Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1171 | #endif
1172 | return 0;
1173 | }
1174 |
1175 | /* Display data for debug if requested */
1176 | #ifdef MIFAREDEBUG
1177 | PN532DEBUGPRINT.print(F("Page "));PN532DEBUGPRINT.print(page);PN532DEBUGPRINT.println(F(":"));
1178 | Adafruit_PN532::PrintHexChar(buffer, 4);
1179 | #endif
1180 |
1181 | // Return OK signal
1182 | return 1;
1183 | }
1184 |
1185 | /**************************************************************************/
1186 | /*!
1187 | Tries to write an entire 4-byte page at the specified block
1188 | address.
1189 |
1190 | @param page The page number to write. (0..63 for most cases)
1191 | @param data The byte array that contains the data to write.
1192 | Should be exactly 4 bytes long.
1193 |
1194 | @returns 1 if everything executed properly, 0 for an error
1195 | */
1196 | /**************************************************************************/
1197 | uint8_t Adafruit_PN532::mifareultralight_WritePage (uint8_t page, uint8_t * data)
1198 | {
1199 |
1200 | if (page >= 64)
1201 | {
1202 | #ifdef MIFAREDEBUG
1203 | PN532DEBUGPRINT.println(F("Page value out of range"));
1204 | #endif
1205 | // Return Failed Signal
1206 | return 0;
1207 | }
1208 |
1209 | #ifdef MIFAREDEBUG
1210 | PN532DEBUGPRINT.print(F("Trying to write 4 byte page"));PN532DEBUGPRINT.println(page);
1211 | #endif
1212 |
1213 | /* Prepare the first command */
1214 | pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1215 | pn532_packetbuffer[1] = 1; /* Card number */
1216 | pn532_packetbuffer[2] = MIFARE_ULTRALIGHT_CMD_WRITE; /* Mifare Ultralight Write command = 0xA2 */
1217 | pn532_packetbuffer[3] = page; /* Page Number (0..63 for most cases) */
1218 | memcpy (pn532_packetbuffer+4, data, 4); /* Data Payload */
1219 |
1220 | /* Send the command */
1221 | if (! sendCommandCheckAck(pn532_packetbuffer, 8))
1222 | {
1223 | #ifdef MIFAREDEBUG
1224 | PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1225 | #endif
1226 |
1227 | // Return Failed Signal
1228 | return 0;
1229 | }
1230 | delay(10);
1231 |
1232 | /* Read the response packet */
1233 | readdata(pn532_packetbuffer, 26);
1234 |
1235 | // Return OK Signal
1236 | return 1;
1237 | }
1238 |
1239 |
1240 | /***** NTAG2xx Functions ******/
1241 |
1242 | /**************************************************************************/
1243 | /*!
1244 | Tries to read an entire 4-byte page at the specified address.
1245 |
1246 | @param page The page number (0..63 in most cases)
1247 | @param buffer Pointer to the byte array that will hold the
1248 | retrieved data (if any)
1249 | */
1250 | /**************************************************************************/
1251 | uint8_t Adafruit_PN532::ntag2xx_ReadPage (uint8_t page, uint8_t * buffer)
1252 | {
1253 | // TAG Type PAGES USER START USER STOP
1254 | // -------- ----- ---------- ---------
1255 | // NTAG 203 42 4 39
1256 | // NTAG 213 45 4 39
1257 | // NTAG 215 135 4 129
1258 | // NTAG 216 231 4 225
1259 |
1260 | if (page >= 231)
1261 | {
1262 | #ifdef MIFAREDEBUG
1263 | PN532DEBUGPRINT.println(F("Page value out of range"));
1264 | #endif
1265 | return 0;
1266 | }
1267 |
1268 | #ifdef MIFAREDEBUG
1269 | PN532DEBUGPRINT.print(F("Reading page "));PN532DEBUGPRINT.println(page);
1270 | #endif
1271 |
1272 | /* Prepare the command */
1273 | pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1274 | pn532_packetbuffer[1] = 1; /* Card number */
1275 | pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
1276 | pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
1277 |
1278 | /* Send the command */
1279 | if (! sendCommandCheckAck(pn532_packetbuffer, 4))
1280 | {
1281 | #ifdef MIFAREDEBUG
1282 | PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1283 | #endif
1284 | return 0;
1285 | }
1286 |
1287 | /* Read the response packet */
1288 | readdata(pn532_packetbuffer, 26);
1289 | #ifdef MIFAREDEBUG
1290 | PN532DEBUGPRINT.println(F("Received: "));
1291 | Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1292 | #endif
1293 |
1294 | /* If byte 8 isn't 0x00 we probably have an error */
1295 | if (pn532_packetbuffer[7] == 0x00)
1296 | {
1297 | /* Copy the 4 data bytes to the output buffer */
1298 | /* Block content starts at byte 9 of a valid response */
1299 | /* Note that the command actually reads 16 byte or 4 */
1300 | /* pages at a time ... we simply discard the last 12 */
1301 | /* bytes */
1302 | memcpy (buffer, pn532_packetbuffer+8, 4);
1303 | }
1304 | else
1305 | {
1306 | #ifdef MIFAREDEBUG
1307 | PN532DEBUGPRINT.println(F("Unexpected response reading block: "));
1308 | Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1309 | #endif
1310 | return 0;
1311 | }
1312 |
1313 | /* Display data for debug if requested */
1314 | #ifdef MIFAREDEBUG
1315 | PN532DEBUGPRINT.print(F("Page "));PN532DEBUGPRINT.print(page);PN532DEBUGPRINT.println(F(":"));
1316 | Adafruit_PN532::PrintHexChar(buffer, 4);
1317 | #endif
1318 |
1319 | // Return OK signal
1320 | return 1;
1321 | }
1322 |
1323 | /**************************************************************************/
1324 | /*!
1325 | Tries to write an entire 4-byte page at the specified block
1326 | address.
1327 |
1328 | @param page The page number to write. (0..63 for most cases)
1329 | @param data The byte array that contains the data to write.
1330 | Should be exactly 4 bytes long.
1331 |
1332 | @returns 1 if everything executed properly, 0 for an error
1333 | */
1334 | /**************************************************************************/
1335 | uint8_t Adafruit_PN532::ntag2xx_WritePage (uint8_t page, uint8_t * data)
1336 | {
1337 | // TAG Type PAGES USER START USER STOP
1338 | // -------- ----- ---------- ---------
1339 | // NTAG 203 42 4 39
1340 | // NTAG 213 45 4 39
1341 | // NTAG 215 135 4 129
1342 | // NTAG 216 231 4 225
1343 |
1344 | if ((page < 4) || (page > 225))
1345 | {
1346 | #ifdef MIFAREDEBUG
1347 | PN532DEBUGPRINT.println(F("Page value out of range"));
1348 | #endif
1349 | // Return Failed Signal
1350 | return 0;
1351 | }
1352 |
1353 | #ifdef MIFAREDEBUG
1354 | PN532DEBUGPRINT.print(F("Trying to write 4 byte page"));PN532DEBUGPRINT.println(page);
1355 | #endif
1356 |
1357 | /* Prepare the first command */
1358 | pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1359 | pn532_packetbuffer[1] = 1; /* Card number */
1360 | pn532_packetbuffer[2] = MIFARE_ULTRALIGHT_CMD_WRITE; /* Mifare Ultralight Write command = 0xA2 */
1361 | pn532_packetbuffer[3] = page; /* Page Number (0..63 for most cases) */
1362 | memcpy (pn532_packetbuffer+4, data, 4); /* Data Payload */
1363 |
1364 | /* Send the command */
1365 | if (! sendCommandCheckAck(pn532_packetbuffer, 8))
1366 | {
1367 | #ifdef MIFAREDEBUG
1368 | PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1369 | #endif
1370 |
1371 | // Return Failed Signal
1372 | return 0;
1373 | }
1374 | delay(10);
1375 |
1376 | /* Read the response packet */
1377 | readdata(pn532_packetbuffer, 26);
1378 |
1379 | // Return OK Signal
1380 | return 1;
1381 | }
1382 |
1383 | /**************************************************************************/
1384 | /*!
1385 | Writes an NDEF URI Record starting at the specified page (4..nn)
1386 |
1387 | Note that this function assumes that the NTAG2xx card is
1388 | already formatted to work as an "NFC Forum Tag".
1389 |
1390 | @param uriIdentifier The uri identifier code (0 = none, 0x01 =
1391 | "http://www.", etc.)
1392 | @param url The uri text to write (null-terminated string).
1393 | @param dataLen The size of the data area for overflow checks.
1394 |
1395 | @returns 1 if everything executed properly, 0 for an error
1396 | */
1397 | /**************************************************************************/
1398 | uint8_t Adafruit_PN532::ntag2xx_WriteNDEFURI (uint8_t uriIdentifier, char * url, uint8_t dataLen)
1399 | {
1400 | uint8_t pageBuffer[4] = { 0, 0, 0, 0 };
1401 |
1402 | // Remove NDEF record overhead from the URI data (pageHeader below)
1403 | uint8_t wrapperSize = 12;
1404 |
1405 | // Figure out how long the string is
1406 | uint8_t len = strlen(url);
1407 |
1408 | // Make sure the URI payload will fit in dataLen (include 0xFE trailer)
1409 | if ((len < 1) || (len+1 > (dataLen-wrapperSize)))
1410 | return 0;
1411 |
1412 | // Setup the record header
1413 | // See NFCForum-TS-Type-2-Tag_1.1.pdf for details
1414 | uint8_t pageHeader[12] =
1415 | {
1416 | /* NDEF Lock Control TLV (must be first and always present) */
1417 | 0x01, /* Tag Field (0x01 = Lock Control TLV) */
1418 | 0x03, /* Payload Length (always 3) */
1419 | 0xA0, /* The position inside the tag of the lock bytes (upper 4 = page address, lower 4 = byte offset) */
1420 | 0x10, /* Size in bits of the lock area */
1421 | 0x44, /* Size in bytes of a page and the number of bytes each lock bit can lock (4 bit + 4 bits) */
1422 | /* NDEF Message TLV - URI Record */
1423 | 0x03, /* Tag Field (0x03 = NDEF Message) */
1424 | len+5, /* Payload Length (not including 0xFE trailer) */
1425 | 0xD1, /* NDEF Record Header (TNF=0x1:Well known record + SR + ME + MB) */
1426 | 0x01, /* Type Length for the record type indicator */
1427 | len+1, /* Payload len */
1428 | 0x55, /* Record Type Indicator (0x55 or 'U' = URI Record) */
1429 | uriIdentifier /* URI Prefix (ex. 0x01 = "http://www.") */
1430 | };
1431 |
1432 | // Write 12 byte header (three pages of data starting at page 4)
1433 | memcpy (pageBuffer, pageHeader, 4);
1434 | if (!(ntag2xx_WritePage (4, pageBuffer)))
1435 | return 0;
1436 | memcpy (pageBuffer, pageHeader+4, 4);
1437 | if (!(ntag2xx_WritePage (5, pageBuffer)))
1438 | return 0;
1439 | memcpy (pageBuffer, pageHeader+8, 4);
1440 | if (!(ntag2xx_WritePage (6, pageBuffer)))
1441 | return 0;
1442 |
1443 | // Write URI (starting at page 7)
1444 | uint8_t currentPage = 7;
1445 | char * urlcopy = url;
1446 | while(len)
1447 | {
1448 | if (len < 4)
1449 | {
1450 | memset(pageBuffer, 0, 4);
1451 | memcpy(pageBuffer, urlcopy, len);
1452 | pageBuffer[len] = 0xFE; // NDEF record footer
1453 | if (!(ntag2xx_WritePage (currentPage, pageBuffer)))
1454 | return 0;
1455 | // DONE!
1456 | return 1;
1457 | }
1458 | else if (len == 4)
1459 | {
1460 | memcpy(pageBuffer, urlcopy, len);
1461 | if (!(ntag2xx_WritePage (currentPage, pageBuffer)))
1462 | return 0;
1463 | memset(pageBuffer, 0, 4);
1464 | pageBuffer[0] = 0xFE; // NDEF record footer
1465 | currentPage++;
1466 | if (!(ntag2xx_WritePage (currentPage, pageBuffer)))
1467 | return 0;
1468 | // DONE!
1469 | return 1;
1470 | }
1471 | else
1472 | {
1473 | // More than one page of data left
1474 | memcpy(pageBuffer, urlcopy, 4);
1475 | if (!(ntag2xx_WritePage (currentPage, pageBuffer)))
1476 | return 0;
1477 | currentPage++;
1478 | urlcopy+=4;
1479 | len-=4;
1480 | }
1481 | }
1482 |
1483 | // Seems that everything was OK (?!)
1484 | return 1;
1485 | }
1486 |
1487 |
1488 | /************** high level communication functions (handles both I2C and SPI) */
1489 |
1490 |
1491 | /**************************************************************************/
1492 | /*!
1493 | @brief Tries to read the SPI or I2C ACK signal
1494 | */
1495 | /**************************************************************************/
1496 | bool Adafruit_PN532::readack() {
1497 | uint8_t ackbuff[6];
1498 |
1499 | readdata(ackbuff, 6);
1500 |
1501 | return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
1502 | }
1503 |
1504 |
1505 | /**************************************************************************/
1506 | /*!
1507 | @brief Return true if the PN532 is ready with a response.
1508 | */
1509 | /**************************************************************************/
1510 | bool Adafruit_PN532::isready() {
1511 | if (_usingSPI) {
1512 | // SPI read status and check if ready.
1513 | #ifdef SPI_HAS_TRANSACTION
1514 | if (_hardwareSPI) SPI.beginTransaction(PN532_SPI_SETTING);
1515 | #endif
1516 | digitalWrite(_ss, LOW);
1517 | delay(2);
1518 | spi_write(PN532_SPI_STATREAD);
1519 | // read byte
1520 | uint8_t x = spi_read();
1521 |
1522 | digitalWrite(_ss, HIGH);
1523 | #ifdef SPI_HAS_TRANSACTION
1524 | if (_hardwareSPI) SPI.endTransaction();
1525 | #endif
1526 |
1527 | // Check if status is ready.
1528 | return x == PN532_SPI_READY;
1529 | }
1530 | else {
1531 | // I2C check if status is ready by IRQ line being pulled low.
1532 | uint8_t x = digitalRead(_irq);
1533 | return x == 0;
1534 | }
1535 | }
1536 |
1537 | /**************************************************************************/
1538 | /*!
1539 | @brief Waits until the PN532 is ready.
1540 |
1541 | @param timeout Timeout before giving up
1542 | */
1543 | /**************************************************************************/
1544 | bool Adafruit_PN532::waitready(uint16_t timeout) {
1545 | uint16_t timer = 0;
1546 | while(!isready()) {
1547 | if (timeout != 0) {
1548 | timer += 10;
1549 | if (timer > timeout) {
1550 | PN532DEBUGPRINT.println("TIMEOUT!");
1551 | return false;
1552 | }
1553 | }
1554 | delay(10);
1555 | }
1556 | return true;
1557 | }
1558 |
1559 | /**************************************************************************/
1560 | /*!
1561 | @brief Reads n bytes of data from the PN532 via SPI or I2C.
1562 |
1563 | @param buff Pointer to the buffer where data will be written
1564 | @param n Number of bytes to be read
1565 | */
1566 | /**************************************************************************/
1567 | void Adafruit_PN532::readdata(uint8_t* buff, uint8_t n) {
1568 | if (_usingSPI) {
1569 | // SPI write.
1570 | #ifdef SPI_HAS_TRANSACTION
1571 | if (_hardwareSPI) SPI.beginTransaction(PN532_SPI_SETTING);
1572 | #endif
1573 | digitalWrite(_ss, LOW);
1574 | delay(2);
1575 | spi_write(PN532_SPI_DATAREAD);
1576 |
1577 | #ifdef PN532DEBUG
1578 | PN532DEBUGPRINT.print(F("Reading: "));
1579 | #endif
1580 | for (uint8_t i=0; i