PN532 NFC shield of Adafruit based on PN532 of Seeed.

Fork of PN532 by Seeed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PN532_SPI.cpp Source File

PN532_SPI.cpp

00001 
00002 #include "PN532_SPI.h"
00003 #include "PN532_debug.h"
00004 
00005 #define STATUS_READ     2
00006 #define DATA_WRITE      1
00007 #define DATA_READ       3
00008 
00009 PN532_SPI::PN532_SPI(SPI &spi, PinName ss) : _ss(ss)
00010 {
00011     command = 0;
00012     _spi = &spi;
00013     _spi->format(8, 0);
00014     _spi->frequency(2000000);
00015 
00016     _ss  = 1;
00017 }
00018 
00019 PN532_SPI::PN532_SPI(SPI *spi, PinName ss) : _ss(ss)
00020 {
00021     command = 0;
00022     _spi = spi;
00023     _spi->format(8, 0);
00024     _spi->frequency(2000000);
00025 
00026     _ss  = 1;
00027 }
00028 
00029 void PN532_SPI::begin()
00030 {
00031 
00032 }
00033 
00034 void PN532_SPI::wakeup()
00035 {
00036     _ss = 0;
00037     wait_ms(2);
00038     _ss = 1;
00039 }
00040 
00041 int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
00042 {
00043     command = header[0];
00044     writeFrame(header, hlen, body, blen);
00045 
00046     uint8_t timeout = PN532_ACK_WAIT_TIME;
00047     while (!isReady()) {
00048         wait_ms(1);
00049         timeout--;
00050         if (0 == timeout) {
00051             DMSG("Time out when waiting for ACK\n");
00052             return -2;
00053         }
00054     }
00055     if (readAckFrame()) {
00056         DMSG("Invalid ACK\n");
00057         return PN532_INVALID_ACK;
00058     }
00059     return 0;
00060 }
00061 
00062 int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
00063 {
00064     uint16_t time = 0;
00065     while (!isReady()) {
00066         wait_ms(1);
00067         time++;
00068         if (timeout > 0 && time > timeout) {
00069             return PN532_TIMEOUT;
00070         }
00071     }
00072 
00073     _ss = 0;
00074     wait_ms(1);
00075 
00076     int16_t result;
00077     do {
00078         write(DATA_READ);
00079 
00080         if (0x00 != read()      ||       // PREAMBLE
00081                 0x00 != read()  ||       // STARTCODE1
00082                 0xFF != read()           // STARTCODE2
00083            ) {
00084 
00085             result = PN532_INVALID_FRAME;
00086             break;
00087         }
00088 
00089         uint8_t length = read();
00090         if (0 != (uint8_t)(length + read())) {   // checksum of length
00091             result = PN532_INVALID_FRAME;
00092             break;
00093         }
00094 
00095         uint8_t cmd = command + 1;               // response command
00096         if (PN532_PN532TOHOST != read() || (cmd) != read()) {
00097             result = PN532_INVALID_FRAME;
00098             break;
00099         }
00100 
00101         DMSG("read:  ");
00102         DMSG_HEX(cmd);
00103 
00104         length -= 2;
00105         if (length > len) {
00106             for (uint8_t i = 0; i < length; i++) {
00107                 DMSG_HEX(read());                 // dump message
00108             }
00109             DMSG("\nNot enough space\n");
00110             read();
00111             read();
00112             result = PN532_NO_SPACE;  // not enough space
00113             break;
00114         }
00115 
00116         uint8_t sum = PN532_PN532TOHOST + cmd;
00117         for (uint8_t i = 0; i < length; i++) {
00118             buf[i] = read();
00119             sum += buf[i];
00120 
00121             DMSG_HEX(buf[i]);
00122         }
00123         DMSG("\n");
00124 
00125         uint8_t checksum = read();
00126         if (0 != (uint8_t)(sum + checksum)) {
00127             DMSG("checksum is not ok\n");
00128             result = PN532_INVALID_FRAME;
00129             break;
00130         }
00131         read();         // POSTAMBLE
00132 
00133         result = length;
00134     } while (0);
00135 
00136     _ss = 1;
00137 
00138     return result;
00139 }
00140 
00141 bool PN532_SPI::isReady()
00142 {
00143     _ss = 0;
00144 
00145     write(STATUS_READ);
00146     uint8_t status = read() & 1;
00147     _ss = 1;
00148     return status;
00149 }
00150 
00151 void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
00152 {
00153     _ss = 0;
00154     wait_ms(2);               // wake up PN532
00155 
00156     write(DATA_WRITE);
00157     write(PN532_PREAMBLE);
00158     write(PN532_STARTCODE1);
00159     write(PN532_STARTCODE2);
00160 
00161     uint8_t length = hlen + blen + 1;   // length of data field: TFI + DATA
00162     write(length);
00163     write(~length + 1);         // checksum of length
00164 
00165     write(PN532_HOSTTOPN532);
00166     uint8_t sum = PN532_HOSTTOPN532;    // sum of TFI + DATA
00167 
00168     DMSG("write: ");
00169 
00170     for (uint8_t i = 0; i < hlen; i++) {
00171         write(header[i]);
00172         sum += header[i];
00173 
00174         DMSG_HEX(header[i]);
00175     }
00176     for (uint8_t i = 0; i < blen; i++) {
00177         write(body[i]);
00178         sum += body[i];
00179         
00180         DMSG_HEX(header[i]);
00181     }
00182 
00183     uint8_t checksum = ~sum + 1;        // checksum of TFI + DATA
00184     write(checksum);
00185     write(PN532_POSTAMBLE);
00186 
00187     _ss = 1;
00188 
00189     DMSG("\n");
00190 }
00191 
00192 int8_t PN532_SPI::readAckFrame()
00193 {
00194     const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
00195 
00196     uint8_t ackBuf[sizeof(PN532_ACK)];
00197 
00198     _ss = 0;
00199     wait_ms(1);
00200     write(DATA_READ);
00201 
00202     for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
00203         ackBuf[i] = read();
00204     }
00205 
00206     _ss = 1;
00207 
00208     return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK));
00209 }