AppNearMe µNFC stack for the NXP PN532 chip License: You can use the stack free of charge to prototype with mbed; if you want to use the stack with your commercial product, get in touch!

Dependents:   IOT_sensor_nfc AppNearMe_MuNFC_PN532_Test p2p_nfc_test NFCMoodLamp ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MuNFCMbedPlatform.cpp Source File

MuNFCMbedPlatform.cpp

00001 /*
00002  MuNFCMbedPlatform.cpp
00003  Copyright (c) Donatien Garnier 2012
00004  donatien.garnier@appnearme.com
00005  http://www.appnearme.com/
00006  */
00007 
00008 #include "mbed.h"
00009 
00010 #include "MuNFCConfig.h"
00011 #include "munfc/nfc_config.h"
00012 
00013 #if MUNFC_RTOS
00014 #include "rtos/rtos.h"
00015 #endif
00016 
00017 InterruptIn* nfc_irq_pin_isr;
00018 DigitalOut* nfc_cs_pin;
00019 SPI* nfc_spi;
00020 
00021 extern "C"
00022 {
00023 #if NFC_CONTROLLER == PN512
00024 #include "munfc/platform/pn512_platform.h"
00025 #elif NFC_CONTROLLER == PN532
00026 #include "munfc/platform/pn532_platform.h"
00027 #endif
00028 #include "munfc/platform/platform_rtos.h"
00029 
00030 #if NFC_CONTROLLER == PN512
00031 void pn512_io_init()
00032 {
00033   nfc_irq_pin_isr->rise(pn512_irq);
00034   *nfc_cs_pin = 1;
00035 }
00036 
00037 /*
00038  * Get the IRQ pin's state
00039  */
00040 bool pn512_irq_pin_get()
00041 {
00042   //return (nfc_irq_pin_int->read() ? true : false);
00043   return (nfc_irq_pin_isr->read() ? true : false);
00044 }
00045 
00046 /*
00047  * Set the CS pin to 0 (active low)
00048  */
00049 void pn512_cs_set()
00050 {
00051   *nfc_cs_pin = 0;
00052 }
00053 
00054 /*
00055  * Set the CS pin to 1 (active high)
00056  */
00057 void pn512_cs_clear()
00058 {
00059   *nfc_cs_pin = 1;
00060 }
00061 
00062 /*
00063  * You MUST call pn512_irq() on each raising front of IRQ pin
00064  */
00065 #endif
00066 
00067 #if NFC_CONTROLLER == PN532
00068 /*
00069  * Init
00070  */
00071 void pn532_io_init(void)
00072 {
00073   nfc_irq_pin_isr->mode(PullUp);
00074   nfc_irq_pin_isr->fall(pn532_irq);
00075   *nfc_cs_pin = 1;
00076 }
00077 
00078 /*
00079  * Get the IRQ pin's state
00080  */
00081 bool pn532_irq_pin_get(void)
00082 {
00083   return (nfc_irq_pin_isr->read() ? false : true);
00084 }
00085 
00086 /*
00087  * Set the CS pin to 0 (active low)
00088  */
00089 void pn532_cs_set(void)
00090 {
00091   *nfc_cs_pin = 0;
00092 }
00093 
00094 /*
00095  * Set the CS pin to 1 (active high)
00096  */
00097 void pn532_cs_clear(void)
00098 {
00099   *nfc_cs_pin = 1;
00100 }
00101 
00102 /*
00103  * You MUST call pn532_irq() on each falling front of IRQ pin
00104  */
00105 #endif
00106 
00107 #if MUNFC_RTOS
00108 struct rtos_semaphore //To be defined by impl
00109 {
00110   Semaphore* s;
00111 };
00112 
00113 struct rtos_semaphore* rtos_semaphore_new() //Should return NULL if fails
00114 {
00115   struct rtos_semaphore* pSem;
00116   pSem = new struct rtos_semaphore;
00117   pSem->s = new Semaphore(1);
00118   pSem->s->wait(osWaitForever);
00119   return pSem;
00120 }
00121 
00122 int rtos_semaphore_produce(struct rtos_semaphore* pSem)
00123 {
00124     pSem->s->release();
00125     return OK;
00126 }
00127 
00128 int rtos_semaphore_consume(struct rtos_semaphore* pSem, int timeout)
00129 {
00130     int resid;
00131     if(timeout == -1)
00132     {
00133       resid = pSem->s->wait(osWaitForever);
00134     }
00135     else
00136     {
00137       resid = pSem->s->wait(timeout);
00138     }
00139     if(resid>0)
00140     {
00141       while( pSem->s->wait(0) > 0 );
00142       return OK;
00143     }
00144     else
00145     {
00146       return ERR_TIMEOUT;
00147     }
00148 }
00149 #else
00150 struct rtos_semaphore //To be defined by impl
00151 {
00152     volatile int p;
00153 };
00154 
00155 struct rtos_semaphore* rtos_semaphore_new() //Should return NULL if fails
00156 {
00157   struct rtos_semaphore* pSem;
00158   pSem = new struct rtos_semaphore;
00159   pSem->p = 1;
00160   return pSem;
00161 }
00162 
00163 //Will only be called from ISR
00164 int rtos_semaphore_produce(struct rtos_semaphore* pSem)
00165 {
00166     pSem->p++;
00167     return OK;
00168 }
00169 
00170 void ___voidf(void)
00171 {
00172 
00173 }
00174 
00175 int rtos_semaphore_consume(struct rtos_semaphore* pSem, int timeout)
00176 {
00177    if(timeout == -1)
00178     {
00179       while(!pSem->p)
00180       {
00181         __WFI();
00182       }
00183       pSem->p--;
00184     }
00185     else if(timeout == 0)
00186     {
00187       if(pSem->p)
00188       {
00189         pSem->p--;
00190       }
00191       else
00192       {
00193         return ERR_TIMEOUT;
00194       }
00195     }
00196     else
00197     {
00198       Timer t;
00199       t.start();
00200       Ticker t_isr;
00201       t_isr.attach_us(&___voidf, 1000); //Just to generate an interrupt periodically
00202       while(!pSem->p)
00203       {
00204         __WFI();
00205         if(t.read_ms()>=timeout)
00206         {
00207             return ERR_TIMEOUT;
00208         }
00209       }
00210       pSem->p--;
00211     }
00212     return OK;
00213 }
00214 #endif
00215 
00216 
00217 //These functions must be implemented for each platform
00218 
00219 #if NFC_CONTROLLER == PN512
00220 /*
00221  * Initialize SPI
00222  */
00223 int pn512_spi_init()
00224 {
00225   nfc_spi->format(8, 3);
00226   nfc_spi->frequency(10000000); //To change to 10000000
00227   return 0;
00228 }
00229 #endif
00230 
00231 #if NFC_CONTROLLER == PN532
00232 /*
00233  * Initialize SPI
00234  */
00235 int pn532_spi_init()
00236 {
00237   nfc_spi->format(8, 0);
00238   nfc_spi->frequency(5000000);
00239   return 0;
00240 }
00241 #endif
00242 
00243 #define reverse(x) ( (x & 0x01) << 7 \
00244                     | (x & 0x02) << 5 \
00245                     | (x & 0x04) << 3 \
00246                     | (x & 0x08) << 1 \
00247                     | (x & 0x10) >> 1 \
00248                     | (x & 0x20) >> 3 \
00249                     | (x & 0x40) >> 5 \
00250                     | (x & 0x80) >> 7 )
00251 
00252 /*
00253  * After skipping outSkip bytes, write outLen bytes
00254  * After skipping inSkip bytes, read inLen bytes
00255  * This will generate MAX(outSkip + outLen, inSkip + inLen) transfers on the SPI bus
00256  */
00257 int spi_transfer(uint8_t* outBuf, size_t outLen, size_t outSkip, uint8_t* inBuf,
00258     size_t inLen, size_t inSkip)
00259 {
00260   int len;
00261   int writeb;
00262   int readb;
00263   int outPos;
00264   int inPos;
00265 
00266   outPos = inPos = 0;
00267 
00268   len =
00269       (outSkip + outLen) > (inSkip + inLen) ? (outSkip + outLen) :
00270           (inSkip + inLen);
00271 
00272   while (len--)
00273   {
00274     if (outSkip)
00275     {
00276       writeb = 0x00;
00277       outSkip--;
00278     }
00279     else if (outPos < outLen)
00280     {
00281       writeb = outBuf[outPos];
00282       outPos++;
00283     }
00284     else
00285     {
00286       writeb = 0x00;
00287     }
00288 
00289 #if NFC_CONTROLLER == PN532
00290     writeb = reverse(writeb);
00291 #endif
00292 
00293     readb = nfc_spi->write(writeb);
00294 
00295 #if NFC_CONTROLLER == PN532
00296     readb = reverse(readb);
00297 #endif
00298 
00299     if (inSkip)
00300     {
00301       inSkip--;
00302     }
00303     else if (inPos < inLen)
00304     {
00305       inBuf[inPos] = readb;
00306       inPos++;
00307     }
00308   }
00309   return 0;
00310 }
00311 
00312 /*
00313  * Write outLen bytes
00314  */
00315 int spi_write(uint8_t* outBuf, size_t outLen)
00316 {
00317   return spi_transfer(outBuf, outLen, 0, (uint8_t*) NULL, 0, 0);
00318 }
00319 
00320 /*
00321  * Read inLen bytes
00322  */
00323 int spi_read(uint8_t* inBuf, size_t inLen)
00324 {
00325   return spi_transfer((uint8_t*) NULL, 0, 0, inBuf, inLen, 0);
00326 }
00327 
00328 /*
00329  * Skip len bytes
00330  */
00331 int spi_skip(size_t len)
00332 {
00333   return spi_transfer((uint8_t*) NULL, 0, len, (uint8_t*) NULL, 0, len);
00334 }
00335 
00336 }
00337