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_I2C.cpp
00001 //////////////////////////////////////////////////////////////////////////////// 00002 // pn532 i2c interface for mbed platform 00003 // 00004 // by dotnfc@163.com 00005 // 2016/09/10 18:16:00 00006 00007 #include "PN532_I2C.h" 00008 #include "PN532_debug.h" 00009 #include "Arduino.h" 00010 00011 00012 PN532_I2C::PN532_I2C(mbed::I2C &wire) 00013 { 00014 _wire = &wire; 00015 command = 0; 00016 } 00017 00018 void PN532_I2C::begin() 00019 { 00020 00021 } 00022 00023 void PN532_I2C::wakeup() 00024 { 00025 00026 } 00027 00028 int8_t PN532_I2C::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) 00029 { 00030 command = header[0]; 00031 MyBuffer <uint8_t> tBuf; 00032 00033 tBuf.put (PN532_PREAMBLE); 00034 tBuf.put (PN532_STARTCODE1); 00035 tBuf.put (PN532_STARTCODE2); 00036 00037 uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA 00038 tBuf.put (length); 00039 tBuf.put (~length + 1); // checksum of length 00040 00041 tBuf.put (PN532_HOSTTOPN532); 00042 uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA 00043 00044 DMSG("write: "); 00045 00046 for (uint8_t i = 0; i < hlen; i++) { 00047 tBuf.put (header[i]); 00048 sum += header[i]; 00049 DMSG_HEX(header[i]); 00050 } 00051 00052 for (uint8_t i = 0; i < blen; i++) { 00053 tBuf.put (body[i]); 00054 sum += body[i]; 00055 DMSG_HEX(body[i]); 00056 } 00057 00058 uint8_t checksum = ~sum + 1; // checksum of TFI + DATA 00059 tBuf.put (checksum); 00060 tBuf.put (PN532_POSTAMBLE); 00061 00062 _wire->write (PN532_I2C_ADDRESS, (const char *)tBuf.head(), tBuf.getLength()); 00063 00064 DMSG("\n"); 00065 00066 return readAckFrame(); 00067 } 00068 00069 00070 int16_t PN532_I2C::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout) 00071 { 00072 uint8_t stat; 00073 uint16_t tlen = 256 + 5; 00074 MyBuffer <uint8_t> tBuf(256 + 5); 00075 Timer timer; 00076 if (timeout !=0) { 00077 timer.start(); 00078 } 00079 00080 do { 00081 if (_wire->read (PN532_I2C_ADDRESS, (char *)&stat, 1) == 0) { 00082 00083 if (stat & 1) { // check the STATUS byte 00084 wait_ms (2); 00085 00086 if (tlen > len) 00087 tlen = len; 00088 00089 if (_wire->read(PN532_I2C_ADDRESS, (char *)tBuf.head(), tlen) == 0) { 00090 break; 00091 } 00092 } 00093 } 00094 00095 if (0 != timeout) { 00096 if (timer.read_ms() > timeout) { 00097 timer.stop (); 00098 return -1; 00099 } 00100 } 00101 00102 } while (1); 00103 00104 if (0x01 != tBuf.get() || // STATUS 00105 0x00 != tBuf.get() || // PREAMBLE 00106 0x00 != tBuf.get() || // STARTCODE1 00107 0xFF != tBuf.get() // STARTCODE2 00108 ) { 00109 00110 return PN532_INVALID_FRAME; 00111 } 00112 00113 uint8_t length = tBuf.get(); 00114 if (0 != (uint8_t)(length + tBuf.get())) { // checksum of length 00115 return PN532_INVALID_FRAME; 00116 } 00117 00118 uint8_t cmd = command + 1; // response command 00119 if (PN532_PN532TOHOST != tBuf.get() || (cmd) != tBuf.get()) { 00120 return PN532_INVALID_FRAME; 00121 } 00122 00123 length -= 2; 00124 if (length > len) { 00125 return PN532_NO_SPACE; // not enough space 00126 } 00127 00128 DMSG("read: "); 00129 DMSG_HEX(cmd); 00130 00131 uint8_t sum = PN532_PN532TOHOST + cmd; 00132 for (uint8_t i = 0; i < length; i++) { 00133 buf[i] = tBuf.get(); 00134 sum += buf[i]; 00135 00136 DMSG_HEX(buf[i]); 00137 } 00138 DMSG("\n"); 00139 00140 uint8_t checksum = tBuf.get(); 00141 if (0 != (uint8_t)(sum + checksum)) { 00142 DMSG("checksum is not ok\n"); 00143 return PN532_INVALID_FRAME; 00144 } 00145 //tBuf.get(); // POSTAMBLE 00146 00147 return length; 00148 } 00149 00150 int8_t PN532_I2C::readAckFrame() 00151 { 00152 const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0}; 00153 MyBuffer <uint8_t> ackBuf(sizeof(PN532_ACK) + 1); 00154 00155 Timer timer; 00156 timer.start(); 00157 00158 do { 00159 // if (_wire->requestFrom(PN532_I2C_ADDRESS, sizeof(PN532_ACK) + 1)) { 00160 if (_wire->read(PN532_I2C_ADDRESS, (char *)ackBuf.head(), sizeof(PN532_ACK) + 1) == 0) { 00161 if (ackBuf.get() & 1) { // check first byte --- status 00162 break; // PN532 is ready 00163 } 00164 } 00165 00166 if (timer.read_ms() > PN532_ACK_WAIT_TIME) { 00167 DMSG("Time out when waiting for ACK\n"); 00168 timer.stop (); 00169 return PN532_TIMEOUT; 00170 } 00171 } while (1); 00172 00173 for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) { 00174 if (ackBuf.get() != PN532_ACK[i]) 00175 return PN532_INVALID_ACK; 00176 } 00177 00178 return 0; 00179 }
Generated on Tue Jul 12 2022 20:44:47 by 1.7.2