Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added API for authenticating, reading and writing memory blocks. Thes…

…e APIs

work with MIFARE cards.
  • Loading branch information...
commit d3796959b54278cca27aedfde7d9373cfbca1e8d 1 parent b239432
authored August 10, 2011
699  PN532.cpp 100644 → 100755
... ...
@@ -1,279 +1,420 @@
1  
-#include <WProgram.h>
2  
-#include "PN532.h"
3  
-
4  
-//#define PN532DEBUG 1
5  
-
6  
-byte pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
7  
-byte pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
8  
-
9  
-#define PN532_PACKBUFFSIZ 64
10  
-byte pn532_packetbuffer[PN532_PACKBUFFSIZ];
11  
- 
12  
-PN532::PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss) {
13  
-  _clk = clk;
14  
-  _miso = miso;
15  
-  _mosi = mosi;
16  
-  _ss = ss;
17  
-
18  
-  pinMode(_ss, OUTPUT);
19  
-  pinMode(_clk, OUTPUT);
20  
-  pinMode(_mosi, OUTPUT);
21  
-  pinMode(_miso, INPUT);
22  
-}
23  
-
24  
-void PN532::begin() {
25  
-  digitalWrite(_ss, LOW);
26  
-  
27  
-  delay(1000);
28  
-
29  
-  // not exactly sure why but we have to send a dummy command to get synced up
30  
-  pn532_packetbuffer[0] = PN532_FIRMWAREVERSION;
31  
-  sendCommandCheckAck(pn532_packetbuffer, 1);
32  
-
33  
-  // ignore response!
34  
-}
35  
-
36  
-uint32_t PN532::getFirmwareVersion(void) {
37  
-  uint32_t response;
38  
-
39  
-  pn532_packetbuffer[0] = PN532_FIRMWAREVERSION;
40  
-  
41  
-  if (! sendCommandCheckAck(pn532_packetbuffer, 1))
42  
-    return 0;
43  
-  
44  
-  // read data packet
45  
-  readspidata(pn532_packetbuffer, 12);
46  
-  // check some basic stuff
47  
-  if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6)) {
48  
-    return 0;
49  
-  }
50  
-  
51  
-  response = pn532_packetbuffer[6];
52  
-  response <<= 8;
53  
-  response |= pn532_packetbuffer[7];
54  
-  response <<= 8;
55  
-  response |= pn532_packetbuffer[8];
56  
-  response <<= 8;
57  
-  response |= pn532_packetbuffer[9];
58  
-
59  
-  return response;
60  
-}
61  
-
62  
-
63  
-// default timeout of one second
64  
-boolean PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout) {
65  
-  uint16_t timer = 0;
66  
-  
67  
-  // write the command
68  
-  spiwritecommand(cmd, cmdlen);
69  
-  
70  
-  // Wait for chip to say its ready!
71  
-  while (readspistatus() != PN532_SPI_READY) {
72  
-    if (timeout != 0) {
73  
-      timer+=10;
74  
-      if (timer > timeout)  
75  
-        return false;
76  
-    }
77  
-    delay(10);
78  
-  }
79  
-  
80  
-  // read acknowledgement
81  
-  if (!spi_readack()) {
82  
-    return false;
83  
-  }
84  
-  
85  
-  timer = 0;
86  
-  // Wait for chip to say its ready!
87  
-  while (readspistatus() != PN532_SPI_READY) {
88  
-    if (timeout != 0) {
89  
-      timer+=10;
90  
-      if (timer > timeout)  
91  
-        return false;
92  
-    }
93  
-    delay(10);
94  
-  }
95  
-  
96  
-  return true; // ack'd command
97  
-}
98  
-
99  
-boolean PN532::SAMConfig(void) {
100  
-  pn532_packetbuffer[0] = PN532_SAMCONFIGURATION;
101  
-  pn532_packetbuffer[1] = 0x01; // normal mode;
102  
-  pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
103  
-  pn532_packetbuffer[3] = 0x01; // use IRQ pin!
104  
-  
105  
-  if (! sendCommandCheckAck(pn532_packetbuffer, 4))
106  
-     return false;
107  
-
108  
-  // read data packet
109  
-  readspidata(pn532_packetbuffer, 8);
110  
-  
111  
-  return  (pn532_packetbuffer[5] == 0x15);
112  
-}
113  
-
114  
-
115  
-uint32_t PN532::readPassiveTargetID(uint8_t cardbaudrate) {
116  
-  uint32_t cid;
117  
-  
118  
-  pn532_packetbuffer[0] = PN532_INLISTPASSIVETARGET;
119  
-  pn532_packetbuffer[1] = 1;  // max 1 cards at once (we can set this to 2 later)
120  
-  pn532_packetbuffer[2] = cardbaudrate;
121  
-  
122  
-  if (! sendCommandCheckAck(pn532_packetbuffer, 3))
123  
-    return 0x0;  // no cards read
124  
-  
125  
-  // read data packet
126  
-  readspidata(pn532_packetbuffer, 20);
127  
-  // check some basic stuff
128  
-  
129  
-  Serial.print("Found "); Serial.print(pn532_packetbuffer[7], DEC); Serial.println(" tags");
130  
-  if (pn532_packetbuffer[7] != 1) 
131  
-    return 0;
132  
-    
133  
-  uint16_t sens_res = pn532_packetbuffer[9];
134  
-  sens_res <<= 8;
135  
-  sens_res |= pn532_packetbuffer[10];
136  
-  Serial.print("Sens Response: 0x");  Serial.println(sens_res, HEX); 
137  
-  Serial.print("Sel Response: 0x");  Serial.println(pn532_packetbuffer[11], HEX); 
138  
-  cid = 0;
139  
-  for (uint8_t i=0; i< pn532_packetbuffer[12]; i++) {
140  
-    cid <<= 8;
141  
-    cid |= pn532_packetbuffer[13+i];
142  
-    Serial.print(" 0x"); Serial.print(pn532_packetbuffer[13+i], HEX); 
143  
-  }
144  
-  Serial.println();
145  
-
146  
-  return cid;
147  
-}
148  
-
149  
-
150  
-/************** high level SPI */
151  
-
152  
-
153  
-boolean PN532::spi_readack() {
154  
-  uint8_t ackbuff[6];
155  
-  
156  
-  readspidata(ackbuff, 6);
157  
-  
158  
-  return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
159  
-}
160  
-
161  
-/************** mid level SPI */
162  
-
163  
-uint8_t PN532::readspistatus(void) {
164  
-  digitalWrite(_ss, LOW);
165  
-  delay(2); 
166  
-  spiwrite(PN532_SPI_STATREAD);
167  
-  // read byte
168  
-  uint8_t x = spiread();
169  
-  
170  
-  digitalWrite(_ss, HIGH);
171  
-  return x;
172  
-}
173  
-
174  
-void PN532::readspidata(uint8_t* buff, uint8_t n) {
175  
-  digitalWrite(_ss, LOW);
176  
-  delay(2); 
177  
-  spiwrite(PN532_SPI_DATAREAD);
178  
-
179  
-#ifdef PN532DEBUG
180  
-  Serial.print("Reading: ");
181  
-#endif
182  
-  for (uint8_t i=0; i<n; i++) {
183  
-    delay(1);
184  
-    buff[i] = spiread();
185  
-#ifdef PN532DEBUG
186  
-    Serial.print(" 0x");
187  
-    Serial.print(buff[i], HEX);
188  
-#endif
189  
-  }
190  
-
191  
-#ifdef PN532DEBUG
192  
-  Serial.println();
193  
-#endif
194  
-
195  
-  digitalWrite(_ss, HIGH);
196  
-}
197  
-
198  
-void PN532::spiwritecommand(uint8_t* cmd, uint8_t cmdlen) {
199  
-  uint8_t checksum;
200  
-
201  
-  cmdlen++;
202  
-  
203  
-#ifdef PN532DEBUG
204  
-  Serial.print("\nSending: ");
205  
-#endif
206  
-
207  
-  digitalWrite(_ss, LOW);
208  
-  delay(2);     // or whatever the delay is for waking up the board
209  
-  spiwrite(PN532_SPI_DATAWRITE);
210  
-
211  
-  checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2;
212  
-  spiwrite(PN532_PREAMBLE);
213  
-  spiwrite(PN532_PREAMBLE);
214  
-  spiwrite(PN532_STARTCODE2);
215  
-
216  
-  spiwrite(cmdlen);
217  
-  spiwrite(~cmdlen + 1);
218  
- 
219  
-  spiwrite(PN532_HOSTTOPN532);
220  
-  checksum += PN532_HOSTTOPN532;
221  
-
222  
-#ifdef PN532DEBUG
223  
-  Serial.print(" 0x"); Serial.print(PN532_PREAMBLE, HEX);
224  
-  Serial.print(" 0x"); Serial.print(PN532_PREAMBLE, HEX);
225  
-  Serial.print(" 0x"); Serial.print(PN532_STARTCODE2, HEX);
226  
-  Serial.print(" 0x"); Serial.print(cmdlen, HEX);
227  
-  Serial.print(" 0x"); Serial.print(~cmdlen + 1, HEX);
228  
-  Serial.print(" 0x"); Serial.print(PN532_HOSTTOPN532, HEX);
229  
-#endif
230  
-
231  
-  for (uint8_t i=0; i<cmdlen-1; i++) {
232  
-   spiwrite(cmd[i]);
233  
-   checksum += cmd[i];
234  
-#ifdef PN532DEBUG
235  
-   Serial.print(" 0x"); Serial.print(cmd[i], HEX);
236  
-#endif
237  
-  }
238  
-  
239  
-  spiwrite(~checksum);
240  
-  spiwrite(PN532_POSTAMBLE);
241  
-  digitalWrite(_ss, HIGH);
242  
-
243  
-#ifdef PN532DEBUG
244  
-  Serial.print(" 0x"); Serial.print(~checksum, HEX);
245  
-  Serial.print(" 0x"); Serial.print(PN532_POSTAMBLE, HEX);
246  
-  Serial.println();
247  
-#endif
248  
-} 
249  
-/************** low level SPI */
250  
-
251  
-void PN532::spiwrite(uint8_t c) {
252  
-  int8_t i;
253  
-  digitalWrite(_clk, HIGH);
254  
-
255  
-  for (i=0; i<8; i++) {
256  
-    digitalWrite(_clk, LOW);
257  
-    if (c & _BV(i)) {
258  
-      digitalWrite(_mosi, HIGH);
259  
-    } else {
260  
-      digitalWrite(_mosi, LOW);
261  
-    }    
262  
-    digitalWrite(_clk, HIGH);
263  
-  }
264  
-}
265  
-
266  
-uint8_t PN532::spiread(void) {
267  
-  int8_t i, x;
268  
-  x = 0;
269  
-  digitalWrite(_clk, HIGH);
270  
-
271  
-  for (i=0; i<8; i++) {
272  
-    if (digitalRead(_miso)) {
273  
-      x |= _BV(i);
274  
-    }
275  
-    digitalWrite(_clk, LOW);
276  
-    digitalWrite(_clk, HIGH);
277  
-  }
278  
-  return x;
279  
-}
  1
