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