Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PN532.cpp
00001 #include "mbed.h" 00002 #include "PN532.h" 00003 #include "string.h" 00004 00005 #define PN532_PACK_BUFF_SIZE 64 00006 uint8_t pn532_packetbuffer[PN532_PACK_BUFF_SIZE]; 00007 00008 uint8_t pn532ack[] = { 00009 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00 00010 }; 00011 uint8_t pn532response_firmwarevers[] = { 00012 0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03 00013 }; 00014 00015 PN532::PN532(PinName mosi, PinName miso, PinName sclk, PinName ss) 00016 { 00017 _spi = new SPI(mosi, miso, sclk); 00018 _spi->frequency(5000000); 00019 _spi->format(8, 0); 00020 _ss = new DigitalOut(ss); 00021 *_ss = 1; 00022 } 00023 00024 void PN532::begin(void) 00025 { 00026 _spi->frequency(5000000); 00027 _spi->format(8, 0); 00028 pn532_packetbuffer[0] = PN532_FIRMWAREVERSION; 00029 printf("begin"); 00030 /*Ignore response!*/ 00031 sendCommandCheckAck(pn532_packetbuffer, 1); 00032 } 00033 00034 uint32_t PN532::getFirmwareVersion(void) 00035 { 00036 uint32_t response; 00037 00038 pn532_packetbuffer[0] = PN532_FIRMWAREVERSION; 00039 00040 if (!sendCommandCheckAck(pn532_packetbuffer, 1)) 00041 return 0; 00042 00043 //Read data packet 00044 read(pn532_packetbuffer, 12); 00045 //Check some basic stuff 00046 if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6)) { 00047 return 0; 00048 } 00049 response = pn532_packetbuffer[6]; 00050 response <<= 8; 00051 response |= pn532_packetbuffer[7]; 00052 response <<= 8; 00053 response |= pn532_packetbuffer[8]; 00054 response <<= 8; 00055 response |= pn532_packetbuffer[9]; 00056 return response; 00057 } 00058 00059 bool PN532::SAMConfig(void) 00060 { 00061 pn532_packetbuffer[0] = PN532_SAMCONFIGURATION; 00062 pn532_packetbuffer[1] = 0x01; // normal mode; 00063 pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second 00064 pn532_packetbuffer[3] = 0x01; // use IRQ pin! 00065 00066 if (! sendCommandCheckAck(pn532_packetbuffer, 4)) 00067 return false; 00068 00069 // read data packet 00070 read(pn532_packetbuffer, 8); 00071 00072 return (pn532_packetbuffer[5] == 0x15); 00073 } 00074 00075 00076 uint32_t PN532::configurePeerAsInitiator(void) 00077 { 00078 pn532_packetbuffer[0] = PN532_INJUMPFORDEP; 00079 pn532_packetbuffer[1] = 0x01; //Active Mode 00080 pn532_packetbuffer[2] = 2;// Use 1 or 2 424 kb/s. 00081 pn532_packetbuffer[3] = 0x01; //Indicates Optional Payload is present 00082 00083 //Polling request payload 00084 pn532_packetbuffer[4] = 0x00; 00085 pn532_packetbuffer[5] = 0xFF; 00086 pn532_packetbuffer[6] = 0xFF; 00087 pn532_packetbuffer[7] = 0x00; 00088 pn532_packetbuffer[8] = 0x00; 00089 00090 if (!sendCommandCheckAck(pn532_packetbuffer, 9)) { 00091 return false; 00092 } 00093 // read data packet 00094 read(pn532_packetbuffer, 19+6); 00095 00096 // check the response 00097 00098 return (pn532_packetbuffer[7] == 0x00); //No error 00099 00100 } 00101 00102 uint32_t PN532::configurePeerAsTarget() 00103 { 00104 uint8_t pbuffer[38] = { 00105 PN532_TGINITASTARGET, 00106 0x00, 00107 0x08, 0x00, //SENS_RES 00108 0x12, 0x34, 0x56, //NFCID1 00109 0x40, //SEL_RES 00110 0x01, 0xFE, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, // POL_RES 00111 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 00112 0xFF, 0xFF, 00113 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, //NFCID3t: Change this to desired value 00114 0x00, 0x00 //Length of general and historical bytes 00115 }; 00116 for(uint8_t i = 0; i < 38; i ++) { 00117 pn532_packetbuffer[i] = pbuffer[i]; 00118 } 00119 00120 if (! sendCommandCheckAck(pn532_packetbuffer, 38)) { 00121 return false; 00122 00123 } 00124 // read data packet 00125 read(pn532_packetbuffer, 18+6); 00126 return (pn532_packetbuffer[23] == 0x00); //No error as it received all response 00127 } 00128 00129 bool PN532::initiatorTxRx(char* dataOut,char* dataIn) 00130 { 00131 pn532_packetbuffer[0] = PN532_INDATAEXCHANGE; 00132 pn532_packetbuffer[1] = 0x01; //Target 01 00133 00134 for(uint8_t iter=(2+0); iter<(2+16); iter++) { 00135 pn532_packetbuffer[iter] = dataOut[iter-2]; //pack the data to send to target 00136 } 00137 00138 if (! sendCommandCheckAck(pn532_packetbuffer, 18)) 00139 return false; 00140 00141 // read data packet 00142 read(pn532_packetbuffer, 18+6); 00143 00144 for(uint8_t iter=8; iter<(8+16); iter++) { 00145 dataIn[iter-8] = pn532_packetbuffer[iter]; //data received from target 00146 } 00147 00148 return (pn532_packetbuffer[7] == 0x00); //No error 00149 } 00150 00151 uint32_t PN532::targetTxRx(char* dataOut,char* dataIn) 00152 { 00153 /* Receiving from Initiator */ 00154 pn532_packetbuffer[0] = PN532_TGGETDATA; 00155 if (! sendCommandCheckAck(pn532_packetbuffer, 1)) 00156 return false; 00157 00158 // read data packet 00159 read(pn532_packetbuffer, 18+6); 00160 00161 for(uint8_t iter=8; iter<(8+16); iter++) { 00162 dataIn[iter-8] = pn532_packetbuffer[iter]; //data received from initiator 00163 } 00164 00165 /* Sending to Initiator */ 00166 if(pn532_packetbuffer[7] == 0x00) { //If no errors in receiving, send data. 00167 pn532_packetbuffer[0] = PN532_TGSETDATA; 00168 for(uint8_t iter=(1+0); iter<(1+16); iter++) { 00169 pn532_packetbuffer[iter] = dataOut[iter-1]; //pack the data to send to target 00170 } 00171 00172 if (! sendCommandCheckAck(pn532_packetbuffer, 17)) 00173 return false; 00174 00175 // read data packet 00176 read(pn532_packetbuffer, 2+6); 00177 00178 return (pn532_packetbuffer[7] == 0x00); //No error 00179 } 00180 return true; 00181 } 00182 00183 bool PN532::sendCommandCheckAck(uint8_t* cmd, uint8_t cmd_len, uint16_t timeout) 00184 { 00185 uint16_t timer = 0; 00186 // write the command 00187 writeCommand(cmd, cmd_len); 00188 // Wait for chip to say it's ready! 00189 00190 00191 while (readSpiStatus() != PN532_SPI_READY) { 00192 00193 if (timeout != 0) { 00194 timer+=10; 00195 if (timer > timeout) 00196 return false; 00197 } 00198 wait_ms(10); 00199 } 00200 00201 00202 // read acknowledgement 00203 if (!checkSpiAck()) { 00204 return false; 00205 } 00206 00207 timer = 0; 00208 // Wait for chip to say its ready! 00209 while (readSpiStatus() != PN532_SPI_READY) { 00210 00211 if (timeout != 0) { 00212 timer+=10; 00213 if (timer > timeout) 00214 return false; 00215 } 00216 wait_ms(10); 00217 } 00218 return true; // ack'd command 00219 } 00220 00221 void PN532::writeCommand(uint8_t buf[], uint8_t len) 00222 { 00223 uint8_t checksum; 00224 len++; 00225 checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2; 00226 00227 *_ss=0; 00228 00229 write(PN532_SPI_DATAWRITE); 00230 write(PN532_PREAMBLE); 00231 write(PN532_STARTCODE1); 00232 write(PN532_STARTCODE2); 00233 write(len); 00234 uint8_t cmdlen_1=~len + 1; 00235 write(cmdlen_1); 00236 write(PN532_HOSTTOPN532); 00237 checksum += PN532_HOSTTOPN532; 00238 00239 for (uint8_t i=0; i<len-1; i++) { 00240 write(buf[i]); 00241 checksum += buf[i]; 00242 } 00243 uint8_t checksum_1=~checksum; 00244 write(checksum_1); 00245 write(PN532_POSTAMBLE); 00246 *_ss = 1; 00247 } 00248 00249 uint8_t PN532::read(uint8_t buff[], uint8_t n) 00250 { 00251 uint8_t response; 00252 *_ss = 0; 00253 write(PN532_SPI_DATAREAD); 00254 for (uint8_t i=0; i < n; i ++) { 00255 wait_ms(1); 00256 buff[i] = read(); 00257 } 00258 *_ss= 1; 00259 response = read(); 00260 return response; 00261 } 00262 00263 00264 bool PN532::checkSpiAck(void) 00265 { 00266 uint8_t ackbuff[6]; 00267 read(ackbuff, 6); 00268 return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6)); 00269 } 00270 00271 uint8_t PN532::readSpiStatus(void) 00272 { 00273 *_ss = 0; 00274 wait_ms(2); 00275 write(PN532_SPI_STATREAD); 00276 uint8_t status = read(); 00277 *_ss=1; 00278 return status; 00279 }
Generated on Wed Jul 13 2022 10:41:14 by
1.7.2