+// PN532 library by adafruit/ladyada
  2
+// MIT license
  3
+
  4
+// authenticateBlock, readMemoryBlock, writeMemoryBlock contributed
  5
+// by Seeed Technology Inc (www.seeedstudio.com)
  6
+
  7
+#include <WProgram.h>
  8
+#include "PN532.h"
  9
+
  10
+//#define PN532DEBUG 1
  11
+
  12
+byte pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
  13
+byte pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
  14
+
  15
+#define PN532_PACKBUFFSIZ 64
  16
+byte pn532_packetbuffer[PN532_PACKBUFFSIZ];
  17
+
  18
+PN532::PN532(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss) {
  19
+    _clk = clk;
  20
+    _miso = miso;
  21
+    _mosi = mosi;
  22
+    _ss = ss;
  23
+
  24
+    pinMode(_ss, OUTPUT);
  25
+    pinMode(_clk, OUTPUT);
  26
+    pinMode(_mosi, OUTPUT);
  27
+    pinMode(_miso, INPUT);
  28
+}
  29
+
  30
+void PN532::begin() {
  31
+    digitalWrite(_ss, LOW);
  32
+
  33
+    delay(1000);
  34
+
  35
+    // not exactly sure why but we have to send a dummy command to get synced up
  36
+    pn532_packetbuffer[0] = PN532_FIRMWAREVERSION;
  37
+    sendCommandCheckAck(pn532_packetbuffer, 1);
  38
+
  39
+    // ignore response!
  40
+}
  41
