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