PN532 Driver library This library provides an abstract API to drive the pn532 nfc chip, with I2C/HSU/SPI interface. Its based on the Seeed Studio's Arduino version.

Dependents:   PN532_ReadUid Nfctest2

Committer:
dotnfc
Date:
Tue Sep 13 06:17:35 2016 +0000
Revision:
1:b5922b3b3257
Parent:
0:db8030e71f55
Remove ununsed files.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dotnfc 0:db8030e71f55 1 ////////////////////////////////////////////////////////////////////////////////
dotnfc 0:db8030e71f55 2 // pn532 spi interface for mbed platform
dotnfc 0:db8030e71f55 3 //
dotnfc 0:db8030e71f55 4 // by dotnfc@163.com
dotnfc 0:db8030e71f55 5 // 2016/09/10 18:16:00
dotnfc 0:db8030e71f55 6
dotnfc 0:db8030e71f55 7 #include "PN532_SPI.h"
dotnfc 0:db8030e71f55 8 #include "PN532_debug.h"
dotnfc 0:db8030e71f55 9
dotnfc 0:db8030e71f55 10 #define STATUS_READ 2
dotnfc 0:db8030e71f55 11 #define DATA_WRITE 1
dotnfc 0:db8030e71f55 12 #define DATA_READ 3
dotnfc 0:db8030e71f55 13
dotnfc 0:db8030e71f55 14 PN532_SPI::PN532_SPI(SPI &spi, PinName ss) : _ss(ss)
dotnfc 0:db8030e71f55 15 {
dotnfc 0:db8030e71f55 16 command = 0;
dotnfc 0:db8030e71f55 17 _spi = &spi;
dotnfc 0:db8030e71f55 18 _spi->format(8, 0);
dotnfc 0:db8030e71f55 19 _spi->frequency(2000000);
dotnfc 0:db8030e71f55 20
dotnfc 0:db8030e71f55 21 _ss = 1;
dotnfc 0:db8030e71f55 22 }
dotnfc 0:db8030e71f55 23
dotnfc 0:db8030e71f55 24 PN532_SPI::PN532_SPI(SPI *spi, PinName ss) : _ss(ss)
dotnfc 0:db8030e71f55 25 {
dotnfc 0:db8030e71f55 26 command = 0;
dotnfc 0:db8030e71f55 27 _spi = spi;
dotnfc 0:db8030e71f55 28 _spi->format(8, 0);
dotnfc 0:db8030e71f55 29 _spi->frequency(2000000);
dotnfc 0:db8030e71f55 30
dotnfc 0:db8030e71f55 31 _ss = 1;
dotnfc 0:db8030e71f55 32 }
dotnfc 0:db8030e71f55 33
dotnfc 0:db8030e71f55 34 void PN532_SPI::begin()
dotnfc 0:db8030e71f55 35 {
dotnfc 0:db8030e71f55 36
dotnfc 0:db8030e71f55 37 }
dotnfc 0:db8030e71f55 38
dotnfc 0:db8030e71f55 39 void PN532_SPI::wakeup()
dotnfc 0:db8030e71f55 40 {
dotnfc 0:db8030e71f55 41 _ss = 0;
dotnfc 0:db8030e71f55 42 wait_ms(2);
dotnfc 0:db8030e71f55 43 _ss = 1;
dotnfc 0:db8030e71f55 44 }
dotnfc 0:db8030e71f55 45
dotnfc 0:db8030e71f55 46 int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
dotnfc 0:db8030e71f55 47 {
dotnfc 0:db8030e71f55 48 command = header[0];
dotnfc 0:db8030e71f55 49 writeFrame(header, hlen, body, blen);
dotnfc 0:db8030e71f55 50
dotnfc 0:db8030e71f55 51 Timer timer;
dotnfc 0:db8030e71f55 52 timer.start();
dotnfc 0:db8030e71f55 53
dotnfc 0:db8030e71f55 54 while (!isReady()) {
dotnfc 0:db8030e71f55 55 if (timer.read_ms() > PN532_ACK_WAIT_TIME) {
dotnfc 0:db8030e71f55 56 DMSG("Time out when waiting for ACK\n");
dotnfc 0:db8030e71f55 57 timer.stop ();
dotnfc 0:db8030e71f55 58 return -2;
dotnfc 0:db8030e71f55 59 }
dotnfc 0:db8030e71f55 60 }
dotnfc 0:db8030e71f55 61 if (readAckFrame()) {
dotnfc 0:db8030e71f55 62 DMSG("Invalid ACK\n");
dotnfc 0:db8030e71f55 63 return PN532_INVALID_ACK;
dotnfc 0:db8030e71f55 64 }
dotnfc 0:db8030e71f55 65 return 0;
dotnfc 0:db8030e71f55 66 }
dotnfc 0:db8030e71f55 67
dotnfc 0:db8030e71f55 68 int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
dotnfc 0:db8030e71f55 69 {
dotnfc 0:db8030e71f55 70 Timer timer;
dotnfc 0:db8030e71f55 71 if (timeout > 0)
dotnfc 0:db8030e71f55 72 timer.start();
dotnfc 0:db8030e71f55 73
dotnfc 0:db8030e71f55 74 while (!isReady()) {
dotnfc 0:db8030e71f55 75
dotnfc 0:db8030e71f55 76 if (timeout > 0){
dotnfc 0:db8030e71f55 77 if (timer.read_ms() > timeout) {
dotnfc 0:db8030e71f55 78 timer.stop();
dotnfc 0:db8030e71f55 79 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 80 }
dotnfc 0:db8030e71f55 81 }
dotnfc 0:db8030e71f55 82 }
dotnfc 0:db8030e71f55 83
dotnfc 0:db8030e71f55 84 _ss = 0;
dotnfc 0:db8030e71f55 85 wait_ms(1);
dotnfc 0:db8030e71f55 86
dotnfc 0:db8030e71f55 87 int16_t result;
dotnfc 0:db8030e71f55 88 do {
dotnfc 0:db8030e71f55 89 write(DATA_READ);
dotnfc 0:db8030e71f55 90
dotnfc 0:db8030e71f55 91 if (0x00 != read() || // PREAMBLE
dotnfc 0:db8030e71f55 92 0x00 != read() || // STARTCODE1
dotnfc 0:db8030e71f55 93 0xFF != read() // STARTCODE2
dotnfc 0:db8030e71f55 94 ) {
dotnfc 0:db8030e71f55 95
dotnfc 0:db8030e71f55 96 result = PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 97 break;
dotnfc 0:db8030e71f55 98 }
dotnfc 0:db8030e71f55 99
dotnfc 0:db8030e71f55 100 uint8_t length = read();
dotnfc 0:db8030e71f55 101 if (0 != (uint8_t)(length + read())) { // checksum of length
dotnfc 0:db8030e71f55 102 result = PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 103 break;
dotnfc 0:db8030e71f55 104 }
dotnfc 0:db8030e71f55 105
dotnfc 0:db8030e71f55 106 uint8_t cmd = command + 1; // response command
dotnfc 0:db8030e71f55 107 if (PN532_PN532TOHOST != read() || (cmd) != read()) {
dotnfc 0:db8030e71f55 108 result = PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 109 break;
dotnfc 0:db8030e71f55 110 }
dotnfc 0:db8030e71f55 111
dotnfc 0:db8030e71f55 112 DMSG("read: ");
dotnfc 0:db8030e71f55 113 DMSG_HEX(cmd);
dotnfc 0:db8030e71f55 114
dotnfc 0:db8030e71f55 115 length -= 2;
dotnfc 0:db8030e71f55 116 if (length > len) {
dotnfc 0:db8030e71f55 117 for (uint8_t i = 0; i < length; i++) {
dotnfc 0:db8030e71f55 118 DMSG_HEX(read()); // dump message
dotnfc 0:db8030e71f55 119 }
dotnfc 0:db8030e71f55 120 DMSG("\nNot enough space\n");
dotnfc 0:db8030e71f55 121 read();
dotnfc 0:db8030e71f55 122 read();
dotnfc 0:db8030e71f55 123 result = PN532_NO_SPACE; // not enough space
dotnfc 0:db8030e71f55 124 break;
dotnfc 0:db8030e71f55 125 }
dotnfc 0:db8030e71f55 126
dotnfc 0:db8030e71f55 127 uint8_t sum = PN532_PN532TOHOST + cmd;
dotnfc 0:db8030e71f55 128 for (uint8_t i = 0; i < length; i++) {
dotnfc 0:db8030e71f55 129 buf[i] = read();
dotnfc 0:db8030e71f55 130 sum += buf[i];
dotnfc 0:db8030e71f55 131
dotnfc 0:db8030e71f55 132 DMSG_HEX(buf[i]);
dotnfc 0:db8030e71f55 133 }
dotnfc 0:db8030e71f55 134 DMSG("\n");
dotnfc 0:db8030e71f55 135
dotnfc 0:db8030e71f55 136 uint8_t checksum = read();
dotnfc 0:db8030e71f55 137 if (0 != (uint8_t)(sum + checksum)) {
dotnfc 0:db8030e71f55 138 DMSG("checksum is not ok\n");
dotnfc 0:db8030e71f55 139 result = PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 140 break;
dotnfc 0:db8030e71f55 141 }
dotnfc 0:db8030e71f55 142 read(); // POSTAMBLE
dotnfc 0:db8030e71f55 143
dotnfc 0:db8030e71f55 144 result = length;
dotnfc 0:db8030e71f55 145 } while (0);
dotnfc 0:db8030e71f55 146
dotnfc 0:db8030e71f55 147 _ss = 1;
dotnfc 0:db8030e71f55 148
dotnfc 0:db8030e71f55 149 return result;
dotnfc 0:db8030e71f55 150 }
dotnfc 0:db8030e71f55 151
dotnfc 0:db8030e71f55 152 bool PN532_SPI::isReady()
dotnfc 0:db8030e71f55 153 {
dotnfc 0:db8030e71f55 154 _ss = 0;
dotnfc 0:db8030e71f55 155
dotnfc 0:db8030e71f55 156 write(STATUS_READ);
dotnfc 0:db8030e71f55 157 uint8_t status = read() & 1;
dotnfc 0:db8030e71f55 158 _ss = 1;
dotnfc 0:db8030e71f55 159 return status;
dotnfc 0:db8030e71f55 160 }
dotnfc 0:db8030e71f55 161
dotnfc 0:db8030e71f55 162 void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
dotnfc 0:db8030e71f55 163 {
dotnfc 0:db8030e71f55 164 _ss = 0;
dotnfc 0:db8030e71f55 165 wait_ms(2); // wake up PN532
dotnfc 0:db8030e71f55 166
dotnfc 0:db8030e71f55 167 write(DATA_WRITE);
dotnfc 0:db8030e71f55 168 write(PN532_PREAMBLE);
dotnfc 0:db8030e71f55 169 write(PN532_STARTCODE1);
dotnfc 0:db8030e71f55 170 write(PN532_STARTCODE2);
dotnfc 0:db8030e71f55 171
dotnfc 0:db8030e71f55 172 uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA
dotnfc 0:db8030e71f55 173 write(length);
dotnfc 0:db8030e71f55 174 write(~length + 1); // checksum of length
dotnfc 0:db8030e71f55 175
dotnfc 0:db8030e71f55 176 write(PN532_HOSTTOPN532);
dotnfc 0:db8030e71f55 177 uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA
dotnfc 0:db8030e71f55 178
dotnfc 0:db8030e71f55 179 DMSG("write: ");
dotnfc 0:db8030e71f55 180
dotnfc 0:db8030e71f55 181 for (uint8_t i = 0; i < hlen; i++) {
dotnfc 0:db8030e71f55 182 write(header[i]);
dotnfc 0:db8030e71f55 183 sum += header[i];
dotnfc 0:db8030e71f55 184
dotnfc 0:db8030e71f55 185 DMSG_HEX(header[i]);
dotnfc 0:db8030e71f55 186 }
dotnfc 0:db8030e71f55 187 for (uint8_t i = 0; i < blen; i++) {
dotnfc 0:db8030e71f55 188 write(body[i]);
dotnfc 0:db8030e71f55 189 sum += body[i];
dotnfc 0:db8030e71f55 190
dotnfc 0:db8030e71f55 191 DMSG_HEX(header[i]);
dotnfc 0:db8030e71f55 192 }
dotnfc 0:db8030e71f55 193
dotnfc 0:db8030e71f55 194 uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
dotnfc 0:db8030e71f55 195 write(checksum);
dotnfc 0:db8030e71f55 196 write(PN532_POSTAMBLE);
dotnfc 0:db8030e71f55 197
dotnfc 0:db8030e71f55 198 _ss = 1;
dotnfc 0:db8030e71f55 199
dotnfc 0:db8030e71f55 200 DMSG("\n");
dotnfc 0:db8030e71f55 201 }
dotnfc 0:db8030e71f55 202
dotnfc 0:db8030e71f55 203 int8_t PN532_SPI::readAckFrame()
dotnfc 0:db8030e71f55 204 {
dotnfc 0:db8030e71f55 205 const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
dotnfc 0:db8030e71f55 206
dotnfc 0:db8030e71f55 207 uint8_t ackBuf[sizeof(PN532_ACK)];
dotnfc 0:db8030e71f55 208
dotnfc 0:db8030e71f55 209 _ss = 0;
dotnfc 0:db8030e71f55 210 wait_ms(1);
dotnfc 0:db8030e71f55 211 write(DATA_READ);
dotnfc 0:db8030e71f55 212
dotnfc 0:db8030e71f55 213 for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
dotnfc 0:db8030e71f55 214 ackBuf[i] = read();
dotnfc 0:db8030e71f55 215 }
dotnfc 0:db8030e71f55 216
dotnfc 0:db8030e71f55 217 _ss = 1;
dotnfc 0:db8030e71f55 218
dotnfc 0:db8030e71f55 219 return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK));
dotnfc 0:db8030e71f55 220 }