+
  42
+uint32_t PN532::getFirmwareVersion(void) {
  43
+    uint32_t response;
  44
+
  45
+    pn532_packetbuffer[0] = PN532_FIRMWAREVERSION;
  46
+
  47
+    if (! sendCommandCheckAck(pn532_packetbuffer, 1))
  48
+        return 0;
  49
+
  50
+    // read data packet
  51
+    readspidata(pn532_packetbuffer, 12);
  52
+    // check some basic stuff
  53
+    if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6)) {
  54
+        return 0;
  55
+    }
  56
+
  57
+    response = pn532_packetbuffer[6];
  58
+    response <<= 8;
  59
+    response |= pn532_packetbuffer[7];
  60
+    response <<= 8;
  61
+    response |= pn532_packetbuffer[8];
  62
+    response <<= 8;
  63
+    response |= pn532_packetbuffer[9];
  64
+
  65
+    return response;
  66
+}
  67
+
  68
+
  69
+// default timeout of one second
  70
+boolean PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout) {
  71
+    uint16_t timer = 0;
  72
+
  73
+    // write the command
  74
+    spiwritecommand(cmd, cmdlen);
  75
+
  76
+    // Wait for chip to say its ready!
  77
+    while (readspistatus() != PN532_SPI_READY) {
  78
+        if (timeout != 0) {
  79
+            timer+=10;
  80
+            if (timer > timeout)
  81
+                return false;
  82
+        }
  83
+        delay(10);
  84
+    }
  85
+
  86
+    // read acknowledgement
  87
+    if (!spi_readack()) {
  88
+        return false;
  89
+    }
  90
+
  91
+    timer = 0;
  92
+    // Wait for chip to say its ready!
  93
+    while (readspistatus() != PN532_SPI_READY) {
  94
+        if (timeout != 0) {
  95
+            timer+=10;
  96
+            if (timer > timeout)
  97
+                return false;
  98
+        }
  99
+        delay(10);
  100
+    }
  101
+
  102
+    return true; // ack'd command
  103
+}
  104
+
  105
+boolean PN532::SAMConfig(void) {
  106
+    pn532_packetbuffer[0] = PN532_SAMCONFIGURATION;
  107
+    pn532_packetbuffer[1] = 0x01; // normal mode;
  108
+    pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
  109
+    pn532_packetbuffer[3] = 0x01; // use IRQ pin!
  110
+
  111
+    if (! sendCommandCheckAck(pn532_packetbuffer, 4))
  112
+        return false;
  113
+
  114
+    // read data packet
  115
+    readspidata(pn532_packetbuffer, 8);
  116
+
  117
+    return  (pn532_packetbuffer[5] == 0x15);
  118
+}
  119
+
  120
