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:
- 2013-01-15
- Revision:
- 13:6f98851e025b
- Parent:
- 11:5be631376e5b
File content as of revision 13:6f98851e025b:
/*
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/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);
}
}
AppNearMe Official