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
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!
Diff: PN532/MuNFCMbedPlatform.cpp
- Revision:
- 11:5be631376e5b
- Child:
- 13:6f98851e025b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PN532/MuNFCMbedPlatform.cpp Wed Nov 07 18:19:09 2012 +0000 @@ -0,0 +1,337 @@ +/* + MuNFCMbedPlatform.cpp + Copyright (c) Donatien Garnier 2012 + donatien.garnier@appnearme.com + http://www.appnearme.com/ + */ + +#include "mbed.h" + +#include "MuNFCConfig.h" +#include "munfc/nfc_config.h" + +#if MUNFC_RTOS +#include "rtos/rtos.h" +#endif + +InterruptIn* nfc_irq_pin_isr; +DigitalOut* nfc_cs_pin; +SPI* nfc_spi; + +extern "C" +{ +#if NFC_CONTROLLER == PN512 +#include "munfc/platform/pn512_platform.h" +#elif NFC_CONTROLLER == PN532 +#include "munfc/platform/pn532_platform.h" +#endif +#include "munfc/platform/rtos.h" + +#if NFC_CONTROLLER == PN512 +void pn512_io_init() +{ + nfc_irq_pin_isr->rise(pn512_irq); + *nfc_cs_pin = 1; +} + +/* + * Get the IRQ pin's state + */ +bool pn512_irq_pin_get() +{ + //return (nfc_irq_pin_int->read() ? true : false); + return (nfc_irq_pin_isr->read() ? true : false); +} + +/* + * Set the CS pin to 0 (active low) + */ +void pn512_cs_set() +{ + *nfc_cs_pin = 0; +} + +/* + * Set the CS pin to 1 (active high) + */ +void pn512_cs_clear() +{ + *nfc_cs_pin = 1; +} + +/* + * You MUST call pn512_irq() on each raising front of IRQ pin + */ +#endif + +#if NFC_CONTROLLER == PN532 +/* + * Init + */ +void pn532_io_init(void) +{ + nfc_irq_pin_isr->mode(PullUp); + nfc_irq_pin_isr->fall(pn532_irq); + *nfc_cs_pin = 1; +} + +/* + * Get the IRQ pin's state + */ +bool pn532_irq_pin_get(void) +{ + return (nfc_irq_pin_isr->read() ? false : true); +} + +/* + * Set the CS pin to 0 (active low) + */ +void pn532_cs_set(void) +{ + *nfc_cs_pin = 0; +} + +/* + * Set the CS pin to 1 (active high) + */ +void pn532_cs_clear(void) +{ + *nfc_cs_pin = 1; +} + +/* + * You MUST call pn532_irq() on each falling front of IRQ pin + */ +#endif + +#if MUNFC_RTOS +struct rtos_semaphore //To be defined by impl +{ + Semaphore* s; +}; + +struct rtos_semaphore* rtos_semaphore_new() //Should return NULL if fails +{ + struct rtos_semaphore* pSem; + pSem = new struct rtos_semaphore; + pSem->s = new Semaphore(1); + pSem->s->wait(osWaitForever); + return pSem; +} + +int rtos_semaphore_produce(struct rtos_semaphore* pSem) +{ + pSem->s->release(); + return OK; +} + +int rtos_semaphore_consume(struct rtos_semaphore* pSem, int timeout) +{ + int resid; + if(timeout == -1) + { + resid = pSem->s->wait(osWaitForever); + } + else + { + resid = pSem->s->wait(timeout); + } + if(resid>0) + { + while( pSem->s->wait(0) > 0 ); + return OK; + } + else + { + return ERR_TIMEOUT; + } +} +#else +struct rtos_semaphore //To be defined by impl +{ + volatile int p; +}; + +struct rtos_semaphore* rtos_semaphore_new() //Should return NULL if fails +{ + struct rtos_semaphore* pSem; + pSem = new struct rtos_semaphore; + pSem->p = 1; + return pSem; +} + +//Will only be called from ISR +int rtos_semaphore_produce(struct rtos_semaphore* pSem) +{ + pSem->p++; + return OK; +} + +void ___voidf(void) +{ + +} + +int rtos_semaphore_consume(struct rtos_semaphore* pSem, int timeout) +{ + if(timeout == -1) + { + while(!pSem->p) + { + __WFI(); + } + pSem->p--; + } + else if(timeout == 0) + { + if(pSem->p) + { + pSem->p--; + } + else + { + return ERR_TIMEOUT; + } + } + else + { + Timer t; + t.start(); + Ticker t_isr; + t_isr.attach_us(&___voidf, 1000); //Just to generate an interrupt periodically + while(!pSem->p) + { + __WFI(); + if(t.read_ms()>=timeout) + { + return ERR_TIMEOUT; + } + } + pSem->p--; + } + return OK; +} +#endif + + +//These functions must be implemented for each platform + +#if NFC_CONTROLLER == PN512 +/* + * Initialize SPI + */ +int pn512_spi_init() +{ + nfc_spi->format(8, 3); + nfc_spi->frequency(10000000); //To change to 10000000 + return 0; +} +#endif + +#if NFC_CONTROLLER == PN532 +/* + * Initialize SPI + */ +int pn532_spi_init() +{ + nfc_spi->format(8, 0); + nfc_spi->frequency(5000000); + return 0; +} +#endif + +#define reverse(x) ( (x & 0x01) << 7 \ + | (x & 0x02) << 5 \ + | (x & 0x04) << 3 \ + | (x & 0x08) << 1 \ + | (x & 0x10) >> 1 \ + | (x & 0x20) >> 3 \ + | (x & 0x40) >> 5 \ + | (x & 0x80) >> 7 ) + +/* + * After skipping outSkip bytes, write outLen bytes + * After skipping inSkip bytes, read inLen bytes + * This will generate MAX(outSkip + outLen, inSkip + inLen) transfers on the SPI bus + */ +int spi_transfer(uint8_t* outBuf, size_t outLen, size_t outSkip, uint8_t* inBuf, + size_t inLen, size_t inSkip) +{ + int len; + int writeb; + int readb; + int outPos; + int inPos; + + outPos = inPos = 0; + + len = + (outSkip + outLen) > (inSkip + inLen) ? (outSkip + outLen) : + (inSkip + inLen); + + while (len--) + { + if (outSkip) + { + writeb = 0x00; + outSkip--; + } + else if (outPos < outLen) + { + writeb = outBuf[outPos]; + outPos++; + } + else + { + writeb = 0x00; + } + +#if NFC_CONTROLLER == PN532 + writeb = reverse(writeb); +#endif + + readb = nfc_spi->write(writeb); + +#if NFC_CONTROLLER == PN532 + readb = reverse(readb); +#endif + + if (inSkip) + { + inSkip--; + } + else if (inPos < inLen) + { + inBuf[inPos] = readb; + inPos++; + } + } + return 0; +} + +/* + * Write outLen bytes + */ +int spi_write(uint8_t* outBuf, size_t outLen) +{ + return spi_transfer(outBuf, outLen, 0, (uint8_t*) NULL, 0, 0); +} + +/* + * Read inLen bytes + */ +int spi_read(uint8_t* inBuf, size_t inLen) +{ + return spi_transfer((uint8_t*) NULL, 0, 0, inBuf, inLen, 0); +} + +/* + * Skip len bytes + */ +int spi_skip(size_t len) +{ + return spi_transfer((uint8_t*) NULL, 0, len, (uint8_t*) NULL, 0, len); +} + +} +