+uint32_t PN532::authenticateBlock(uint8_t cardnumber /*1 or 2*/,uint32_t cid /*Card NUID*/, uint8_t blockaddress /*0 to 63*/,uint8_t authtype/*Either KEY_A or KEY_B */, uint8_t * keys) {
  121
+    pn532_packetbuffer[0] = PN532_INDATAEXCHANGE;
  122
+    pn532_packetbuffer[1] = cardnumber;  // either card 1 or 2 (tested for card 1)
  123
+    if(authtype == KEY_A)
  124
+    {
  125
+        pn532_packetbuffer[2] = PN532_AUTH_WITH_KEYA;
  126
+    }
  127
+    else
  128
+    {
  129
+        pn532_packetbuffer[2] = PN532_AUTH_WITH_KEYB;
  130
+    }
  131
+    pn532_packetbuffer[3] = blockaddress; //This address can be 0-63 for MIFARE 1K card
  132
+
  133
+    pn532_packetbuffer[4] = keys[0];
  134
+    pn532_packetbuffer[5] = keys[1];
  135
+    pn532_packetbuffer[6] = keys[2];
  136
+    pn532_packetbuffer[7] = keys[3];
  137
+    pn532_packetbuffer[8] = keys[4];
  138
+    pn532_packetbuffer[9] = keys[5];
  139
+
  140
+    pn532_packetbuffer[10] = ((cid >> 24) & 0xFF);
  141
+    pn532_packetbuffer[11] = ((cid >> 16) & 0xFF);
  142
+    pn532_packetbuffer[12] = ((cid >> 8) & 0xFF);
  143
+    pn532_packetbuffer[13] = ((cid >> 0) & 0xFF);
  144
+
  145
+    if (! sendCommandCheckAck(pn532_packetbuffer, 14))
  146
+        return false;
  147
+
  148
+    // read data packet
  149
+    readspidata(pn532_packetbuffer, 2+6);
  150
+
  151
+#ifdef PN532DEBUG
  152
+    for(int iter=0;iter<14;iter++)
  153
+    {
  154
+        Serial.print(pn532_packetbuffer[iter], HEX);
  155
+        Serial.print(" ");
  156
+    }
  157
+    Serial.println();
  158
+    // check some basic stuff
  159
+
  160
+    Serial.println("AUTH");
  161
+    for(uint8_t i=0;i<2+6;i++)
  162
+    {
  163
+        Serial.print(pn532_packetbuffer[i], HEX); Serial.println(" ");
  164
+    }
  165
+#endif
  166
+
  167
+    if((pn532_packetbuffer[6] == 0x41) && (pn532_packetbuffer[7] == 0x00))
  168
+    {
  169
+  	return true;
  170
+    }
  171
+    else
  172
+    {
  173
+  	return false;
  174
+    }
  175
+
  176
+}
  177
+
  178
+uint32_t PN532::readMemoryBlock(uint8_t cardnumber /*1 or 2*/,uint8_t blockaddress /*0 to 63*/, uint8_t * block) {
  179
+    pn532_packetbuffer[0] = PN532_INDATAEXCHANGE;
  180
+    pn532_packetbuffer[1] = cardnumber;  // either card 1 or 2 (tested for card 1)
  181
+    pn532_packetbuffer[2] = PN532_MIFARE_READ;
  182
+    pn532_packetbuffer[3] = blockaddress; //This address can be 0-63 for MIFARE 1K card
  183
+
  184
+    if (! sendCommandCheckAck(pn532_packetbuffer, 4))
  185
+        return false;
  186
+
  187
+    // read data packet
  188
+    readspidata(pn532_packetbuffer, 18+6);
  189
+    // check some basic stuff
  190
+#ifdef PN532DEBUG
  191
+    Serial.println("READ");
  192
+#endif
  193
+    for(uint8_t i=8;i<18+6;i++)
  194
+    {
  195
+        block[i-8] = pn532_packetbuffer[i];
  196
+#ifdef PN532DEBUG
  197
+        Serial.print(pn532_packetbuffer[i], HEX); Serial.print(" ");
  198
+#endif
  199
+    }
  200
+    if((pn532_packetbuffer[6] == 0x41) && (pn532_packetbuffer[7] == 0x00))
  201
+    {
  202
+  	return true; //read successful
  203
+    }
  204
+    else
  205
+    {
  206
+  	return false;
  207
+    }
  208
+
  209
+}
  210
+
  211
+//Do not write to Sector Trailer Block unless you know what you are doing.
  212
+uint32_t PN532::writeMemoryBlock(uint8_t cardnumber /*1 or 2*/,uint8_t blockaddress /*0 to 63*/, uint8_t * block) {
  213
+    pn532_packetbuffer[0] = PN532_INDATAEXCHANGE;
  214
+    pn532_packetbuffer[1] = cardnumber;  // either card 1 or 2 (tested for card 1)
  215
+    pn532_packetbuffer[2] = PN532_MIFARE_WRITE;
  216
+    pn532_packetbuffer[3] = blockaddress;
  217
+
  218
+    for(uint8_t byte=0; byte <16; byte++)
  219
+    {
  220
+        pn532_packetbuffer[4+byte] = block[byte];
  221
+    }
  222
+
  223
+    if (! sendCommandCheckAck(pn532_packetbuffer, 20))
  224
+        return false;
  225
+    // read data packet
  226
+    readspidata(pn532_packetbuffer, 2+6);
  227
+
  228
+#ifdef PN532DEBUG
  229
+    // check some basic stuff
  230
+    Serial.println("WRITE");
  231
+    for(uint8_t i=0;i<2+6;i++)
  232
+    {
  233
+        Serial.print(pn532_packetbuffer[i], HEX); Serial.println(" ");
  234
+    }
  235
+#endif
  236
+
  237
+    if((pn532_packetbuffer[6] == 0x41) && (pn532_packetbuffer[7] == 0x00))
  238
+    {
  239
+  	return true; //write successful
  240
+    }
  241
+    else
  242
+    {
  243
+  	return false;
  244
+    }
  245
+}
  246
+
  247
