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:
- 6:15b1c45d50d4
- Parent:
- 3:0b949b2d3b55
- Child:
- 9:621a03f8d2f3
diff -r 6aa189c3aa19 -r 15b1c45d50d4 PN532/MuNFCMbedPlatform.cpp --- a/PN532/MuNFCMbedPlatform.cpp Wed Aug 15 13:48:43 2012 +0000 +++ b/PN532/MuNFCMbedPlatform.cpp Thu Aug 16 15:35:56 2012 +0000 @@ -1,339 +1,365 @@ -/* - 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 - -//DigitalIn* nfc_irq_pin_int; -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->fall(pn532_irq); - *nfc_cs_pin = 1; -} - -/* - * Get the IRQ pin's state - */ -bool pn532_irq_pin_get(void) -{ - //return (nfc_irq_pin_int->read() ? false : true); - 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; - wait_us(10); -} - -/* - * 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) - { - 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--; - } - printf("OK\n"); - 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); -} - -} - +/* + 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 + +//DigitalIn* nfc_irq_pin_int; +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) +{ + #if defined( TARGET_LPC11U24 ) + nfc_irq_pin_isr->rise(pn532_irq); //Cannot trigger on falling edge + #else + nfc_irq_pin_isr->fall(pn532_irq); + #endif + *nfc_cs_pin = 1; +} + +/* + * Get the IRQ pin's state + */ +bool pn532_irq_pin_get(void) +{ + //return (nfc_irq_pin_int->read() ? false : true); + #if defined( TARGET_LPC11U24 ) + return (nfc_irq_pin_isr->read() ? true : false); + #else + return (nfc_irq_pin_isr->read() ? false : true); + #endif +} + +/* + * 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; + //wait_us(10); +} + +/* + * 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; +} + +DigitalOut led1(LED2); +DigitalOut led2(LED3); +DigitalOut led3(LED4); +int rtos_semaphore_produce(struct rtos_semaphore* pSem) +{ + static int count = 0; + count ++; + if(count >= 8) + count = 0; + + led1 = (count&1)?1:0; + led2 = (count&2)?1:0; + led3 = (count&4)?1:0; + + 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 ); + //printf("S\n"); + return OK; + } + else + { + //printf("T\n"); + 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 + + #if defined( TARGET_LPC11U24 ) + //wait_us(30); + #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); +} + +} +