1 /**************************************************************************/
3 @file pn532_mifare_ultralight.c
5 /**************************************************************************/
7 /* MIFARE ULTRALIGHT DESCRIPTION
8 =============================
10 MIFARE Ultralight cards typically contain 512 bits (64 bytes) of
11 memory, including 4 bytes (32-bits) of OTP (One Time Programmable)
12 memory where the individual bits can be written but not erased.
14 MF0ICU1 Mifare Ultralight Functional Specification:
15 http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
18 Mifare Ultralight cards have a 7-byte UID
22 Mifare Ultralight cards have 512 bits (64 bytes) of EEPROM memory,
23 including 4 byte (32 bits) of OTP memory. Unlike Mifare Classic cards,
24 there is no authentication on a per block level, although the blocks
25 can be set to "read-only" mode using Lock Bytes (described below).
27 EEPROM memory is organised into 16 pages of four bytes eachs, in
32 0 Serial Number (4 bytes)
33 1 Serial Number (4 bytes)
34 2 Byte 0: Serial Number
35 Byte 1: Internal Memory
37 3 One-time programmable memory (4 bytes)
38 4..15 User memory (4 bytes)
42 Bytes 2 and 3 of page 2 are referred to as "Lock Bytes". Each
43 page from 0x03 and higher can individually locked by setting the
44 corresponding locking bit to "1" to prevent further write access,
45 effectively making the memory read only.
47 For information on the lock byte mechanism, refer to section 8.5.2 of
48 the datasheet (referenced above).
52 Page 3 is the OTP memory, and by default all bits on this page are
53 set to 0. These bits can be bitwise modified using the Mifare WRITE
54 command, and individual bits can be set to 1, but can not be changed
57 Data Pages (Pages 4..15)
58 ------------------------
59 Pages 4 to 15 are can be freely read from and written to,
60 provided there is no conflict with the Lock Bytes described above.
62 After production, the bytes have the following default values:
65 ---- ----------------------
68 5..15 0x00 0x00 0x00 0x00
73 Before you can access the cards, you must following two steps:
75 1.) 'Connect' to a Mifare Ultralight card and retrieve the 7 byte
78 2.) Memory can be read and written directly once a passive mode
79 connection has been made. No authentication is required for
80 Mifare Ultralight cards.
87 #include "../pn532_bus.h"
88 #include "pn532_mifare_ultralight.h"
90 #include "core/systick/systick.h"
92 /**************************************************************************/
94 Tries to detect MIFARE targets in passive mode.
96 @param pbtCUID Pointer to the byte array where the card's 7 byte
97 UID will be stored once a card is detected
98 @param pszUIDLen Pointer to the size of the card UID in bytes
100 Response for a valid ISO14443A 106KBPS (Mifare Ultralight, etc.)
101 should be in the following format. See UM0701-02 section
102 7.3.5 for more information
105 ------------- ------------------------------------------
106 b0..6 Frame header and preamble
108 b8 Tag Number (only one used in this example)
114 SENS_RES SEL_RES Manufacturer/Card Type NFCID Len
115 -------- ------- ----------------------- ---------
116 00 44 00 NXP Mifare Ultralight 7 bytes
118 @note Possible error messages are:
120 - PN532_ERROR_WRONGCARDTYPE
122 /**************************************************************************/
123 pn532_error_t
pn532_mifareultralight_WaitForPassiveTarget (byte_t
* pbtCUID
, size_t * szCUIDLen
)
125 byte_t abtResponse
[PN532_RESPONSELEN_INLISTPASSIVETARGET
];
129 #ifdef PN532_DEBUGMODE
130 PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE
);
133 /* Try to initialise a single ISO14443A tag at 106KBPS */
134 /* Note: To wait for a card with a known UID, append the four byte */
135 /* UID to the end of the command. */
136 byte_t abtCommand
[] = { PN532_COMMAND_INLISTPASSIVETARGET
, 0x01, PN532_MODULATION_ISO14443A_106KBPS
};
137 error
= pn532Write(abtCommand
, sizeof(abtCommand
));
141 /* Wait until we get a valid response or a timeout */
145 error
= pn532Read(abtResponse
, &szLen
);
146 } while (error
== PN532_ERROR_RESPONSEBUFFEREMPTY
);
150 /* Check SENS_RES to make sure this is a Mifare Ultralight card */
151 /* Mifare Ultralight = 00 44 */
152 if (abtResponse
[10] == 0x44)
154 /* Card appears to be Mifare Ultralight */
155 *szCUIDLen
= abtResponse
[12];
156 for (uint8_t i
=0; i
< *szCUIDLen
; i
++)
158 pbtCUID
[i
] = abtResponse
[13+i
];
160 #ifdef PN532_DEBUGMODE
161 PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE
);
162 PN532_DEBUG(" ATQA: ");
163 pn532PrintHex(abtResponse
+9, 2);
164 PN532_DEBUG(" SAK: %02x%s", abtResponse
[11], CFG_PRINTF_NEWLINE
);
165 PN532_DEBUG(" UID: ");
166 pn532PrintHex(pbtCUID
, *szCUIDLen
);
171 /* Card is ISO14443A but doesn't appear to be Mifare Ultralight */
172 /* Mifare Classic = 0x0002, 0x0004, 0x0008 */
173 /* Mifare DESFire = 0x0344 */
174 /* Innovision Jewel = 0x0C00 */
175 #ifdef PN532_DEBUGMODE
176 PN532_DEBUG("Wrong Card Type (Expected ATQA 00 44) %s%s", CFG_PRINTF_NEWLINE
, CFG_PRINTF_NEWLINE
);
177 PN532_DEBUG(" ATQA : ");
178 pn532PrintHex(abtResponse
+9, 2);
179 PN532_DEBUG(" SAK : %02x%s", abtResponse
[11], CFG_PRINTF_NEWLINE
);
180 PN532_DEBUG(" UID Length : %d%s", abtResponse
[12], CFG_PRINTF_NEWLINE
);
181 PN532_DEBUG(" UID : ");
183 for (pos
=0; pos
< abtResponse
[12]; pos
++)
185 printf("%02x ", abtResponse
[13 + pos
]);
187 printf("%s%s", CFG_PRINTF_NEWLINE
, CFG_PRINTF_NEWLINE
);
189 return PN532_ERROR_WRONGCARDTYPE
;
192 return PN532_ERROR_NONE
;
195 /**************************************************************************/
197 Tries to read an entire 4-byte page at the specified address.
199 @param page The page number (0..63 in most cases)
200 @param pbtBuffer Pointer to the byte array that will hold the
201 retrieved data (if any)
203 @note Possible error messages are:
205 - PN532_ERROR_ADDRESSOUTOFRANGE
206 - PN532_ERROR_BLOCKREADFAILED
208 /**************************************************************************/
209 pn532_error_t
pn532_mifareultralight_ReadPage (uint8_t page
, byte_t
* pbtBuffer
)
212 byte_t abtCommand
[4];
213 byte_t abtResponse
[PN532_RESPONSELEN_INDATAEXCHANGE
];
218 return PN532_ERROR_ADDRESSOUTOFRANGE
;
221 #ifdef PN532_DEBUGMODE
222 PN532_DEBUG("Reading page %03d%s", page
, CFG_PRINTF_NEWLINE
);
225 /* Prepare the command */
226 abtCommand
[0] = PN532_COMMAND_INDATAEXCHANGE
;
227 abtCommand
[1] = 1; /* Card number */
228 abtCommand
[2] = PN532_MIFARE_CMD_READ
; /* Mifare Read command = 0x30 */
229 abtCommand
[3] = page
; /* Page Number (0..63 in most cases) */
231 /* Send the commands */
232 error
= pn532Write(abtCommand
, sizeof(abtCommand
));
235 /* Bus error, etc. */
236 #ifdef PN532_DEBUGMODE
237 PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE
);
242 /* Read the response */
243 memset(abtResponse
, 0, PN532_RESPONSELEN_INDATAEXCHANGE
);
247 error
= pn532Read(abtResponse
, &szLen
);
249 while (error
== PN532_ERROR_RESPONSEBUFFEREMPTY
);
252 #ifdef PN532_DEBUGMODE
253 PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE
);
258 /* Make sure we have a valid response (should be 26 bytes long) */
261 /* Copy the 4 data bytes to the output buffer */
262 /* Block content starts at byte 8 of a valid response */
263 /* Note that the command actually reads 16 byte or 4 */
264 /* pages at a time ... we simply discard the last 12 */
266 memcpy (pbtBuffer
, abtResponse
+8, 4);
270 #ifdef PN532_DEBUGMODE
271 PN532_DEBUG("Unexpected response reading block %d. Bad key?%s", page
, CFG_PRINTF_NEWLINE
);
273 return PN532_ERROR_BLOCKREADFAILED
;
276 /* Display data for debug if requested */
277 #ifdef PN532_DEBUGMODE
278 PN532_DEBUG("Page %02d: ", page
, CFG_PRINTF_NEWLINE
);
279 pn532PrintHexVerbose(pbtBuffer
, 4);
283 return PN532_ERROR_NONE
;
290 // bool bFailure = false;
291 // uint32_t uiReadedPages = 0;
293 // printf ("Reading %d pages |", uiBlocks + 1);
295 // for (page = 0; page <= uiBlocks; page += 4) {
296 // // Try to read out the data block
297 // if (nfc_initiator_mifare_cmd (pnd, MC_READ, page, &mp)) {
298 // memcpy (mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
304 // print_success_or_failure (bFailure, &uiReadedPages);
305 // print_success_or_failure (bFailure, &uiReadedPages);
306 // print_success_or_failure (bFailure, &uiReadedPages);
307 // print_success_or_failure (bFailure, &uiReadedPages);
310 // printf ("Done, %d of %d pages readed.\n", uiReadedPages, uiBlocks + 1);
313 // return (!bFailure);