diff --git a/lib/lib_div/rfid-1.4.7/src/MFRC522.cpp b/lib/lib_div/rfid-1.4.7/src/MFRC522.cpp index a4f70e6dd..fbae40085 100644 --- a/lib/lib_div/rfid-1.4.7/src/MFRC522.cpp +++ b/lib/lib_div/rfid-1.4.7/src/MFRC522.cpp @@ -130,7 +130,7 @@ void MFRC522::PCD_ReadRegister( PCD_Register reg, ///< The register to read from */ void MFRC522::PCD_SetRegisterBitMask( PCD_Register reg, ///< The register to update. One of the PCD_Register enums. byte mask ///< The bits to set. - ) { + ) { byte tmp; tmp = PCD_ReadRegister(reg); PCD_WriteRegister(reg, tmp | mask); // set bit mask @@ -150,7 +150,7 @@ void MFRC522::PCD_ClearRegisterBitMask( PCD_Register reg, ///< The register to u /** * Use the CRC coprocessor in the MFRC522 to calculate a CRC_A. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::PCD_CalculateCRC( byte *data, ///< In: Pointer to the data to transfer to the FIFO for CRC calculation. @@ -162,7 +162,7 @@ MFRC522::StatusCode MFRC522::PCD_CalculateCRC( byte *data, ///< In: Pointer to PCD_WriteRegister(FIFOLevelReg, 0x80); // FlushBuffer = 1, FIFO initialization PCD_WriteRegister(FIFODataReg, length, data); // Write data to the FIFO PCD_WriteRegister(CommandReg, PCD_CalcCRC); // Start the calculation - + // Wait for the CRC calculation to complete. Each iteration of the while-loop takes 17.73μs. // TODO check/modify for other architectures than Arduino Uno 16bit @@ -196,12 +196,12 @@ void MFRC522::PCD_Init() { // Set the chipSelectPin as digital output, do not select the slave yet pinMode(_chipSelectPin, OUTPUT); digitalWrite(_chipSelectPin, HIGH); - + // If a valid pin number has been set, pull device out of power down / reset state. if (_resetPowerDownPin != UNUSED_PIN) { // First set the resetPowerDownPin as digital input, to check the MFRC522 power down mode. pinMode(_resetPowerDownPin, INPUT); - + if (digitalRead(_resetPowerDownPin) == LOW) { // The MFRC522 chip is in power down mode. pinMode(_resetPowerDownPin, OUTPUT); // Now set the resetPowerDownPin as digital output. digitalWrite(_resetPowerDownPin, LOW); // Make sure we have a clean LOW state. @@ -216,7 +216,7 @@ void MFRC522::PCD_Init() { if (!hardReset) { // Perform a soft reset if we haven't triggered a hard reset above. PCD_Reset(); } - + // Reset baud rates PCD_WriteRegister(TxModeReg, 0x00); PCD_WriteRegister(RxModeReg, 0x00); @@ -230,7 +230,7 @@ void MFRC522::PCD_Init() { PCD_WriteRegister(TPrescalerReg, 0xA9); // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs. PCD_WriteRegister(TReloadRegH, 0x03); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout. PCD_WriteRegister(TReloadRegL, 0xE8); - + PCD_WriteRegister(TxASKReg, 0x40); // Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting PCD_WriteRegister(ModeReg, 0x3D); // Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4) PCD_AntennaOn(); // Enable the antenna driver pins TX1 and TX2 (they were disabled by the reset) @@ -251,7 +251,7 @@ void MFRC522::PCD_Init( byte chipSelectPin, ///< Arduino pin connected to MFRC5 byte resetPowerDownPin ///< Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low) ) { _chipSelectPin = chipSelectPin; - _resetPowerDownPin = resetPowerDownPin; + _resetPowerDownPin = resetPowerDownPin; // Set the chipSelectPin as digital output, do not select the slave yet PCD_Init(); } // End PCD_Init() @@ -262,7 +262,7 @@ void MFRC522::PCD_Init( byte chipSelectPin, ///< Arduino pin connected to MFRC5 void MFRC522::PCD_Reset() { PCD_WriteRegister(CommandReg, PCD_SoftReset); // Issue the SoftReset command. // The datasheet does not mention how long the SoftRest command takes to complete. - // But the MFRC522 might have been in soft power-down mode (triggered by bit 4 of CommandReg) + // But the MFRC522 might have been in soft power-down mode (triggered by bit 4 of CommandReg) // Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74μs. Let us be generous: 50ms. uint8_t count = 0; do { @@ -293,7 +293,7 @@ void MFRC522::PCD_AntennaOff() { * Get the current MFRC522 Receiver Gain (RxGain[2:0]) value. * See 9.3.3.6 / table 98 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf * NOTE: Return value scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved bits. - * + * * @return Value of the RxGain, scrubbed to the 3 bits used. */ byte MFRC522::PCD_GetAntennaGain() { @@ -315,29 +315,29 @@ void MFRC522::PCD_SetAntennaGain(byte mask) { /** * Performs a self-test of the MFRC522 * See 16.1.1 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf - * + * * @return Whether or not the test passed. Or false if no firmware reference is available. */ bool MFRC522::PCD_PerformSelfTest() { // This follows directly the steps outlined in 16.1.1 // 1. Perform a soft reset. PCD_Reset(); - + // 2. Clear the internal buffer by writing 25 bytes of 00h byte ZEROES[25] = {0x00}; PCD_WriteRegister(FIFOLevelReg, 0x80); // flush the FIFO buffer PCD_WriteRegister(FIFODataReg, 25, ZEROES); // write 25 bytes of 00h to FIFO PCD_WriteRegister(CommandReg, PCD_Mem); // transfer to internal buffer - + // 3. Enable self-test PCD_WriteRegister(AutoTestReg, 0x09); - + // 4. Write 00h to FIFO buffer PCD_WriteRegister(FIFODataReg, 0x00); - + // 5. Start self-test by issuing the CalcCRC command PCD_WriteRegister(CommandReg, PCD_CalcCRC); - + // 6. Wait for self-test to complete byte n; for (uint8_t i = 0; i < 0xFF; i++) { @@ -354,18 +354,18 @@ bool MFRC522::PCD_PerformSelfTest() { } } PCD_WriteRegister(CommandReg, PCD_Idle); // Stop calculating CRC for new content in the FIFO. - + // 7. Read out resulting 64 bytes from the FIFO buffer. byte result[64]; PCD_ReadRegister(FIFODataReg, 64, result, 0); - + // Auto self-test done // Reset AutoTestReg register to be 0 again. Required for normal operation. PCD_WriteRegister(AutoTestReg, 0x00); - + // Determine firmware version (see section 9.3.4.8 in spec) byte version = PCD_ReadRegister(VersionReg); - + // Pick the appropriate reference values const byte *reference; switch (version) { @@ -384,14 +384,14 @@ bool MFRC522::PCD_PerformSelfTest() { default: // Unknown version return false; // abort test } - + // Verify that the results match up to our expectations for (uint8_t i = 0; i < 64; i++) { if (result[i] != pgm_read_byte(&(reference[i]))) { return false; } } - + // Test passed; all is good. return true; } // End PCD_PerformSelfTest() @@ -405,22 +405,22 @@ bool MFRC522::PCD_PerformSelfTest() { //For more details about power control, refer to the datasheet - page 33 (8.6) void MFRC522::PCD_SoftPowerDown(){//Note : Only soft power down mode is available throught software - byte val = PCD_ReadRegister(CommandReg); // Read state of the command register - val |= (1<<4);// set PowerDown bit ( bit 4 ) to 1 + byte val = PCD_ReadRegister(CommandReg); // Read state of the command register + val |= (1<<4);// set PowerDown bit ( bit 4 ) to 1 PCD_WriteRegister(CommandReg, val);//write new value to the command register } void MFRC522::PCD_SoftPowerUp(){ - byte val = PCD_ReadRegister(CommandReg); // Read state of the command register - val &= ~(1<<4);// set PowerDown bit ( bit 4 ) to 0 + byte val = PCD_ReadRegister(CommandReg); // Read state of the command register + val &= ~(1<<4);// set PowerDown bit ( bit 4 ) to 0 PCD_WriteRegister(CommandReg, val);//write new value to the command register - // wait until PowerDown bit is cleared (this indicates end of wake up procedure) - const uint32_t timeout = (uint32_t)millis() + 500;// create timer for timeout (just in case) - - while(millis()<=timeout){ // set timeout to 500 ms + // wait until PowerDown bit is cleared (this indicates end of wake up procedure) + const uint32_t timeout = (uint32_t)millis() + 500;// create timer for timeout (just in case) + + while(millis()<=timeout){ // set timeout to 500 ms val = PCD_ReadRegister(CommandReg);// Read state of the command register - if(!(val & (1<<4))){ // if powerdown bit is 0 - break;// wake up procedure is finished + if(!(val & (1<<4))){ // if powerdown bit is 0 + break;// wake up procedure is finished } } } @@ -432,7 +432,7 @@ void MFRC522::PCD_SoftPowerUp(){ /** * Executes the Transceive command. * CRC validation can only be done if backData and backLen are specified. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::PCD_TransceiveData( byte *sendData, ///< Pointer to the data to transfer to the FIFO. @@ -466,7 +466,7 @@ MFRC522::StatusCode MFRC522::PCD_CommunicateWithPICC( byte command, ///< The co // Prepare values for BitFramingReg byte txLastBits = validBits ? *validBits : 0; byte bitFraming = (rxAlign << 4) + txLastBits; // RxAlign = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0] - + PCD_WriteRegister(CommandReg, PCD_Idle); // Stop any active command. PCD_WriteRegister(ComIrqReg, 0x7F); // Clear all seven interrupt request bits PCD_WriteRegister(FIFOLevelReg, 0x80); // FlushBuffer = 1, FIFO initialization @@ -476,7 +476,7 @@ MFRC522::StatusCode MFRC522::PCD_CommunicateWithPICC( byte command, ///< The co if (command == PCD_Transceive) { PCD_SetRegisterBitMask(BitFramingReg, 0x80); // StartSend=1, transmission of data starts } - + // Wait for the command to complete. // In PCD_Init() we set the TAuto flag in TModeReg. This means the timer automatically starts when the PCD stops transmitting. // Each iteration of the do-while-loop takes 17.86μs. @@ -495,15 +495,15 @@ MFRC522::StatusCode MFRC522::PCD_CommunicateWithPICC( byte command, ///< The co if (i == 0) { return STATUS_TIMEOUT; } - + // Stop now if any errors except collisions were detected. byte errorRegValue = PCD_ReadRegister(ErrorReg); // ErrorReg[7..0] bits are: WrErr TempErr reserved BufferOvfl CollErr CRCErr ParityErr ProtocolErr if (errorRegValue & 0x13) { // BufferOvfl ParityErr ProtocolErr return STATUS_ERROR; } - + byte _validBits = 0; - + // If the caller wants data back, get it from the MFRC522. if (backData && backLen) { byte n = PCD_ReadRegister(FIFOLevelReg); // Number of bytes in the FIFO @@ -517,12 +517,12 @@ MFRC522::StatusCode MFRC522::PCD_CommunicateWithPICC( byte command, ///< The co *validBits = _validBits; } } - + // Tell about collisions if (errorRegValue & 0x08) { // CollErr return STATUS_COLLISION; } - + // Perform CRC_A validation if requested. if (backData && backLen && checkCRC) { // In this case a MIFARE Classic NAK is not OK. @@ -543,14 +543,14 @@ MFRC522::StatusCode MFRC522::PCD_CommunicateWithPICC( byte command, ///< The co return STATUS_CRC_WRONG; } } - + return STATUS_OK; } // End PCD_CommunicateWithPICC() /** * Transmits a REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame. * Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::PICC_RequestA( byte *bufferATQA, ///< The buffer to store the ATQA (Answer to request) in @@ -562,7 +562,7 @@ MFRC522::StatusCode MFRC522::PICC_RequestA( byte *bufferATQA, ///< The buffer to /** * Transmits a Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame. * Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::PICC_WakeupA( byte *bufferATQA, ///< The buffer to store the ATQA (Answer to request) in @@ -574,16 +574,16 @@ MFRC522::StatusCode MFRC522::PICC_WakeupA( byte *bufferATQA, ///< The buffer to /** * Transmits REQA or WUPA commands. * Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. - */ + */ MFRC522::StatusCode MFRC522::PICC_REQA_or_WUPA( byte command, ///< The command to send - PICC_CMD_REQA or PICC_CMD_WUPA byte *bufferATQA, ///< The buffer to store the ATQA (Answer to request) in byte *bufferSize ///< Buffer size, at least two bytes. Also number of bytes returned if STATUS_OK. ) { byte validBits; MFRC522::StatusCode status; - + if (bufferATQA == nullptr || *bufferSize < 2) { // The ATQA response is 2 bytes long. return STATUS_NO_ROOM; } @@ -605,7 +605,7 @@ MFRC522::StatusCode MFRC522::PICC_REQA_or_WUPA( byte command, ///< The command * On success: * - The chosen PICC is in state ACTIVE(*) and all other PICCs have returned to state IDLE/HALT. (Figure 7 of the ISO/IEC 14443-3 draft.) * - The UID size and value of the chosen PICC is returned in *uid along with the SAK. - * + * * A PICC UID consists of 4, 7 or 10 bytes. * Only 4 bytes can be specified in a SELECT command, so for the longer UIDs two or three iterations are used: * UID size Number of UID bytes Cascade levels Example of PICC @@ -613,7 +613,7 @@ MFRC522::StatusCode MFRC522::PICC_REQA_or_WUPA( byte command, ///< The command * single 4 1 MIFARE Classic * double 7 2 MIFARE Ultralight * triple 10 3 Not currently in use? - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct. Normally output, but can also be used to supply a known UID. @@ -632,13 +632,13 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct byte buffer[9]; // The SELECT/ANTICOLLISION commands uses a 7 byte standard frame + 2 bytes CRC_A byte bufferUsed; // The number of bytes used in the buffer, ie the number of bytes to transfer to the FIFO. byte rxAlign; // Used in BitFramingReg. Defines the bit position for the first bit received. - byte txLastBits; // Used in BitFramingReg. The number of valid bits in the last transmitted byte. + byte txLastBits; // Used in BitFramingReg. The number of valid bits in the last transmitted byte. byte *responseBuffer; byte responseLength; - + // Description of buffer structure: // Byte 0: SEL Indicates the Cascade Level: PICC_CMD_SEL_CL1, PICC_CMD_SEL_CL2 or PICC_CMD_SEL_CL3 - // Byte 1: NVB Number of Valid Bits (in complete command, not just the UID): High nibble: complete bytes, Low nibble: Extra bits. + // Byte 1: NVB Number of Valid Bits (in complete command, not just the UID): High nibble: complete bytes, Low nibble: Extra bits. // Byte 2: UID-data or CT See explanation below. CT means Cascade Tag. // Byte 3: UID-data // Byte 4: UID-data @@ -657,15 +657,15 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct // 10 bytes 1 CT uid0 uid1 uid2 // 2 CT uid3 uid4 uid5 // 3 uid6 uid7 uid8 uid9 - + // Sanity checks if (validBits > 80) { return STATUS_INVALID; } - + // Prepare MFRC522 PCD_ClearRegisterBitMask(CollReg, 0x80); // ValuesAfterColl=1 => Bits received after collision are cleared. - + // Repeat Cascade Level loop until we have a complete UID. uidComplete = false; while (!uidComplete) { @@ -676,24 +676,24 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct uidIndex = 0; useCascadeTag = validBits && uid->size > 4; // When we know that the UID has more than 4 bytes break; - + case 2: buffer[0] = PICC_CMD_SEL_CL2; uidIndex = 3; useCascadeTag = validBits && uid->size > 7; // When we know that the UID has more than 7 bytes break; - + case 3: buffer[0] = PICC_CMD_SEL_CL3; uidIndex = 6; useCascadeTag = false; // Never used in CL3. break; - + default: return STATUS_INTERNAL_ERROR; break; } - + // How many UID bits are known in this Cascade Level? currentLevelKnownBits = validBits - (8 * uidIndex); if (currentLevelKnownBits < 0) { @@ -718,7 +718,7 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct if (useCascadeTag) { currentLevelKnownBits += 8; } - + // Repeat anti collision loop until we can transmit all UID bits + BCC and receive a SAK - max 32 iterations. selectDone = false; while (!selectDone) { @@ -750,11 +750,11 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct responseBuffer = &buffer[index]; responseLength = sizeof(buffer) - index; } - + // Set bit adjustments rxAlign = txLastBits; // Having a separate variable is overkill. But it makes the next line easier to read. PCD_WriteRegister(BitFramingReg, (rxAlign << 4) + txLastBits); // RxAlign = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0] - + // Transmit the buffer and receive the response. result = PCD_TransceiveData(buffer, bufferUsed, responseBuffer, &responseLength, &txLastBits, rxAlign); if (result == STATUS_COLLISION) { // More than one PICC in the field => collision. @@ -766,7 +766,7 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct if (collisionPos == 0) { collisionPos = 32; } - if (collisionPos <= currentLevelKnownBits) { // No progress - should not happen + if (collisionPos <= currentLevelKnownBits) { // No progress - should not happen return STATUS_INTERNAL_ERROR; } // Choose the PICC with the bit set. @@ -781,7 +781,7 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct } else { // STATUS_OK if (currentLevelKnownBits >= 32) { // This was a SELECT. - selectDone = true; // No more anticollision + selectDone = true; // No more anticollision // We continue below outside the while. } else { // This was an ANTICOLLISION. @@ -791,16 +791,16 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct } } } // End of while (!selectDone) - + // We do not check the CBB - it was constructed by us above. - + // Copy the found UID bytes from buffer[] to uid->uidByte[] index = (buffer[2] == PICC_CMD_CT) ? 3 : 2; // source index in buffer[] bytesToCopy = (buffer[2] == PICC_CMD_CT) ? 3 : 4; for (count = 0; count < bytesToCopy; count++) { uid->uidByte[uidIndex + count] = buffer[index++]; } - + // Check response SAK (Select Acknowledge) if (responseLength != 3 || txLastBits != 0) { // SAK must be exactly 24 bits (1 byte + CRC_A). return STATUS_ERROR; @@ -821,7 +821,7 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct uid->sak = responseBuffer[0]; } } // End of while (!uidComplete) - + // Set correct uid->size uid->size = 3 * cascadeLevel + 1; @@ -832,11 +832,11 @@ MFRC522::StatusCode MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct * Instructs a PICC in state ACTIVE(*) to go to state HALT. * * @return STATUS_OK on success, STATUS_??? otherwise. - */ + */ MFRC522::StatusCode MFRC522::PICC_HaltA() { MFRC522::StatusCode result; byte buffer[4]; - + // Build command buffer buffer[0] = PICC_CMD_HLTA; buffer[1] = 0; @@ -845,7 +845,7 @@ MFRC522::StatusCode MFRC522::PICC_HaltA() { if (result != STATUS_OK) { return result; } - + // Send the command. // The standard says: // If the PICC responds with any modulation during a period of 1 ms after the end of the frame containing the @@ -872,9 +872,9 @@ MFRC522::StatusCode MFRC522::PICC_HaltA() { * For use with MIFARE Classic PICCs. * The PICC must be selected - ie in state ACTIVE(*) - before calling this function. * Remember to call PCD_StopCrypto1() after communicating with the authenticated PICC - otherwise no new communications can start. - * + * * All keys are set to FFFFFFFFFFFFh at chip delivery. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. Probably STATUS_TIMEOUT if you supply the wrong key. */ MFRC522::StatusCode MFRC522::PCD_Authenticate(byte command, ///< PICC_CMD_MF_AUTH_KEY_A or PICC_CMD_MF_AUTH_KEY_B @@ -883,7 +883,7 @@ MFRC522::StatusCode MFRC522::PCD_Authenticate(byte command, ///< PICC_CMD_MF_AU Uid *uid ///< Pointer to Uid struct. The first 4 bytes of the UID is used. ) { byte waitIRq = 0x10; // IdleIRq - + // Build command buffer byte sendData[12]; sendData[0] = command; @@ -898,7 +898,7 @@ MFRC522::StatusCode MFRC522::PCD_Authenticate(byte command, ///< PICC_CMD_MF_AU for (byte i = 0; i < 4; i++) { // The last 4 bytes of the UID sendData[8+i] = uid->uidByte[i+uid->size-4]; } - + // Start the authentication. return PCD_CommunicateWithPICC(PCD_MFAuthent, waitIRq, &sendData[0], sizeof(sendData)); } // End PCD_Authenticate() @@ -914,18 +914,18 @@ void MFRC522::PCD_StopCrypto1() { /** * Reads 16 bytes (+ 2 bytes CRC_A) from the active PICC. - * + * * For MIFARE Classic the sector containing the block must be authenticated before calling this function. - * + * * For MIFARE Ultralight only addresses 00h to 0Fh are decoded. * The MF0ICU1 returns a NAK for higher addresses. * The MF0ICU1 responds to the READ command by sending 16 bytes starting from the page address defined by the command argument. * For example; if blockAddr is 03h then pages 03h, 04h, 05h, 06h are returned. * A roll-back is implemented: If blockAddr is 0Eh, then the contents of pages 0Eh, 0Fh, 00h and 01h are returned. - * + * * The buffer must be at least 18 bytes because a CRC_A is also returned. * Checks the CRC_A before returning STATUS_OK. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Read( byte blockAddr, ///< MIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The first page to return data from. @@ -933,12 +933,12 @@ MFRC522::StatusCode MFRC522::MIFARE_Read( byte blockAddr, ///< MIFARE Classic: byte *bufferSize ///< Buffer size, at least 18 bytes. Also number of bytes returned if STATUS_OK. ) { MFRC522::StatusCode result; - + // Sanity check if (buffer == nullptr || *bufferSize < 18) { return STATUS_NO_ROOM; } - + // Build command buffer buffer[0] = PICC_CMD_MF_READ; buffer[1] = blockAddr; @@ -947,20 +947,20 @@ MFRC522::StatusCode MFRC522::MIFARE_Read( byte blockAddr, ///< MIFARE Classic: if (result != STATUS_OK) { return result; } - + // Transmit the buffer and receive the response, validate CRC_A. return PCD_TransceiveData(buffer, 4, buffer, bufferSize, nullptr, 0, true); } // End MIFARE_Read() /** * Writes 16 bytes to the active PICC. - * + * * For MIFARE Classic the sector containing the block must be authenticated before calling this function. - * + * * For MIFARE Ultralight the operation is called "COMPATIBILITY WRITE". * Even though 16 bytes are transferred to the Ultralight PICC, only the least significant 4 bytes (bytes 0 to 3) * are written to the specified address. It is recommended to set the remaining bytes 04h to 0Fh to all logic 0. - * * + * * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Write( byte blockAddr, ///< MIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The page (2-15) to write to. @@ -968,12 +968,12 @@ MFRC522::StatusCode MFRC522::MIFARE_Write( byte blockAddr, ///< MIFARE Classic: byte bufferSize ///< Buffer size, must be at least 16 bytes. Exactly 16 bytes are written. ) { MFRC522::StatusCode result; - + // Sanity check if (buffer == nullptr || bufferSize < 16) { return STATUS_INVALID; } - + // Mifare Classic protocol requires two communications to perform a write. // Step 1: Tell the PICC we want to write to block blockAddr. byte cmdBuffer[2]; @@ -983,19 +983,19 @@ MFRC522::StatusCode MFRC522::MIFARE_Write( byte blockAddr, ///< MIFARE Classic: if (result != STATUS_OK) { return result; } - + // Step 2: Transfer the data result = PCD_MIFARE_Transceive(buffer, bufferSize); // Adds CRC_A and checks that the response is MF_ACK. if (result != STATUS_OK) { return result; } - + return STATUS_OK; } // End MIFARE_Write() /** * Writes a 4 byte page to the active MIFARE Ultralight PICC. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Ultralight_Write( byte page, ///< The page (2-15) to write to. @@ -1003,18 +1003,18 @@ MFRC522::StatusCode MFRC522::MIFARE_Ultralight_Write( byte page, ///< The page byte bufferSize ///< Buffer size, must be at least 4 bytes. Exactly 4 bytes are written. ) { MFRC522::StatusCode result; - + // Sanity check if (buffer == nullptr || bufferSize < 4) { return STATUS_INVALID; } - + // Build commmand buffer byte cmdBuffer[6]; cmdBuffer[0] = PICC_CMD_UL_WRITE; cmdBuffer[1] = page; memcpy(&cmdBuffer[2], buffer, 4); - + // Perform the write result = PCD_MIFARE_Transceive(cmdBuffer, 6); // Adds CRC_A and checks that the response is MF_ACK. if (result != STATUS_OK) { @@ -1028,7 +1028,7 @@ MFRC522::StatusCode MFRC522::MIFARE_Ultralight_Write( byte page, ///< The page * For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. * Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001]. * Use MIFARE_Transfer() to store the result in a block. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Decrement( byte blockAddr, ///< The block (0-0xff) number. @@ -1042,7 +1042,7 @@ MFRC522::StatusCode MFRC522::MIFARE_Decrement( byte blockAddr, ///< The block (0 * For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. * Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001]. * Use MIFARE_Transfer() to store the result in a block. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Increment( byte blockAddr, ///< The block (0-0xff) number. @@ -1056,7 +1056,7 @@ MFRC522::StatusCode MFRC522::MIFARE_Increment( byte blockAddr, ///< The block (0 * For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. * Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001]. * Use MIFARE_Transfer() to store the result in a block. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Restore( byte blockAddr ///< The block (0-0xff) number. @@ -1068,7 +1068,7 @@ MFRC522::StatusCode MFRC522::MIFARE_Restore( byte blockAddr ///< The block (0-0x /** * Helper function for the two-step MIFARE Classic protocol operations Decrement, Increment and Restore. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_TwoStepHelper( byte command, ///< The command to use @@ -1077,7 +1077,7 @@ MFRC522::StatusCode MFRC522::MIFARE_TwoStepHelper( byte command, ///< The comman ) { MFRC522::StatusCode result; byte cmdBuffer[2]; // We only need room for 2 bytes. - + // Step 1: Tell the PICC the command and block address cmdBuffer[0] = command; cmdBuffer[1] = blockAddr; @@ -1085,13 +1085,13 @@ MFRC522::StatusCode MFRC522::MIFARE_TwoStepHelper( byte command, ///< The comman if (result != STATUS_OK) { return result; } - + // Step 2: Transfer the data result = PCD_MIFARE_Transceive( (byte *)&data, 4, true); // Adds CRC_A and accept timeout as success. if (result != STATUS_OK) { return result; } - + return STATUS_OK; } // End MIFARE_TwoStepHelper() @@ -1099,14 +1099,14 @@ MFRC522::StatusCode MFRC522::MIFARE_TwoStepHelper( byte command, ///< The comman * MIFARE Transfer writes the value stored in the volatile memory into one MIFARE Classic block. * For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. * Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001]. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_Transfer( byte blockAddr ///< The block (0-0xff) number. ) { MFRC522::StatusCode result; byte cmdBuffer[2]; // We only need room for 2 bytes. - + // Tell the PICC we want to transfer the result into block blockAddr. cmdBuffer[0] = PICC_CMD_MF_TRANSFER; cmdBuffer[1] = blockAddr; @@ -1119,11 +1119,11 @@ MFRC522::StatusCode MFRC522::MIFARE_Transfer( byte blockAddr ///< The block (0-0 /** * Helper routine to read the current value from a Value Block. - * + * * Only for MIFARE Classic and only for blocks in "value block" mode, that * is: with access bits [C1 C2 C3] = [110] or [001]. The sector containing - * the block must be authenticated before calling this function. - * + * the block must be authenticated before calling this function. + * * @param[in] blockAddr The block (0x00-0xff) number. * @param[out] value Current value of the Value Block. * @return STATUS_OK on success, STATUS_??? otherwise. @@ -1132,7 +1132,7 @@ MFRC522::StatusCode MFRC522::MIFARE_GetValue(byte blockAddr, int32_t *value) { MFRC522::StatusCode status; byte buffer[18]; byte size = sizeof(buffer); - + // Read the block status = MIFARE_Read(blockAddr, buffer, &size); if (status == STATUS_OK) { @@ -1144,18 +1144,18 @@ MFRC522::StatusCode MFRC522::MIFARE_GetValue(byte blockAddr, int32_t *value) { /** * Helper routine to write a specific value into a Value Block. - * + * * Only for MIFARE Classic and only for blocks in "value block" mode, that * is: with access bits [C1 C2 C3] = [110] or [001]. The sector containing - * the block must be authenticated before calling this function. - * + * the block must be authenticated before calling this function. + * * @param[in] blockAddr The block (0x00-0xff) number. * @param[in] value New value of the Value Block. * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::MIFARE_SetValue(byte blockAddr, int32_t value) { byte buffer[18]; - + // Translate the int32_t into 4 bytes; repeated 2x in value block buffer[0] = buffer[ 8] = (value & 0xFF); buffer[1] = buffer[ 9] = (value & 0xFF00) >> 8; @@ -1169,16 +1169,16 @@ MFRC522::StatusCode MFRC522::MIFARE_SetValue(byte blockAddr, int32_t value) { // Address 2x with inverse address 2x buffer[12] = buffer[14] = blockAddr; buffer[13] = buffer[15] = ~blockAddr; - + // Write the whole data block return MIFARE_Write(blockAddr, buffer, 16); } // End MIFARE_SetValue() /** * Authenticate with a NTAG216. - * + * * Only for NTAG216. First implemented by Gargantuanman. - * + * * @param[in] passWord password. * @param[in] pACK result success???. * @return STATUS_OK on success, STATUS_??? otherwise. @@ -1190,32 +1190,32 @@ MFRC522::StatusCode MFRC522::PCD_NTAG216_AUTH(byte* passWord, byte pACK[]) //Aut MFRC522::StatusCode result; byte cmdBuffer[18]; // We need room for 16 bytes data and 2 bytes CRC_A. - + cmdBuffer[0] = 0x1B; //Comando de autentificacion - + for (byte i = 0; i<4; i++) cmdBuffer[i+1] = passWord[i]; - + result = PCD_CalculateCRC(cmdBuffer, 5, &cmdBuffer[5]); - + if (result!=STATUS_OK) { return result; } - + // Transceive the data, store the reply in cmdBuffer[] byte waitIRq = 0x30; // RxIRq and IdleIRq // byte cmdBufferSize = sizeof(cmdBuffer); byte validBits = 0; byte rxlength = 5; result = PCD_CommunicateWithPICC(PCD_Transceive, waitIRq, cmdBuffer, 7, cmdBuffer, &rxlength, &validBits); - + pACK[0] = cmdBuffer[0]; pACK[1] = cmdBuffer[1]; - + if (result!=STATUS_OK) { return result; } - + return STATUS_OK; } // End PCD_NTAG216_AUTH() @@ -1227,7 +1227,7 @@ MFRC522::StatusCode MFRC522::PCD_NTAG216_AUTH(byte* passWord, byte pACK[]) //Aut /** * Wrapper for MIFARE protocol communication. * Adds CRC_A, executes the Transceive command and checks that the response is MF_ACK or a timeout. - * + * * @return STATUS_OK on success, STATUS_??? otherwise. */ MFRC522::StatusCode MFRC522::PCD_MIFARE_Transceive( byte *sendData, ///< Pointer to the data to transfer to the FIFO. Do NOT include the CRC_A. @@ -1236,20 +1236,20 @@ MFRC522::StatusCode MFRC522::PCD_MIFARE_Transceive( byte *sendData, ///< Pointe ) { MFRC522::StatusCode result; byte cmdBuffer[18]; // We need room for 16 bytes data and 2 bytes CRC_A. - + // Sanity check if (sendData == nullptr || sendLen > 16) { return STATUS_INVALID; } - + // Copy sendData[] to cmdBuffer[] and add CRC_A memcpy(cmdBuffer, sendData, sendLen); result = PCD_CalculateCRC(cmdBuffer, sendLen, &cmdBuffer[sendLen]); - if (result != STATUS_OK) { + if (result != STATUS_OK) { return result; } sendLen += 2; - + // Transceive the data, store the reply in cmdBuffer[] byte waitIRq = 0x30; // RxIRq and IdleIRq byte cmdBufferSize = sizeof(cmdBuffer); @@ -1273,9 +1273,10 @@ MFRC522::StatusCode MFRC522::PCD_MIFARE_Transceive( byte *sendData, ///< Pointe /** * Returns a __FlashStringHelper pointer to a status code name. - * + * * @return const __FlashStringHelper * */ +/* const __FlashStringHelper *MFRC522::GetStatusCodeName(MFRC522::StatusCode code ///< One of the StatusCode enums. ) { switch (code) { @@ -1291,15 +1292,31 @@ const __FlashStringHelper *MFRC522::GetStatusCodeName(MFRC522::StatusCode code / default: return F("Unknown error"); } } // End GetStatusCodeName() +*/ +String MFRC522::GetStatusCodeName(MFRC522::StatusCode code ///< One of the StatusCode enums. + ) { + switch (code) { + case STATUS_OK: return F("Success."); + case STATUS_ERROR: return F("Error in communication."); + case STATUS_COLLISION: return F("Collision detected."); + case STATUS_TIMEOUT: return F("Timeout in communication."); + case STATUS_NO_ROOM: return F("A buffer is not big enough."); + case STATUS_INTERNAL_ERROR: return F("Internal error in the code. Should not happen."); + case STATUS_INVALID: return F("Invalid argument."); + case STATUS_CRC_WRONG: return F("The CRC_A does not match."); + case STATUS_MIFARE_NACK: return F("A MIFARE PICC responded with NAK."); + default: return F("Unknown error"); + } +} // End GetStatusCodeName() /** * Translates the SAK (Select Acknowledge) to a PICC type. - * + * * @return PICC_Type */ MFRC522::PICC_Type MFRC522::PICC_GetType(byte sak ///< The SAK byte returned from PICC_Select(). ) { - // http://www.nxp.com/documents/application_note/AN10833.pdf + // http://www.nxp.com/documents/application_note/AN10833.pdf // 3.2 Coding of Select Acknowledge (SAK) // ignore 8-bit (iso14443 starts with LSBit = bit 1) // fixes wrong type for manufacturer Infineon (http://nfc-tools.org/index.php?title=ISO14443A) @@ -1321,9 +1338,10 @@ MFRC522::PICC_Type MFRC522::PICC_GetType(byte sak ///< The SAK byte returned fr /** * Returns a __FlashStringHelper pointer to the PICC type name. - * + * * @return const __FlashStringHelper * */ +/* const __FlashStringHelper *MFRC522::PICC_GetTypeName(PICC_Type piccType ///< One of the PICC_Type enums. ) { switch (piccType) { @@ -1341,6 +1359,24 @@ const __FlashStringHelper *MFRC522::PICC_GetTypeName(PICC_Type piccType ///< One default: return F("Unknown type"); } } // End PICC_GetTypeName() +*/ +String MFRC522::PICC_GetTypeName(PICC_Type piccType ///< One of the PICC_Type enums. + ) { + switch (piccType) { + case PICC_TYPE_ISO_14443_4: return F("PICC compliant with ISO/IEC 14443-4"); + case PICC_TYPE_ISO_18092: return F("PICC compliant with ISO/IEC 18092 (NFC)"); + case PICC_TYPE_MIFARE_MINI: return F("MIFARE Mini, 320 bytes"); + case PICC_TYPE_MIFARE_1K: return F("MIFARE 1KB"); + case PICC_TYPE_MIFARE_4K: return F("MIFARE 4KB"); + case PICC_TYPE_MIFARE_UL: return F("MIFARE Ultralight or Ultralight C"); + case PICC_TYPE_MIFARE_PLUS: return F("MIFARE Plus"); + case PICC_TYPE_MIFARE_DESFIRE: return F("MIFARE DESFire"); + case PICC_TYPE_TNP3XXX: return F("MIFARE TNP3XXX"); + case PICC_TYPE_NOT_COMPLETE: return F("SAK indicates UID is not complete."); + case PICC_TYPE_UNKNOWN: + default: return F("Unknown type"); + } +} // End PICC_GetTypeName() /** * Dumps debug info about the connected PCD to Serial. @@ -1368,15 +1404,15 @@ void MFRC522::PCD_DumpVersionToSerial() { /** * Dumps debug info about the selected PICC to Serial. * On success the PICC is halted after dumping the data. - * For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried. + * For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried. */ void MFRC522::PICC_DumpToSerial(Uid *uid ///< Pointer to Uid struct returned from a successful PICC_Select(). ) { MIFARE_Key key; - + // Dump UID, SAK and Type PICC_DumpDetailsToSerial(uid); - + // Dump contents PICC_Type piccType = PICC_GetType(uid->sak); switch (piccType) { @@ -1389,11 +1425,11 @@ void MFRC522::PICC_DumpToSerial(Uid *uid ///< Pointer to Uid struct returned fro } PICC_DumpMifareClassicToSerial(uid, piccType, &key); break; - + case PICC_TYPE_MIFARE_UL: PICC_DumpMifareUltralightToSerial(); break; - + case PICC_TYPE_ISO_14443_4: case PICC_TYPE_MIFARE_DESFIRE: case PICC_TYPE_ISO_18092: @@ -1401,13 +1437,13 @@ void MFRC522::PICC_DumpToSerial(Uid *uid ///< Pointer to Uid struct returned fro case PICC_TYPE_TNP3XXX: Serial.println(F("Dumping memory contents not implemented for that PICC type.")); break; - + case PICC_TYPE_UNKNOWN: case PICC_TYPE_NOT_COMPLETE: default: break; // No memory dump here } - + Serial.println(); PICC_HaltA(); // Already done if it was a MIFARE Classic PICC. } // End PICC_DumpToSerial() @@ -1425,15 +1461,15 @@ void MFRC522::PICC_DumpDetailsToSerial(Uid *uid ///< Pointer to Uid struct retur else Serial.print(F(" ")); Serial.print(uid->uidByte[i], HEX); - } + } Serial.println(); - + // SAK Serial.print(F("Card SAK: ")); if(uid->sak < 0x10) Serial.print(F("0")); Serial.println(uid->sak, HEX); - + // (suggested) PICC type PICC_Type piccType = PICC_GetType(uid->sak); Serial.print(F("PICC type: ")); @@ -1454,21 +1490,21 @@ void MFRC522::PICC_DumpMifareClassicToSerial( Uid *uid, ///< Pointer to Uid st // Has 5 sectors * 4 blocks/sector * 16 bytes/block = 320 bytes. no_of_sectors = 5; break; - + case PICC_TYPE_MIFARE_1K: // Has 16 sectors * 4 blocks/sector * 16 bytes/block = 1024 bytes. no_of_sectors = 16; break; - + case PICC_TYPE_MIFARE_4K: // Has (32 sectors * 4 blocks/sector + 8 sectors * 16 blocks/sector) * 16 bytes/block = 4096 bytes. no_of_sectors = 40; break; - + default: // Should not happen. Ignore. break; } - + // Dump sectors, highest address first. if (no_of_sectors) { Serial.println(F("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits")); @@ -1493,7 +1529,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U byte firstBlock; // Address of lowest address to dump actually last block dumped) byte no_of_blocks; // Number of blocks in sector bool isSectorTrailer; // Set to true while handling the "last" (ie highest address) in the sector. - + // The access bits are stored in a peculiar fashion. // There are four groups: // g[3] Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39) @@ -1508,7 +1544,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U byte g[4]; // Access bits for each of the four groups. byte group; // 0-3 - active group for access bits bool firstInGroup; // True for the first block dumped in the group - + // Determine position and size of sector. if (sector < 32) { // Sectors 0..31 has 4 blocks each no_of_blocks = 4; @@ -1521,7 +1557,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U else { // Illegal input, no MIFARE Classic PICC has more than 40 sectors. return; } - + // Dump blocks, highest address first. byte byteCount; byte buffer[18]; @@ -1558,7 +1594,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U status = PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, uid); if (status != STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); return; } } @@ -1567,7 +1603,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U status = MIFARE_Read(blockAddr, buffer, &byteCount); if (status != STATUS_OK) { Serial.print(F("MIFARE_Read() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); continue; } // Dump data @@ -1596,7 +1632,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3); isSectorTrailer = false; } - + // Which access group is this block in? if (no_of_blocks == 4) { group = blockOffset; @@ -1606,7 +1642,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U group = blockOffset / 5; firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5); } - + if (firstInGroup) { // Print access bits Serial.print(F(" [ ")); @@ -1618,7 +1654,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U Serial.print(F(" Inverted access bits did not match! ")); } } - + if (group != 3 && (g[group] == 1 || g[group] == 6)) { // Not a sector trailer, a value block int32_t value = (int32_t(buffer[3])<<24) | (int32_t(buffer[2])<<16) | (int32_t(buffer[1])<<8) | int32_t(buffer[0]); Serial.print(F(" Value=0x")); Serial.print(value, HEX); @@ -1626,7 +1662,7 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U } Serial.println(); } - + return; } // End PICC_DumpMifareClassicSectorToSerial() @@ -1638,7 +1674,7 @@ void MFRC522::PICC_DumpMifareUltralightToSerial() { byte byteCount; byte buffer[18]; byte i; - + Serial.println(F("Page 0 1 2 3")); // Try the mpages of the original Ultralight. Ultralight C has more pages. for (byte page = 0; page < 16; page +=4) { // Read returns data for 4 pages at a time. @@ -1647,7 +1683,7 @@ void MFRC522::PICC_DumpMifareUltralightToSerial() { status = MIFARE_Read(page, buffer, &byteCount); if (status != STATUS_OK) { Serial.print(F("MIFARE_Read() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); break; } // Dump data @@ -1684,7 +1720,7 @@ void MFRC522::MIFARE_SetAccessBits( byte *accessBitBuffer, ///< Pointer to byte byte c1 = ((g3 & 4) << 1) | ((g2 & 4) << 0) | ((g1 & 4) >> 1) | ((g0 & 4) >> 2); byte c2 = ((g3 & 2) << 2) | ((g2 & 2) << 1) | ((g1 & 2) << 0) | ((g0 & 2) >> 1); byte c3 = ((g3 & 1) << 3) | ((g2 & 1) << 2) | ((g1 & 1) << 1) | ((g0 & 1) << 0); - + accessBitBuffer[0] = (~c2 & 0xF) << 4 | (~c1 & 0xF); accessBitBuffer[1] = c1 << 4 | (~c3 & 0xF); accessBitBuffer[2] = c3 << 4 | c2; @@ -1699,7 +1735,7 @@ void MFRC522::MIFARE_SetAccessBits( byte *accessBitBuffer, ///< Pointer to byte * this sequence works immediately when the card is in the reader vicinity. * This means you can use this method even on "bricked" cards that your reader does * not recognise anymore (see MFRC522::MIFARE_UnbrickUidSector). - * + * * Of course with non-bricked devices, you're free to select them before calling this function. */ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { @@ -1710,9 +1746,9 @@ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { // > 43 // < A (4 bits only) // Then you can write to sector 0 without authenticating - + PICC_HaltA(); // 50 00 57 CD - + byte cmd = 0x40; byte validBits = 7; /* Our command is only 7 bits. After receiving card response, this will contain amount of valid response bits. */ @@ -1723,7 +1759,7 @@ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { if(logErrors) { Serial.println(F("Card did not respond to 0x40 after HALT command. Are you sure it is a UID changeable one?")); Serial.print(F("Error name: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); } return false; } @@ -1737,7 +1773,7 @@ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { } return false; } - + cmd = 0x43; validBits = 8; status = PCD_TransceiveData(&cmd, (byte)1, response, &received, &validBits, (byte)0, false); // 43 @@ -1745,7 +1781,7 @@ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { if(logErrors) { Serial.println(F("Error in communication at command 0x43, after successfully executing 0x40")); Serial.print(F("Error name: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); } return false; } @@ -1759,7 +1795,7 @@ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { } return false; } - + // You can now write to sector 0 without authenticating! return true; } // End MIFARE_OpenUidBackdoor() @@ -1773,7 +1809,7 @@ bool MFRC522::MIFARE_OpenUidBackdoor(bool logErrors) { * Make sure to have selected the card before this function is called. */ bool MFRC522::MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors) { - + // UID + BCC byte can not be larger than 16 together if (!newUid || !uidSize || uidSize > 15) { if (logErrors) { @@ -1781,31 +1817,31 @@ bool MFRC522::MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors) { } return false; } - + // Authenticate for reading MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; MFRC522::StatusCode status = PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, (byte)1, &key, &uid); if (status != STATUS_OK) { - + if (status == STATUS_TIMEOUT) { // We get a read timeout if no card is selected yet, so let's select one - + // Wake the card up again if sleeping // byte atqa_answer[2]; // byte atqa_size = 2; // PICC_WakeupA(atqa_answer, &atqa_size); - + if (!PICC_IsNewCardPresent() || !PICC_ReadCardSerial()) { Serial.println(F("No card was previously selected, and none are available. Failed to set UID.")); return false; } - + status = PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, (byte)1, &key, &uid); if (status != STATUS_OK) { // We tried, time to give up if (logErrors) { Serial.println(F("Failed to authenticate to card for reading, could not set UID: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); } return false; } @@ -1813,12 +1849,12 @@ bool MFRC522::MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors) { else { if (logErrors) { Serial.print(F("PCD_Authenticate() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); } return false; } } - + // Read block 0 byte block0_buffer[18]; byte byteCount = sizeof(block0_buffer); @@ -1826,25 +1862,25 @@ bool MFRC522::MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors) { if (status != STATUS_OK) { if (logErrors) { Serial.print(F("MIFARE_Read() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); Serial.println(F("Are you sure your KEY A for sector 0 is 0xFFFFFFFFFFFF?")); } return false; } - + // Write new UID to the data we just read, and calculate BCC byte byte bcc = 0; for (uint8_t i = 0; i < uidSize; i++) { block0_buffer[i] = newUid[i]; bcc ^= newUid[i]; } - + // Write BCC byte to buffer block0_buffer[uidSize] = bcc; - + // Stop encrypted traffic so we can send raw bytes PCD_StopCrypto1(); - + // Activate UID backdoor if (!MIFARE_OpenUidBackdoor(logErrors)) { if (logErrors) { @@ -1852,22 +1888,22 @@ bool MFRC522::MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors) { } return false; } - + // Write modified block 0 back to card status = MIFARE_Write((byte)0, block0_buffer, (byte)16); if (status != STATUS_OK) { if (logErrors) { Serial.print(F("MIFARE_Write() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); } return false; } - + // Wake the card up again byte atqa_answer[2]; byte atqa_size = 2; PICC_WakeupA(atqa_answer, &atqa_size); - + return true; } @@ -1876,15 +1912,15 @@ bool MFRC522::MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors) { */ bool MFRC522::MIFARE_UnbrickUidSector(bool logErrors) { MIFARE_OpenUidBackdoor(logErrors); - - byte block0_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - + + byte block0_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + // Write modified block 0 back to card MFRC522::StatusCode status = MIFARE_Write((byte)0, block0_buffer, (byte)16); if (status != STATUS_OK) { if (logErrors) { Serial.print(F("MIFARE_Write() failed: ")); - Serial.println(GetStatusCodeName(status)); + Serial.println(GetStatusCodeName(status).c_str()); } return false; } @@ -1898,7 +1934,7 @@ bool MFRC522::MIFARE_UnbrickUidSector(bool logErrors) { /** * Returns true if a PICC responds to PICC_CMD_REQA. * Only "new" cards in state IDLE are invited. Sleeping cards in state HALT are ignored. - * + * * @return bool */ bool MFRC522::PICC_IsNewCardPresent() { @@ -1920,10 +1956,10 @@ bool MFRC522::PICC_IsNewCardPresent() { * Returns true if a UID could be read. * Remember to call PICC_IsNewCardPresent(), PICC_RequestA() or PICC_WakeupA() first. * The read UID is available in the class variable uid. - * + * * @return bool */ bool MFRC522::PICC_ReadCardSerial() { MFRC522::StatusCode result = PICC_Select(&uid); return (result == STATUS_OK); -} // End +} // End diff --git a/lib/lib_div/rfid-1.4.7/src/MFRC522.h b/lib/lib_div/rfid-1.4.7/src/MFRC522.h index 5ebbd27dd..f04dd966d 100644 --- a/lib/lib_div/rfid-1.4.7/src/MFRC522.h +++ b/lib/lib_div/rfid-1.4.7/src/MFRC522.h @@ -1,10 +1,10 @@ /** * Library to use Arduino MFRC522 module. - * + * * @authors Dr.Leong, Miguel Balboa, Søren Thing Andersen, Tom Clement, many more! See GitLog. - * + * * For more information read the README. - * + * * Please read this file for an overview and then MFRC522.cpp for comments on the specific functions. */ #ifndef MFRC522_h @@ -92,7 +92,7 @@ public: DivIEnReg = 0x03 << 1, // enable and disable interrupt request control bits ComIrqReg = 0x04 << 1, // interrupt request bits DivIrqReg = 0x05 << 1, // interrupt request bits - ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed + ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed Status1Reg = 0x07 << 1, // communication status bits Status2Reg = 0x08 << 1, // receiver and transmitter status bits FIFODataReg = 0x09 << 1, // input and output of 64 byte FIFO buffer @@ -102,10 +102,10 @@ public: BitFramingReg = 0x0D << 1, // adjustments for bit-oriented frames CollReg = 0x0E << 1, // bit position of the first bit-collision detected on the RF interface // 0x0F // reserved for future use - + // Page 1: Command // 0x10 // reserved for future use - ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving + ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving TxModeReg = 0x12 << 1, // defines transmission data rate and framing RxModeReg = 0x13 << 1, // defines reception data rate and framing TxControlReg = 0x14 << 1, // controls the logical behavior of the antenna driver pins TX1 and TX2 @@ -120,7 +120,7 @@ public: MfRxReg = 0x1D << 1, // controls some MIFARE communication receive parameters // 0x1E // reserved for future use SerialSpeedReg = 0x1F << 1, // selects the speed of the serial UART interface - + // Page 2: Configuration // 0x20 // reserved for future use CRCResultRegH = 0x21 << 1, // shows the MSB and LSB values of the CRC calculation @@ -129,7 +129,7 @@ public: ModWidthReg = 0x24 << 1, // controls the ModWidth setting? // 0x25 // reserved for future use RFCfgReg = 0x26 << 1, // configures the receiver gain - GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation + GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation CWGsPReg = 0x28 << 1, // defines the conductance of the p-driver output during periods of no modulation ModGsPReg = 0x29 << 1, // defines the conductance of the p-driver output during periods of modulation TModeReg = 0x2A << 1, // defines settings for the internal timer @@ -138,7 +138,7 @@ public: TReloadRegL = 0x2D << 1, TCounterValueRegH = 0x2E << 1, // shows the 16-bit timer value TCounterValueRegL = 0x2F << 1, - + // Page 3: Test Registers // 0x30 // reserved for future use TestSel1Reg = 0x31 << 1, // general test signal configuration @@ -157,7 +157,7 @@ public: // 0x3E // reserved for production tests // 0x3F // reserved for production tests }; - + // MFRC522 commands. Described in chapter 10 of the datasheet. enum PCD_Command : byte { PCD_Idle = 0x00, // no action, cancels current command execution @@ -171,7 +171,7 @@ public: PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader PCD_SoftReset = 0x0F // resets the MFRC522 }; - + // MFRC522 RxGain[2:0] masks, defines the receiver's signal voltage gain factor (on the PCD). // Described in 9.3.3.6 / table 98 of the datasheet at http://www.nxp.com/documents/data_sheet/MFRC522.pdf enum PCD_RxGain : byte { @@ -187,7 +187,7 @@ public: RxGain_avg = 0x04 << 4, // 100b - 33 dB, average, convenience for RxGain_33dB RxGain_max = 0x07 << 4 // 111b - 48 dB, maximum, convenience for RxGain_48dB }; - + // Commands sent to the PICC. enum PICC_Command : byte { // The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4) @@ -214,18 +214,18 @@ public: // The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight. PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC. }; - + // MIFARE constants that does not fit anywhere else enum MIFARE_Misc { MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK. MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes. }; - + // PICC types we can detect. Remember to update PICC_GetTypeName() if you add more. // last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered enum PICC_Type : byte { PICC_TYPE_UNKNOWN , - PICC_TYPE_ISO_14443_4 , // PICC compliant with ISO/IEC 14443-4 + PICC_TYPE_ISO_14443_4 , // PICC compliant with ISO/IEC 14443-4 PICC_TYPE_ISO_18092 , // PICC compliant with ISO/IEC 18092 (NFC) PICC_TYPE_MIFARE_MINI , // MIFARE Classic protocol, 320 bytes PICC_TYPE_MIFARE_1K , // MIFARE Classic protocol, 1KB @@ -236,7 +236,7 @@ public: PICC_TYPE_TNP3XXX , // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure PICC_TYPE_NOT_COMPLETE = 0xff // SAK indicates UID is not complete. }; - + // Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more. // last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered enum StatusCode : byte { @@ -250,7 +250,7 @@ public: STATUS_CRC_WRONG , // The CRC_A does not match STATUS_MIFARE_NACK = 0xff // A MIFARE PICC responded with NAK. }; - + // A struct used for passing the UID of a PICC. typedef struct { byte size; // Number of bytes in the UID. 4, 7 or 10. @@ -262,17 +262,17 @@ public: typedef struct { byte keyByte[MF_KEY_SIZE]; } MIFARE_Key; - + // Member variables Uid uid; // Used by PICC_ReadCardSerial(). - + ///////////////////////////////////////////////////////////////////////////////////// // Functions for setting up the Arduino ///////////////////////////////////////////////////////////////////////////////////// MFRC522(); MFRC522(byte resetPowerDownPin); MFRC522(byte chipSelectPin, byte resetPowerDownPin); - + ///////////////////////////////////////////////////////////////////////////////////// // Basic interface functions for communicating with the MFRC522 ///////////////////////////////////////////////////////////////////////////////////// @@ -283,7 +283,7 @@ public: void PCD_SetRegisterBitMask(PCD_Register reg, byte mask); void PCD_ClearRegisterBitMask(PCD_Register reg, byte mask); StatusCode PCD_CalculateCRC(byte *data, byte length, byte *result); - + ///////////////////////////////////////////////////////////////////////////////////// // Functions for manipulating the MFRC522 ///////////////////////////////////////////////////////////////////////////////////// @@ -296,13 +296,13 @@ public: byte PCD_GetAntennaGain(); void PCD_SetAntennaGain(byte mask); bool PCD_PerformSelfTest(); - + ///////////////////////////////////////////////////////////////////////////////////// // Power control functions ///////////////////////////////////////////////////////////////////////////////////// void PCD_SoftPowerDown(); void PCD_SoftPowerUp(); - + ///////////////////////////////////////////////////////////////////////////////////// // Functions for communicating with PICCs ///////////////////////////////////////////////////////////////////////////////////// @@ -329,19 +329,21 @@ public: StatusCode MIFARE_GetValue(byte blockAddr, int32_t *value); StatusCode MIFARE_SetValue(byte blockAddr, int32_t value); StatusCode PCD_NTAG216_AUTH(byte *passWord, byte pACK[]); - + ///////////////////////////////////////////////////////////////////////////////////// // Support functions ///////////////////////////////////////////////////////////////////////////////////// StatusCode PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout = false); // old function used too much memory, now name moved to flash; if you need char, copy from flash to memory //const char *GetStatusCodeName(byte code); - static const __FlashStringHelper *GetStatusCodeName(StatusCode code); +// static const __FlashStringHelper *GetStatusCodeName(StatusCode code); + String GetStatusCodeName(StatusCode code); static PICC_Type PICC_GetType(byte sak); // old function used too much memory, now name moved to flash; if you need char, copy from flash to memory //const char *PICC_GetTypeName(byte type); - static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type); - +// static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type); + String PICC_GetTypeName(PICC_Type type); + // Support functions for debuging void PCD_DumpVersionToSerial(); void PICC_DumpToSerial(Uid *uid); @@ -349,19 +351,19 @@ public: void PICC_DumpMifareClassicToSerial(Uid *uid, PICC_Type piccType, MIFARE_Key *key); void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector); void PICC_DumpMifareUltralightToSerial(); - + // Advanced functions for MIFARE void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3); bool MIFARE_OpenUidBackdoor(bool logErrors); bool MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors); bool MIFARE_UnbrickUidSector(bool logErrors); - + ///////////////////////////////////////////////////////////////////////////////////// // Convenience functions - does not add extra functionality ///////////////////////////////////////////////////////////////////////////////////// virtual bool PICC_IsNewCardPresent(); virtual bool PICC_ReadCardSerial(); - + protected: byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low) byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low) diff --git a/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino b/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino index 7cb2daf93..dcd9f5d3a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino @@ -86,7 +86,7 @@ void RC522ScanForTag(void) { } #endif // USE_RC522_DATA_FUNCTION #ifdef USE_RC522_TYPE_INFORMATION - ResponseAppend_P(PSTR(",\"" D_JSON_TYPE "\":\"%s\""), Mfrc522->PICC_GetTypeName(picc_type)); + ResponseAppend_P(PSTR(",\"" D_JSON_TYPE "\":\"%s\""), Mfrc522->PICC_GetTypeName(picc_type).c_str()); #endif // USE_RC522_TYPE_INFORMATION ResponseJsonEndEnd(); MqttPublishTeleSensor();