diff --git a/PN5180.cpp b/PN5180.cpp index 81d4d34..55ac4e4 100644 --- a/PN5180.cpp +++ b/PN5180.cpp @@ -99,10 +99,10 @@ bool PN5180::writeRegister(uint8_t reg, uint32_t value) { For all 4 byte command parameter transfers (e.g. register values), the payload parameters passed follow the little endian approach (Least Significant Byte first). */ - uint8_t buf[6] = { PN5180_WRITE_REGISTER, reg, p[0], p[1], p[2], p[3] }; + uint8_t cmd[] = { PN5180_WRITE_REGISTER, reg, p[0], p[1], p[2], p[3] }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(buf, 6); + transceiveCommand(cmd, sizeof(cmd)); SPI.endTransaction(); return true; @@ -129,10 +129,10 @@ bool PN5180::writeRegisterWithOrMask(uint8_t reg, uint32_t mask) { PN5180DEBUG("\n"); #endif - uint8_t buf[6] = { PN5180_WRITE_REGISTER_OR_MASK, reg, p[0], p[1], p[2], p[3] }; + uint8_t cmd[] = { PN5180_WRITE_REGISTER_OR_MASK, reg, p[0], p[1], p[2], p[3] }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(buf, 6); + transceiveCommand(cmd, sizeof(cmd)); SPI.endTransaction(); return true; @@ -159,10 +159,10 @@ bool PN5180::writeRegisterWithAndMask(uint8_t reg, uint32_t mask) { PN5180DEBUG("\n"); #endif - uint8_t buf[6] = { PN5180_WRITE_REGISTER_AND_MASK, reg, p[0], p[1], p[2], p[3] }; + uint8_t cmd[] = { PN5180_WRITE_REGISTER_AND_MASK, reg, p[0], p[1], p[2], p[3] }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(buf, 6); + transceiveCommand(cmd, sizeof(cmd)); SPI.endTransaction(); return true; @@ -180,10 +180,10 @@ bool PN5180::readRegister(uint8_t reg, uint32_t *value) { PN5180DEBUG(formatHex(reg)); PN5180DEBUG(F("...\n")); - uint8_t cmd[2] = { PN5180_READ_REGISTER, reg }; + uint8_t cmd[] = { PN5180_READ_REGISTER, reg }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(cmd, 2, (uint8_t*)value, 4); + transceiveCommand(cmd, sizeof(cmd), (uint8_t*)value, 4); SPI.endTransaction(); PN5180DEBUG(F("Register value=0x")); @@ -196,31 +196,31 @@ bool PN5180::readRegister(uint8_t reg, uint32_t *value) { /* * WRITE_EEPROM - 0x06 */ - bool PN5180::writeEEPROM(uint8_t addr, uint8_t *data, int len) { - if ((addr > 254) || ((addr+len) > 254)) { - PN5180DEBUG(F("ERROR: Writing beyond addr 254!\n")); - return false; - } - - PN5180DEBUG(F("Writing to EEPROM at 0x")); - PN5180DEBUG(formatHex(addr)); - PN5180DEBUG(F(", size=")); - PN5180DEBUG(len); - PN5180DEBUG(F("...\n")); - - uint8_t buffer[len+2]; - buffer[0] = PN5180_WRITE_EEPROM; - buffer[1] = addr; - for (int i=0; i 254) || ((addr+len) > 254)) { + PN5180DEBUG(F("ERROR: Writing beyond addr 254!\n")); + return false; + } + + PN5180DEBUG(F("Writing to EEPROM at 0x")); + PN5180DEBUG(formatHex(addr)); + PN5180DEBUG(F(", size=")); + PN5180DEBUG(len); + PN5180DEBUG(F("...\n")); + + uint8_t cmd[len+2]; + cmd[0] = PN5180_WRITE_EEPROM; + cmd[1] = addr; + for (int i=0; i 508) { + if (len < 0 || (unsigned int)len > sizeof(readBuffer)) { Serial.println(F("*** FATAL: Reading more than 508 bytes is not supported!")); - return 0L; + return 0; } - if (NULL == buffer) { + if (buffer == NULL) { buffer = readBuffer; } @@ -349,10 +349,10 @@ uint8_t * PN5180::readData(int len, uint8_t *buffer /* = NULL */) { PN5180DEBUG(len); PN5180DEBUG(F(")...\n")); - uint8_t cmd[2] = { PN5180_READ_DATA, 0x00 }; + uint8_t cmd[] = { PN5180_READ_DATA, 0x00 }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(cmd, 2, buffer, len); + transceiveCommand(cmd, sizeof(cmd), buffer, len); SPI.endTransaction(); #ifdef DEBUG @@ -392,10 +392,10 @@ bool PN5180::loadRFConfig(uint8_t txConf, uint8_t rxConf) { PN5180DEBUG(formatHex(rxConf)); PN5180DEBUG("\n"); - uint8_t cmd[3] = { PN5180_LOAD_RF_CONFIG, txConf, rxConf }; + uint8_t cmd[] = { PN5180_LOAD_RF_CONFIG, txConf, rxConf }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(cmd, 3); + transceiveCommand(cmd, sizeof(cmd)); SPI.endTransaction(); return true; @@ -409,13 +409,13 @@ bool PN5180::loadRFConfig(uint8_t txConf, uint8_t rxConf) { bool PN5180::setRF_on() { PN5180DEBUG(F("Set RF ON\n")); - uint8_t cmd[2] = { PN5180_RF_ON, 0x00 }; + uint8_t cmd[] = { PN5180_RF_ON, 0x00 }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(cmd, 2); + transceiveCommand(cmd, sizeof(cmd)); SPI.endTransaction(); - while (0 == (TX_RFON_IRQ_STAT & getIRQStatus())); // wait for RF field to set up + while (!(getIRQStatus() & TX_RFON_IRQ_STAT)); // wait for RF field to set up clearIRQStatus(TX_RFON_IRQ_STAT); return true; } @@ -428,13 +428,13 @@ bool PN5180::setRF_on() { bool PN5180::setRF_off() { PN5180DEBUG(F("Set RF OFF\n")); - uint8_t cmd[2] { PN5180_RF_OFF, 0x00 }; + uint8_t cmd[] { PN5180_RF_OFF, 0x00 }; SPI.beginTransaction(PN5180_SPI_SETTINGS); - transceiveCommand(cmd, 2); + transceiveCommand(cmd, sizeof(cmd)); SPI.endTransaction(); - while (0 == (TX_RFOFF_IRQ_STAT & getIRQStatus())); // wait for RF field to shut down + while (!(getIRQStatus() & TX_RFOFF_IRQ_STAT)); // wait for RF field to shut down clearIRQStatus(TX_RFOFF_IRQ_STAT); return true; } @@ -488,7 +488,7 @@ bool PN5180::transceiveCommand(uint8_t *sendBuffer, size_t sendBufferLen, uint8_ #endif // 0. - while (LOW != digitalRead(PN5180_BUSY)); // wait until busy is low + while (digitalRead(PN5180_BUSY) != LOW); // wait until busy is low // 1. digitalWrite(PN5180_NSS, LOW); delay(2); // 2. @@ -496,15 +496,15 @@ bool PN5180::transceiveCommand(uint8_t *sendBuffer, size_t sendBufferLen, uint8_ SPI.transfer(sendBuffer[i]); } // 3. - while(HIGH != digitalRead(PN5180_BUSY)); // wait until BUSY is high + while(digitalRead(PN5180_BUSY) != HIGH); // wait until BUSY is high // 4. digitalWrite(PN5180_NSS, HIGH); delay(1); // 5. - while (LOW != digitalRead(PN5180_BUSY)); // wait unitl BUSY is low + while (digitalRead(PN5180_BUSY) != LOW); // wait unitl BUSY is low // check, if write-only // - if ((0 == recvBuffer) || (0 == recvBufferLen)) return true; + if ((recvBuffer == NULL) || (recvBufferLen == 0)) return true; PN5180DEBUG(F("Receiving SPI frame...\n")); // 1. @@ -514,11 +514,11 @@ bool PN5180::transceiveCommand(uint8_t *sendBuffer, size_t sendBufferLen, uint8_ recvBuffer[i] = SPI.transfer(0xff); } // 3. - while(HIGH != digitalRead(PN5180_BUSY)); // wait until BUSY is high + while(digitalRead(PN5180_BUSY) != HIGH); // wait until BUSY is high // 4. digitalWrite(PN5180_NSS, HIGH); delay(1); // 5. - while(LOW != digitalRead(PN5180_BUSY)); // wait until BUSY is low + while(digitalRead(PN5180_BUSY) != LOW); // wait until BUSY is low #ifdef DEBUG PN5180DEBUG(F("Received: ")); @@ -541,7 +541,7 @@ void PN5180::reset() { digitalWrite(PN5180_RST, HIGH); // 2ms to ramp up required delay(10); - while (0 == (IDLE_IRQ_STAT & getIRQStatus())); // wait for system to start up + while (!(getIRQStatus() & IDLE_IRQ_STAT)); // wait for system to start up clearIRQStatus(0xffffffff); // clear all flags } diff --git a/PN5180FeliCa.cpp b/PN5180FeliCa.cpp index 9b70c66..d7528ff 100644 --- a/PN5180FeliCa.cpp +++ b/PN5180FeliCa.cpp @@ -51,71 +51,61 @@ bool PN5180FeliCa::setupRF() { * buffer[18..19] is POL_RES data * * return value: the uid length in bytes: -* - zero if no tag was recognized -* - 8 if a FeliCa tag was recognized +* - zero if no tag was recognized +* - 8 if a FeliCa tag was recognized */ uint8_t PN5180FeliCa::pol_req(uint8_t *buffer) { - uint8_t cmd[6]; - uint8_t uidLength = 0; - // Load FeliCa 424 protocol - if (!loadRFConfig(0x09, 0x89)) - return 0; - // OFF Crypto - if (!writeRegisterWithAndMask(SYSTEM_CONFIG, 0xFFFFFFBF)) - return 0; - - //send FeliCa request (every packet starts with length) - cmd[0] = 0x06; //total length - cmd[1] = 0x00; //POL_REQ command - cmd[2] = 0xFF; // - cmd[3] = 0xFF; // any target - cmd[4] = 0x01; // System Code request - cmd[5] = 0x00; // 1 timeslot only - - if (!sendData(cmd, 6, 0x00)) - return 0; - //wait a little to avoid bug with some cards - delay(50); - - //response packet should be 0x14 (20 bytes total length), 0x01 Response Code, 8 IDm bytes, 8 PMm bytes, 2 Request Data bytes - //READ 20 bytes reply + uint8_t cmd[] = { + 0x06, //total length + 0x00, //POL_REQ command + 0xFF, // + 0xFF, // any target + 0x01, // System Code request + 0x00, // 1 timeslot only + }; + // Load FeliCa 424 protocol + if (!loadRFConfig(0x09, 0x89)) + return 0; + // OFF Crypto + if (!writeRegisterWithAndMask(SYSTEM_CONFIG, 0xFFFFFFBF)) + return 0; + + //send FeliCa request (every packet starts with length) + if (!sendData(cmd, sizeof(cmd))) + return 0; + //wait a little to avoid bug with some cards + delay(50); + + //response packet should be 0x14 (20 bytes total length), 0x01 Response Code, 8 IDm bytes, 8 PMm bytes, 2 Request Data bytes + //READ 20 bytes reply uint8_t *internalBuffer = readData(20); - if (!internalBuffer) - return 0; - for (int i=0; i<20; i++) { + if (!internalBuffer) + return 0; + for (int i=0; i<20; i++) { buffer[i] = internalBuffer[i]; - } - - //check Response Code - if ( buffer[1] != 0x01 ){ - uidLength = 0; - } else { - uidLength = 8; - } - return uidLength; + } + + // Check response code and return corresponding UID length + return buffer[1] == 0x01 ? 8 : 0; } uint8_t PN5180FeliCa::readCardSerial(uint8_t *buffer) { + uint8_t response[20] = { 0 }; + uint8_t uidLength; - uint8_t response[20]; - uint8_t uidLength; - - for (int i = 0; i < 20; i++) - response[i] = 0; - - uidLength = pol_req(response); + uidLength = pol_req(response); - // no reply - if (uidLength == 0) - return 0; + // no reply + if (uidLength == 0) + return 0; - for (int i = 0; i < uidLength; i++) - buffer[i] = response[i+2]; + for (int i=0; i #include "Debug.h" -PN5180ISO14443::PN5180ISO14443(uint8_t SSpin, uint8_t BUSYpin, uint8_t RSTpin) +PN5180ISO14443::PN5180ISO14443(uint8_t SSpin, uint8_t BUSYpin, uint8_t RSTpin) : PN5180(SSpin, BUSYpin, RSTpin) { } @@ -44,13 +44,14 @@ bool PN5180ISO14443::setupRF() { } uint16_t PN5180ISO14443::rxBytesReceived() { - uint32_t rxStatus; - uint16_t len = 0; - readRegister(RX_STATUS, &rxStatus); - // Lower 9 bits has length - len = (uint16_t)(rxStatus & 0x000001ff); - return len; + uint32_t rxStatus; + uint16_t len = 0; + readRegister(RX_STATUS, &rxStatus); + // Lower 9 bits has length + len = (uint16_t)(rxStatus & 0x000001ff); + return len; } + /* * buffer : must be 10 byte array * buffer[0-1] is ATQA @@ -60,183 +61,175 @@ uint16_t PN5180ISO14443::rxBytesReceived() { * kind : 0 we send REQA, 1 we send WUPA * * return value: the uid length: -* - zero if no tag was recognized -* - single Size UID (4 byte) -* - double Size UID (7 byte) -* - triple Size UID (10 byte) - not yet supported +* - zero if no tag was recognized +* - single Size UID (4 byte) +* - double Size UID (7 byte) +* - triple Size UID (10 byte) - not yet supported */ uint8_t PN5180ISO14443::activateTypeA(uint8_t *buffer, uint8_t kind) { - uint8_t cmd[7]; - uint8_t uidLength = 0; - // Load standard TypeA protocol - if (!loadRFConfig(0x0, 0x80)) - return 0; - - // OFF Crypto - if (!writeRegisterWithAndMask(SYSTEM_CONFIG, 0xFFFFFFBF)) - return 0; - // Clear RX CRC - if (!writeRegisterWithAndMask(CRC_RX_CONFIG, 0xFFFFFFFE)) - return 0; - // Clear TX CRC - if (!writeRegisterWithAndMask(CRC_TX_CONFIG, 0xFFFFFFFE)) - return 0; - //Send REQA/WUPA, 7 bits in last byte - cmd[0] = (kind == 0) ? 0x26 : 0x52; - if (!sendData(cmd, 1, 0x07)) - return 0; - // READ 2 bytes ATQA into buffer - if (!readData(2, buffer)) - return 0; - //Send Anti collision 1, 8 bits in last byte - cmd[0] = 0x93; - cmd[1] = 0x20; - if (!sendData(cmd, 2, 0x00)) - return 0; - //Read 5 bytes, we will store at offset 2 for later usage - if (!readData(5, cmd+2)) - return 0; - //Enable RX CRC calculation - if (!writeRegisterWithOrMask(CRC_RX_CONFIG, 0x01)) - return 0; - //Enable TX CRC calculation - if (!writeRegisterWithOrMask(CRC_TX_CONFIG, 0x01)) - return 0; - //Send Select anti collision 1, the remaining bytes are already in offset 2 onwards - cmd[0] = 0x93; - cmd[1] = 0x70; - if (!sendData(cmd, 7, 0x00)) - return 0; - //Read 1 byte SAK into buffer[2] - if (!readData(1, buffer+2)) - return 0; - // Check if the tag is 4 Byte UID or 7 byte UID and requires anti collision 2 - // If Bit 3 is 0 it is 4 Byte UID - if ((buffer[2] & 0x04) == 0) { - // Take first 4 bytes of anti collision as UID store at offset 3 onwards. job done - for (int i = 0; i < 4; i++) buffer[3+i] = cmd[2 + i]; - uidLength = 4; - } - else { - // Take First 3 bytes of UID, Ignore first byte 88(CT) - if (cmd[2] != 0x88) - return 0; - for (int i = 0; i < 3; i++) buffer[3+i] = cmd[3 + i]; - // Clear RX CRC - if (!writeRegisterWithAndMask(CRC_RX_CONFIG, 0xFFFFFFFE)) - return 0; - // Clear TX CRC - if (!writeRegisterWithAndMask(CRC_TX_CONFIG, 0xFFFFFFFE)) - return 0; - // Do anti collision 2 - cmd[0] = 0x95; - cmd[1] = 0x20; - if (!sendData(cmd, 2, 0x00)) - return 0; - //Read 5 bytes. we will store at offset 2 for later use - if (!readData(5, cmd+2)) - return 0; - // first 4 bytes belongs to last 4 UID bytes, we keep it. - for (int i = 0; i < 4; i++) { - buffer[6 + i] = cmd[2+i]; - } - //Enable RX CRC calculation - if (!writeRegisterWithOrMask(CRC_RX_CONFIG, 0x01)) - return 0; - //Enable TX CRC calculation - if (!writeRegisterWithOrMask(CRC_TX_CONFIG, 0x01)) - return 0; - //Send Select anti collision 2 - cmd[0] = 0x95; - cmd[1] = 0x70; - if (!sendData(cmd, 7, 0x00)) - return 0; - //Read 1 byte SAK into buffer[2] - if (!readData(1, buffer + 2)) - return 0; - uidLength = 7; - } - return uidLength; + uint8_t cmd[7]; + uint8_t uidLength = 0; + // Load standard TypeA protocol + if (!loadRFConfig(0x0, 0x80)) + return 0; + + // OFF Crypto + if (!writeRegisterWithAndMask(SYSTEM_CONFIG, 0xFFFFFFBF)) + return 0; + // Clear RX CRC + if (!writeRegisterWithAndMask(CRC_RX_CONFIG, 0xFFFFFFFE)) + return 0; + // Clear TX CRC + if (!writeRegisterWithAndMask(CRC_TX_CONFIG, 0xFFFFFFFE)) + return 0; + //Send REQA/WUPA, 7 bits in last byte + cmd[0] = (kind == 0) ? 0x26 : 0x52; + if (!sendData(cmd, 1, 7)) + return 0; + // READ 2 bytes ATQA into buffer + if (!readData(2, buffer)) + return 0; + //Send Anti collision 1, 8 bits in last byte + cmd[0] = 0x93; + cmd[1] = 0x20; + if (!sendData(cmd, 2)) + return 0; + //Read 5 bytes, we will store at offset 2 for later usage + if (!readData(5, cmd+2)) + return 0; + //Enable RX CRC calculation + if (!writeRegisterWithOrMask(CRC_RX_CONFIG, 0x01)) + return 0; + //Enable TX CRC calculation + if (!writeRegisterWithOrMask(CRC_TX_CONFIG, 0x01)) + return 0; + //Send Select anti collision 1, the remaining bytes are already in offset 2 onwards + cmd[0] = 0x93; + cmd[1] = 0x70; + if (!sendData(cmd, 7)) + return 0; + //Read 1 byte SAK into buffer[2] + if (!readData(1, buffer+2)) + return 0; + // Check if the tag is 4 Byte UID or 7 byte UID and requires anti collision 2 + // If Bit 3 is 0 it is 4 Byte UID + if ((buffer[2] & 0x04) == 0) { + // Take first 4 bytes of anti collision as UID store at offset 3 onwards. job done + for (int i=0; i<4; i++) + buffer[3+i] = cmd[2+i]; + uidLength = 4; + } + else { + // Take First 3 bytes of UID, Ignore first byte 88(CT) + if (cmd[2] != 0x88) + return 0; + for (int i=0; i<3; i++) + buffer[3+i] = cmd[3+i]; + // Clear RX CRC + if (!writeRegisterWithAndMask(CRC_RX_CONFIG, 0xFFFFFFFE)) + return 0; + // Clear TX CRC + if (!writeRegisterWithAndMask(CRC_TX_CONFIG, 0xFFFFFFFE)) + return 0; + // Do anti collision 2 + cmd[0] = 0x95; + cmd[1] = 0x20; + if (!sendData(cmd, 2)) + return 0; + //Read 5 bytes. we will store at offset 2 for later use + if (!readData(5, cmd+2)) + return 0; + // first 4 bytes belongs to last 4 UID bytes, we keep it. + for (int i=0; i<4; i++) { + buffer[6+i] = cmd[2+i]; + } + //Enable RX CRC calculation + if (!writeRegisterWithOrMask(CRC_RX_CONFIG, 0x01)) + return 0; + //Enable TX CRC calculation + if (!writeRegisterWithOrMask(CRC_TX_CONFIG, 0x01)) + return 0; + //Send Select anti collision 2 + cmd[0] = 0x95; + cmd[1] = 0x70; + if (!sendData(cmd, 7)) + return 0; + //Read 1 byte SAK into buffer[2] + if (!readData(1, buffer + 2)) + return 0; + uidLength = 7; + } + return uidLength; } bool PN5180ISO14443::mifareBlockRead(uint8_t blockno, uint8_t *buffer) { - bool success = false; - uint16_t len; - uint8_t cmd[2]; - // Send mifare command 30,blockno - cmd[0] = 0x30; - cmd[1] = blockno; - if (!sendData(cmd, 2, 0x00)) - return false; - //Check if we have received any data from the tag - delay(5); - len = rxBytesReceived(); - if (len == 16) { - // READ 16 bytes into buffer - if (readData(16, buffer)) - success = true; - } - return success; + bool success = false; + uint16_t len; + uint8_t cmd[] = { 0x30, blockno }; + if (!sendData(cmd, sizeof(cmd))) + return false; + //Check if we have received any data from the tag + delay(5); + len = rxBytesReceived(); + if (len == 16) { + // READ 16 bytes into buffer + if (readData(16, buffer)) + success = true; + } + return success; } uint8_t PN5180ISO14443::mifareBlockWrite16(uint8_t blockno, uint8_t *buffer) { - uint8_t cmd[1]; - // Clear RX CRC - writeRegisterWithAndMask(CRC_RX_CONFIG, 0xFFFFFFFE); - - // Mifare write part 1 - cmd[0] = 0xA0; - cmd[1] = blockno; - sendData(cmd, 2, 0x00); - readData(1, cmd); - - // Mifare write part 2 - sendData(buffer,16, 0x00); - delay(10); - - // Read ACK/NAK - readData(1, cmd); - - //Enable RX CRC calculation - writeRegisterWithOrMask(CRC_RX_CONFIG, 0x1); - return cmd[0]; + uint8_t cmd[] = { 0xA0, blockno }; + // Clear RX CRC + writeRegisterWithAndMask(CRC_RX_CONFIG, 0xFFFFFFFE); + + // Mifare write part 1 + sendData(cmd, sizeof(cmd)); + readData(1, cmd); + + // Mifare write part 2 + sendData(buffer, 16); + delay(10); + + // Read ACK/NAK + readData(1, cmd); + + //Enable RX CRC calculation + writeRegisterWithOrMask(CRC_RX_CONFIG, 0x01); + return cmd[0]; } bool PN5180ISO14443::mifareHalt() { - uint8_t cmd[1]; - //mifare Halt - cmd[0] = 0x50; - cmd[1] = 0x00; - sendData(cmd, 2, 0x00); - return true; + uint8_t cmd[] = { 0x50, 0x00 }; + sendData(cmd, sizeof(cmd)); + return true; } uint8_t PN5180ISO14443::readCardSerial(uint8_t *buffer) { - - uint8_t response[10]; - uint8_t uidLength; - // Always return 10 bytes - // Offset 0..1 is ATQA - // Offset 2 is SAK. - // UID 4 bytes : offset 3 to 6 is UID, offset 7 to 9 to Zero - // UID 7 bytes : offset 3 to 9 is UID - for (int i = 0; i < 10; i++) response[i] = 0; - uidLength = activateTypeA(response, 1); - if ((response[0] == 0xFF) && (response[1] == 0xFF)) - return 0; - // check for valid uid - if ((response[3] == 0x00) && (response[4] == 0x00) && (response[5] == 0x00) && (response[6] == 0x00)) - return 0; - if ((response[3] == 0xFF) && (response[4] == 0xFF) && (response[5] == 0xFF) && (response[6] == 0xFF)) - return 0; - for (int i = 0; i < 7; i++) buffer[i] = response[i+3]; - mifareHalt(); - return uidLength; + uint8_t response[10] = { 0 }; + uint8_t uidLength; + // Always return 10 bytes + // Offset 0..1 is ATQA + // Offset 2 is SAK. + // UID 4 bytes : offset 3 to 6 is UID, offset 7 to 9 to Zero + // UID 7 bytes : offset 3 to 9 is UID + uidLength = activateTypeA(response, 1); + if ((response[0] == 0xFF) && (response[1] == 0xFF)) + return 0; + // check for valid uid + if ((response[3] == 0x00) && (response[4] == 0x00) && (response[5] == 0x00) && (response[6] == 0x00)) + return 0; + if ((response[3] == 0xFF) && (response[4] == 0xFF) && (response[5] == 0xFF) && (response[6] == 0xFF)) + return 0; + for (int i=0; i<7; i++) + buffer[i] = response[i+3]; + mifareHalt(); + return uidLength; } bool PN5180ISO14443::isCardPresent() { - uint8_t buffer[10]; - return (readCardSerial(buffer) >=4); + uint8_t buffer[10]; + return (readCardSerial(buffer) >=4); } - diff --git a/PN5180ISO14443.h b/PN5180ISO14443.h index 166d183..321d99f 100644 --- a/PN5180ISO14443.h +++ b/PN5180ISO14443.h @@ -25,7 +25,7 @@ class PN5180ISO14443 : public PN5180 { public: PN5180ISO14443(uint8_t SSpin, uint8_t BUSYpin, uint8_t RSTpin); - + private: uint16_t rxBytesReceived(); public: @@ -37,10 +37,10 @@ class PN5180ISO14443 : public PN5180 { /* * Helper functions */ -public: +public: bool setupRF(); - uint8_t readCardSerial(uint8_t *buffer); - bool isCardPresent(); + uint8_t readCardSerial(uint8_t *buffer); + bool isCardPresent(); }; #endif /* PN5180ISO14443_H */ diff --git a/PN5180ISO15693.cpp b/PN5180ISO15693.cpp index 53d1fc9..db4aea4 100644 --- a/PN5180ISO15693.cpp +++ b/PN5180ISO15693.cpp @@ -46,7 +46,7 @@ ISO15693ErrorCode PN5180ISO15693::getInventory(uint8_t *uid) { uint8_t *readBuffer; ISO15693ErrorCode rc = issueISO15693Command(inventory, sizeof(inventory), &readBuffer); - if (ISO15693_EC_OK != rc) { + if (rc != ISO15693_EC_OK) { return rc; } @@ -77,22 +77,22 @@ ISO15693ErrorCode PN5180ISO15693::getInventory(uint8_t *uid) { * when ERROR flag is set: * SOF, Resp.Flags, ErrorCode, CRC16, EOF * - * Response Flags: - * xxxx.3xx0 - * |||\_ Error flag: 0=no error, 1=error detected, see error field - * \____ Extension flag: 0=no extension, 1=protocol format is extended - * - * If Error flag is set, the following error codes are defined: - * 01 = The command is not supported, i.e. the request code is not recognized. - * 02 = The command is not recognized, i.e. a format error occurred. - * 03 = The option is not supported. - * 0F = Unknown error. - * 10 = The specific block is not available. - * 11 = The specific block is already locked and cannot be locked again. - * 12 = The specific block is locked and cannot be changed. - * 13 = The specific block was not successfully programmed. - * 14 = The specific block was not successfully locked. - * A0-DF = Custom command error codes + * Response Flags: + * xxxx.3xx0 + * |||\_ Error flag: 0=no error, 1=error detected, see error field + * \____ Extension flag: 0=no extension, 1=protocol format is extended + * + * If Error flag is set, the following error codes are defined: + * 01 = The command is not supported, i.e. the request code is not recognized. + * 02 = The command is not recognized, i.e. a format error occurred. + * 03 = The option is not supported. + * 0F = Unknown error. + * 10 = The specific block is not available. + * 11 = The specific block is already locked and cannot be locked again. + * 12 = The specific block is locked and cannot be changed. + * 13 = The specific block was not successfully programmed. + * 14 = The specific block was not successfully locked. + * A0-DF = Custom command error codes * * when ERROR flag is NOT set: * SOF, Flags, BlockData (len=blockLength), CRC16, EOF @@ -121,7 +121,7 @@ ISO15693ErrorCode PN5180ISO15693::readSingleBlock(uint8_t *uid, uint8_t blockNo, uint8_t *resultPtr; ISO15693ErrorCode rc = issueISO15693Command(readSingleBlock, sizeof(readSingleBlock), &resultPtr); - if (ISO15693_EC_OK != rc) { + if (rc != ISO15693_EC_OK) { return rc; } @@ -212,7 +212,7 @@ ISO15693ErrorCode PN5180ISO15693::writeSingleBlock(uint8_t *uid, uint8_t blockNo uint8_t *resultPtr; ISO15693ErrorCode rc = issueISO15693Command(writeCmd, writeCmdSize, &resultPtr); - if (ISO15693_EC_OK != rc) { + if (rc != ISO15693_EC_OK) { free(writeCmd); return rc; } @@ -284,7 +284,7 @@ ISO15693ErrorCode PN5180ISO15693::getSystemInfo(uint8_t *uid, uint8_t *blockSize uint8_t *readBuffer; ISO15693ErrorCode rc = issueISO15693Command(sysInfo, sizeof(sysInfo), &readBuffer); - if (ISO15693_EC_OK != rc) { + if (rc != ISO15693_EC_OK) { return rc; } @@ -305,21 +305,20 @@ ISO15693ErrorCode PN5180ISO15693::getSystemInfo(uint8_t *uid, uint8_t *blockSize uint8_t infoFlags = readBuffer[1]; if (infoFlags & 0x01) { // DSFID flag - uint8_t dsfid = *p++; PN5180DEBUG("DSFID="); // Data storage format identifier - PN5180DEBUG(formatHex(dsfid)); + PN5180DEBUG(formatHex(*p)); PN5180DEBUG("\n"); + p++; } #ifdef DEBUG else PN5180DEBUG(F("No DSFID\n")); #endif if (infoFlags & 0x02) { // AFI flag - uint8_t afi = *p++; PN5180DEBUG(F("AFI=")); // Application family identifier - PN5180DEBUG(formatHex(afi)); + PN5180DEBUG(formatHex(*p)); PN5180DEBUG(F(" - ")); - switch (afi >> 4) { + switch (*p >> 4) { case 0: PN5180DEBUG(F("All families")); break; case 1: PN5180DEBUG(F("Transport")); break; case 2: PN5180DEBUG(F("Financial")); break; @@ -336,22 +335,18 @@ ISO15693ErrorCode PN5180ISO15693::getSystemInfo(uint8_t *uid, uint8_t *blockSize default: PN5180DEBUG(F("Unknown")); break; } PN5180DEBUG("\n"); + p++; } #ifdef DEBUG else PN5180DEBUG(F("No AFI\n")); #endif if (infoFlags & 0x04) { // VICC Memory size - *numBlocks = *p++; - *blockSize = *p++; - *blockSize = (*blockSize) & 0x1f; - - *blockSize = *blockSize + 1; // range: 1-32 - *numBlocks = *numBlocks + 1; // range: 1-256 - uint16_t viccMemSize = (*blockSize) * (*numBlocks); + *numBlocks = (*p++) + 1; // range: 1-256 TODO may cause overflow (blockSize needs to be 16 bit) + *blockSize = (*p++ & 0x1f) + 1; // range: 1-32 PN5180DEBUG("VICC MemSize="); - PN5180DEBUG(viccMemSize); + PN5180DEBUG((*blockSize) * (*numBlocks)); PN5180DEBUG(" BlockSize="); PN5180DEBUG(*blockSize); PN5180DEBUG(" NumBlocks="); @@ -363,10 +358,10 @@ ISO15693ErrorCode PN5180ISO15693::getSystemInfo(uint8_t *uid, uint8_t *blockSize #endif if (infoFlags & 0x08) { // IC reference - uint8_t icRef = *p++; PN5180DEBUG("IC Ref="); - PN5180DEBUG(formatHex(icRef)); + PN5180DEBUG(formatHex(*p)); PN5180DEBUG("\n"); + p++; } #ifdef DEBUG else PN5180DEBUG(F("No IC ref\n")); @@ -406,8 +401,7 @@ ISO15693ErrorCode PN5180ISO15693::setPassword(uint8_t *password, uint8_t *random setPassword[5] = password[1] ^ random[1]; setPassword[6] = password[2] ^ random[0]; setPassword[7] = password[3] ^ random[1]; - ISO15693ErrorCode rc = issueISO15693Command(setPassword, sizeof(setPassword), &readBuffer); - return rc; + return issueISO15693Command(setPassword, sizeof(setPassword), &readBuffer); } ISO15693ErrorCode PN5180ISO15693::enablePrivacy(uint8_t *password, uint8_t *random) { @@ -417,8 +411,7 @@ ISO15693ErrorCode PN5180ISO15693::enablePrivacy(uint8_t *password, uint8_t *rand setPrivacy[4] = password[1] ^ random[1]; setPrivacy[5] = password[2] ^ random[0]; setPrivacy[6] = password[3] ^ random[1]; - ISO15693ErrorCode rc = issueISO15693Command(setPrivacy, sizeof(setPrivacy), &readBuffer); - return rc; + return issueISO15693Command(setPrivacy, sizeof(setPrivacy), &readBuffer); } ISO15693ErrorCode PN5180ISO15693::writePassword(uint8_t *password, uint8_t *uid) { @@ -428,8 +421,7 @@ ISO15693ErrorCode PN5180ISO15693::writePassword(uint8_t *password, uint8_t *uid) writePassword[13] = password[1]; writePassword[14] = password[2]; writePassword[15] = password[3]; - ISO15693ErrorCode rc = issueISO15693Command(writePassword, sizeof(writePassword), &readBuffer); - return rc; + return issueISO15693Command(writePassword, sizeof(writePassword), &readBuffer); } @@ -472,16 +464,14 @@ ISO15693ErrorCode PN5180ISO15693::newpasswordICODESLIX2(uint8_t *newpassword, ui // set password to unlock the tag rc = setPassword(oldpassword, random); - if (rc != ISO15693_EC_OK) { return rc; } // write new password rc = writePassword(newpassword, uid); - - return rc; + return rc; } @@ -549,10 +539,10 @@ ISO15693ErrorCode PN5180ISO15693::issueISO15693Command(uint8_t *cmd, uint8_t cmd sendData(cmd, cmdLen); delay(10); uint32_t status = getIRQStatus(); - if (0 == (status & RX_SOF_DET_IRQ_STAT)) { + if (!(status & RX_SOF_DET_IRQ_STAT)) { return EC_NO_CARD; } - while (0 == (status & RX_IRQ_STAT)) { + while (!(status & RX_IRQ_STAT)) { delay(10); status = getIRQStatus(); } @@ -570,7 +560,7 @@ ISO15693ErrorCode PN5180ISO15693::issueISO15693Command(uint8_t *cmd, uint8_t cmd PN5180DEBUG("\n"); *resultPtr = readData(len); - if (0L == *resultPtr) { + if (*resultPtr == NULL) { PN5180DEBUG(F("*** ERROR in readData!\n")); return ISO15693_EC_UNKNOWN_ERROR; } @@ -579,15 +569,15 @@ ISO15693ErrorCode PN5180ISO15693::issueISO15693Command(uint8_t *cmd, uint8_t cmd Serial.print("Read="); for (int i=0; i