#include <string.h>
#include "pn532.h"
-#include "pn532_drvr.h"
+#include "pn532_bus.h"
#include "core/systick/systick.h"
#include "core/uart/uart.h"
size_t szPos;
for (szPos=0; szPos < szBytes; szPos++)
{
- PN532_DEBUG("%02x ", pbtData[szPos]);
+ printf("%02x ", pbtData[szPos]);
}
- PN532_DEBUG(CFG_PRINTF_NEWLINE);
+ printf(CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*!
+ @brief Prints a hexadecimal value in plain characters, along with
+ the char equivalents in the following format
+
+ AA BB CC DD EE FF ......
+
+ @param pbtData Pointer to the byte data
+ @param szBytes Data length in bytes
+*/
+/**************************************************************************/
+void pn532PrintHexVerbose(const byte_t * pbtData, const size_t szBytes)
+{
+ size_t szPos;
+ for (szPos=0; szPos < szBytes; szPos++)
+ {
+ printf("%02x", pbtData[szPos]);
+ }
+ printf(" ");
+ for (szPos=0; szPos < szBytes; szPos++)
+ {
+ printf("%c", pbtData[szPos] == 0 ? '.' : pbtData[szPos]);
+ }
+ printf(CFG_PRINTF_NEWLINE);
}
/**************************************************************************/
memset(&pcb, 0, sizeof(pn532_pcb_t));
// Initialise the underlying HW
- pn532HWInit();
+ pn532_bus_HWInit();
// Set the PCB flags to an appropriate state
pcb.initialised = TRUE;
}
-/**************************************************************************/
-/*!
- @brief Configures the PN532 for a specific modulation and
- baud rate
-*/
-/**************************************************************************/
-pn532_error_t pn532Configure(pn532_modulation_t mod)
-{
- // ToDo
-
- return PN532_ERROR_NONE;
-}
-
/**************************************************************************/
/*!
@brief Reads the response buffer from the PN532
- @param abtCommand
- The byte array containg the command and any
- optional paramaters
- @param szLen
- The number of bytes in abtCommand
+ @param pbtResponse
+ The byte array that will hold the response data
+ @param pszLen
+ Pointer to the number of bytes in pbtCommand
*/
/**************************************************************************/
-pn532_error_t pn532Read(byte_t * abtResponse, size_t * pszLen)
+pn532_error_t pn532Read(byte_t * pbtResponse, size_t * pszLen)
{
- if (!pcb.initialised) pn532Init();
+ if (!pcb.initialised) pn532Init();
// Try to wake the device up if it's in sleep mode
if (pcb.state == PN532_STATE_SLEEP)
{
- pn532_error_t wakeupError = pn532Wakeup();
+ pn532_error_t wakeupError = pn532_bus_Wakeup();
if (wakeupError)
- {
return wakeupError;
- }
}
// Read the response if the device is in an appropriate state
if (pcb.state == PN532_STATE_READY)
{
- return pn532ReadResponse(abtResponse, pszLen);
+ return pn532_bus_ReadResponse(pbtResponse, pszLen);
}
else
{
+ #ifdef PN532_DEBUGMODE
PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
+ #endif
return PN532_ERROR_UNABLETOINIT;
}
}
@param abtCommand
The byte array containg the command and any
- optional paramaters
+ optional parameters
@param szLen
The number of bytes in abtCommand
*/
// Try to wake the device up if it's in sleep mode
if (pcb.state == PN532_STATE_SLEEP)
{
- pn532_error_t wakeupError = pn532Wakeup();
+ pn532_error_t wakeupError = pn532_bus_Wakeup();
if (wakeupError)
- {
return wakeupError;
- }
}
// Send the command if the device is in an appropriate state
if (pcb.state == PN532_STATE_READY)
{
- return pn532SendCommand(abtCommand, szLen);
+ return pn532_bus_SendCommand(abtCommand, szLen);
}
else
{
+ #ifdef PN532_DEBUGMODE
PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
+ #endif
return PN532_ERROR_UNABLETOINIT;
}
}
-
#include "projectconfig.h"
+// Comment out this line to disable debug output
+#define PN532_DEBUGMODE
#define PN532_DEBUG(fmt, args...) printf(fmt, ##args)
-typedef enum pn532_state_e
-{
- PN532_STATE_SLEEP,
- PN532_STATE_READY,
- PN532_STATE_BUSY
-}
-pn532_state_t;
-
-/* Error messages generate by the stack (not to be confused with app level errors from the PN532) */
+/* Error messages generated by the stack */
+/* Not to be confused with app level errors from the PN532 */
+/* These are the errors that are returned by the PN532 driver */
typedef enum pn532_error_e
{
PN532_ERROR_NONE = 0x00,
PN532_ERROR_EXTENDEDFRAME = 0x07, // Extended frames currently unsupported
PN532_ERROR_LENCHECKSUMMISMATCH = 0x08,
PN532_ERROR_RESPONSEBUFFEREMPTY = 0x09, // No response data received
- PN532_ERROR_SPIREADYSTATUSTIMEOUT = 0x0A // Timeout waiting for 'ready' status (SPI only)
-
+ PN532_ERROR_SPIREADYSTATUSTIMEOUT = 0x0A, // Timeout waiting for 'ready' status (SPI only)
+ PN532_ERROR_TIMEOUTWAITINGFORCARD = 0x0B, // No card detected in field with the specified timeout
+ PN532_ERROR_BLOCKREADFAILED = 0x0C, // Unexpected response to block read request
+ PN532_ERROR_WRONGCARDTYPE = 0x0D, // Card is not the expected format (based on SENS_RES/ATQA value)
+ PN532_ERROR_ADDRESSOUTOFRANGE = 0x0E // Specified block and page is out of range
} pn532_error_t;
typedef enum pn532_modulation_e
PN532_MODULATION_JEWEL_106KBPS = 0x04
} pn532_modulation_t;
+/* HW Commands for the PN532. */
+/* See UM0701-02 - PN532 User Manual */
+enum
+{
+ PN532_COMMAND_DIAGNOSE = 0x00,
+ PN532_COMMAND_GETFIRMWAREVERSION = 0x02,
+ PN532_COMMAND_GETGENERALSTATUS = 0x04,
+ PN532_COMMAND_READREGISTER = 0x06,
+ PN532_COMMAND_WRITEREGISTER = 0x08,
+ PN532_COMMAND_READGPIO = 0x0C,
+ PN532_COMMAND_WRITEGPIO = 0x0E,
+ PN532_COMMAND_SETSERIALBAUDRATE = 0x10,
+ PN532_COMMAND_SETPARAMETERS = 0x12,
+ PN532_COMMAND_SAMCONFIGURATION = 0x14,
+ PN532_COMMAND_POWERDOWN = 0x16,
+ PN532_COMMAND_RFCONFIGURATION = 0x32,
+ PN532_COMMAND_RFREGULATIONTEST = 0x58,
+ PN532_COMMAND_INJUMPFORDEP = 0x56,
+ PN532_COMMAND_INJUMPFORPSL = 0x46,
+ PN532_COMMAND_INLISTPASSIVETARGET = 0x4A,
+ PN532_COMMAND_INATR = 0x50,
+ PN532_COMMAND_INPSL = 0x4E,
+ PN532_COMMAND_INDATAEXCHANGE = 0x40,
+ PN532_COMMAND_INCOMMUNICATETHRU = 0x42,
+ PN532_COMMAND_INDESELECT = 0x44,
+ PN532_COMMAND_INRELEASE = 0x52,
+ PN532_COMMAND_INSELECT = 0x54,
+ PN532_COMMAND_INAUTOPOLL = 0x60,
+ PN532_COMMAND_TGINITASTARGET = 0x8C,
+ PN532_COMMAND_TGSETGENERALBYTES = 0x92,
+ PN532_COMMAND_TGGETDATA = 0x86,
+ PN532_COMMAND_TGSETDATA = 0x8E,
+ PN532_COMMAND_TGSETMETADATA = 0x94,
+ PN532_COMMAND_TGGETINITIATORCOMMAND = 0x88,
+ PN532_COMMAND_TGRESPONSETOINITIATOR = 0x90,
+ PN532_COMMAND_TGGETTARGETSTATUS = 0x8A
+};
+
+/* Application level errors generated by the PN532 chip */
+/* See UM0701-02 - PN532 User Manual */
+enum
+{
+ PN532_APPERROR_NONE = 0x00,
+ PN532_APPERROR_TIMEOUT = 0x01,
+ PN532_APPERROR_CRCERROR = 0x02,
+ PN532_APPERROR_PARITYERROR = 0x04,
+ PN532_APPERROR_FRAMINGERROR = 0x05,
+ PN532_APPERROR_BITCOLLISION = 0x06,
+ PN532_APPERROR_INSUFFICIENTBUFFER = 0x07,
+ PN532_APPERROR_RFBUFFEROVERFLOW = 0x09,
+ PN532_APPERROR_RFFIELDTIMEOUT = 0x0A,
+ PN532_APPERROR_RFPROTOCOLERROR = 0x0B,
+ PN532_APPERROR_TEMPERROR = 0x0D,
+ PN532_APPERROR_INTERNBUFFEROVERFLOW = 0x0E,
+ PN532_APPERROR_INVALIDPARAMETER = 0x10,
+ PN532_APPERROR_DEP_UNSUPPORTEDCMD = 0x12,
+ PN532_APPERROR_DEP_INVALIDOFORMAT = 0x13,
+ PN532_APPERROR_AUTHENTERR = 0x14,
+ PN532_APPERROR_UIDCCHECKERROR = 0x23,
+ PN532_APPERROR_DEP_INVALIDDEVSTATE = 0x25,
+ PN532_APPERROR_OPERATIONNOTALLOWED = 0x26,
+ PN532_APPERROR_CMDNOTACCEPTABLE = 0x27,
+ PN532_APPERROR_TARGETRELEASED = 0x29,
+ PN532_APPERROR_IDMISMATCH = 0x2A,
+ PN532_APPERROR_CARDDISAPPEARED = 0x2B,
+ PN532_APPERROR_NFCID3MISMATCH = 0x2C,
+ PN532_APPERROR_OVERCURRENTEVENT = 0x2D,
+ PN532_APPERROR_NADMISSINGINDEP = 0x2E
+};
+
+/* Possible states for the PN532 SW Stack */
+typedef enum pn532_state_e
+{
+ PN532_STATE_SLEEP,
+ PN532_STATE_READY,
+ PN532_STATE_BUSY
+}
+pn532_state_t;
+
/* PN532 Protocol control block */
typedef struct
{
uint32_t appError;
} pn532_pcb_t;
-void pn532Init();
+void pn532PrintHex(const byte_t * pbtData, const size_t szBytes);
+void pn532PrintHexVerbose(const byte_t * pbtData, const size_t szBytes);
pn532_pcb_t * pn532GetPCB();
-pn532_error_t pn532SetModulation(pn532_modulation_t mod);
+void pn532Init();
+pn532_error_t pn532Read(byte_t *pbtResponse, size_t * pszLen);
pn532_error_t pn532Write(byte_t *abtCommand, size_t szLen);
-pn532_error_t pn532Read(byte_t *abtResponse, size_t * pszLen);
-void pn532PrintHex(const byte_t * pbtData, const size_t szBytes);
#endif
--- /dev/null
+/**************************************************************************/
+/*!
+ @file pn532_bus.h
+*/
+/**************************************************************************/
+
+#ifndef __PN532_BUS_H__
+#define __PN532_BUS_H__
+
+#include "projectconfig.h"
+#include "pn532.h"
+
+#define PN532_BUS_UART
+
+#define PN532_RSTPD_PORT (2)
+#define PN532_RSTPD_PIN (2)
+#define PN532_SPI_CSPORT (0)
+#define PN532_SPI_CSPIN (2)
+
+#define PN532_NORMAL_FRAME__DATA_MAX_LEN (254)
+#define PN532_NORMAL_FRAME__OVERHEAD (8)
+#define PN532_EXTENDED_FRAME__DATA_MAX_LEN (264)
+#define PN532_EXTENDED_FRAME__OVERHEAD (11)
+#define PN532_BUFFER_LEN (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD)
+#define PN532_UART_BAUDRATE (115200)
+
+// Generic interface for the different serial buses available on the PN532
+void pn532_bus_HWInit(void);
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData);
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen);
+bool pn532_bus_TransceiveBytes(const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx);
+pn532_error_t pn532_bus_Wakeup(void);
+
+#endif
+++ /dev/null
-/**************************************************************************/
-/*!
- @file pn532_drvr.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_DRV_H__
-#define __PN532_DRV_H__
-
-#include "projectconfig.h"
-#include "pn532.h"
-
-#define PN532_UART
-// #define PN532_SPI
-
-#define PN532_DEBUG(fmt, args...) printf(fmt, ##args)
-
-#define PN532_RSTPD_PORT (2)
-#define PN532_RSTPD_PIN (2)
-#define PN532_SPI_CSPORT (0)
-#define PN532_SPI_CSPIN (2)
-
-#define PN532_NORMAL_FRAME__DATA_MAX_LEN (254)
-#define PN532_NORMAL_FRAME__OVERHEAD (8)
-#define PN532_EXTENDED_FRAME__DATA_MAX_LEN (264)
-#define PN532_EXTENDED_FRAME__OVERHEAD (11)
-#define PN532_BUFFER_LEN (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD)
-#define PN532_UART_BAUDRATE (115200)
-
-enum
-{
- PN532_COMMAND_DIAGNOSE = 0x00,
- PN532_COMMAND_GETFIRMWAREVERSION = 0x02,
- PN532_COMMAND_GETGENERALSTATUS = 0x04,
- PN532_COMMAND_READREGISTER = 0x06,
- PN532_COMMAND_WRITEREGISTER = 0x08,
- PN532_COMMAND_READGPIO = 0x0C,
- PN532_COMMAND_WRITEGPIO = 0x0E,
- PN532_COMMAND_SETSERIALBAUDRATE = 0x10,
- PN532_COMMAND_SETPARAMETERS = 0x12,
- PN532_COMMAND_SAMCONFIGURATION = 0x14,
- PN532_COMMAND_POWERDOWN = 0x16,
- PN532_COMMAND_RFCONFIGURATION = 0x32,
- PN532_COMMAND_RFREGULATIONTEST = 0x58,
- PN532_COMMAND_INJUMPFORDEP = 0x56,
- PN532_COMMAND_INJUMPFORPSL = 0x46,
- PN532_COMMAND_INLISTPASSIVETARGET = 0x4A,
- PN532_COMMAND_INATR = 0x50,
- PN532_COMMAND_INPSL = 0x4E,
- PN532_COMMAND_INDATAEXCHANGE = 0x40,
- PN532_COMMAND_INCOMMUNICATETHRU = 0x42,
- PN532_COMMAND_INDESELECT = 0x44,
- PN532_COMMAND_INRELEASE = 0x52,
- PN532_COMMAND_INSELECT = 0x54,
- PN532_COMMAND_INAUTOPOLL = 0x60,
- PN532_COMMAND_TGINITASTARGET = 0x8C,
- PN532_COMMAND_TGSETGENERALBYTES = 0x92,
- PN532_COMMAND_TGGETDATA = 0x86,
- PN532_COMMAND_TGSETDATA = 0x8E,
- PN532_COMMAND_TGSETMETADATA = 0x94,
- PN532_COMMAND_TGGETINITIATORCOMMAND = 0x88,
- PN532_COMMAND_TGRESPONSETOINITIATOR = 0x90,
- PN532_COMMAND_TGGETTARGETSTATUS = 0x8A
-};
-
-/* Application level errors generated by the PN532 chip */
-enum
-{
- PN532_APPERROR_NONE = 0x00,
- PN532_APPERROR_TIMEOUT = 0x01,
- PN532_APPERROR_CRCERROR = 0x02,
- PN532_APPERROR_PARITYERROR = 0x04,
- PN532_APPERROR_FRAMINGERROR = 0x05,
- PN532_APPERROR_BITCOLLISION = 0x06,
- PN532_APPERROR_INSUFFICIENTBUFFER = 0x07,
- PN532_APPERROR_RFBUFFEROVERFLOW = 0x09,
- PN532_APPERROR_RFFIELDTIMEOUT = 0x0A,
- PN532_APPERROR_RFPROTOCOLERROR = 0x0B,
- PN532_APPERROR_TEMPERROR = 0x0D,
- PN532_APPERROR_INTERNBUFFEROVERFLOW = 0x0E,
- PN532_APPERROR_INVALIDPARAMETER = 0x10,
- PN532_APPERROR_DEP_UNSUPPORTEDCMD = 0x12,
- PN532_APPERROR_DEP_INVALIDOFORMAT = 0x13,
- PN532_APPERROR_AUTHENTERR = 0x14,
- PN532_APPERROR_UIDCCHECKERROR = 0x23,
- PN532_APPERROR_DEP_INVALIDDEVSTATE = 0x25,
- PN532_APPERROR_OPERATIONNOTALLOWED = 0x26,
- PN532_APPERROR_CMDNOTACCEPTABLE = 0x27,
- PN532_APPERROR_TARGETRELEASED = 0x29,
- PN532_APPERROR_IDMISMATCH = 0x2A,
- PN532_APPERROR_CARDDISAPPEARED = 0x2B,
- PN532_APPERROR_NFCID3MISMATCH = 0x2C,
- PN532_APPERROR_OVERCURRENTEVENT = 0x2D,
- PN532_APPERROR_NADMISSINGINDEP = 0x2E
-};
-
-void pn532HWInit(void);
-pn532_error_t pn532BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData);
-pn532_error_t pn532SendCommand(const byte_t * pbtData, const size_t szData);
-pn532_error_t pn532ReadResponse(byte_t * pbtResponse, size_t * pszRxLen);
-pn532_error_t pn532Wakeup(void);
-
-#endif
+++ /dev/null
-/**************************************************************************/
-/*!
- @file pn532_drvr_spi.c
-*/
-/**************************************************************************/
-#include "pn532_drvr.h"
-
-#ifdef PN532_SPI
-
-#include <string.h>
-#include "core/systick/systick.h"
-#include "core/gpio/gpio.h"
-#include "core/ssp/ssp.h"
-
-#define PN532_SELECT gpioSetValue(PN532_SPI_CSPORT, PN532_SPI_CSPIN, 0);
-#define PN532_DESELECT gpioSetValue(PN532_SPI_CSPORT, PN532_SPI_CSPIN, 1);
-
-#define PN532_SPI_STATREAD 0x02
-#define PN532_SPI_DATAWRITE 0x01
-#define PN532_SPI_DATAREAD 0x03
-#define PN532_SPI_READY 0x01
-
-// The number of attempts to make while waiting for the status ready bit
-// Each attempt is 1ms
-#define PN532_SPI_TIMEOUT 100
-
-/**************************************************************************/
-/*!
- @brief Writes a single byte via SPI
-*/
-/**************************************************************************/
-uint8_t pn532SPIWrite(unsigned char data)
-{
- // Note: bits have to be reversed since SPI is LSB on the PN532
- // Thankfully the M3 has a quick HW reverse command (RBIT)
- while ((SSP_SSP0SR & SSP_SSP0SR_TNF_NOTFULL) == 0);
- SSP_SSP0DR = ((unsigned char)(RBIT(data)>>24)); // Write
- while ((SSP_SSP0SR & SSP_SSP0SR_RNE_NOTEMPTY) == 0);
- data = ((unsigned char)(RBIT(SSP_SSP0DR)>>24)); // Read
- return data;
-}
-
-/**************************************************************************/
-/*!
- @brief Writes a byte array via SPI
-*/
-/**************************************************************************/
-void pn532SPIWriteArray(byte_t * pbtData, size_t len)
-{
- while (len != 0)
- {
- pn532SPIWrite(*pbtData);
- pbtData++;
- len--;
- }
-}
-
-/**************************************************************************/
-/*!
- @brief Reads a single byte via SPI
-*/
-/**************************************************************************/
-uint8_t pn532SPIRead(void)
-{
- return pn532SPIWrite(0x00);
-}
-
-/**************************************************************************/
-/*!
- @brief Reads a byte array via SPI
-*/
-/**************************************************************************/
-void pn532SPIReadArray(uint8_t* buff, size_t len)
-{
- size_t i;
- for (i=0; i<len; i++)
- {
- buff[i] = pn532SPIRead();
- }
-}
-
-
-/**************************************************************************/
-/*!
- @brief Sends a status request (SPI only)
-*/
-/**************************************************************************/
-uint8_t pn532GetStatus()
-{
- unsigned char res;
-
- // Send SPI status request
- PN532_SELECT;
- pn532SPIWrite(PN532_SPI_STATREAD);
- res = pn532SPIRead();
- PN532_DESELECT;
-
- return res;
-}
-
-/**************************************************************************/
-/*!
- @brief Initialises SPI and configures the PN532
-*/
-/**************************************************************************/
-void pn532HWInit(void)
-{
- PN532_DEBUG("Initialising SPI %s", CFG_PRINTF_NEWLINE);
- sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge);
-
- // Configure CS pin
- gpioSetDir(PN532_SPI_CSPORT, PN532_SPI_CSPIN, gpioDirection_Output);
- PN532_DESELECT;
-
- // Reset PN532 and wait for it to finish booting
- gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
- PN532_DEBUG("Resetting the PN532...\r\n");
- gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
- systickDelay(400);
- gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
- systickDelay(100);
-}
-
-/**************************************************************************/
-/*!
- @brief Builds a standard PN532 frame using the supplied data
-
- @param pbtFrame Pointer to the field that will hold the frame data
- @param pszFrame Pointer to the field that will hold the frame length
- @param pbtData Pointer to the data to insert in a frame
- @param swData Length of the data to insert in bytes
-
- @note Possible error messages are:
-
- - PN532_ERROR_EXTENDEDFRAME
-*/
-/**************************************************************************/
-pn532_error_t pn532BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
-{
- if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN)
- {
- // Extended frames currently unsupported
- return PN532_ERROR_EXTENDEDFRAME;
- }
-
- // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
- pbtFrame[3] = szData + 1;
- // LCS - Packet length checksum
- pbtFrame[4] = 256 - (szData + 1);
- // TFI
- pbtFrame[5] = 0xD4;
- // DATA - Copy the PN53X command into the packet buffer
- memcpy (pbtFrame + 6, pbtData, szData);
-
- // DCS - Calculate data payload checksum
- byte_t btDCS = (256 - 0xD4);
- size_t szPos;
- for (szPos = 0; szPos < szData; szPos++)
- {
- btDCS -= pbtData[szPos];
- }
- pbtFrame[6 + szData] = btDCS;
-
- // 0x00 - End of stream marker
- pbtFrame[szData + 7] = 0x00;
-
- (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
-
- return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Sends the specified command to the PN532, automatically
- creating an appropriate frame for it
-
- @param pdbData Pointer to the byte data to send
- @param szData Length in bytes of the data to send
-
- @note Possible error messages are:
-
- - PN532_ERROR_BUSY
- - PN532_ERROR_NOACK
- - PN532_ERROR_INVALIDACK
- - PN532_ERROR_SPIREADYSTATUSTIMEOUT
-*/
-/**************************************************************************/
-pn532_error_t pn532SendCommand(const byte_t * pbtData, const size_t szData)
-{
- pn532_pcb_t *pn532 = pn532GetPCB();
-
- // Check busy flag
- if (pn532->state == PN532_STATE_BUSY)
- {
- return PN532_ERROR_BUSY;
- }
- pn532->state = PN532_STATE_BUSY;
-
- // Every packet must start with "00 00 ff"
- byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
- size_t szFrame = 0;
-
- // Build the frame
- pn532BuildFrame (abtFrame, &szFrame, pbtData, szData);
-
- // Register the last command that was sent
- pn532->lastCommand = pbtData[0];
-
- // Output the frame data for debugging if requested
- PN532_DEBUG("Sending (%02d): ", szFrame);
- pn532PrintHex(abtFrame, szFrame);
-
- PN532_SELECT;
- systickDelay(5);
-
- // Send data to the PN532
- pn532SPIWrite(PN532_SPI_DATAWRITE);
- pn532SPIWriteArray(abtFrame, szFrame);
-
- // Wait for READY status
- size_t t = 0;
- while (pn532GetStatus() != PN532_SPI_READY)
- {
- if(t++>PN532_SPI_TIMEOUT)
- {
- PN532_DEBUG("Timeout waiting for READY status%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_SPIREADYSTATUSTIMEOUT;
- }
- systickDelay(1);
- }
-
- // Read ACK
- PN532_SELECT;
- pn532SPIWrite(PN532_SPI_DATAREAD);
- const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
- byte_t abtRxBuf[6];
- pn532SPIReadArray(abtRxBuf, 6);
- PN532_DESELECT;
-
- // Make sure the received ACK matches the prototype
- if (0 != (memcmp (abtRxBuf, abtAck, 6)))
- {
- PN532_DEBUG ("Invalid ACK: ");
- pn532PrintHex(abtRxBuf, 6);
- PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_INVALIDACK;
- }
-
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Reads a response from the PN532
-
- @note Possible error message are:
-
- - PN532_ERROR_BUSY
- - PN532_ERROR_RESPONSEBUFFEREMPTY
- - PN532_ERROR_PREAMBLEMISMATCH
- - PN532_ERROR_APPLEVELERROR
- - PN532_ERROR_EXTENDEDFRAME
- - PN532_ERROR_LENCHECKSUMMISMATCH
- - PN532_ERROR_SPIREADYSTATUSTIMEOUT
-*/
-/**************************************************************************/
-pn532_error_t pn532ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
-{
- size_t t, i;
- pn532_pcb_t *pn532 = pn532GetPCB();
-
- // Check if we're busy
- if (pn532->state == PN532_STATE_BUSY)
- {
- return PN532_ERROR_BUSY;
- }
- pn532->state = PN532_STATE_BUSY;
- pn532->appError = PN532_APPERROR_NONE;
-
- // Wait for the response ready signal
- t = 0;
- while (pn532GetStatus() != PN532_SPI_READY)
- {
- if(t++>PN532_SPI_TIMEOUT)
- {
- PN532_DEBUG("Timeout waiting for READY status%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_SPIREADYSTATUSTIMEOUT;
- }
- systickDelay(1);
- }
-
- PN532_SELECT;
- systickDelay(1);
-
- pn532SPIWrite(PN532_SPI_DATAREAD);
-
- // Check preamble
- pbtResponse[0] = pn532SPIRead();
- pbtResponse[1] = pn532SPIRead();
- pbtResponse[2] = pn532SPIRead();
- const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
- if (0 != (memcmp (pbtResponse, pn53x_preamble, 3)))
- {
- PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_PREAMBLEMISMATCH;
- }
-
- // Check the frame type
- pbtResponse[3] = pn532SPIRead();
- pbtResponse[4] = pn532SPIRead();
- pbtResponse[5] = pn532SPIRead();
- if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4]))
- {
- // Error frame
- PN532_DEBUG("Application level error (%02d)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
- // Set application error message ID
- pn532->appError = pbtResponse[5];
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_APPLEVELERROR;
- }
- else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4]))
- {
- // Extended frame
- PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_EXTENDEDFRAME;
- }
- else
- {
- // Check checksum, unless this is a response to the wakeup command
- if (pn532->lastCommand = PN532_COMMAND_SAMCONFIGURATION)
- {
- *pszRxLen = 6;
- }
- else
- {
- // Normal frame
- if (256 != (pbtResponse[3] + pbtResponse[4]))
- {
- // TODO: Retry
- PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
- pn532PrintHex(pbtResponse, 6);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_LENCHECKSUMMISMATCH;
- }
- // Read payload
- size_t szPayloadLen = pbtResponse[3] - 2;
- for (i=0; i<szPayloadLen; i++)
- {
- pbtResponse[i+6] = pn532SPIRead();
- }
- // Get checksum and postamble
- pbtResponse[i+7] = pn532SPIRead();
- pbtResponse[i+8] = pn532SPIRead();
- pbtResponse[i+9] = pn532SPIRead();
- // Set frame length
- *pszRxLen = i + 10;
- }
- }
-
- // Display the raw response data for debugging if requested
- PN532_DEBUG("Received (%02d): ", *pszRxLen);
- pn532PrintHex(pbtResponse, *pszRxLen);
-
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Sends the wakeup sequence to the PN532.
-*/
-/**************************************************************************/
-pn532_error_t pn532Wakeup(void)
-{
- size_t szLen;
- byte_t abtWakeUp[] = { 0x01,0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
- // byte_t abtWakeUp[] = { 0x01,0x00,0x00,0xff,0x03,0xfd,0xd4,PN532_COMMAND_SAMCONFIGURATION,0x01,0x17,0x00 };
-
- pn532_pcb_t *pn532 = pn532GetPCB();
-
- PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
-
- PN532_SELECT;
- systickDelay(2);
-
- // Transmit wakeup sequence
- pn532SPIWriteArray(abtWakeUp, sizeof(abtWakeUp));
- systickDelay(100);
-
- // Register the last command that was sent
- pn532->lastCommand = PN532_COMMAND_SAMCONFIGURATION;
-
- byte_t response[32];
- pn532ReadResponse(response, &szLen);
- PN532_DESELECT;
-
- // Todo: Check for error ... currently throws a checksum error
- // that isn't really an error
-
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NONE;
-}
-
-#endif // #ifdef PN532_SPI
+++ /dev/null
-/**************************************************************************/
-/*!
- @file pn532_drvr_uart.c
-*/
-/**************************************************************************/
-#include <string.h>
-
-#include "pn532.h"
-#include "pn532_drvr.h"
-
-#ifdef PN532_UART
-
-#include "core/systick/systick.h"
-#include "core/gpio/gpio.h"
-#include "core/uart/uart.h"
-
-/**************************************************************************/
-/*!
- @brief Initialises UART and configures the PN532
-*/
-/**************************************************************************/
-void pn532HWInit(void)
-{
- PN532_DEBUG("Initialising UART (%d)%s", PN532_UART_BAUDRATE, CFG_PRINTF_NEWLINE);
- uartInit(PN532_UART_BAUDRATE);
-
- // Set reset pin as output and reset device
- gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
- PN532_DEBUG("Resetting the PN532...\r\n");
- gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
- systickDelay(400);
- gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
-
- // Wait for the PN532 to finish booting
- systickDelay(100);
-}
-
-/**************************************************************************/
-/*!
- @brief Builds a standard PN532 frame using the supplied data
-
- @param pbtFrame Pointer to the field that will hold the frame data
- @param pszFrame Pointer to the field that will hold the frame length
- @param pbtData Pointer to the data to insert in a frame
- @param swData Length of the data to insert in bytes
-
- @note Possible error messages are:
-
- - PN532_ERROR_EXTENDEDFRAME
-*/
-/**************************************************************************/
-pn532_error_t pn532BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
-{
- if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN)
- {
- // Extended frames currently unsupported
- return PN532_ERROR_EXTENDEDFRAME;
- }
-
- // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
- pbtFrame[3] = szData + 1;
- // LCS - Packet length checksum
- pbtFrame[4] = 256 - (szData + 1);
- // TFI
- pbtFrame[5] = 0xD4;
- // DATA - Copy the PN53X command into the packet buffer
- memcpy (pbtFrame + 6, pbtData, szData);
-
- // DCS - Calculate data payload checksum
- byte_t btDCS = (256 - 0xD4);
- size_t szPos;
- for (szPos = 0; szPos < szData; szPos++)
- {
- btDCS -= pbtData[szPos];
- }
- pbtFrame[6 + szData] = btDCS;
-
- // 0x00 - End of stream marker
- pbtFrame[szData + 7] = 0x00;
-
- (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
-
- return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Sends the specified command to the PN532, automatically
- creating an appropriate frame for it
-
- @param pdbData Pointer to the byte data to send
- @param szData Length in bytes of the data to send
-
- @note Possible error messages are:
-
- - PN532_ERROR_BUSY
- - PN532_ERROR_NOACK
- - PN532_ERROR_INVALIDACK
-*/
-/**************************************************************************/
-pn532_error_t pn532SendCommand(const byte_t * pbtData, const size_t szData)
-{
- pn532_pcb_t *pn532 = pn532GetPCB();
-
- // Check if we're busy
- if (pn532->state == PN532_STATE_BUSY)
- {
- return PN532_ERROR_BUSY;
- }
-
- // Flag the stack as busy
- pn532->state = PN532_STATE_BUSY;
-
- // Every packet must start with "00 00 ff"
- byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
- size_t szFrame = 0;
-
- // Build the frame
- pn532BuildFrame (abtFrame, &szFrame, pbtData, szData);
-
- // Keep track of the last command that was sent
- pn532->lastCommand = pbtData[0];
-
- // Output the frame data for debugging if requested
- PN532_DEBUG("Sending (%02d): ", szFrame);
- pn532PrintHex(abtFrame, szFrame);
-
- // Send data to the PN532
- uartSend (abtFrame, szFrame);
-
- // Wait for ACK
- byte_t abtRxBuf[6];
- uart_pcb_t *uart = uartGetPCB();
- systickDelay(10); // FIXME: How long should we wait for ACK?
- if (uart->rxfifo.len < 6)
- {
- // Unable to read ACK
- PN532_DEBUG ("Unable to read ACK%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NOACK;
- }
-
- // Read ACK ... this will also remove it from the buffer
- const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
- abtRxBuf[0] = uartRxBufferRead();
- abtRxBuf[1] = uartRxBufferRead();
- abtRxBuf[2] = uartRxBufferRead();
- abtRxBuf[3] = uartRxBufferRead();
- abtRxBuf[4] = uartRxBufferRead();
- abtRxBuf[5] = uartRxBufferRead();
-
- // Make sure the received ACK matches the prototype
- if (0 != (memcmp (abtRxBuf, abtAck, 6)))
- {
- PN532_DEBUG ("Invalid ACK: ");
- pn532PrintHex(abtRxBuf, 6);
- PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_INVALIDACK;
- }
-
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Reads a response from the PN532
-
- @note Possible error message are:
-
- - PN532_ERROR_BUSY
- - PN532_ERROR_RESPONSEBUFFEREMPTY
- - PN532_ERROR_PREAMBLEMISMATCH
- - PN532_ERROR_APPLEVELERROR
- - PN532_ERROR_EXTENDEDFRAME
- - PN532_ERROR_LENCHECKSUMMISMATCH
-*/
-/**************************************************************************/
-pn532_error_t pn532ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
-{
- pn532_pcb_t *pn532 = pn532GetPCB();
-
- // Check if we're busy
- if (pn532->state == PN532_STATE_BUSY)
- {
- return PN532_ERROR_BUSY;
- }
-
- // Flag the stack as busy
- pn532->state = PN532_STATE_BUSY;
-
- // Reset the app error flag
- pn532->appError = PN532_APPERROR_NONE;
-
- // Read response from uart
- if (!uartRxBufferReadArray(pbtResponse, pszRxLen))
- {
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_RESPONSEBUFFEREMPTY;
- }
-
- // Display the raw response data for debugging if requested
- PN532_DEBUG("Received (%02d): ", *pszRxLen);
- pn532PrintHex(pbtResponse, *pszRxLen);
-
- // Check preamble
- const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
- if (0 != (memcmp (pbtResponse, pn53x_preamble, 3)))
- {
- PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_PREAMBLEMISMATCH;
- }
-
- // Check the frame type
- if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4]))
- {
- // Error frame
- PN532_DEBUG("Application level error (%02d)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
- // Set application error message ID
- pn532->appError = pbtResponse[5];
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_APPLEVELERROR;
- }
- else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4]))
- {
- // Extended frame
- PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_EXTENDEDFRAME;
- }
- else
- {
- // Normal frame
- if (256 != (pbtResponse[3] + pbtResponse[4]))
- {
- // TODO: Retry
- PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_LENCHECKSUMMISMATCH;
- }
- // size_t szPayloadLen = abtRx[3] - 2;
- }
-
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Sends the wakeup sequence to the PN532.
-*/
-/**************************************************************************/
-pn532_error_t pn532Wakeup(void)
-{
- size_t szLen;
- byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
-
- pn532_pcb_t *pn532 = pn532GetPCB();
-
- PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
- uartSend(abtWakeUp,sizeof(abtWakeUp));
- systickDelay(100);
-
- byte_t response[32];
- pn532ReadResponse(response, &szLen);
-
- // Todo: Check for error ... currently throws a checksum error
- // that isn't really an error
-
- pn532->state = PN532_STATE_READY;
- return PN532_ERROR_NONE;
-}
-
-#endif // #ifdef PN532_UART
\ No newline at end of file
+++ /dev/null
-/**************************************************************************/
-/*!
- @file pn532_mifare.c
-*/
-/**************************************************************************/
-#include <string.h>
-
-#include "pn532.h"
-#include "pn532_mifare.h"
-
-bool pn532MifareCmd(const pn532_mifare_cmd_t mc, const uint8_t ui8Block, pn532_mifare_param_t * pmp)
-{
- byte_t abtRx[265];
- size_t szRx = sizeof(abtRx);
- size_t szParamLen;
- byte_t abtCmd[265];
- bool bEasyFraming;
-
- abtCmd[0] = mc; // The MIFARE Classic command
- abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
-
- switch (mc) {
- // Read and store command have no parameter
- case PN532_MIFARE_CMD_READ:
- case PN532_MIFARE_CMD_STORE:
- szParamLen = 0;
- break;
-
- // Authenticate command
- case PN532_MIFARE_CMD_AUTH_A:
- case PN532_MIFARE_CMD_AUTH_B:
- szParamLen = sizeof (pn532_mifare_param_auth_t);
- break;
-
- // Data command
- case PN532_MIFARE_CMD_WRITE:
- szParamLen = sizeof (pn532_mifare_param_data_t);
- break;
-
- // Value command
- case PN532_MIFARE_CMD_DECREMENT:
- case PN532_MIFARE_CMD_INCREMENT:
- case PN532_MIFARE_CMD_TRANSFER:
- szParamLen = sizeof (pn532_mifare_param_value_t);
- break;
-
- // Please fix your code, you never should reach this statement
- default:
- return false;
- break;
- }
-
- // When available, copy the parameter bytes
- if (szParamLen)
- memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen);
-
-// bEasyFraming = pnd->bEasyFraming;
-// if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
-// nfc_perror (pnd, "nfc_configure");
-// return false;
-// }
-//
-// // Fire the mifare command
-// if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx)) {
-// if (pnd->iLastError == EINVRXFRAM) {
-// // "Invalid received frame" AKA EINVRXFRAM, usual means we are
-// // authenticated on a sector but the requested MIFARE cmd (read, write)
-// // is not permitted by current acces bytes;
-// // So there is nothing to do here.
-// } else {
-// nfc_perror (pnd, "nfc_initiator_transceive_bytes");
-// }
-// nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming);
-// return false;
-// }
-// if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) {
-// nfc_perror (pnd, "nfc_configure");
-// return false;
-// }
-//
-// // When we have executed a read command, copy the received bytes into the param
-// if (mc == MC_READ) {
-// if (szRx == 16) {
-// memcpy (pmp->mpd.abtData, abtRx, 16);
-// } else {
-// return false;
-// }
-// }
-
- // Command succesfully executed
- return true;
-}
+++ /dev/null
-/**************************************************************************/
-/*!
- @file pn532_mifare.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_MIFARE_H__
-#define __PN532_MIFARE_H__
-
-#include "projectconfig.h"
-
-typedef enum pn532_mifare_cmd_e
-{
- PN532_MIFARE_CMD_AUTH_A = 0x60,
- PN532_MIFARE_CMD_AUTH_B = 0x61,
- PN532_MIFARE_CMD_READ = 0x30,
- PN532_MIFARE_CMD_WRITE = 0xA0,
- PN532_MIFARE_CMD_TRANSFER = 0xB0,
- PN532_MIFARE_CMD_DECREMENT = 0xC0,
- PN532_MIFARE_CMD_INCREMENT = 0xC1,
- PN532_MIFARE_CMD_STORE = 0xC2
-}
-pn532_mifare_cmd_t;
-
-typedef struct
-{
- byte_t abtKey[6];
- byte_t abtUid[4];
-}
-pn532_mifare_param_auth_t;
-
-typedef struct
-{
- byte_t abtData[16];
-}
-pn532_mifare_param_data_t;
-
-typedef struct
-{
- byte_t abtValue[4];
-}
-pn532_mifare_param_value_t;
-
-typedef union
-{
- pn532_mifare_param_auth_t mpa;
- pn532_mifare_param_data_t mpd;
- pn532_mifare_param_value_t mpv;
-}
-pn532_mifare_param_t;
-
-// MIFARE Classic
-typedef struct
-{
- byte_t abtUID[4];
- byte_t btBCC;
- byte_t btUnknown;
- byte_t abtATQA[2];
- byte_t abtUnknown[8];
-}
-pn532_mifare_classic_block_manufacturer_t;
-
-typedef struct
-{
- byte_t abtData[16];
-}
-pn532_mifare_classic_block_data_t;
-
-typedef struct
-{
- byte_t abtKeyA[6];
- byte_t abtAccessBits[4];
- byte_t abtKeyB[6];
-}
-pn532_mifare_classic_block_trailer_t;
-
-typedef union
-{
- pn532_mifare_classic_block_manufacturer_t mbm;
- pn532_mifare_classic_block_data_t mbd;
- pn532_mifare_classic_block_trailer_t mbt;
-}
-pn532_mifare_classic_block_t;
-
-typedef struct
-{
- pn532_mifare_classic_block_t amb[256];
-}
-pn532_mifare_classic_tag_t;
-
-// MIFARE Ultralight
-typedef struct
-{
- byte_t sn0[3];
- byte_t btBCC0;
- byte_t sn1[4];
- byte_t btBCC1;
- byte_t internal;
- byte_t lock[2];
- byte_t otp[4];
-}
-pn532_mifareul_block_manufacturer_t;
-
-typedef struct
-{
- byte_t abtData[16];
-}
-pn532_mifareul_block_data_t;
-
-typedef union
-{
- pn532_mifareul_block_manufacturer_t mbm;
- pn532_mifareul_block_data_t mbd;
-}
-pn532_mifareul_block_t;
-
-typedef struct
-{
- pn532_mifareul_block_t amb[4];
-}
-pn532_mifareul_tag_t;
-
-#endif