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_HSU.cpp
00001 //////////////////////////////////////////////////////////////////////////////// 00002 // pn532 hsu interface for mbed platform 00003 // 00004 // by dotnfc@163.com 00005 // 2016/09/10 18:16:00 00006 00007 #include "PN532_HSU.h" 00008 #include "PN532_debug.h" 00009 00010 00011 PN532_HSU::PN532_HSU(HardwareSerial &serial) 00012 { 00013 _serial = &serial; 00014 command = 0; 00015 } 00016 00017 void PN532_HSU::begin() 00018 { 00019 _serial->baud(115200); 00020 } 00021 00022 void PN532_HSU::wakeup() 00023 { 00024 const uint8_t wakeup_cmd[] = { 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x05, 0xFB, 0xD4, 0x14, 0x01, 0x00, 0x01, 0x16, 0x00 }; 00025 _serial->write(wakeup_cmd, sizeof(wakeup_cmd)); 00026 00027 delay (50); 00028 00029 /** dump serial buffer */ 00030 if(_serial->readable()){ 00031 DMSG("Dump sperial buffer: "); 00032 } 00033 while(_serial->readable()){ 00034 uint8_t ret = _serial->getc(); 00035 DMSG_HEX(ret); 00036 } 00037 DMSG("\n"); 00038 } 00039 00040 int8_t PN532_HSU::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) 00041 { 00042 /** dump serial buffer */ 00043 if(_serial->readable()){ 00044 DMSG("Dump sperial buffer: "); 00045 } 00046 while(_serial->readable()){ 00047 uint8_t ret = _serial->getc(); 00048 DMSG_HEX(ret); 00049 } 00050 DMSG("\n"); 00051 00052 command = header[0]; 00053 00054 _serial->write(PN532_PREAMBLE); 00055 _serial->write(PN532_STARTCODE1); 00056 _serial->write(PN532_STARTCODE2); 00057 00058 uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA 00059 _serial->write(length); 00060 _serial->write(~length + 1); // checksum of length 00061 00062 _serial->write(PN532_HOSTTOPN532); 00063 uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA 00064 00065 DMSG("\nWrite: "); 00066 00067 _serial->write(header, hlen); 00068 for (uint8_t i = 0; i < hlen; i++) { 00069 sum += header[i]; 00070 00071 DMSG_HEX(header[i]); 00072 } 00073 00074 _serial->write(body, blen); 00075 for (uint8_t i = 0; i < blen; i++) { 00076 sum += body[i]; 00077 00078 DMSG_HEX(body[i]); 00079 } 00080 00081 uint8_t checksum = ~sum + 1; // checksum of TFI + DATA 00082 _serial->write(checksum); 00083 _serial->write(PN532_POSTAMBLE); 00084 00085 delay (50); 00086 return readAckFrame(); 00087 } 00088 00089 int16_t PN532_HSU::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout) 00090 { 00091 uint8_t tmp[3]; 00092 00093 delay(100); 00094 00095 DMSG("\nRead: "); 00096 00097 /** Frame Preamble and Start Code */ 00098 if(receive(tmp, 3, timeout)<=0){ 00099 return PN532_TIMEOUT; 00100 } 00101 if(0 != tmp[0] || 0!= tmp[1] || 0xFF != tmp[2]){ 00102 DMSG("Preamble error"); 00103 return PN532_INVALID_FRAME; 00104 } 00105 00106 /** receive length and check */ 00107 uint8_t length[2]; 00108 if(receive(length, 2, timeout) <= 0){ 00109 return PN532_TIMEOUT; 00110 } 00111 if( 0 != (uint8_t)(length[0] + length[1]) ){ 00112 DMSG("Length error\n"); 00113 return PN532_INVALID_FRAME; 00114 } 00115 length[0] -= 2; 00116 if( length[0] > len){ 00117 return PN532_NO_SPACE; 00118 } 00119 00120 /** receive command byte */ 00121 uint8_t cmd = command + 1; // response command 00122 if(receive(tmp, 2, timeout) <= 0){ 00123 return PN532_TIMEOUT; 00124 } 00125 if( PN532_PN532TOHOST != tmp[0] || cmd != tmp[1]){ 00126 DMSG("Command error\n"); 00127 return PN532_INVALID_FRAME; 00128 } 00129 00130 if(receive(buf, length[0], timeout) != length[0]){ 00131 return PN532_TIMEOUT; 00132 } 00133 uint8_t sum = PN532_PN532TOHOST + cmd; 00134 for(uint8_t i=0; i<length[0]; i++){ 00135 sum += buf[i]; 00136 } 00137 00138 /** checksum and postamble */ 00139 if(receive(tmp, 2, timeout) <= 0){ 00140 return PN532_TIMEOUT; 00141 } 00142 if( 0 != (uint8_t)(sum + tmp[0]) || 0 != tmp[1] ){ 00143 DMSG("Checksum error\n"); 00144 return PN532_INVALID_FRAME; 00145 } 00146 00147 DMSG ("\n"); 00148 return length[0]; 00149 } 00150 00151 int8_t PN532_HSU::readAckFrame() 00152 { 00153 const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0}; 00154 uint8_t ackBuf[sizeof(PN532_ACK)]; 00155 00156 delay(100); 00157 00158 DMSG("\nAck: "); 00159 00160 if( receive(ackBuf, sizeof(PN532_ACK), PN532_ACK_WAIT_TIME) <= 0 ){ 00161 DMSG("Timeout\n"); 00162 return PN532_TIMEOUT; 00163 } 00164 00165 if( memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK)) ){ 00166 DMSG("Invalid\n"); 00167 return PN532_INVALID_ACK; 00168 } 00169 return 0; 00170 } 00171 00172 /** 00173 @brief receive data . 00174 @param buf --> return value buffer. 00175 len --> length expect to receive. 00176 timeout --> time of reveiving 00177 @retval number of received bytes, 0 means no data received. 00178 */ 00179 int8_t PN532_HSU::receive(uint8_t *buf, int len, uint16_t timeout) 00180 { 00181 int read_bytes = 0; 00182 int ret; 00183 Timer tmr_hsu; 00184 unsigned long start_millis; 00185 00186 tmr_hsu.start(); 00187 while (read_bytes < len) { 00188 start_millis = tmr_hsu.read_ms(); // millis(); 00189 do { 00190 ret = _serial->getc(); 00191 if (ret >= 0) { 00192 break; 00193 } 00194 delay(10); 00195 } while((timeout == 0) || ((tmr_hsu.read_ms() /* millis() */ - start_millis ) < timeout)); 00196 00197 if (ret < 0) { 00198 if(read_bytes){ 00199 tmr_hsu.stop (); 00200 return read_bytes; 00201 }else{ 00202 tmr_hsu.stop (); 00203 return PN532_TIMEOUT; 00204 } 00205 } 00206 buf[read_bytes] = (uint8_t)ret; 00207 DMSG_HEX(ret); 00208 read_bytes++; 00209 } 00210 00211 tmr_hsu.stop (); 00212 return read_bytes; 00213 }
Generated on Tue Jul 12 2022 20:44:47 by 1.7.2