From: Kevin Townsend Date: Sat, 13 Aug 2011 22:46:44 +0000 (+0200) Subject: Cleaned up PN532 (in progress) X-Git-Url: http://git.rohieb.name/hackover2013-badge-firmware.git/commitdiff_plain/2d0f1c5e6cd990966564f3ff6aa8358cb4d0cdfa Cleaned up PN532 (in progress) --- diff --git a/drivers/sensors/pn532/pn532.c b/drivers/sensors/pn532/pn532.c index 350d4cb..ca91aba 100644 --- a/drivers/sensors/pn532/pn532.c +++ b/drivers/sensors/pn532/pn532.c @@ -6,7 +6,7 @@ #include #include "pn532.h" -#include "pn532_drvr.h" +#include "pn532_bus.h" #include "core/systick/systick.h" #include "core/uart/uart.h" @@ -25,9 +25,35 @@ void pn532PrintHex(const byte_t * pbtData, const size_t szBytes) 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); } /**************************************************************************/ @@ -54,58 +80,44 @@ void pn532Init(void) 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; } } @@ -119,7 +131,7 @@ pn532_error_t pn532Read(byte_t * abtResponse, size_t * pszLen) @param abtCommand The byte array containg the command and any - optional paramaters + optional parameters @param szLen The number of bytes in abtCommand */ @@ -131,22 +143,21 @@ pn532_error_t pn532Write(byte_t * abtCommand, size_t szLen) // 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; } } - diff --git a/drivers/sensors/pn532/pn532.h b/drivers/sensors/pn532/pn532.h index a88f06b..a48ad1c 100644 --- a/drivers/sensors/pn532/pn532.h +++ b/drivers/sensors/pn532/pn532.h @@ -9,17 +9,13 @@ #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, @@ -32,8 +28,11 @@ typedef enum pn532_error_e 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 @@ -45,6 +44,85 @@ 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 { @@ -55,11 +133,11 @@ 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 diff --git a/drivers/sensors/pn532/pn532_bus.h b/drivers/sensors/pn532/pn532_bus.h new file mode 100644 index 0000000..1d578cc --- /dev/null +++ b/drivers/sensors/pn532/pn532_bus.h @@ -0,0 +1,34 @@ +/**************************************************************************/ +/*! + @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 diff --git a/drivers/sensors/pn532/pn532_drvr.h b/drivers/sensors/pn532/pn532_drvr.h deleted file mode 100644 index f314fa1..0000000 --- a/drivers/sensors/pn532/pn532_drvr.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************/ -/*! - @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 diff --git a/drivers/sensors/pn532/pn532_drvr_spi.c b/drivers/sensors/pn532/pn532_drvr_spi.c deleted file mode 100644 index f55621a..0000000 --- a/drivers/sensors/pn532/pn532_drvr_spi.c +++ /dev/null @@ -1,410 +0,0 @@ -/**************************************************************************/ -/*! - @file pn532_drvr_spi.c -*/ -/**************************************************************************/ -#include "pn532_drvr.h" - -#ifdef PN532_SPI - -#include -#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 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; istate = 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 diff --git a/drivers/sensors/pn532/pn532_drvr_uart.c b/drivers/sensors/pn532/pn532_drvr_uart.c deleted file mode 100644 index abe029f..0000000 --- a/drivers/sensors/pn532/pn532_drvr_uart.c +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************/ -/*! - @file pn532_drvr_uart.c -*/ -/**************************************************************************/ -#include - -#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 diff --git a/drivers/sensors/pn532/pn532_mifare.c b/drivers/sensors/pn532/pn532_mifare.c deleted file mode 100644 index 1176833..0000000 --- a/drivers/sensors/pn532/pn532_mifare.c +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************/ -/*! - @file pn532_mifare.c -*/ -/**************************************************************************/ -#include - -#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; -} diff --git a/drivers/sensors/pn532/pn532_mifare.h b/drivers/sensors/pn532/pn532_mifare.h deleted file mode 100644 index 0ea8464..0000000 --- a/drivers/sensors/pn532/pn532_mifare.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************/ -/*! - @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