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!
PN532/MuNFCMbedPlatform.cpp
- Committer:
- AppNearMe
- Date:
- 2012-07-26
- Revision:
- 2:913eb8fdfd9d
- Parent:
- 0:480387549d89
- Child:
- 3:0b949b2d3b55
File content as of revision 2:913eb8fdfd9d:
/* 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); } }