+uint32_t PN532::readPassiveTargetID(uint8_t cardbaudrate) {
  248
+    uint32_t cid;
  249
+
  250
+    pn532_packetbuffer[0] = PN532_INLISTPASSIVETARGET;
  251
+    pn532_packetbuffer[1] = 1;  // max 1 cards at once (we can set this to 2 later)
  252
+    pn532_packetbuffer[2] = cardbaudrate;
  253
+
  254
+    if (! sendCommandCheckAck(pn532_packetbuffer, 3))
  255
+        return 0x0;  // no cards read
  256
+
  257
+    // read data packet
  258
+    readspidata(pn532_packetbuffer, 20);
  259
+    // check some basic stuff
  260
+
  261
+    Serial.print("Found "); Serial.print(pn532_packetbuffer[7], DEC); Serial.println(" tags");
  262
+    if (pn532_packetbuffer[7] != 1)
  263
+        return 0;
  264
+    
  265
+    uint16_t sens_res = pn532_packetbuffer[9];
  266
+    sens_res <<= 8;
  267
+    sens_res |= pn532_packetbuffer[10];
  268
+    Serial.print("Sens Response: 0x");  Serial.println(sens_res, HEX);
  269
+    Serial.print("Sel Response: 0x");  Serial.println(pn532_packetbuffer[11], HEX);
  270
+    cid = 0;
  271
+    for (uint8_t i=0; i< pn532_packetbuffer[12]; i++) {
  272
+        cid <<= 8;
  273
+        cid |= pn532_packetbuffer[13+i];
  274
+        Serial.print(" 0x"); Serial.print(pn532_packetbuffer[13+i], HEX);
  275
+    }
  276
+
  277
+#ifdef PN532DEBUG
  278
+    Serial.println("TargetID");
  279
+    for(uint8_t i=0;i<20;i++)
  280
+    {
  281
+        Serial.print(pn532_packetbuffer[i], HEX); Serial.println(" ");
  282
+    }
  283
+#endif  
  284
+    return cid;
  285
+}
  286
+
  287
+
  288
+/************** high level SPI */
  289
+
  290
+
  291
+boolean PN532::spi_readack() {
  292
+    uint8_t ackbuff[6];
  293
+
  294
+    readspidata(ackbuff, 6);
  295
+
  296
+    return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
  297
+}
  298
+
  299
+/************** mid level SPI */
  300
+
  301
+uint8_t PN532::readspistatus(void) {
  302
+    digitalWrite(_ss, LOW);
  303
+    delay(2);
  304
+    spiwrite(PN532_SPI_STATREAD);
  305
+    // read byte
  306
+    uint8_t x = spiread();
  307
+
  308
+    
  309
+
  310
+    digitalWrite(_ss, HIGH);
  311
+    return x;
  312
+}
  313
+
  314
+void PN532::readspidata(uint8_t* buff, uint8_t n) {
  315
+    digitalWrite(_ss, LOW);
  316
+    delay(2);
  317
+    spiwrite(PN532_SPI_DATAREAD);
  318
+
  319
+#ifdef PN532DEBUG
  320
+    Serial.print("Reading: ");
  321
+#endif
  322
+    for (uint8_t i=0; i<n; i++) {
  323
+        delay(1);
  324
+        buff[i] = spiread();
  325
+#ifdef PN532DEBUG
  326
+        Serial.print(" 0x");
  327
+        Serial.print(buff[i], HEX);
  328
+#endif
  329
+    }
  330
+
  331
+#ifdef PN532DEBUG
  332
+    Serial.println();
  333
+#endif
  334
+
  335
+    digitalWrite(_ss, HIGH);
  336
+}
  337
+
  338
+void PN532::spiwritecommand(uint8_t* cmd, uint8_t cmdlen) {
  339
+    uint8_t checksum;
  340
+
  341
+    cmdlen++;
  342
+
  343
+#ifdef PN532DEBUG
  344
+    Serial.print("\nSending: ");
  345
+#endif
  346
+
  347
+    digitalWrite(_ss, LOW);
  348
+    delay(2);     // or whatever the delay is for waking up the board
  349
+    spiwrite(PN532_SPI_DATAWRITE);
  350
+
  351
+    checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2;
  352
+    spiwrite(PN532_PREAMBLE);
  353
+    spiwrite(PN532_PREAMBLE);
  354
+    spiwrite(PN532_STARTCODE2);
  355
+
  356
+    spiwrite(cmdlen);
  357
+    uint8_t cmdlen_1=~cmdlen + 1;
  358
+    spiwrite(cmdlen_1);
  359
+
  360
+    spiwrite(PN532_HOSTTOPN532);
  361
+    checksum += PN532_HOSTTOPN532;
  362
+
  363
+#ifdef PN532DEBUG
  364
+    Serial.print(" 0x"); Serial.print(PN532_PREAMBLE, HEX);
  365
+    Serial.print(" 0x"); Serial.print(PN532_PREAMBLE, HEX);
  366
+    Serial.print(" 0x"); Serial.print(PN532_STARTCODE2, HEX);
  367
+    Serial.print(" 0x"); Serial.print(cmdlen, HEX);
  368
+    Serial.print(" 0x"); Serial.print(cmdlen_1, HEX);
  369
+    Serial.print(" 0x"); Serial.print(PN532_HOSTTOPN532, HEX);
  370
+#endif
  371
+
  372
+    for (uint8_t i=0; i<cmdlen-1; i++) {
  373
+        spiwrite(cmd[i]);
  374
+        checksum += cmd[i];
  375
+#ifdef PN532DEBUG
  376
+        Serial.print(" 0x"); Serial.print(cmd[i], HEX);
  377
+#endif
  378
+    }
  379
+    uint8_t checksum_1=~checksum;
  380
+    spiwrite(checksum_1);
  381
+    spiwrite(PN532_POSTAMBLE);
  382
+    digitalWrite(_ss, HIGH);
  383
+
  384
+#ifdef PN532DEBUG
  385
+    Serial.print(" 0x"); Serial.print(checksum_1, HEX);
  386
+    Serial.print(" 0x"); Serial.print(PN532_POSTAMBLE, HEX);
  387
+    Serial.println();
  388
+#endif
  389
+} 
  390
+/************** low level SPI */
  391
+
  392
