Pinconfig für Endbadge.
[hackover2013-badge-firmware.git] / drivers / rf / pn532 / helpers / pn532_mifare_ultralight.c
1 /**************************************************************************/
2 /*!
3 @file pn532_mifare_ultralight.c
4 */
5 /**************************************************************************/
6
7 /* MIFARE ULTRALIGHT DESCRIPTION
8 =============================
9
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.
13
14 MF0ICU1 Mifare Ultralight Functional Specification:
15 http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
16
17
18 Mifare Ultralight cards have a 7-byte UID
19
20 EEPROM MEMORY
21 =============
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).
26
27 EEPROM memory is organised into 16 pages of four bytes eachs, in
28 the following order
29
30 Page Description
31 ---- ------------
32 0 Serial Number (4 bytes)
33 1 Serial Number (4 bytes)
34 2 Byte 0: Serial Number
35 Byte 1: Internal Memory
36 Byte 2..3: lock bytes
37 3 One-time programmable memory (4 bytes)
38 4..15 User memory (4 bytes)
39
40 Lock Bytes (Page 2)
41 -------------------
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.
46
47 For information on the lock byte mechanism, refer to section 8.5.2 of
48 the datasheet (referenced above).
49
50 OTP Bytes (Page 3)
51 ------------------
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
55 back to 0.
56
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.
61
62 After production, the bytes have the following default values:
63
64 Page Byte Values
65 ---- ----------------------
66 0 1 2 3
67 4 0xFF 0xFF 0xFF 0xFF
68 5..15 0x00 0x00 0x00 0x00
69
70 ACCESSING DATA BLOCKS
71 =====================
72
73 Before you can access the cards, you must following two steps:
74
75 1.) 'Connect' to a Mifare Ultralight card and retrieve the 7 byte
76 UID of the card.
77
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.
81
82 */
83
84 #include <string.h>
85
86 #include "../pn532.h"
87 #include "../pn532_bus.h"
88 #include "pn532_mifare_ultralight.h"
89
90 #include "core/systick/systick.h"
91
92 /**************************************************************************/
93 /*!
94 Tries to detect MIFARE targets in passive mode.
95
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
99
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
103
104 byte Description
105 ------------- ------------------------------------------
106 b0..6 Frame header and preamble
107 b7 Tags Found
108 b8 Tag Number (only one used in this example)
109 b9..10 SENS_RES
110 b11 SEL_RES
111 b12 NFCID Length
112 b13..NFCIDLen NFCID
113
114 SENS_RES SEL_RES Manufacturer/Card Type NFCID Len
115 -------- ------- ----------------------- ---------
116 00 44 00 NXP Mifare Ultralight 7 bytes
117
118 @note Possible error messages are:
119
120 - PN532_ERROR_WRONGCARDTYPE
121 */
122 /**************************************************************************/
123 pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen)
124 {
125 byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
126 pn532_error_t error;
127 size_t szLen;
128
129 #ifdef PN532_DEBUGMODE
130 PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
131 #endif
132
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));
138 if (error)
139 return error;
140
141 /* Wait until we get a valid response or a timeout */
142 do
143 {
144 systickDelay(25);
145 error = pn532Read(abtResponse, &szLen);
146 } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
147 if (error)
148 return error;
149
150 /* Check SENS_RES to make sure this is a Mifare Ultralight card */
151 /* Mifare Ultralight = 00 44 */
152 if (abtResponse[10] == 0x44)
153 {
154 /* Card appears to be Mifare Ultralight */
155 *szCUIDLen = abtResponse[12];
156 uint8_t i;
157 for (i=0; i < *szCUIDLen; i++)
158 {
159 pbtCUID[i] = abtResponse[13+i];
160 }
161 #ifdef PN532_DEBUGMODE
162 PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
163 PN532_DEBUG(" ATQA: ");
164 pn532PrintHex(abtResponse+9, 2);
165 PN532_DEBUG(" SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
166 PN532_DEBUG(" UID: ");
167 pn532PrintHex(pbtCUID, *szCUIDLen);
168 #endif
169 }
170 else
171 {
172 /* Card is ISO14443A but doesn't appear to be Mifare Ultralight */
173 /* Mifare Classic = 0x0002, 0x0004, 0x0008 */
174 /* Mifare DESFire = 0x0344 */
175 /* Innovision Jewel = 0x0C00 */
176 #ifdef PN532_DEBUGMODE
177 PN532_DEBUG("Wrong Card Type (Expected ATQA 00 44) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
178 PN532_DEBUG(" ATQA : ");
179 pn532PrintHex(abtResponse+9, 2);
180 PN532_DEBUG(" SAK : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
181 PN532_DEBUG(" UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
182 PN532_DEBUG(" UID : ");
183 size_t pos;
184 for (pos=0; pos < abtResponse[12]; pos++)
185 {
186 printf("%02x ", abtResponse[13 + pos]);
187 }
188 printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
189 #endif
190 return PN532_ERROR_WRONGCARDTYPE;
191 }
192
193 return PN532_ERROR_NONE;
194 }
195
196 /**************************************************************************/
197 /*!
198 Tries to read an entire 4-byte page at the specified address.
199
200 @param page The page number (0..63 in most cases)
201 @param pbtBuffer Pointer to the byte array that will hold the
202 retrieved data (if any)
203
204 @note Possible error messages are:
205
206 - PN532_ERROR_ADDRESSOUTOFRANGE
207 - PN532_ERROR_BLOCKREADFAILED
208 */
209 /**************************************************************************/
210 pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer)
211 {
212 pn532_error_t error;
213 byte_t abtCommand[4];
214 byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
215 size_t szLen;
216
217 if (page >= 64)
218 {
219 return PN532_ERROR_ADDRESSOUTOFRANGE;
220 }
221
222 #ifdef PN532_DEBUGMODE
223 PN532_DEBUG("Reading page %03d%s", page, CFG_PRINTF_NEWLINE);
224 #endif
225
226 /* Prepare the command */
227 abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
228 abtCommand[1] = 1; /* Card number */
229 abtCommand[2] = PN532_MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
230 abtCommand[3] = page; /* Page Number (0..63 in most cases) */
231
232 /* Send the commands */
233 error = pn532Write(abtCommand, sizeof(abtCommand));
234 if (error)
235 {
236 /* Bus error, etc. */
237 #ifdef PN532_DEBUGMODE
238 PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
239 #endif
240 return error;
241 }
242
243 /* Read the response */
244 memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
245 do
246 {
247 systickDelay(50);
248 error = pn532Read(abtResponse, &szLen);
249 }
250 while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
251 if (error)
252 {
253 #ifdef PN532_DEBUGMODE
254 PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
255 #endif
256 return error;
257 }
258
259 /* Make sure we have a valid response (should be 26 bytes long) */
260 if (szLen == 26)
261 {
262 /* Copy the 4 data bytes to the output buffer */
263 /* Block content starts at byte 9 of a valid response */
264 /* Note that the command actually reads 16 byte or 4 */
265 /* pages at a time ... we simply discard the last 12 */
266 /* bytes */
267 memcpy (pbtBuffer, abtResponse+8, 4);
268 }
269 else
270 {
271 #ifdef PN532_DEBUGMODE
272 PN532_DEBUG("Unexpected response reading block %d. Bad key?%s", page, CFG_PRINTF_NEWLINE);
273 #endif
274 return PN532_ERROR_BLOCKREADFAILED;
275 }
276
277 /* Display data for debug if requested */
278 #ifdef PN532_DEBUGMODE
279 PN532_DEBUG("Page %02d: ", page, CFG_PRINTF_NEWLINE);
280 pn532PrintHexVerbose(pbtBuffer, 4);
281 #endif
282
283 // Return OK signal
284 return PN532_ERROR_NONE;
285 }
286
This page took 0.055168 seconds and 5 git commands to generate.