Marius 90 / Mbed 2 deprecated pn532-SPI-p2p

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PN532.cpp Source File

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 }