diff --git a/src/PN532.cpp b/src/PN532.cpp index c0dd18c..f4df823 100644 --- a/src/PN532.cpp +++ b/src/PN532.cpp @@ -13,11 +13,10 @@ #include "Arduino.h" #include "PN532.h" -#define HAL(func) (_interface->func) +#define HAL(func) (_interface->func) -PN532::PN532(PN532Interface &interface) -{ - _interface = &interface; +PN532::PN532(PN532Interface &interface) { + _interface = &interface; } /**************************************************************************/ @@ -25,10 +24,11 @@ PN532::PN532(PN532Interface &interface) @brief Setups the HW */ /**************************************************************************/ -void PN532::begin() -{ - HAL(begin)(); - HAL(wakeup)(); +void PN532::begin() { + HAL(begin) + (); + HAL(wakeup) + (); } /**************************************************************************/ @@ -38,31 +38,30 @@ void PN532::begin() @returns The chip's firmware version and ID */ /**************************************************************************/ -uint32_t PN532::getFirmwareVersion(void) -{ - uint32_t response; +uint32_t PN532::getFirmwareVersion(void) { + uint32_t response; - pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION; + pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION; - if (HAL(writeCommand)(pn532_packetbuffer, 1)) { - return 0; - } + if (HAL(writeCommand)(pn532_packetbuffer, 1)) { + return 0; + } - // read data packet - int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); - if (0 > status) { - return 0; - } + // read data packet + int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + if (0 > status) { + return 0; + } - response = pn532_packetbuffer[0]; - response <<= 8; - response |= pn532_packetbuffer[1]; - response <<= 8; - response |= pn532_packetbuffer[2]; - response <<= 8; - response |= pn532_packetbuffer[3]; + response = pn532_packetbuffer[0]; + response <<= 8; + response |= pn532_packetbuffer[1]; + response <<= 8; + response |= pn532_packetbuffer[2]; + response <<= 8; + response |= pn532_packetbuffer[3]; - return response; + return response; } @@ -75,27 +74,26 @@ uint32_t PN532::getFirmwareVersion(void) @returns The register value. */ /**************************************************************************/ -uint32_t PN532::readRegister(uint16_t reg) -{ - uint32_t response; +uint32_t PN532::readRegister(uint16_t reg) { + uint32_t response; - pn532_packetbuffer[0] = PN532_COMMAND_READREGISTER; - pn532_packetbuffer[1] = (reg >> 8) & 0xFF; - pn532_packetbuffer[2] = reg & 0xFF; + pn532_packetbuffer[0] = PN532_COMMAND_READREGISTER; + pn532_packetbuffer[1] = (reg >> 8) & 0xFF; + pn532_packetbuffer[2] = reg & 0xFF; - if (HAL(writeCommand)(pn532_packetbuffer, 3)) { - return 0; - } + if (HAL(writeCommand)(pn532_packetbuffer, 3)) { + return 0; + } - // read data packet - int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); - if (0 > status) { - return 0; - } + // read data packet + int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + if (0 > status) { + return 0; + } - response = pn532_packetbuffer[0]; + response = pn532_packetbuffer[0]; - return response; + return response; } /**************************************************************************/ @@ -108,27 +106,26 @@ uint32_t PN532::readRegister(uint16_t reg) @returns 0 for failure, 1 for success. */ /**************************************************************************/ -uint32_t PN532::writeRegister(uint16_t reg, uint8_t val) -{ - uint32_t response; +uint32_t PN532::writeRegister(uint16_t reg, uint8_t val) { + uint32_t response; - pn532_packetbuffer[0] = PN532_COMMAND_WRITEREGISTER; - pn532_packetbuffer[1] = (reg >> 8) & 0xFF; - pn532_packetbuffer[2] = reg & 0xFF; - pn532_packetbuffer[3] = val; + pn532_packetbuffer[0] = PN532_COMMAND_WRITEREGISTER; + pn532_packetbuffer[1] = (reg >> 8) & 0xFF; + pn532_packetbuffer[2] = reg & 0xFF; + pn532_packetbuffer[3] = val; - if (HAL(writeCommand)(pn532_packetbuffer, 4)) { - return 0; - } + if (HAL(writeCommand)(pn532_packetbuffer, 4)) { + return 0; + } - // read data packet - int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); - if (0 > status) { - return 0; - } + // read data packet + int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + if (0 > status) { + return 0; + } - return 1; + return 1; } /**************************************************************************/ @@ -136,17 +133,16 @@ uint32_t PN532::writeRegister(uint16_t reg, uint8_t val) @brief Configures the SAM (Secure Access Module) */ /**************************************************************************/ -bool PN532::SAMConfig(void) -{ - pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION; - pn532_packetbuffer[1] = 0x01; // normal mode; - pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second - pn532_packetbuffer[3] = 0x01; // use IRQ pin! +bool PN532::SAMConfig(void) { + pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION; + pn532_packetbuffer[1] = 0x01; // normal mode; + pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second + pn532_packetbuffer[3] = 0x01; // use IRQ pin! - if (HAL(writeCommand)(pn532_packetbuffer, 4)) - return false; + if (HAL(writeCommand)(pn532_packetbuffer, 4)) + return false; - return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); + return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); } /**************************************************************************/ @@ -159,18 +155,17 @@ bool PN532::SAMConfig(void) @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ -bool PN532::setPassiveActivationRetries(uint8_t maxRetries) -{ - pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; - pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries) - pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF) - pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01) - pn532_packetbuffer[4] = maxRetries; +bool PN532::setPassiveActivationRetries(uint8_t maxRetries) { + pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; + pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries) + pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF) + pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01) + pn532_packetbuffer[4] = maxRetries; - if (HAL(writeCommand)(pn532_packetbuffer, 5)) - return 0x0; // no ACK + if (HAL(writeCommand)(pn532_packetbuffer, 5)) + return 0x0; // no ACK - return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); + return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); } /**************************************************************************/ @@ -190,17 +185,16 @@ bool PN532::setPassiveActivationRetries(uint8_t maxRetries) */ /**************************************************************************/ -bool PN532::setRFField(uint8_t autoRFCA, uint8_t rFOnOff) -{ - pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; - pn532_packetbuffer[1] = 1; - pn532_packetbuffer[2] = 0x00 | autoRFCA | rFOnOff; +bool PN532::setRFField(uint8_t autoRFCA, uint8_t rFOnOff) { + pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; + pn532_packetbuffer[1] = 1; + pn532_packetbuffer[2] = 0x00 | autoRFCA | rFOnOff; - if (HAL(writeCommand)(pn532_packetbuffer, 3)) { - return 0x0; // command failed - } + if (HAL(writeCommand)(pn532_packetbuffer, 3)) { + return 0x0; // command failed + } - return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); + return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); } /***** ISO14443A Commands ******/ @@ -218,23 +212,22 @@ bool PN532::setRFField(uint8_t autoRFCA, uint8_t rFOnOff) @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ -bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout) -{ - pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; - pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later) - pn532_packetbuffer[2] = cardbaudrate; +bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout) { + pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; + pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later) + pn532_packetbuffer[2] = cardbaudrate; - if (HAL(writeCommand)(pn532_packetbuffer, 3)) { - return 0x0; // command failed - } + if (HAL(writeCommand)(pn532_packetbuffer, 3)) { + return 0x0; // command failed + } - // read data packet - if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) { - return 0x0; - } + // read data packet + if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) { + return 0x0; + } - // check some basic stuff - /* ISO14443A card response should be in the following format: + // check some basic stuff + /* ISO14443A card response should be in the following format: byte Description ------------- ------------------------------------------ @@ -246,21 +239,21 @@ bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uid b6..NFCIDLen NFCID */ - if (pn532_packetbuffer[0] != 1) - return 0; + if (pn532_packetbuffer[0] != 1) + return 0; - uint16_t sens_res = pn532_packetbuffer[2]; - sens_res <<= 8; - sens_res |= pn532_packetbuffer[3]; + uint16_t sens_res = pn532_packetbuffer[2]; + sens_res <<= 8; + sens_res |= pn532_packetbuffer[3]; - /* Card appears to be Mifare Classic */ - *uidLength = pn532_packetbuffer[5]; + /* Card appears to be Mifare Classic */ + *uidLength = pn532_packetbuffer[5]; - for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) { - uid[i] = pn532_packetbuffer[6 + i]; - } + for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) { + uid[i] = pn532_packetbuffer[6 + i]; + } - return 1; + return 1; } @@ -272,13 +265,12 @@ bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uid in the sector (block 0 relative to the current sector) */ /**************************************************************************/ -bool PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock) -{ - // Test if we are in the small or big sectors - if (uiBlock < 128) - return ((uiBlock) % 4 == 0); - else - return ((uiBlock) % 16 == 0); +bool PN532::mifareclassic_IsFirstBlock(uint32_t uiBlock) { + // Test if we are in the small or big sectors + if (uiBlock < 128) + return ((uiBlock) % 4 == 0); + else + return ((uiBlock) % 16 == 0); } /**************************************************************************/ @@ -286,13 +278,12 @@ bool PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock) Indicates whether the specified block number is the sector trailer */ /**************************************************************************/ -bool PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock) -{ - // Test if we are in the small or big sectors - if (uiBlock < 128) - return ((uiBlock + 1) % 4 == 0); - else - return ((uiBlock + 1) % 16 == 0); +bool PN532::mifareclassic_IsTrailerBlock(uint32_t uiBlock) { + // Test if we are in the small or big sectors + if (uiBlock < 128) + return ((uiBlock + 1) % 4 == 0); + else + return ((uiBlock + 1) % 16 == 0); } /**************************************************************************/ @@ -314,39 +305,39 @@ bool PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock) @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ -uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) -{ - uint8_t i; +uint8_t PN532::mifareclassic_AuthenticateBlock(uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) { + uint8_t i; - // Hang on to the key and uid data - memcpy (_key, keyData, 6); - memcpy (_uid, uid, uidLen); - _uidLen = uidLen; + // Hang on to the key and uid data + memcpy(_key, keyData, 6); + memcpy(_uid, uid, uidLen); + _uidLen = uidLen; - // Prepare the authentication command // - pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */ - pn532_packetbuffer[1] = 1; /* Max card numbers */ - pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A; - pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */ - memcpy (pn532_packetbuffer + 4, _key, 6); - for (i = 0; i < _uidLen; i++) { - pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */ - } + // Prepare the authentication command // + pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */ + pn532_packetbuffer[1] = 1; /* Max card numbers */ + pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A; + pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */ + memcpy(pn532_packetbuffer + 4, _key, 6); + for (i = 0; i < _uidLen; i++) { + pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */ + } - if (HAL(writeCommand)(pn532_packetbuffer, 10 + _uidLen)) - return 0; + if (HAL(writeCommand)(pn532_packetbuffer, 10 + _uidLen)) + return 0; - // Read the response packet - HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + // Read the response packet + HAL(readResponse) + (pn532_packetbuffer, sizeof(pn532_packetbuffer)); - // Check if the response is valid and we are authenticated??? - // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00 - // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good - if (pn532_packetbuffer[0] != 0x00) { - return 0; - } + // Check if the response is valid and we are authenticated??? + // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00 + // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good + if (pn532_packetbuffer[0] != 0x00) { + return 0; + } - return 1; + return 1; } /**************************************************************************/ @@ -362,33 +353,33 @@ uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, ui @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ -uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) -{ +uint8_t PN532::mifareclassic_ReadDataBlock(uint8_t blockNumber, uint8_t *data) { - /* Prepare the command */ - pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; - pn532_packetbuffer[1] = 1; /* Card number */ - pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */ - pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ + /* Prepare the command */ + pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; + pn532_packetbuffer[1] = 1; /* Card number */ + pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */ + pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ - /* Send the command */ - if (HAL(writeCommand)(pn532_packetbuffer, 4)) { - return 0; - } + /* Send the command */ + if (HAL(writeCommand)(pn532_packetbuffer, 4)) { + return 0; + } - /* Read the response packet */ - HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + /* Read the response packet */ + HAL(readResponse) + (pn532_packetbuffer, sizeof(pn532_packetbuffer)); - /* If byte 8 isn't 0x00 we probably have an error */ - if (pn532_packetbuffer[0] != 0x00) { - return 0; - } + /* If byte 8 isn't 0x00 we probably have an error */ + if (pn532_packetbuffer[0] != 0x00) { + return 0; + } - /* Copy the 16 data bytes to the output buffer */ - /* Block content starts at byte 9 of a valid response */ - memcpy (data, pn532_packetbuffer + 1, 16); + /* Copy the 16 data bytes to the output buffer */ + /* Block content starts at byte 9 of a valid response */ + memcpy(data, pn532_packetbuffer + 1, 16); - return 1; + return 1; } /**************************************************************************/ @@ -403,22 +394,21 @@ uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ -uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) -{ - /* Prepare the first command */ - pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; - pn532_packetbuffer[1] = 1; /* Card number */ - pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */ - pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ - memcpy (pn532_packetbuffer + 4, data, 16); /* Data Payload */ +uint8_t PN532::mifareclassic_WriteDataBlock(uint8_t blockNumber, uint8_t *data) { + /* Prepare the first command */ + pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; + pn532_packetbuffer[1] = 1; /* Card number */ + pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */ + pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ + memcpy(pn532_packetbuffer + 4, data, 16); /* Data Payload */ - /* Send the command */ - if (HAL(writeCommand)(pn532_packetbuffer, 20)) { - return 0; - } + /* Send the command */ + if (HAL(writeCommand)(pn532_packetbuffer, 20)) { + return 0; + } - /* Read the response packet */ - return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); + /* Read the response packet */ + return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); } /**************************************************************************/ @@ -431,39 +421,38 @@ uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) @param responseLength Pointer to the response data length */ /**************************************************************************/ -bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength) -{ - uint8_t i; +bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength) { + uint8_t i; - pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE; - pn532_packetbuffer[1] = inListedTag; + pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE; + pn532_packetbuffer[1] = inListedTag; - if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) { - return false; - } + if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) { + return false; + } - int16_t status = HAL(readResponse)(response, *responseLength, 1000); - if (status < 0) { - return false; - } + int16_t status = HAL(readResponse)(response, *responseLength, 1000); + if (status < 0) { + return false; + } - if ((response[0] & 0x3f) != 0) { - return false; - } + if ((response[0] & 0x3f) != 0) { + return false; + } - uint8_t length = status; - length -= 1; + uint8_t length = status; + length -= 1; - if (length > *responseLength) { - length = *responseLength; // silent truncation... - } + if (length > *responseLength) { + length = *responseLength; // silent truncation... + } - for (uint8_t i = 0; i < length; i++) { - response[i] = response[i + 1]; - } - *responseLength = length; + for (uint8_t i = 0; i < length; i++) { + response[i] = response[i + 1]; + } + *responseLength = length; - return true; + return true; } /**************************************************************************/ @@ -472,141 +461,137 @@ bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, peer acting as card/responder. */ /**************************************************************************/ -bool PN532::inListPassiveTarget() -{ - pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; - pn532_packetbuffer[1] = 1; - pn532_packetbuffer[2] = 0; +bool PN532::inListPassiveTarget() { + pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; + pn532_packetbuffer[1] = 1; + pn532_packetbuffer[2] = 0; - if (HAL(writeCommand)(pn532_packetbuffer, 3)) { - return false; - } + if (HAL(writeCommand)(pn532_packetbuffer, 3)) { + return false; + } - int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 30000); - if (status < 0) { - return false; - } + int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 30000); + if (status < 0) { + return false; + } - if (pn532_packetbuffer[0] != 1) { - return false; - } + if (pn532_packetbuffer[0] != 1) { + return false; + } - inListedTag = pn532_packetbuffer[1]; + inListedTag = pn532_packetbuffer[1]; - return true; + return true; } -int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout){ - - int8_t status = HAL(writeCommand)(command, len); - if (status < 0) { - return -1; - } +int8_t PN532::tgInitAsTarget(const uint8_t *command, const uint8_t len, const uint16_t timeout) { - status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout); - if (status > 0) { - return 1; - } else if (PN532_TIMEOUT == status) { - return 0; - } else { - return -2; - } + int8_t status = HAL(writeCommand)(command, len); + if (status < 0) { + return -1; + } + + status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout); + if (status > 0) { + return 1; + } else if (PN532_TIMEOUT == status) { + return 0; + } else { + return -2; + } } /** * Peer to Peer */ -int8_t PN532::tgInitAsTarget(uint16_t timeout) -{ - const uint8_t command[] = { - PN532_COMMAND_TGINITASTARGET, - 0, - 0x00, 0x00, //SENS_RES - 0x00, 0x00, 0x00, //NFCID1 - 0x40, //SEL_RES +int8_t PN532::tgInitAsTarget(uint16_t timeout) { + const uint8_t command[] = { + PN532_COMMAND_TGINITASTARGET, + 0, + 0x00, 0x00, //SENS_RES + 0x00, 0x00, 0x00, //NFCID1 + 0x40, //SEL_RES - 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, // POL_RES - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, + 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, // POL_RES + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, - 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value + 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value - 0x06, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x00// LLCP magic number and version parameter - }; - return tgInitAsTarget(command, sizeof(command), timeout); + 0x06, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x00 // LLCP magic number and version parameter + }; + return tgInitAsTarget(command, sizeof(command), timeout); } -int16_t PN532::tgGetData(uint8_t *buf, uint8_t len) -{ - buf[0] = PN532_COMMAND_TGGETDATA; +int16_t PN532::tgGetData(uint8_t *buf, uint8_t len) { + buf[0] = PN532_COMMAND_TGGETDATA; - if (HAL(writeCommand)(buf, 1)) { - return -1; - } + if (HAL(writeCommand)(buf, 1)) { + return -1; + } - int16_t status = HAL(readResponse)(buf, len, 3000); - if (0 >= status) { - return status; - } + int16_t status = HAL(readResponse)(buf, len, 3000); + if (0 >= status) { + return status; + } - uint16_t length = status - 1; + uint16_t length = status - 1; - if (buf[0] != 0) { - return -5; - } + if (buf[0] != 0) { + return -5; + } - for (uint8_t i = 0; i < length; i++) { - buf[i] = buf[i + 1]; - } + for (uint8_t i = 0; i < length; i++) { + buf[i] = buf[i + 1]; + } - return length; + return length; } -bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) -{ - if (hlen > (sizeof(pn532_packetbuffer) - 1)) { - if ((body != 0) || (header == pn532_packetbuffer)) { - return false; - } - - pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; - if (HAL(writeCommand)(pn532_packetbuffer, 1, header, hlen)) { - return false; - } - } else { - for (int8_t i = hlen - 1; i >= 0; i--){ - pn532_packetbuffer[i + 1] = header[i]; - } - pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; - - if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) { - return false; - } +bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) { + if (hlen > (sizeof(pn532_packetbuffer) - 1)) { + if ((body != 0) || (header == pn532_packetbuffer)) { + return false; } - if (0 > HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000)) { - return false; + pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; + if (HAL(writeCommand)(pn532_packetbuffer, 1, header, hlen)) { + return false; } - - if (0 != pn532_packetbuffer[0]) { - return false; + } else { + for (int8_t i = hlen - 1; i >= 0; i--) { + pn532_packetbuffer[i + 1] = header[i]; } + pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; - return true; + if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) { + return false; + } + } + + if (0 > HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000)) { + return false; + } + + if (0 != pn532_packetbuffer[0]) { + return false; + } + + return true; } -int16_t PN532::inRelease(const uint8_t relevantTarget){ +int16_t PN532::inRelease(const uint8_t relevantTarget) { - pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE; - pn532_packetbuffer[1] = relevantTarget; + pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE; + pn532_packetbuffer[1] = relevantTarget; - if (HAL(writeCommand)(pn532_packetbuffer, 2)) { - return 0; - } + if (HAL(writeCommand)(pn532_packetbuffer, 2)) { + return 0; + } - // read data packet - return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + // read data packet + return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); } @@ -629,8 +614,7 @@ int16_t PN532::inRelease(const uint8_t relevantTarget){ < 0: error */ /**************************************************************************/ -int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t * idm, uint8_t * pmm, uint16_t *systemCodeResponse, uint16_t timeout) -{ +int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout) { pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; pn532_packetbuffer[1] = 1; pn532_packetbuffer[2] = 1; @@ -665,14 +649,14 @@ int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t * } uint8_t i; - for (i=0; i<8; ++i) { - idm[i] = pn532_packetbuffer[4+i]; - _felicaIDm[i] = pn532_packetbuffer[4+i]; - pmm[i] = pn532_packetbuffer[12+i]; - _felicaPMm[i] = pn532_packetbuffer[12+i]; + for (i = 0; i < 8; ++i) { + idm[i] = pn532_packetbuffer[4 + i]; + _felicaIDm[i] = pn532_packetbuffer[4 + i]; + pmm[i] = pn532_packetbuffer[12 + i]; + _felicaPMm[i] = pn532_packetbuffer[12 + i]; } - if ( responseLength == 20 ) { + if (responseLength == 20) { *systemCodeResponse = (uint16_t)((pn532_packetbuffer[20] << 8) + pn532_packetbuffer[21]); } @@ -691,13 +675,12 @@ int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t * < 0: error */ /**************************************************************************/ -int8_t PN532::felica_SendCommand (const uint8_t *command, uint8_t commandlength, uint8_t *response, uint8_t *responseLength) -{ +int8_t PN532::felica_SendCommand(const uint8_t *command, uint8_t commandlength, uint8_t *response, uint8_t *responseLength) { if (commandlength > 0xFE) { return -1; } - pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE; + pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = inListedTag; pn532_packetbuffer[2] = commandlength + 1; @@ -712,13 +695,13 @@ int8_t PN532::felica_SendCommand (const uint8_t *command, uint8_t commandlength, } // Check status (pn532_packetbuffer[0]) - if ((pn532_packetbuffer[0] & 0x3F)!=0) { + if ((pn532_packetbuffer[0] & 0x3F) != 0) { return -4; } // length check *responseLength = pn532_packetbuffer[1] - 1; - if ( (status - 2) != *responseLength) { + if ((status - 2) != *responseLength) { return -5; } @@ -739,26 +722,25 @@ int8_t PN532::felica_SendCommand (const uint8_t *command, uint8_t commandlength, < 0: error */ /**************************************************************************/ -int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions) -{ +int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions) { if (numNode > FELICA_REQ_SERVICE_MAX_NODE_NUM) { return -1; } - uint8_t i, j=0; - uint8_t cmdLen = 1 + 8 + 1 + 2*numNode; + uint8_t i, j = 0; + uint8_t cmdLen = 1 + 8 + 1 + 2 * numNode; uint8_t cmd[cmdLen]; cmd[j++] = FELICA_CMD_REQUEST_SERVICE; - for (i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { cmd[j++] = _felicaIDm[i]; } cmd[j++] = numNode; - for (i=0; i> 8) & 0xff; } - uint8_t response[10+2*numNode]; + uint8_t response[10 + 2 * numNode]; uint8_t responseLength; if (felica_SendCommand(cmd, cmdLen, response, &responseLength) != 1) { @@ -766,12 +748,12 @@ int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uin } // length check - if ( responseLength != 10+2*numNode ) { + if (responseLength != 10 + 2 * numNode) { return -3; } - for(i=0; i FELICA_READ_MAX_SERVICE_NUM) { return -1; } @@ -829,43 +809,43 @@ int8_t PN532::felica_ReadWithoutEncryption (uint8_t numService, const uint16_t * return -2; } - uint8_t i, j=0, k; - uint8_t cmdLen = 1 + 8 + 1 + 2*numService + 1 + 2*numBlock; + uint8_t i, j = 0, k; + uint8_t cmdLen = 1 + 8 + 1 + 2 * numService + 1 + 2 * numBlock; uint8_t cmd[cmdLen]; cmd[j++] = FELICA_CMD_READ_WITHOUT_ENCRYPTION; - for (i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { cmd[j++] = _felicaIDm[i]; } cmd[j++] = numService; - for (i=0; i> 8) & 0xff; } cmd[j++] = numBlock; - for (i=0; i> 8) & 0xFF; cmd[j++] = blockList[i] & 0xff; } - uint8_t response[12+16*numBlock]; + uint8_t response[12 + 16 * numBlock]; uint8_t responseLength; if (felica_SendCommand(cmd, cmdLen, response, &responseLength) != 1) { return -3; } // length check - if ( responseLength != 12+16*numBlock ) { + if (responseLength != 12 + 16 * numBlock) { return -4; } // status flag check - if ( response[9] != 0 || response[10] != 0 ) { + if (response[9] != 0 || response[10] != 0) { return -5; } k = 12; - for(i=0; i FELICA_WRITE_MAX_SERVICE_NUM) { return -1; } @@ -896,25 +875,25 @@ int8_t PN532::felica_WriteWithoutEncryption (uint8_t numService, const uint16_t return -2; } - uint8_t i, j=0, k; - uint8_t cmdLen = 1 + 8 + 1 + 2*numService + 1 + 2*numBlock + 16 * numBlock; + uint8_t i, j = 0, k; + uint8_t cmdLen = 1 + 8 + 1 + 2 * numService + 1 + 2 * numBlock + 16 * numBlock; uint8_t cmd[cmdLen]; cmd[j++] = FELICA_CMD_WRITE_WITHOUT_ENCRYPTION; - for (i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { cmd[j++] = _felicaIDm[i]; } cmd[j++] = numService; - for (i=0; i> 8) & 0xff; } cmd[j++] = numBlock; - for (i=0; i> 8) & 0xFF; cmd[j++] = blockList[i] & 0xff; } - for (i=0; i 0 success * = 0 timeout * < 0 failed */ - int8_t tgInitAsTarget(uint16_t timeout = 0); - int8_t tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout = 0); + int8_t tgInitAsTarget(uint16_t timeout = 0); + int8_t tgInitAsTarget(const uint8_t *command, const uint8_t len, const uint16_t timeout = 0); - int16_t tgGetData(uint8_t *buf, uint8_t len); - bool tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0); + int16_t tgGetData(uint8_t *buf, uint8_t len); + bool tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0); - int16_t inRelease(const uint8_t relevantTarget = 0); + int16_t inRelease(const uint8_t relevantTarget = 0); - // ISO14443A functions - bool inListPassiveTarget(); - bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 1000); - bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength); + // ISO14443A functions + bool inListPassiveTarget(); + bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 1000); + bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength); - // Mifare Classic functions - bool mifareclassic_IsFirstBlock (uint32_t uiBlock); - bool mifareclassic_IsTrailerBlock (uint32_t uiBlock); - uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData); - uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data); - uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data); + // Mifare Classic functions + bool mifareclassic_IsFirstBlock(uint32_t uiBlock); + bool mifareclassic_IsTrailerBlock(uint32_t uiBlock); + uint8_t mifareclassic_AuthenticateBlock(uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData); + uint8_t mifareclassic_ReadDataBlock(uint8_t blockNumber, uint8_t *data); + uint8_t mifareclassic_WriteDataBlock(uint8_t blockNumber, uint8_t *data); - // FeliCa Functions - int8_t felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout=1000); - int8_t felica_SendCommand (const uint8_t * command, uint8_t commandlength, uint8_t * response, uint8_t * responseLength); - int8_t felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions) ; - int8_t felica_RequestResponse(uint8_t *mode); - int8_t felica_ReadWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]); - int8_t felica_WriteWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]); - int8_t felica_RequestSystemCode(uint8_t *numSystemCode, uint16_t *systemCodeList); - int8_t felica_Release(); + // FeliCa Functions + int8_t felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout = 1000); + int8_t felica_SendCommand(const uint8_t *command, uint8_t commandlength, uint8_t *response, uint8_t *responseLength); + int8_t felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions); + int8_t felica_RequestResponse(uint8_t *mode); + int8_t felica_ReadWithoutEncryption(uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]); + int8_t felica_WriteWithoutEncryption(uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]); + int8_t felica_RequestSystemCode(uint8_t *numSystemCode, uint16_t *systemCodeList); + int8_t felica_Release(); - uint8_t *getBuffer(uint8_t *len) { - *len = sizeof(pn532_packetbuffer) - 4; - return pn532_packetbuffer; - }; + uint8_t *getBuffer(uint8_t *len) { + *len = sizeof(pn532_packetbuffer) - 4; + return pn532_packetbuffer; + }; private: - uint8_t _uid[7]; // ISO14443A uid - uint8_t _uidLen; // uid len - uint8_t _key[6]; // Mifare Classic key - uint8_t inListedTag; // Tg number of inlisted tag. - uint8_t _felicaIDm[8]; // FeliCa IDm (NFCID2) - uint8_t _felicaPMm[8]; // FeliCa PMm (PAD) + uint8_t _uid[7]; // ISO14443A uid + uint8_t _uidLen; // uid len + uint8_t _key[6]; // Mifare Classic key + uint8_t inListedTag; // Tg number of inlisted tag. + uint8_t _felicaIDm[8]; // FeliCa IDm (NFCID2) + uint8_t _felicaPMm[8]; // FeliCa PMm (PAD) - uint8_t pn532_packetbuffer[64]; + uint8_t pn532_packetbuffer[64]; - PN532Interface *_interface; + PN532Interface *_interface; }; #endif diff --git a/src/PN532Interface.h b/src/PN532Interface.h index 281bf3a..5cd7a09 100644 --- a/src/PN532Interface.h +++ b/src/PN532Interface.h @@ -5,32 +5,32 @@ #ifndef __PN532_INTERFACE_H__ #define __PN532_INTERFACE_H__ -#define PN532_PREAMBLE (0x00) -#define PN532_STARTCODE1 (0x00) -#define PN532_STARTCODE2 (0xFF) -#define PN532_POSTAMBLE (0x00) +#define PN532_PREAMBLE (0x00) +#define PN532_STARTCODE1 (0x00) +#define PN532_STARTCODE2 (0xFF) +#define PN532_POSTAMBLE (0x00) -#define PN532_HOSTTOPN532 (0xD4) -#define PN532_PN532TOHOST (0xD5) +#define PN532_HOSTTOPN532 (0xD4) +#define PN532_PN532TOHOST (0xD5) -#define PN532_ACK_WAIT_TIME (10) // ms, timeout of waiting for ACK +#define PN532_ACK_WAIT_TIME (10) // ms, timeout of waiting for ACK -#define PN532_INVALID_ACK (-1) -#define PN532_TIMEOUT (-2) -#define PN532_INVALID_FRAME (-3) -#define PN532_NO_SPACE (-4) +#define PN532_INVALID_ACK (-1) +#define PN532_TIMEOUT (-2) +#define PN532_INVALID_FRAME (-3) +#define PN532_NO_SPACE (-4) -#define REVERSE_BITS_ORDER(b) b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; \ - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; \ - b = (b & 0xAA) >> 1 | (b & 0x55) << 1 +#define REVERSE_BITS_ORDER(b) \ + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; \ + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; \ + b = (b & 0xAA) >> 1 | (b & 0x55) << 1 -class PN532Interface -{ +class PN532Interface { public: - virtual void begin() = 0; - virtual void wakeup() = 0; + virtual void begin() = 0; + virtual void wakeup() = 0; - /** + /** * @brief write a command and check ack * @param header packet header * @param hlen length of header @@ -39,9 +39,9 @@ public: * @return 0 success * not 0 failed */ - virtual int8_t writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0) = 0; + virtual int8_t writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0) = 0; - /** + /** * @brief read the response of a command, strip prefix and suffix * @param buf to contain the response data * @param len lenght to read @@ -49,8 +49,7 @@ public: * @return >=0 length of response without prefix and suffix * <0 failed to read response */ - virtual int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 1000) = 0; + virtual int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 1000) = 0; }; #endif - diff --git a/src/PN532_SPI.cpp b/src/PN532_SPI.cpp index 0fdcd29..d65f4ea 100644 --- a/src/PN532_SPI.cpp +++ b/src/PN532_SPI.cpp @@ -5,195 +5,182 @@ #include "PN532_SPI.h" #include "Arduino.h" -#define STATUS_READ 2 -#define DATA_WRITE 1 -#define DATA_READ 3 +#define STATUS_READ 2 +#define DATA_WRITE 1 +#define DATA_READ 3 -PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t ss) -{ - command = 0; - _spi = &spi; - _ss = ss; +PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t ss) { + command = 0; + _spi = &spi; + _ss = ss; } -void PN532_SPI::begin() -{ - pinMode(_ss, OUTPUT); +void PN532_SPI::begin() { + pinMode(_ss, OUTPUT); - _spi->begin(); - _spi->setDataMode(SPI_MODE0); // PN532 only supports mode0 - _spi->setBitOrder(LSBFIRST); + _spi->begin(); + _spi->setDataMode(SPI_MODE0); // PN532 only supports mode0 + _spi->setBitOrder(LSBFIRST); #ifndef __SAM3X8E__ - _spi->setClockDivider(SPI_CLOCK_DIV8); // set clock 2MHz(max: 5MHz) + _spi->setClockDivider(SPI_CLOCK_DIV8); // set clock 2MHz(max: 5MHz) #else - /** DUE spi library does not support SPI_CLOCK_DIV8 macro */ - _spi->setClockDivider(42); // set clock 2MHz(max: 5MHz) + /** DUE spi library does not support SPI_CLOCK_DIV8 macro */ + _spi->setClockDivider(42); // set clock 2MHz(max: 5MHz) #endif - } -void PN532_SPI::wakeup() -{ - digitalWrite(_ss, LOW); - delay(2); - digitalWrite(_ss, HIGH); +void PN532_SPI::wakeup() { + digitalWrite(_ss, LOW); + delay(2); + digitalWrite(_ss, HIGH); } -int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) -{ - command = header[0]; - writeFrame(header, hlen, body, blen); - - uint8_t timeout = PN532_ACK_WAIT_TIME; - while (!isReady()) { - delay(1); - timeout--; - if (0 == timeout) { - return -2; - } - } - if (readAckFrame()) { - return PN532_INVALID_ACK; - } - return 0; -} +int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) { + command = header[0]; + writeFrame(header, hlen, body, blen); -int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout) -{ - uint16_t time = 0; - while (!isReady()) { - delay(1); - time++; - if (timeout > 0 && time > timeout) { - return PN532_TIMEOUT; - } - } - - digitalWrite(_ss, LOW); + uint8_t timeout = PN532_ACK_WAIT_TIME; + while (!isReady()) { delay(1); - - int16_t result; - do { - write(DATA_READ); - - if (0x00 != read() || // PREAMBLE - 0x00 != read() || // STARTCODE1 - 0xFF != read() // STARTCODE2 - ) { - - result = PN532_INVALID_FRAME; - break; - } - - uint8_t length = read(); - if (0 != (uint8_t)(length + read())) { // checksum of length - result = PN532_INVALID_FRAME; - break; - } - - uint8_t cmd = command + 1; // response command - if (PN532_PN532TOHOST != read() || (cmd) != read()) { - result = PN532_INVALID_FRAME; - break; - } - - - length -= 2; - if (length > len) { - for (uint8_t i = 0; i < length; i++) { - } - read(); - read(); - result = PN532_NO_SPACE; // not enough space - break; - } - - uint8_t sum = PN532_PN532TOHOST + cmd; - for (uint8_t i = 0; i < length; i++) { - buf[i] = read(); - sum += buf[i]; - - } - - uint8_t checksum = read(); - if (0 != (uint8_t)(sum + checksum)) { - result = PN532_INVALID_FRAME; - break; - } - read(); // POSTAMBLE - - result = length; - } while (0); - - digitalWrite(_ss, HIGH); - - return result; -} - -bool PN532_SPI::isReady() -{ - digitalWrite(_ss, LOW); - - write(STATUS_READ); - uint8_t status = read() & 1; - digitalWrite(_ss, HIGH); - return status; -} - -void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) -{ - digitalWrite(_ss, LOW); - delay(2); // wake up PN532 - - write(DATA_WRITE); - write(PN532_PREAMBLE); - write(PN532_STARTCODE1); - write(PN532_STARTCODE2); - - uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA - write(length); - write(~length + 1); // checksum of length - - write(PN532_HOSTTOPN532); - uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA - - - for (uint8_t i = 0; i < hlen; i++) { - write(header[i]); - sum += header[i]; - + timeout--; + if (0 == timeout) { + return -2; } - for (uint8_t i = 0; i < blen; i++) { - write(body[i]); - sum += body[i]; - - } - - uint8_t checksum = ~sum + 1; // checksum of TFI + DATA - write(checksum); - write(PN532_POSTAMBLE); - - digitalWrite(_ss, HIGH); - + } + if (readAckFrame()) { + return PN532_INVALID_ACK; + } + return 0; } -int8_t PN532_SPI::readAckFrame() -{ - const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0}; - - uint8_t ackBuf[sizeof(PN532_ACK)]; - - digitalWrite(_ss, LOW); +int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout) { + uint16_t time = 0; + while (!isReady()) { delay(1); + time++; + if (timeout > 0 && time > timeout) { + return PN532_TIMEOUT; + } + } + + digitalWrite(_ss, LOW); + delay(1); + + int16_t result; + do { write(DATA_READ); - for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) { - ackBuf[i] = read(); + if (0x00 != read() || // PREAMBLE + 0x00 != read() || // STARTCODE1 + 0xFF != read() // STARTCODE2 + ) { + + result = PN532_INVALID_FRAME; + break; } - digitalWrite(_ss, HIGH); + uint8_t length = read(); + if (0 != (uint8_t)(length + read())) { // checksum of length + result = PN532_INVALID_FRAME; + break; + } - return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK)); + uint8_t cmd = command + 1; // response command + if (PN532_PN532TOHOST != read() || (cmd) != read()) { + result = PN532_INVALID_FRAME; + break; + } + + + length -= 2; + if (length > len) { + for (uint8_t i = 0; i < length; i++) { + } + read(); + read(); + result = PN532_NO_SPACE; // not enough space + break; + } + + uint8_t sum = PN532_PN532TOHOST + cmd; + for (uint8_t i = 0; i < length; i++) { + buf[i] = read(); + sum += buf[i]; + } + + uint8_t checksum = read(); + if (0 != (uint8_t)(sum + checksum)) { + result = PN532_INVALID_FRAME; + break; + } + read(); // POSTAMBLE + + result = length; + } while (0); + + digitalWrite(_ss, HIGH); + + return result; +} + +bool PN532_SPI::isReady() { + digitalWrite(_ss, LOW); + + write(STATUS_READ); + uint8_t status = read() & 1; + digitalWrite(_ss, HIGH); + return status; +} + +void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) { + digitalWrite(_ss, LOW); + delay(2); // wake up PN532 + + write(DATA_WRITE); + write(PN532_PREAMBLE); + write(PN532_STARTCODE1); + write(PN532_STARTCODE2); + + uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA + write(length); + write(~length + 1); // checksum of length + + write(PN532_HOSTTOPN532); + uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA + + + for (uint8_t i = 0; i < hlen; i++) { + write(header[i]); + sum += header[i]; + } + for (uint8_t i = 0; i < blen; i++) { + write(body[i]); + sum += body[i]; + } + + uint8_t checksum = ~sum + 1; // checksum of TFI + DATA + write(checksum); + write(PN532_POSTAMBLE); + + digitalWrite(_ss, HIGH); +} + +int8_t PN532_SPI::readAckFrame() { + const uint8_t PN532_ACK[] = { 0, 0, 0xFF, 0, 0xFF, 0 }; + + uint8_t ackBuf[sizeof(PN532_ACK)]; + + digitalWrite(_ss, LOW); + delay(1); + write(DATA_READ); + + for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) { + ackBuf[i] = read(); + } + + digitalWrite(_ss, HIGH); + + return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK)); } diff --git a/src/PN532_SPI.h b/src/PN532_SPI.h index cceada4..19938f7 100644 --- a/src/PN532_SPI.h +++ b/src/PN532_SPI.h @@ -9,30 +9,30 @@ #include "PN532Interface.h" class PN532_SPI : public PN532Interface { public: - PN532_SPI(SPIClass &spi, uint8_t ss); - - void begin(); - void wakeup(); - int8_t writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0); + PN532_SPI(SPIClass &spi, uint8_t ss); + + void begin(); + void wakeup(); + int8_t writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0); + + int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout); - int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout); - private: - SPIClass* _spi; - uint8_t _ss; - uint8_t command; - - bool isReady(); - void writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0); - int8_t readAckFrame(); - - inline void write(uint8_t data) { - _spi->transfer(data); - }; + SPIClass *_spi; + uint8_t _ss; + uint8_t command; - inline uint8_t read() { - return _spi->transfer(0); - }; + bool isReady(); + void writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0); + int8_t readAckFrame(); + + inline void write(uint8_t data) { + _spi->transfer(data); + }; + + inline uint8_t read() { + return _spi->transfer(0); + }; }; #endif diff --git a/src/connection.h b/src/connection.h new file mode 100644 index 0000000..e609c77 --- /dev/null +++ b/src/connection.h @@ -0,0 +1,76 @@ +/* +库代码来自:https://github.com/spicetools/spicetools/tree/master/api/resources/arduino +删除了未使用的函数。 +*/ +#ifndef SPICEAPI_CONNECTION_H +#define SPICEAPI_CONNECTION_H + +#include + +#ifndef SPICEAPI_INTERFACE +#define SPICEAPI_INTERFACE Serial +#endif + +namespace spiceapi { + +class Connection { +private: + uint8_t* receive_buffer; + size_t receive_buffer_size; + +public: + Connection(size_t receive_buffer_size); + void reset(); + const char* request(char* json); +}; +} + +spiceapi::Connection::Connection(size_t receive_buffer_size) { + this->receive_buffer = new uint8_t[receive_buffer_size]; + this->receive_buffer_size = receive_buffer_size; + this->reset(); +} + +void spiceapi::Connection::reset() { + + // drop all input + while (SPICEAPI_INTERFACE.available()) { + SPICEAPI_INTERFACE.read(); + } +} + +const char* spiceapi::Connection::request(char* json_data) { + auto json_len = strlen(json_data) + 1; + + // send + auto send_result = SPICEAPI_INTERFACE.write((const char*)json_data, (int)json_len); + SPICEAPI_INTERFACE.flush(); + if (send_result < (int)json_len) { + return ""; + } + + // receive + size_t receive_data_len = 0; + while (SPICEAPI_INTERFACE) { + + // read single byte + auto b = SPICEAPI_INTERFACE.read(); + if (b < 0) continue; + receive_buffer[receive_data_len++] = b; + + // check for buffer overflow + if (receive_data_len >= receive_buffer_size) { + this->reset(); + return ""; + } + + // check for message end + if (receive_buffer[receive_data_len - 1] == 0) + break; + } + + // return resulting json + return (const char*)&receive_buffer[0]; +} + +#endif //SPICEAPI_CONNECTION_H diff --git a/src/wrappers.h b/src/wrappers.h new file mode 100644 index 0000000..a33a194 --- /dev/null +++ b/src/wrappers.h @@ -0,0 +1,140 @@ +/* +库代码来自:https://github.com/spicetools/spicetools/tree/master/api/resources/arduino +删除了未使用的函数。 +*/ +#ifndef SPICEAPI_WRAPPERS_H +#define SPICEAPI_WRAPPERS_H + +#define ARDUINOJSON_USE_LONG_LONG 1 +#include "ArduinoJson.h" + +#include +#include "connection.h" + +// default buffer sizes +#ifndef SPICEAPI_WRAPPER_BUFFER_SIZE +#define SPICEAPI_WRAPPER_BUFFER_SIZE 256 +#endif +#ifndef SPICEAPI_WRAPPER_BUFFER_SIZE_STR +#define SPICEAPI_WRAPPER_BUFFER_SIZE_STR 256 +#endif + +namespace spiceapi { + +/* + * Structs + */ + +struct InfoAvs { + String model, dest, spec, rev, ext; +}; + +// static storage +char JSON_BUFFER_STR[SPICEAPI_WRAPPER_BUFFER_SIZE_STR]; + +/* + * Helpers + */ + +uint64_t msg_gen_id() { + static uint64_t id_global = 0; + return ++id_global; +} + +char *doc2str(DynamicJsonDocument *doc) { + char *buf = JSON_BUFFER_STR; + serializeJson(*doc, buf, SPICEAPI_WRAPPER_BUFFER_SIZE_STR); + return buf; +} + +DynamicJsonDocument *request_gen(const char *module, const char *function) { + + // create document + auto doc = new DynamicJsonDocument(SPICEAPI_WRAPPER_BUFFER_SIZE); + + // add attributes + (*doc)["id"] = msg_gen_id(); + (*doc)["module"] = module; + (*doc)["function"] = function; + + // add params + (*doc).createNestedArray("params"); + + // return document + return doc; +} + +DynamicJsonDocument *response_get(Connection &con, const char *json) { + + // parse document + DynamicJsonDocument *doc = new DynamicJsonDocument(SPICEAPI_WRAPPER_BUFFER_SIZE); + auto err = deserializeJson(*doc, (char *)json); + + // check for parse error + if (err) { + delete doc; + return nullptr; + } + + // check id + if (!(*doc)["id"].is()) { + delete doc; + return nullptr; + } + + // check errors + auto errors = (*doc)["errors"]; + if (!errors.is()) { + delete doc; + return nullptr; + } + + // check error count + if (errors.as().size() > 0) { + delete doc; + return nullptr; + } + + // check data + if (!(*doc)["data"].is()) { + delete doc; + return nullptr; + } + + // return document + return doc; +} + +bool card_insert(Connection &con, size_t index, const char *card_id) { + auto req = request_gen("card", "insert"); + auto params = (*req)["params"].as(); + params.add(index); + params.add(card_id); + auto req_str = doc2str(req); + delete req; + auto res = response_get(con, con.request(req_str)); + if (!res) + return false; + delete res; + return true; +} + +bool info_avs(Connection &con, InfoAvs &info) { + auto req = request_gen("info", "avs"); + auto req_str = doc2str(req); + delete req; + auto res = response_get(con, con.request(req_str)); + if (!res) + return false; + auto data = (*res)["data"][0]; + info.model = (const char *)data["model"]; + info.dest = (const char *)data["dest"]; + info.spec = (const char *)data["spec"]; + info.rev = (const char *)data["rev"]; + info.ext = (const char *)data["ext"]; + delete res; + return true; +} +} + +#endif //SPICEAPI_WRAPPERS_H