+void PN532::spiwrite(uint8_t c) {
  393
+    int8_t i;
  394
+    digitalWrite(_clk, HIGH);
  395
+
  396
+    for (i=0; i<8; i++) {
  397
+        digitalWrite(_clk, LOW);
  398
+        if (c & _BV(i)) {
  399
+            digitalWrite(_mosi, HIGH);
  400
+        } else {
  401
+            digitalWrite(_mosi, LOW);
  402
+        }
  403
+        digitalWrite(_clk, HIGH);
  404
+    }
  405
+}
  406
+
  407
+uint8_t PN532::spiread(void) {
  408
+    int8_t i, x;
  409
+    x = 0;
  410
+    digitalWrite(_clk, HIGH);
  411
+
  412
+    for (i=0; i<8; i++) {
  413
+        if (digitalRead(_miso)) {
  414
+            x |= _BV(i);
  415
+        }
  416
+        digitalWrite(_clk, LOW);
  417
+        digitalWrite(_clk, HIGH);
  418
+    }
  419
+    return x;
  420
+}
123  PN532.h 100644 → 100755
... ...
@@ -1,50 +1,73 @@
1  
-// PN532 library by adafruit/ladyada
2  
-// MIT license
3  
-
4  
-#include <WProgram.h>
5  
-
6  
-#define PN532_PREAMBLE 0x00
7  
-#define PN532_STARTCODE1 0x00
8  
-#define PN532_STARTCODE2 0xFF
9  
-#define PN532_POSTAMBLE 0x00
10  
-
11  
-#define PN532_HOSTTOPN532 0xD4
12  
-
13  
-#define PN532_FIRMWAREVERSION 0x02
14  
-#define PN532_GETGENERALSTATUS 0x04
15  
-#define PN532_SAMCONFIGURATION  0x14
16  
-#define PN532_INLISTPASSIVETARGET 0x4A
17  
-#define PN532_WAKEUP 0x55
18  
-
19  
-
20  
-#define  PN532_SPI_STATREAD 0x02
21  
-#define  PN532_SPI_DATAWRITE 0x01
22  
-#define  PN532_SPI_DATAREAD 0x03
23  
-#define  PN532_SPI_READY 0x01
24  
-
25  
-#define PN532_MIFARE_ISO14443A 0x0
26  
-
27  
-class PN532{
28  
- public:
29  
-  PN532(uint8_t cs, uint8_t clk, uint8_t mosi, uint8_t miso);
30  
-
31  
-  void begin(void);
32  
-
33  
-  boolean SAMConfig(void);
34  
-  uint32_t getFirmwareVersion(void);
35  
-  uint32_t readPassiveTargetID(uint8_t cardbaudrate);
36  
-
37  
-  boolean sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout = 1000);
38  
-
39  
-  //
40  
-
41  
- private:
42  
-  uint8_t _ss, _clk, _mosi, _miso;
43  
-
44  
-  boolean spi_readack();
45  
-  uint8_t readspistatus(void);
46  
-  void readspidata(uint8_t* buff, uint8_t n);
47  
-  void spiwritecommand(uint8_t* cmd, uint8_t cmdlen);
48  
-  void spiwrite(uint8_t c);
49  
-  uint8_t spiread(void);
50  
-};
  1
+// PN532 library by adafruit/ladyada
  2
+// MIT license
  3
+
  4
+// authenticateBlock, readMemoryBlock, writeMemoryBlock contributed
  5
+// by Seeed Technology Inc (www.seeedstudio.com)
  6
+
  7
+
  8
+#include <WProgram.h>
  9
+
  10
+#define PN532_PREAMBLE 0x00
  11
+#define PN532_STARTCODE1 0x00
  12
+#define PN532_STARTCODE2 0xFF
  13
+#define PN532_POSTAMBLE 0x00
  14
+
  15
+#define PN532_HOSTTOPN532 0xD4
  16
+
  17
+#define PN532_FIRMWAREVERSION 0x02
  18
+#define PN532_GETGENERALSTATUS 0x04
  19
+#define PN532_SAMCONFIGURATION  0x14
  20
+#define PN532_INLISTPASSIVETARGET 0x4A
  21
+#define PN532_INDATAEXCHANGE 0x40
  22
+#define PN532_MIFARE_READ 0x30
  23
+#define PN532_MIFARE_WRITE 0xA0
  24
+
  25
+#define PN532_AUTH_WITH_KEYA 0x60
  26
+#define PN532_AUTH_WITH_KEYB 0x61
  27
+
  28
+
  29
+#define PN532_WAKEUP 0x55
  30
+
  31
+#define  PN532_SPI_STATREAD 0x02
  32
+#define  PN532_SPI_DATAWRITE 0x01
  33
+#define  PN532_SPI_DATAREAD 0x03
  34
+#define  PN532_SPI_READY 0x01
  35
+
  36
+#define PN532_MIFARE_ISO14443A 0x0
  37
+
  38
+#define KEY_A	1
  39
+#define KEY_B	2
  40
+
  41
+
  42
+class PN532{
  43
+public:
  44
+    PN532(uint8_t cs, uint8_t clk, uint8_t mosi, uint8_t miso);
  45
+
  46
+    void begin(void);
  47
+
  48
+    boolean SAMConfig(void);
  49
+    uint32_t getFirmwareVersion(void);
  50
+    uint32_t readPassiveTargetID(uint8_t cardbaudrate);
  51
+    uint32_t authenticateBlock(	uint8_t cardnumber /*1 or 2*/,
  52
+				uint32_t cid /*Card NUID*/,
  53
+				uint8_t blockaddress /*0 to 63*/,
  54
+				uint8_t authtype /*Either KEY_A or KEY_B */,
  55
+				uint8_t * keys);
  56
+
  57
+    uint32_t readMemoryBlock(uint8_t cardnumber /*1 or 2*/,uint8_t blockaddress /*0 to 63*/, uint8_t * block);
  58
+    uint32_t writeMemoryBlock(uint8_t cardnumber /*1 or 2*/,uint8_t blockaddress /*0 to 63*/, uint8_t * block);
  59
+
  60
+    boolean sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout = 1000);
  61
