PN532 NFC library for Seeed Studio's NFC Shield
Fork of PN532 by
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 17:32:26 by 1.7.2