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!

Files at this revision

API Documentation at this revision

Comitter:
AppNearMe
Date:
Wed Nov 07 18:19:09 2012 +0000
Parent:
10:2af578c635cd
Child:
12:6eddbfe6b015
Commit message:
Updated library

Changed in this revision

PN532/EventCallback.cpp Show annotated file Show diff for this revision Revisions of this file
PN532/EventCallback.h Show annotated file Show diff for this revision Revisions of this file
PN532/MuNFC.cpp Show annotated file Show diff for this revision Revisions of this file
PN532/MuNFC.h Show annotated file Show diff for this revision Revisions of this file
PN532/MuNFCMbedPlatform.cpp Show annotated file Show diff for this revision Revisions of this file
PN532/NFCEvent.h Show annotated file Show diff for this revision Revisions of this file
PN532/NdefCallback.cpp Show annotated file Show diff for this revision Revisions of this file
PN532/NdefCallback.h Show annotated file Show diff for this revision Revisions of this file
PN532/TLVList.cpp Show annotated file Show diff for this revision Revisions of this file
PN532/TLVList.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/core/buffer.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/core/debug.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/core/errors.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/core/fwk.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/drv/pn532/pn532.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/ndef/appnearme_ndef.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/ndef/appnearme_ndef_tlv.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/nfc_config.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/platform/pn532_platform.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/platform/rtos.h Show annotated file Show diff for this revision Revisions of this file
PN532/munfc/platform/spi.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/EventCallback.cpp	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,47 @@
+/*
+    EventCallback.cpp 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+#include "EventCallback.h"
+
+EventCallback::EventCallback()
+{
+
+}
+
+void EventCallback::init(void (*fn)(transaction_event_callback, void*))
+{
+  fn(staticCallback, this);
+}
+
+void EventCallback::attach(void (*fn)(NFCEvent, void*), void* arg)
+{
+  m_inst = NULL;
+  m_fn = fn;
+  m_arg = arg;
+}
+
+void EventCallback::callback(transaction_event event, transaction_type type)
+{
+  if(m_inst)
+  {
+    m_caller(this, (NFCEvent)event); //At some point, should not cast event directly
+  }
+  else if(m_fn)
+  {
+    m_fn((NFCEvent)event, m_arg);
+  }
+}
+
+/*static*/ void EventCallback::staticCallback(transaction_event event, transaction_type type, void* param)
+{
+  ((EventCallback*)(param))->callback(event, type);
+}
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/EventCallback.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,65 @@
+/*
+    EventCallback.h 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+
+#ifndef EVENTCALLBACK_H_
+#define EVENTCALLBACK_H_
+
+#include "NFCEvent.h"
+
+#include "munfc/core/fwk.h"
+#include "munfc/event/transaction_event.h"
+
+class EventCallback
+{
+protected:
+  EventCallback();
+
+  void init( void (*fn)(transaction_event_callback, void*) ); //Callable by MuNFC
+
+  void attach(void (*fn)(NFCEvent, void*), void* arg);
+
+  template <class T>
+  void attach(T* inst, void (T::*member)(NFCEvent))
+  {
+    m_fn = NULL;
+    m_inst = inst;
+    memcpy(m_pMember, (char*)&member, sizeof(member));
+    m_caller = &EventCallback::memberCaller<T>;
+  }
+
+
+private:
+  void callback(transaction_event event, transaction_type type);
+
+  //Function
+  void(*m_fn)(NFCEvent, void*);
+  void* m_arg;
+
+
+  //Member of object instance
+  void* m_inst;
+  char m_pMember[16];
+  void (*m_caller)(EventCallback*, NFCEvent);
+
+  template <class T>
+  static inline void memberCaller(EventCallback* p, NFCEvent event)
+  {
+    T* inst = (T*) p->m_inst;
+    void (T::*member)(NFCEvent);
+    memcpy(&member, p->m_pMember, sizeof(member));
+    (inst->*member)(event);
+  }
+
+  static void staticCallback(transaction_event event, transaction_type type, void* param);
+
+  friend class MuNFC;
+};
+
+
+
+#endif /* EVENTCALLBACK_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/MuNFC.cpp	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,114 @@
+/*
+    MuNFC.cpp
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+
+#include "MuNFC.h"
+#include "MuNFCConfig.h"
+
+#include "mbed.h"
+#if MUNFC_RTOS
+#include "rtos/rtos.h"
+#endif
+
+#include "munfc/core/fwk.h"
+#include "munfc/event/transaction_event.h"
+#include "munfc/target/target_nfctype2.h"
+#include "munfc/target/target_nfctype4.h"
+#include "munfc/ndef/appnearme_ndef.h"
+#include "munfc/ndef/appnearme_ndef_tlv.h"
+
+#include <cstring> //For memcpy, strlen
+
+//TODO add handles in NFC stack to avoid ugly things like that
+//extern DigitalIn* nfc_irq_pin_int;
+extern InterruptIn* nfc_irq_pin_isr;
+extern DigitalOut* nfc_cs_pin;
+extern SPI* nfc_spi;
+
+#define SIGNAL_START 0x01
+
+MuNFC::MuNFC(char appHash[16], uint32_t version,
+    PinName mosi, PinName miso, PinName sclk, PinName cs, PinName isr) :
+   /* m_irq_pin_int(isr),*/ m_irq_pin_isr(isr), m_cs_pin(cs), m_spi(mosi, miso, sclk)
+#if MUNFC_RTOS
+  , m_pThread(NULL)//m_thread(MuNFC::staticCallback, (void*)this)
+#endif
+{
+  //nfc_irq_pin_int = &m_irq_pin_int;
+  nfc_irq_pin_isr = &m_irq_pin_isr;
+  nfc_cs_pin = &m_cs_pin;
+  nfc_spi = &m_spi;
+
+  appnearme_ndef_init(appHash, version);
+  m_eventCb.init(transaction_event_register_callback);
+  m_encodeCb.init(appnearme_ndef_register_encode_callback);
+  m_decodeCb.init(appnearme_ndef_register_decode_callback);
+}
+
+MuNFC::~MuNFC()
+{
+  #if MUNFC_RTOS
+  if(m_pThread != NULL)
+  {
+    delete m_pThread;
+  }
+  #endif
+}
+
+bool MuNFC::init()
+{
+  #if MUNFC_RTOS
+  if(m_pThread == NULL)
+  {
+    m_pThread = new Thread(MuNFC::staticCallback, (void*)this);
+  }
+  #endif
+
+#if NFC_CONTROLLER == PN512
+  int ret = target_nfctype2_start();
+#elif NFC_CONTROLLER == PN532
+  int ret = target_nfctype4_start();
+#endif
+  if(ret != OK)
+  {
+    return false;
+  }
+  return true;
+}
+
+#if MUNFC_RTOS
+void MuNFC::run()
+{
+  //Start NFC thread
+  m_pThread->signal_set(SIGNAL_START);
+}
+
+void MuNFC::process()
+{
+  Thread::signal_wait(SIGNAL_START);
+  do
+  {
+    poll(-1);
+  } while(true);
+}
+#endif
+
+void MuNFC::poll(int timeoutMs) //TODO add Timeout
+{
+#if NFC_CONTROLLER == PN512
+    target_nfctype2_process();
+#elif NFC_CONTROLLER == PN532
+    target_nfctype4_process();
+#endif
+}
+
+#if MUNFC_RTOS
+  /*static*/ void MuNFC::staticCallback(void const* p)
+  {
+    ((MuNFC*)p)->process();
+  }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/MuNFC.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,178 @@
+/*
+    MuNFC.h
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+
+#ifndef MUNFC_H_
+#define MUNFC_H_
+
+#include "MuNFCConfig.h"
+
+#include <cstdint> //For uint_*t
+#include <cstring> //For size_t
+
+using std::uint8_t;
+using std::uint16_t;
+using std::uint32_t;
+using std::size_t;
+
+#include "NFCEvent.h"
+#include "NdefCallback.h"
+#include "EventCallback.h"
+#include "TLVList.h"
+
+#include "mbed.h"
+#if MUNFC_RTOS
+#include "rtos/rtos.h"
+#endif
+
+/** A library for embedded NFC applications using NXP's PN512/PN532 NFC transceivers.
+* Visit http://www.appnearme.com/
+*/
+class MuNFC
+{
+public:
+
+
+  /** Instantiate the µNFC stack for the following mobile app and using the following PN512/PN532 chip.
+   * @param appHash 16 chars-long hash of the corresponding mobile app
+   * @param version Minimum version of the mobile app to use in BCD format encoded as an uint32_t (0x01000000 is version 1.0.0.0)
+   * @param mosi MOSI pin of the SPI interface
+   * @param miso MISO pin of the SPI interface
+   * @param sclk SCLK pin of the SPI interface
+   * @param cs CS pin connected to the chip
+   * @param isr ISR pin connected to the chip
+   */
+  MuNFC(char appHash[16], uint32_t version,
+      PinName mosi, PinName miso, PinName sclk, PinName cs, PinName isr);
+
+  ~MuNFC();
+
+  /** Set Encode Callback.
+   *  The encode callback will be called on each start of NFC transaction.
+   *  to populate the data structure that will be transmitted to the reader
+   *  @param fn pointer to the function to be called
+   *  @param arg argument that will be passed to the callback
+   */
+  inline void encode(void (*fn)(TLVList*, void*), void* arg)
+  {
+    m_encodeCb.attach(fn, arg);
+  }
+
+  /** Set Encode Callback.
+   *  The encode callback will be called on each start of NFC transaction.
+   *  to populate the data structure that will be transmitted to the reader
+   *  @param inst pointer to the object on which to call the member
+   *  @param member pointer to the object's member to be called
+   */
+  template <class T>
+  inline void encode(T* inst, void (T::*member)(TLVList*))
+  {
+    m_encodeCb.attach(inst, member);
+  }
+
+  /** Set Decode Callback.
+   *  The decode callback will be called on each successful termination of NFC transaction.
+   *  populated with the data structure that was transmitted by the reader
+   *  @param fn pointer to the function to be called
+   *  @param arg argument that will be passed to the callback
+   */
+  inline void decode(void (*fn)(TLVList*, void*), void* arg)
+  {
+    m_decodeCb.attach(fn, arg);
+  }
+
+  /** Set Decode Callback.
+   *  The decode callback will be called on each successful termination of NFC transaction.
+   *  populated with the data structure that was transmitted by the reader
+   *  @param inst pointer to the object on which to call the member
+   *  @param member pointer to the object's member to be called
+   */
+  template <class T>
+  inline void decode(T* inst, void (T::*member)(TLVList*))
+  {
+    m_decodeCb.attach(inst, member);
+  }
+
+  /** Set Event Callback.
+   *  The event callback will be called on each of the following event:
+   *  - Transaction started
+   *  - Transaction successful
+   *  - Transaction failed
+   *  @param fn pointer to the function to be called
+   *  @param arg argument that will be passed to the callback
+   */
+  inline void event(void (*fn)(NFCEvent, void*), void* arg)
+  {
+    m_eventCb.attach(fn, arg);
+  }
+
+  /** Set Event Callback.
+   *  The event callback will be called on each of the following event:
+   *  - Transaction started
+   *  - Transaction successful
+   *  - Transaction failed
+   *  @param fn pointer to the function to be called
+   *  @param arg argument that will be passed to the callback
+   */
+  template <class T>
+  inline void event(T* inst, void (T::*member)(NFCEvent))
+  {
+    m_eventCb.attach(inst, member);
+  }
+
+  /** Initialize stack.
+   *  @return true if stack was initialized correctly, false otherwise
+   */
+  bool init();
+
+//#if MUNFC_RTOS -- flags must be disabled for proper doxygen support
+  /** Start NFC thread (threaded mode)
+   *
+   */
+  void run();
+//#endif
+
+#if MUNFC_RTOS
+protected:
+  /** NFC Thread
+   *
+   */
+  void process();
+#endif
+
+#if MUNFC_RTOS
+  protected:
+#else
+  public:
+#endif
+  /** Poll for NFC reader (polling mode).
+   *  @param timeoutMs (maximum polling time)
+   */
+  void poll(int timeoutMs);
+
+private:
+#if MUNFC_RTOS
+  static void staticCallback(void const* p);
+#endif
+
+  NdefCallback m_encodeCb;
+  NdefCallback m_decodeCb;
+  EventCallback m_eventCb;
+
+  //DigitalIn m_irq_pin_int;
+  InterruptIn m_irq_pin_isr;
+  DigitalOut m_cs_pin;
+  SPI m_spi;
+
+#if MUNFC_RTOS
+  Thread* m_pThread;
+#endif
+
+};
+
+
+#endif /* MUNFC_H_ */
--- /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);
+}
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/NFCEvent.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,25 @@
+/*
+    NFCEvent.h 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+/** \file NFCEvent.h
+*    NFC-related events
+*/
+
+#ifndef NFCEVENT_H_
+#define NFCEVENT_H_
+
+/** NFC-related events
+ *
+ */
+enum NFCEvent
+{
+  NFC_TRANSACTION_STARTED, //!< Transaction with reader started (anticollision successful)
+  NFC_TRANSACTION_SUCCESSFUL, //!< Transaction with reader successful
+  NFC_TRANSACTION_FAILED //!< Transaction with reader failed
+};
+
+#endif /* NFCEVENT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/NdefCallback.cpp	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,46 @@
+/*
+    NdefCallback.cpp 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+#include "NdefCallback.h"
+#include "TLVList.h"
+
+NdefCallback::NdefCallback()
+{
+
+}
+
+void NdefCallback::init(void (*fn)(appnearme_ndef_callback, void*))
+{
+  fn(staticCallback, this);
+}
+
+void NdefCallback::attach(void (*fn)(TLVList*, void*), void* arg)
+{
+  m_inst = NULL;
+  m_fn = fn;
+  m_arg = arg;
+}
+
+void NdefCallback::callback(tlv_list* payload)
+{
+  m_tlvList.wrap(payload);
+  if(m_inst)
+  {
+    m_caller(this, &m_tlvList);
+  }
+  else if(m_fn)
+  {
+    m_fn(&m_tlvList, m_arg);
+  }
+}
+
+/*static*/ void NdefCallback::staticCallback(tlv_list* payload, void* param)
+{
+  ((NdefCallback*)(param))->callback(payload);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/NdefCallback.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,65 @@
+/*
+    NdefCallback.h 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+
+#ifndef NDEFCALLBACK_H_
+#define NDEFCALLBACK_H_
+
+#include "TLVList.h"
+
+#include "munfc/core/fwk.h"
+#include "munfc/ndef/appnearme_ndef.h"
+
+class NdefCallback
+{
+protected:
+  NdefCallback(); //Callable by MuNFC
+
+  void init(void (*fn)(appnearme_ndef_callback, void*));
+
+  void attach(void (*fn)(TLVList*, void*), void* arg);
+
+  template <class T>
+  void attach(T* inst, void (T::*member)(TLVList*))
+  {
+    m_fn = NULL;
+    m_inst = inst;
+    memcpy(m_pMember, (char*)&member, sizeof(member));
+    m_caller = &NdefCallback::memberCaller<T>;
+  }
+
+private:
+  void callback(tlv_list* payload);
+
+  //Data
+  TLVList m_tlvList;
+
+  //Function
+  void(*m_fn)(TLVList*, void*);
+  void* m_arg;
+
+  //Member of object instance
+  void* m_inst;
+  char m_pMember[16];
+  void (*m_caller)(NdefCallback*, TLVList*);
+
+  template <class T>
+  static inline void memberCaller(NdefCallback* p, TLVList* tlvList)
+  {
+    T* inst = (T*) (p->m_inst);
+    void (T::*member)(TLVList*);
+    memcpy(&member, p->m_pMember, sizeof(member));
+    (inst->*member)(tlvList);
+  }
+
+  static void staticCallback(tlv_list* payload, void* param);
+
+  friend class MuNFC;
+};
+
+
+#endif /* NDEFCALLBACK_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/TLVList.cpp	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,246 @@
+/*
+    TLVList.cpp 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+#include "TLVList.h"
+
+#include "munfc/core/fwk.h"
+#include "munfc/ndef/appnearme_ndef_tlv.h"
+
+#include <cstring> //For memcpy, strlen
+using std::memcpy;
+using std::strlen;
+
+TLVList::TLVList() : m_tlvList(NULL)
+{
+
+}
+
+void TLVList::wrap(tlv_list* payload)
+{
+  m_tlvList = payload;
+  m_space = true;
+  m_type = NONE;
+}
+
+
+
+/* Getters */
+
+/** Iterate to next item
+ *  @return type if next item exists, NONE otherwise
+ */
+TLVList::TLVType TLVList::getNext()
+{
+  if(!m_tlvList)
+  {
+    return NONE;
+  }
+
+  m_type = (TLVList::TLVType) appnearme_ndef_tlv_next_type(m_tlvList); //Explicit cast, this is the same enum
+  switch(m_type)
+  {
+  case UINT8:
+    m_arrayLen = 0;
+    m_uint8 = appnearme_ndef_tlv_get_uint8(m_tlvList);
+    break;
+  case UINT32:
+    m_arrayLen = 0;
+    m_uint32 = appnearme_ndef_tlv_get_uint32(m_tlvList);
+    break;
+  case UINT8_ARRAY:
+    //In this order, otherwise would break state-machine
+    m_arrayLen = appnearme_ndef_tlv_get_array_length(m_tlvList);
+    m_array = appnearme_ndef_tlv_get_array(m_tlvList);
+    break;
+  case STRING:
+    //In this order, otherwise would break state-machine
+    m_strLen = appnearme_ndef_tlv_get_string_length(m_tlvList);
+    m_str = appnearme_ndef_tlv_get_string(m_tlvList);
+    break;
+  }
+  return m_type;
+}
+
+/** Get current item's type.
+*  @return type if item exists, NONE otherwise
+*/
+TLVList::TLVType TLVList::getType()
+{
+  return m_type;
+}
+
+/** Get uint8_t value
+ * If the current item's type is uint32_t, the value will be masked with 0xFF
+ *  @return uint8_t value OR 0 if the type is incompatible
+ */
+uint8_t TLVList::getUInt8()
+{
+  switch(m_type)
+  {
+  case UINT8:
+    return m_uint8;
+  case UINT32:
+    return m_uint32 & 0xFF;
+  default:
+    return 0;
+  }
+}
+
+/** Get uint32_t value
+ * If the current item's type is uint8_t, the value will be casted to uint32_t
+ *  @return uint32_t value OR 0 if the type is incompatible
+ */
+uint32_t TLVList::getUInt32()
+{
+  switch(m_type)
+  {
+  case UINT32:
+    return m_uint32;
+  case UINT8:
+    return m_uint8 & 0xFF;
+  default:
+    return 0;
+  }
+}
+
+/** Get array length
+ *  @return bytes array length
+ */
+size_t TLVList::getArrayLength()
+{
+  switch(m_type)
+  {
+  case UINT8_ARRAY:
+    return m_arrayLen;
+  default:
+    return 0;
+  }
+}
+
+/** Get array
+ *  @param buf pointer to buffer's start
+ *  @param maxLen maximum number of bytes to copy
+ *  @return number of copied bytes
+ */
+size_t TLVList::getArray(uint8_t* buf, size_t maxLen)
+{
+  if(m_type != UINT8_ARRAY)
+  {
+    return 0;
+  }
+  size_t len = MIN(maxLen, m_arrayLen);
+  memcpy(buf, m_array, len);
+  return len;
+}
+
+/** Get string length
+ *  @return string length
+ */
+size_t TLVList::getStringLength()
+{
+  switch(m_type)
+  {
+  case STRING:
+    return m_strLen;
+  default:
+    return 0;
+  }
+}
+
+
+/** Get string
+ *  Copy string to buffer (including null-terminating char)
+ *  @param str pointer to string's start
+ *  @param maxLen maximum number of chars to copy (not including null-terminating char)
+ *  @return number of copied chars
+ */
+size_t TLVList::getString(char* str, size_t maxLen)
+{
+  if(m_type != STRING)
+  {
+    return 0;
+  }
+  size_t len = MIN(maxLen, m_strLen);
+  memcpy(str, m_str, len);
+  str[len] = '\0'; //Add null-terminating char
+  return len;
+}
+
+/* Setters */
+
+/** Check whether there is space left in list
+ *  @return true if there is space left, false otherwise
+ */
+bool TLVList::isSpace()
+{
+  return m_space;
+}
+
+/** Put uint8_t value
+ *  @param value uint8_t value
+ *  @return true on success, false if there is not enough space in buffer
+ */
+bool TLVList::putUInt8(uint8_t value)
+{
+  int res = appnearme_ndef_tlv_put_uint8(m_tlvList, value);
+  if( !res )
+  {
+    m_space = false;
+    return false;
+  }
+  return true;
+}
+
+/** Put uint32_t value
+ *  @param value uint32_t value
+ *  @return true on success, false if there is not enough space in buffer
+ */
+bool TLVList::putUInt32(uint32_t value)
+{
+  int res = appnearme_ndef_tlv_put_uint32(m_tlvList, value);
+  if( !res )
+  {
+    m_space = false;
+    return false;
+  }
+  return true;
+}
+
+/** Put array
+ *  @param buf pointer to buffer's start
+ *  @param len number of bytes to copy
+ *  @return number of copied bytes
+ */
+size_t TLVList::putArray(uint8_t* buf, size_t len)
+{
+  int res = appnearme_ndef_tlv_put_array(m_tlvList, buf, len);
+  if( !res )
+  {
+    m_space = false;
+    return 0;
+  }
+  return len;
+}
+
+/** Put string
+ *  @param str pointer to null-terminated string's start
+ *  @return number of copied bytes
+ */
+size_t TLVList::putString(char* str)
+{
+  int res = appnearme_ndef_tlv_put_string(m_tlvList, str);
+  if( !res )
+  {
+    m_space = false;
+    return 0;
+  }
+  return strlen(str);
+}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/TLVList.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,162 @@
+/*
+    TLVList.h 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+/** \file TLVList.h
+*    List of Type/Length/Values items
+*/
+
+#ifndef TLVLIST_H_
+#define TLVLIST_H_
+
+#include <cstdint> //For uint_*t
+#include <cstring> //For size_t
+
+using std::uint8_t;
+using std::uint16_t;
+using std::uint32_t;
+using std::size_t;
+
+typedef struct __tlv_list tlv_list;
+
+/** A simple container
+* List of Type/Length/Values items
+*/
+class TLVList
+{
+public:
+
+  //getNext...
+  //get()
+  //put()
+
+
+  //typedef tlv_type TLVType;
+  /** Type of a TLV item
+   *
+   */
+  enum TLVType
+  {
+    UINT8, //!< Unsigned char (byte)
+    UINT32, //!< Unsigned int
+    UINT8_ARRAY, ///< Byte array
+    STRING, //!<String
+    NONE, //!<End of packet
+    UNKNOWN //!< Unknown type
+  };
+
+  /* Getters */
+
+  /** Iterate to next item.
+   *  @return type if next item exists, NONE otherwise
+   */
+  TLVType getNext();
+
+  /** Get current item's type.
+   *  @return type if item exists, NONE otherwise
+   */
+  TLVType getType();
+
+  /** Get uint8_t value.
+   * If the current item's type is uint32_t, the value will be masked with 0xFF.
+   *  @return uint8_t value OR 0 if the type is incompatible
+   */
+  uint8_t getUInt8();
+
+  /** Get uint32_t value.
+   * If the current item's type is uint8_t, the value will be casted to uint32_t.
+   *  @return uint32_t value OR 0 if the type is incompatible
+   */
+  uint32_t getUInt32();
+
+  /** Get array length.
+   *  @return bytes array length
+   */
+  size_t getArrayLength();
+
+  /** Get array.
+   *  @param buf pointer to buffer's start
+   *  @param maxLen maximum number of bytes to copy
+   *  @return number of copied bytes
+   */
+  size_t getArray(uint8_t* buf, size_t maxLen);
+
+  /** Get string length.
+   *  @return string length
+   */
+  size_t getStringLength();
+
+  /** Get string.
+   *  Copy string to buffer (including null-terminating char).
+   *  @param str pointer to string's start
+   *  @param maxLen maximum number of chars to copy (not including null-terminating char)
+   *  @return number of copied chars
+   */
+  size_t getString(char* str, size_t maxLen);
+
+  /* Setters */
+
+  /** Check whether there is space left in list.
+   *  @return true if there is space left, false otherwise
+   */
+  bool isSpace();
+
+  /** Put uint8_t value.
+   *  @param value uint8_t value
+   *  @return true on success, false if there is not enough space in buffer
+   */
+  bool putUInt8(uint8_t value);
+
+  /** Put uint32_t value.
+   *  @param value uint32_t value
+   *  @return true on success, false if there is not enough space in buffer
+   */
+  bool putUInt32(uint32_t value);
+
+  /** Put array.
+   *  @param buf pointer to buffer's start
+   *  @param len number of bytes to copy
+   *  @return number of copied bytes
+   */
+  size_t putArray(uint8_t* buf, size_t len);
+
+  /** Put string.
+   *  @param str pointer to null-terminated string's start
+   *  @return number of copied bytes
+   */
+  size_t putString(char* str);
+
+protected:
+  TLVList();
+
+  void wrap(tlv_list* payload);
+
+private:
+  tlv_list* m_tlvList;
+
+  TLVType m_type;
+
+  union
+  {
+    uint8_t m_uint8;
+    uint32_t m_uint32;
+    uint8_t* m_array;
+    char* m_str;
+  };
+
+  union
+  {
+    size_t m_arrayLen;
+    size_t m_strLen;
+  };
+
+  bool m_space;
+
+  friend class NdefCallback;
+};
+
+
+#endif /* TLVLIST_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/core/buffer.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,86 @@
+/*
+  buffer.h
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+#ifndef BUFFER_H_
+#define BUFFER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "core/fwk.h"
+
+typedef struct __buffer
+{
+  uint8_t* bufdata;
+  size_t size;
+
+  uint8_t* start;
+  size_t first_byte_length; //In bits
+
+  uint8_t* end;
+  size_t last_byte_length; //In bits
+
+  struct __buffer* next;
+
+} buffer;
+
+void buffer_init(buffer* pBuf, uint8_t* bufdata, size_t size);
+
+void buffer_byref(buffer* pBuf, uint8_t* bufdata, size_t length); //New buffer by ref on a size_t array, no malloc (useful on PIC for instance)
+
+buffer* buffer_new(size_t size); //malloc
+
+uint8_t* buffer_data(buffer* pBuf);
+
+void buffer_reset(buffer* pBuf);
+
+size_t buffer_size(buffer* pBuf);
+
+size_t buffer_length(buffer* pBuf);
+
+bool buffer_empty(buffer* pBuf);
+
+void buffer_set_length(buffer* pBuf, size_t length);
+
+size_t buffer_last_byte_length(buffer* pBuf);
+
+void buffer_set_last_byte_length(buffer* pBuf, size_t length);
+
+size_t buffer_bits_count(buffer* pBuf);
+
+void buffer_write_byte(buffer* pBuf, uint8_t b);
+
+void buffer_write_bit(buffer* pBuf, uint8_t b);
+
+#if 0
+size_t buffer_read_byte(buffer* pBuf, uint8_t b);
+
+size_t buffer_read_bit(buffer* pBuf, uint8_t b);
+#endif
+
+buffer* buffer_next(buffer* pBuf);
+
+void buffer_set_next(buffer* pBuf, buffer* pNextBuf);
+
+void buffer_append(buffer* pBuf, buffer* pAppBuf);
+
+void buffer_unlink(buffer* pBuf, buffer* pLinkedBuf);
+
+size_t buffer_total_size(buffer* pBuf);
+
+size_t buffer_total_length(buffer* pBuf);
+
+void buffer_set_total_length(buffer* pBuf, size_t length);
+
+void buffer_free(buffer* pBuf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BUFFER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/core/debug.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,67 @@
+/*
+    debug.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+#include "core/fwk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !DEBUG_DISABLED
+
+void debug(int level, const char* module, int line, const char* fmt, ...);
+void debugx_enter(void);
+void debugx(const char* fmt, ...);
+void debugx_leave(void);
+
+#else
+#ifdef __DEBUG__
+#undef __DEBUG__
+#define __DEBUG__ 0
+#endif
+
+#endif
+
+#if __DEBUG__ > 0
+#ifndef __MODULE__
+#error "__MODULE__ must be defined"
+#endif
+#endif
+
+#if __DEBUG__ >= 1
+#define ERR(...) do{ debug(1, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
+#else
+#define ERR(...)
+#endif
+
+#if __DEBUG__ >= 2
+#define WARN(...) do{ debug(2, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
+#else
+#define WARN(...)
+#endif
+
+#if __DEBUG__ >= 3
+#define DBG(...) do{ debug(3, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
+#define DBGX_ENTER() do{ debugx_enter(); }while(0);
+#define DBGX(...) do{ debugx(__VA_ARGS__); }while(0)
+#define DBGX_LEAVE() do{ debugx_leave(); }while(0);
+#else
+#define DBG(...)
+#define DBGX_ENTER()
+#define DBGX(...)
+#define DBGX_LEAVE()
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/core/errors.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,30 @@
+/*
+    errors.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+#ifndef ERRORS_H_
+#define ERRORS_H_
+
+#define OK                    0   //No error
+
+#define ERR_UNKNOWN           1
+#define ERR_LENGTH            2
+#define ERR_NOT_FOUND         3
+#define ERR_UNSUPPORTED       4
+#define ERR_PARAMS            5
+#define ERR_BUFFER_TOO_SMALL  6
+#define ERR_TIMEOUT           7
+#define ERR_CRC               8
+#define ERR_NOCARD            9
+#define ERR_PARITY            10
+#define ERR_FIELD             11 //Lost RF field
+#define ERR_COLLISION         12
+#define ERR_WRONG_COMM        13
+#define ERR_PROTOCOL          14 //Protocol is not conformant
+#define ERR_BUSY              15
+#define ERR_CONTROLLER        16 //Controller failure
+
+#endif /* ERRORS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/core/fwk.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,51 @@
+/*
+    fwk.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+
+#ifndef FWK_H_
+#define FWK_H_
+
+#include "nfc_config.h"
+
+//Standard types definition
+#include "stdint.h"
+
+#include "stddef.h"
+
+//Definition of size_t on 32-bit arch
+#if !defined (__SIZE_TYPE__)
+typedef uint32_t size_t;
+#endif
+
+#ifndef __cplusplus
+typedef uint8_t bool; //Define boolean type for pure-C functions
+#define true 1
+#define false 0
+#endif
+
+//NULL pointer definition
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+//Error codes
+#include "errors.h"
+
+//RTOS abstraction
+#include "platform/rtos.h"
+
+//Debugging
+#include "debug.h"
+
+//Buffer
+#include "buffer.h"
+
+//Macros
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+#endif /* FWK_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/drv/pn532/pn532.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,25 @@
+/*
+    pn532.h 
+    Copyright (c) Donatien Garnier 2012
+    donatien.garnier@appnearme.com
+    http://www.appnearme.com/
+*/
+
+
+#ifndef PN532_H_
+#define PN532_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * To be called on each interrupt
+ */
+void pn532_irq(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PN532_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/ndef/appnearme_ndef.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,39 @@
+/*
+    appnearme_ndef.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+
+#ifndef APPNEARME_NDEF_H_
+#define APPNEARME_NDEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "core/fwk.h"
+#include "core/buffer.h"
+
+#include "appnearme_ndef_tlv.h"
+
+#define APPNEARME_HASH_SIZE 16
+
+typedef void (*appnearme_ndef_callback)(tlv_list* payload, void* param);
+
+int appnearme_ndef_init(char app_hash[APPNEARME_HASH_SIZE], uint32_t version);
+
+void appnearme_ndef_register_encode_callback(appnearme_ndef_callback cb, void* param);
+
+void appnearme_ndef_register_decode_callback(appnearme_ndef_callback cb, void* param);
+
+int appnearme_ndef_encode_message(buffer* pMem);
+
+int appnearme_ndef_decode_message(buffer* pMem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APPNEARME_NDEF_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/ndef/appnearme_ndef_tlv.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,63 @@
+/*
+    appnearme_ndef_tlv.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+#ifndef APPNEARME_NDEF_TLV_H_
+#define APPNEARME_NDEF_TLV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "core/fwk.h"
+#include "core/buffer.h"
+
+typedef enum __tlv_type
+{
+  UINT8,
+  UINT32,
+  UINT8_ARRAY,
+  STRING,
+  NONE, //End of packet
+  UNKNOWN
+} tlv_type;
+
+typedef struct __tlv_list
+{
+  buffer* buf;
+  size_t pos;
+  //bool writer_nreader;
+} tlv_list;
+
+void appnearme_ndef_tlv_byref(tlv_list* pList, buffer* pBuf/*, bool writer_nreader*/);
+
+tlv_type appnearme_ndef_tlv_next_type(tlv_list* pList);
+
+uint8_t appnearme_ndef_tlv_get_uint8(tlv_list* pList);
+
+uint32_t appnearme_ndef_tlv_get_uint32(tlv_list* pList);
+
+size_t appnearme_ndef_tlv_get_array_length(tlv_list* pList);
+
+uint8_t* appnearme_ndef_tlv_get_array(tlv_list* pList);
+
+size_t appnearme_ndef_tlv_get_string_length(tlv_list* pList);
+
+char* appnearme_ndef_tlv_get_string(tlv_list* pList);
+
+int appnearme_ndef_tlv_put_uint8(tlv_list* pList, uint8_t b); //-1 if no space left
+
+int appnearme_ndef_tlv_put_uint32(tlv_list* pList, uint32_t b);
+
+int appnearme_ndef_tlv_put_array(tlv_list* pList, uint8_t* data, size_t len);
+
+int appnearme_ndef_tlv_put_string(tlv_list* pList, char* str);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APPNEARME_NDEF_TLV_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/nfc_config.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,21 @@
+/*
+    nfc_config.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+
+#ifndef NFC_CONFIG_H_
+#define NFC_CONFIG_H_
+
+#define PN512 1
+#define PN532 2
+
+#define DEBUG_DISABLED 0
+#define TARGET_HW_ANTICOLLISION 1
+//#define NFC_CONTROLLER PN532 //In Makefile
+//#define APPNEARME_HASH "00000001aZSe2vF5"
+//#define APPNEARME_VERSION 0x01000000
+
+#endif /* NFC_CONFIG_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/platform/pn532_platform.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,53 @@
+/*
+    pn532_platform.h
+    Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+
+#ifndef PN532_PLATFORM_H_
+#define PN532_PLATFORM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "core/fwk.h"
+
+#include "drv/pn532/pn532.h"
+
+/*
+ * Initialize SPI
+ */
+int pn532_spi_init(void);
+
+/*
+ * Init
+ */
+void pn532_io_init(void);
+
+/*
+ * Get the IRQ pin's state
+ */
+bool pn532_irq_pin_get(void);
+
+/*
+ * Set the CS pin to 0 (active low)
+ */
+void pn532_cs_set(void);
+
+/*
+ * Set the CS pin to 1 (active high)
+ */
+void pn532_cs_clear(void);
+
+/*
+ * You MUST call pn532_irq() on each falling front of IRQ pin
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PN532_PLATFORM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/platform/rtos.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,30 @@
+/*
+    rtos.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+
+#ifndef RTOS_H_
+#define RTOS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "core/fwk.h"
+
+struct rtos_semaphore; //To be defined by impl
+typedef struct rtos_semaphore rtos_semaphore_t;
+
+rtos_semaphore_t* rtos_semaphore_new(void); //Should return NULL if fails
+
+int rtos_semaphore_produce(rtos_semaphore_t* pSem);
+int rtos_semaphore_consume(rtos_semaphore_t* pSem, int timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTOS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PN532/munfc/platform/spi.h	Wed Nov 07 18:19:09 2012 +0000
@@ -0,0 +1,45 @@
+/*
+    spi.h 
+  Copyright (c) Donatien Garnier 2012
+  donatien.garnier@appnearme.com
+  http://www.appnearme.com/
+*/
+
+#ifndef SPI_H_
+#define SPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "core/fwk.h"
+
+//These functions must be implemented for each platform
+
+/*
+ * 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 );
+
+/*
+ * Write outLen bytes
+ */
+int spi_write( uint8_t* outBuf, size_t outLen );
+
+/*
+ * Read inLen bytes
+ */
+int spi_read( uint8_t* inBuf, size_t inLen );
+
+/*
+ * Skip len bytes
+ */
+int spi_skip( size_t len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPI_H_ */