+
  62
+    //
  63
+
  64
+private:
  65
+    uint8_t _ss, _clk, _mosi, _miso;
  66
+
  67
+    boolean spi_readack();
  68
+    uint8_t readspistatus(void);
  69
+    void readspidata(uint8_t* buff, uint8_t n);
  70
+    void spiwritecommand(uint8_t* cmd, uint8_t cmdlen);
  71
+    void spiwrite(uint8_t c);
  72
+    uint8_t spiread(void);
  73
+};
99  examples/readAllMemoryBlocks/readAllMemoryBlocks.pde
... ...
@@ -0,0 +1,99 @@
  1
+//This example reads all MIFARE memory block from 0x00 to 0x63. It is tested with a new MIFARE 1K cards. Uses default keys for authentication.
  2
+//Contributed by Seeed Technology Inc (www.seeedstudio.com)
  3
+
  4
+#include <PN532.h>
  5
+
  6
+#define SCK 13
  7
+#define MOSI 11
  8
+#define SS 10
  9
+#define MISO 12
  10
+
  11
+PN532 nfc(SCK, MISO, MOSI, SS);
  12
+
  13
+void setup(void) {
  14
+    Serial.begin(9600);
  15
+    Serial.println("Hello!");
  16
+
  17
+    nfc.begin();
  18
+
  19
+    uint32_t versiondata = nfc.getFirmwareVersion();
  20
+    if (! versiondata) {
  21
+        Serial.print("Didn't find PN53x board");
  22
+        while (1); // halt
  23
+    }
  24
+    // Got ok data, print it out!
  25
+    Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  26
+    Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  27
+    Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  28
+    Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
  29
+
  30
+    // configure board to read RFID tags and cards
  31
+    nfc.SAMConfig();
  32
+}
  33
+
  34
+
  35
+void loop(void) {
  36
+    uint32_t id;
  37
+    // look for MiFare type cards
  38
+    id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  39
+
  40
+    if (id != 0)
  41
+    {
  42
+        Serial.print("Read card #");
  43
+        Serial.println(id);
  44
+        Serial.println();
  45
+
  46
+        uint8_t keys[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};  // default key of a fresh card
  47
+        for(uint8_t blockn=0;blockn<64;blockn++) {
  48
+            if(nfc.authenticateBlock(1, id ,blockn,KEY_A,keys)) //authenticate block blockn
  49
+            {
  50
+                //if authentication successful
  51
+                uint8_t block[16];
  52
+                //read memory block blockn
  53
+                if(nfc.readMemoryBlock(1,blockn,block))
  54
+                {
  55
+                    //if read operation is successful
  56
+                    for(uint8_t i=0;i<16;i++)
  57
+                    {
  58
+                        //print memory block
  59
+                        Serial.print(block[i],HEX);
  60
+                        if(block[i] <= 0xF) //Data arrangement / beautify
  61
+                        {
  62
+                            Serial.print("  ");
  63
+                        }
  64
+                        else
  65
+                        {
  66
+                            Serial.print(" ");
  67
+                        }
  68
+                    }
  69
+
  70
+                    Serial.print("| Block ");
  71
+                    if(blockn <= 9) //Data arrangement / beautify
  72
+                    {
  73
+                        Serial.print(" ");
  74
+                    }
  75
+                    Serial.print(blockn,DEC);
  76
+                    Serial.print(" | ");
  77
+
  78
+                    if(blockn == 0)
  79
+                    {
  80
+                        Serial.println("Manufacturer Block");
  81
+                    }
  82
+                    else
  83
+                    {
  84
+                        if(((blockn + 1) % 4) == 0)
  85
+                        {
  86
+                            Serial.println("Sector Trailer");
  87
+                        }
  88
+                        else
  89
+                        {
  90
+                            Serial.println("Data Block");
  91
+                        }
  92
+                    }
  93
+                }
  94
+            }
  95
+        }
  96
+    }
  97
+    delay(2000);
  98
+}
  99
+
38  examples/readMifare/readMifare.pde → examples/readMifareMemory/readMifareMemory.pde 100644 → 100755
... ...
@@ -1,9 +1,12 @@
  1
+//This example reads a MIFARE memory block. It is tested with a new MIFARE 1K cards. Uses default keys.
  2
+//Contributed by Seeed Technology Inc (www.seeedstudio.com)
  3
+
1 4
 #include <PN532.h>
2 5
 
3  
-#define SCK 2
4  
-#define MOSI 3
5  
-#define SS 4
6  
-#define MISO 5
  6
+#define SCK 13
  7
+#define MOSI 11
  8
+#define SS 10
  9
+#define MISO 12
7 10
 
8 11
 PN532 nfc(SCK, MISO, MOSI, SS);
9 12
 
@@ -24,7 +27,7 @@ void setup(void) {
24 27
   Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
25 28
   Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
26 29
   
27  
-  // configure board to read RFID tags
  30
+  // configure board to read RFID tags and cards
28 31
   nfc.SAMConfig();
29 32
 }
30 33
 
@@ -34,9 +37,30 @@ void loop(void) {
34 37
   // look for MiFare type cards
35 38
   id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
36 39
   
37  
-  if (id != 0) {
  40
+  if (id != 0) 
  41
+  {
38 42
     Serial.print("Read card #"); Serial.println(id);
  43
+    
  44
+    uint8_t keys[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  45
+    if(nfc.authenticateBlock(1, id ,0x08,KEY_A,keys)) //authenticate block 0x08
  46
+    {
  47
+    //if authentication successful
  48
+    uint8_t block[16];
  49
+    //read memory block 0x08
  50
+    if(nfc.readMemoryBlock(1,0x08,block))
  51
+    {
  52
+    //if read operation is successful
  53
+      for(uint8_t i=0;i<16;i++)
  54
+      {
  55
+        //print memory block
  56
+        Serial.print(block[i],HEX);
  57
+        Serial.print(" ");
  58
+      }
  59
+      Serial.println();
  60
+    }
  61
+   }
39 62
   }
  63
+  
  64
+  delay(500);
40 65
 }
41 66
 
42  
-    
42  examples/readMifareTargetID/readMifareTargetID.pde
... ...
@@ -0,0 +1,42 @@
  1
+#include <PN532.h>
  2
+
  3
+#define SCK 13
  4
+#define MOSI 11
  5
+#define SS 10
  6
+#define MISO 12
  7
+
  8
+PN532 nfc(SCK, MISO, MOSI, SS);
  9
+
  10
+void setup(void) {
  11
+    Serial.begin(9600);
  12
+    Serial.println("Hello!");
  13
+
  14
+    nfc.begin();
  15
+
  16
+    uint32_t versiondata = nfc.getFirmwareVersion();
  17
+    if (! versiondata) {
  18
+        Serial.print("Didn't find PN53x board");
  19
+        while (1); // halt
  20
+    }
  21
+    // Got ok data, print it out!
  22
+    Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  23
+    Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  24
+    Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  25
+    Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
  26
+
  27
+    // configure board to read RFID tags and cards
  28
+    nfc.SAMConfig();
  29
+}
  30
+
  31
+
  32
+void loop(void) {
  33
+    uint32_t id;
  34
+    // look for MiFare type cards
  35
+    id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  36
+
  37
+    if (id != 0) {
  38
+        Serial.print("Read card #"); Serial.println(id);
  39
+    }
  40
+}
  41
+
  42
+
87  examples/writeMifareMemory/writeMifareMemory.pde
... ...
@@ -0,0 +1,87 @@
  1
+// This example writes a MIFARE memory block 0x08. It is tested with a new MIFARE 1K cards. Uses default keys.
  2
+// Note: Memory block 0 is readonly and contains manufacturer data. Do not write to Sector Trailer block
  3
+// unless you know what you are doing. Otherwise, the MIFARE card may be unusable in the future.
  4
+
  5
+//Contributed by Seeed Technology Inc (www.seeedstudio.com)
  6
+
  7
+#include <PN532.h>
  8
+
  9
+#define SCK 13
  10
+#define MOSI 11
  11
+#define SS 10
  12
+#define MISO 12
  13
+
  14
+PN532 nfc(SCK, MISO, MOSI, SS);
  15
+
  16
+uint8_t written=0;
  17
+
  18
+void setup(void) {
  19
+  Serial.begin(9600);
  20
+  Serial.println("Hello!");
  21
+
  22
+  nfc.begin();
  23
+
  24
+  uint32_t versiondata = nfc.getFirmwareVersion();
  25
+  if (! versiondata) {
  26
+    Serial.print("Didn't find PN53x board");
  27
+    while (1); // halt
  28
+  }
  29
+  // Got ok data, print it out!
  30
+  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  31
+  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  32
+  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  33
+  Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
  34
+  
  35
+  // configure board to read RFID tags and cards
  36
+  nfc.SAMConfig();
  37
+}
  38
+
  39
+
  40
+void loop(void) {
  41
+  uint32_t id;
  42
+  // look for MiFare type cards
  43
+  id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  44
+  
  45
+  if (id != 0) 
  46
+  {
  47
+    Serial.print("Read card #"); Serial.println(id);
  48
+    Serial.println();
  49
+    
  50
+    uint8_t keys[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  51
+    uint8_t writeBuffer[16];
  52
+    for(uint8_t ii=0;ii<16;ii++)
  53
+    { 
  54
+       writeBuffer[ii]=ii; //Fill buffer with 0,1,2....F
  55
+    }
  56
+    if(nfc.authenticateBlock(1, id ,0x08,KEY_A,keys)) //authenticate block 0x08
  57
+    {
  58
+    //if authentication successful
  59
+
  60
+    if(written == 0) //Not written
  61
+    {
  62
+    written = nfc.writeMemoryBlock(1,0x08,writeBuffer); // Write writeBuffer[] to block 0x08
  63
+    if(written)
  64
+      Serial.println("Write Successful");   
  65
+    }
  66
+
  67
+    
  68
+    uint8_t block[16];
  69
+    //read memory block 0x08
  70
+    if(nfc.readMemoryBlock(1,0x08,block))
  71
+    {
  72
+    Serial.println("Read block 0x08:");   
  73
+    //if read operation is successful
  74
+      for(uint8_t i=0;i<16;i++)
  75
+      {
  76
+        //print memory block
  77
+        Serial.print(block[i],HEX);
  78
+        Serial.print(" ");
  79
+      }
  80
+      Serial.println();
  81
+     }
  82
+   }
  83
+  }
  84
+  
  85
+  delay(500);
  86
+}
  87
+

0 notes on commit d379695

Please sign in to comment.
Something went wrong with that request. Please try again.