Merge branch 'master' into example_firmware_check
This commit is contained in:
85
MFRC522.cpp
85
MFRC522.cpp
@@ -18,18 +18,8 @@
|
|||||||
MFRC522::MFRC522( byte chipSelectPin, ///< Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
|
MFRC522::MFRC522( 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)
|
byte resetPowerDownPin ///< Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
|
||||||
) {
|
) {
|
||||||
// Set the chipSelectPin as digital output, do not select the slave yet
|
|
||||||
_chipSelectPin = chipSelectPin;
|
_chipSelectPin = chipSelectPin;
|
||||||
pinMode(_chipSelectPin, OUTPUT);
|
|
||||||
digitalWrite(_chipSelectPin, HIGH);
|
|
||||||
|
|
||||||
// Set the resetPowerDownPin as digital output, do not reset or power down.
|
|
||||||
_resetPowerDownPin = resetPowerDownPin;
|
_resetPowerDownPin = resetPowerDownPin;
|
||||||
pinMode(_resetPowerDownPin, OUTPUT);
|
|
||||||
digitalWrite(_resetPowerDownPin, LOW);
|
|
||||||
|
|
||||||
// Set SPI bus to work with MFRC522 chip.
|
|
||||||
setSPIConfig();
|
|
||||||
} // End constructor
|
} // End constructor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,7 +90,7 @@ void MFRC522::PCD_ReadRegister( byte reg, ///< The register to read from. One o
|
|||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Serial.print("Reading "); Serial.print(count); Serial.println(" bytes from register.");
|
//Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" bytes from register."));
|
||||||
byte address = 0x80 | (reg & 0x7E); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
byte address = 0x80 | (reg & 0x7E); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||||
byte index = 0; // Index in values array.
|
byte index = 0; // Index in values array.
|
||||||
digitalWrite(_chipSelectPin, LOW); // Select slave
|
digitalWrite(_chipSelectPin, LOW); // Select slave
|
||||||
@@ -194,6 +184,16 @@ byte MFRC522::PCD_CalculateCRC( byte *data, ///< In: Pointer to the data to tra
|
|||||||
* Initializes the MFRC522 chip.
|
* Initializes the MFRC522 chip.
|
||||||
*/
|
*/
|
||||||
void MFRC522::PCD_Init() {
|
void MFRC522::PCD_Init() {
|
||||||
|
// Set the chipSelectPin as digital output, do not select the slave yet
|
||||||
|
pinMode(_chipSelectPin, OUTPUT);
|
||||||
|
digitalWrite(_chipSelectPin, HIGH);
|
||||||
|
|
||||||
|
// Set the resetPowerDownPin as digital output, do not reset or power down.
|
||||||
|
pinMode(_resetPowerDownPin, OUTPUT);
|
||||||
|
|
||||||
|
// Set SPI bus to work with MFRC522 chip.
|
||||||
|
setSPIConfig();
|
||||||
|
|
||||||
if (digitalRead(_resetPowerDownPin) == LOW) { //The MFRC522 chip is in power down mode.
|
if (digitalRead(_resetPowerDownPin) == LOW) { //The MFRC522 chip is in power down mode.
|
||||||
digitalWrite(_resetPowerDownPin, HIGH); // Exit power down mode. This triggers a hard reset.
|
digitalWrite(_resetPowerDownPin, HIGH); // Exit power down mode. This triggers a hard reset.
|
||||||
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74<37>s. Let us be generous: 50ms.
|
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74<37>s. Let us be generous: 50ms.
|
||||||
@@ -285,9 +285,9 @@ bool MFRC522::PCD_PerformSelfTest() {
|
|||||||
|
|
||||||
// 2. Clear the internal buffer by writing 25 bytes of 00h
|
// 2. Clear the internal buffer by writing 25 bytes of 00h
|
||||||
byte ZEROES[25] = {0x00};
|
byte ZEROES[25] = {0x00};
|
||||||
PCD_SetRegisterBitMask(FIFOLevelReg, 0x80); // flush the FIFO buffer
|
PCD_SetRegisterBitMask(FIFOLevelReg, 0x80); // flush the FIFO buffer
|
||||||
PCD_WriteRegister(FIFODataReg, 25, ZEROES); // write 25 bytes of 00h to FIFO
|
PCD_WriteRegister(FIFODataReg, 25, ZEROES); // write 25 bytes of 00h to FIFO
|
||||||
PCD_WriteRegister(CommandReg, PCD_Mem); // transfer to internal buffer
|
PCD_WriteRegister(CommandReg, PCD_Mem); // transfer to internal buffer
|
||||||
|
|
||||||
// 3. Enable self-test
|
// 3. Enable self-test
|
||||||
PCD_WriteRegister(AutoTestReg, 0x09);
|
PCD_WriteRegister(AutoTestReg, 0x09);
|
||||||
@@ -323,6 +323,12 @@ bool MFRC522::PCD_PerformSelfTest() {
|
|||||||
// Pick the appropriate reference values
|
// Pick the appropriate reference values
|
||||||
const byte *reference;
|
const byte *reference;
|
||||||
switch (version) {
|
switch (version) {
|
||||||
|
case 0x88: // Fudan Semiconductor FM17522 clone
|
||||||
|
reference = FM17522_firmware_reference;
|
||||||
|
break;
|
||||||
|
case 0x90: // Version 0.0
|
||||||
|
reference = MFRC522_firmware_referenceV0_0;
|
||||||
|
break;
|
||||||
case 0x91: // Version 1.0
|
case 0x91: // Version 1.0
|
||||||
reference = MFRC522_firmware_referenceV1_0;
|
reference = MFRC522_firmware_referenceV1_0;
|
||||||
break;
|
break;
|
||||||
@@ -545,7 +551,7 @@ byte MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct. Normally outp
|
|||||||
byte count;
|
byte count;
|
||||||
byte index;
|
byte index;
|
||||||
byte uidIndex; // The first index in uid->uidByte[] that is used in the current Cascade Level.
|
byte uidIndex; // The first index in uid->uidByte[] that is used in the current Cascade Level.
|
||||||
char currentLevelKnownBits; // The number of known UID bits in the current Cascade Level.
|
int8_t currentLevelKnownBits; // The number of known UID bits in the current Cascade Level.
|
||||||
byte buffer[9]; // The SELECT/ANTICOLLISION commands uses a 7 byte standard frame + 2 bytes CRC_A
|
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 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 rxAlign; // Used in BitFramingReg. Defines the bit position for the first bit received.
|
||||||
@@ -641,7 +647,7 @@ byte MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct. Normally outp
|
|||||||
while (!selectDone) {
|
while (!selectDone) {
|
||||||
// Find out how many bits and bytes to send and receive.
|
// Find out how many bits and bytes to send and receive.
|
||||||
if (currentLevelKnownBits >= 32) { // All UID bits in this Cascade Level are known. This is a SELECT.
|
if (currentLevelKnownBits >= 32) { // All UID bits in this Cascade Level are known. This is a SELECT.
|
||||||
//Serial.print("SELECT: currentLevelKnownBits="); Serial.println(currentLevelKnownBits, DEC);
|
//Serial.print(F("SELECT: currentLevelKnownBits=")); Serial.println(currentLevelKnownBits, DEC);
|
||||||
buffer[1] = 0x70; // NVB - Number of Valid Bits: Seven whole bytes
|
buffer[1] = 0x70; // NVB - Number of Valid Bits: Seven whole bytes
|
||||||
// Calculate BCC - Block Check Character
|
// Calculate BCC - Block Check Character
|
||||||
buffer[6] = buffer[2] ^ buffer[3] ^ buffer[4] ^ buffer[5];
|
buffer[6] = buffer[2] ^ buffer[3] ^ buffer[4] ^ buffer[5];
|
||||||
@@ -657,7 +663,7 @@ byte MFRC522::PICC_Select( Uid *uid, ///< Pointer to Uid struct. Normally outp
|
|||||||
responseLength = 3;
|
responseLength = 3;
|
||||||
}
|
}
|
||||||
else { // This is an ANTICOLLISION.
|
else { // This is an ANTICOLLISION.
|
||||||
//Serial.print("ANTICOLLISION: currentLevelKnownBits="); Serial.println(currentLevelKnownBits, DEC);
|
//Serial.print(F("ANTICOLLISION: currentLevelKnownBits=")); Serial.println(currentLevelKnownBits, DEC);
|
||||||
txLastBits = currentLevelKnownBits % 8;
|
txLastBits = currentLevelKnownBits % 8;
|
||||||
count = currentLevelKnownBits / 8; // Number of whole bytes in the UID part.
|
count = currentLevelKnownBits / 8; // Number of whole bytes in the UID part.
|
||||||
index = 2 + count; // Number of whole bytes: SEL + NVB + UIDs
|
index = 2 + count; // Number of whole bytes: SEL + NVB + UIDs
|
||||||
@@ -1141,6 +1147,7 @@ byte MFRC522::PCD_MIFARE_Transceive( byte *sendData, ///< Pointer to the data t
|
|||||||
/**
|
/**
|
||||||
* Returns a __FlashStringHelper pointer to a status code name.
|
* Returns a __FlashStringHelper pointer to a status code name.
|
||||||
*
|
*
|
||||||
|
* @return const __FlashStringHelper *
|
||||||
*/
|
*/
|
||||||
const __FlashStringHelper *MFRC522::GetStatusCodeName(byte code ///< One of the StatusCode enums.
|
const __FlashStringHelper *MFRC522::GetStatusCodeName(byte code ///< One of the StatusCode enums.
|
||||||
) {
|
) {
|
||||||
@@ -1194,6 +1201,7 @@ byte MFRC522::PICC_GetType(byte sak ///< The SAK byte returned from PICC_Select
|
|||||||
/**
|
/**
|
||||||
* Returns a __FlashStringHelper pointer to the PICC type name.
|
* Returns a __FlashStringHelper pointer to the PICC type name.
|
||||||
*
|
*
|
||||||
|
* @return const __FlashStringHelper *
|
||||||
*/
|
*/
|
||||||
const __FlashStringHelper *MFRC522::PICC_GetTypeName(byte piccType ///< One of the PICC_Type enums.
|
const __FlashStringHelper *MFRC522::PICC_GetTypeName(byte piccType ///< One of the PICC_Type enums.
|
||||||
) {
|
) {
|
||||||
@@ -1224,7 +1232,10 @@ void MFRC522::PICC_DumpToSerial(Uid *uid ///< Pointer to Uid struct returned fro
|
|||||||
// UID
|
// UID
|
||||||
Serial.print(F("Card UID:"));
|
Serial.print(F("Card UID:"));
|
||||||
for (byte i = 0; i < uid->size; i++) {
|
for (byte i = 0; i < uid->size; i++) {
|
||||||
Serial.print(uid->uidByte[i] < 0x10 ? " 0" : " ");
|
if(uid->uidByte[i] < 0x10)
|
||||||
|
Serial.print(F(" 0"));
|
||||||
|
else
|
||||||
|
Serial.print(F(" "));
|
||||||
Serial.print(uid->uidByte[i], HEX);
|
Serial.print(uid->uidByte[i], HEX);
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
@@ -1299,7 +1310,7 @@ void MFRC522::PICC_DumpMifareClassicToSerial( Uid *uid, ///< Pointer to Uid str
|
|||||||
// Dump sectors, highest address first.
|
// Dump sectors, highest address first.
|
||||||
if (no_of_sectors) {
|
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"));
|
Serial.println(F("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits"));
|
||||||
for (char i = no_of_sectors - 1; i >= 0; i--) {
|
for (int8_t i = no_of_sectors - 1; i >= 0; i--) {
|
||||||
PICC_DumpMifareClassicSectorToSerial(uid, key, i);
|
PICC_DumpMifareClassicSectorToSerial(uid, key, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1354,11 +1365,14 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U
|
|||||||
byte buffer[18];
|
byte buffer[18];
|
||||||
byte blockAddr;
|
byte blockAddr;
|
||||||
isSectorTrailer = true;
|
isSectorTrailer = true;
|
||||||
for (char blockOffset = no_of_blocks - 1; blockOffset >= 0; blockOffset--) {
|
for (int8_t blockOffset = no_of_blocks - 1; blockOffset >= 0; blockOffset--) {
|
||||||
blockAddr = firstBlock + blockOffset;
|
blockAddr = firstBlock + blockOffset;
|
||||||
// Sector number - only on first line
|
// Sector number - only on first line
|
||||||
if (isSectorTrailer) {
|
if (isSectorTrailer) {
|
||||||
Serial.print(sector < 10 ? " " : " "); // Pad with spaces
|
if(sector < 10)
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
|
else
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
Serial.print(sector);
|
Serial.print(sector);
|
||||||
Serial.print(F(" "));
|
Serial.print(F(" "));
|
||||||
}
|
}
|
||||||
@@ -1366,7 +1380,14 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U
|
|||||||
Serial.print(F(" "));
|
Serial.print(F(" "));
|
||||||
}
|
}
|
||||||
// Block number
|
// Block number
|
||||||
Serial.print(blockAddr < 10 ? " " : (blockAddr < 100 ? " " : " ")); // Pad with spaces
|
if(blockAddr < 10)
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
|
else {
|
||||||
|
if(blockAddr < 100)
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
|
else
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
|
}
|
||||||
Serial.print(blockAddr);
|
Serial.print(blockAddr);
|
||||||
Serial.print(F(" "));
|
Serial.print(F(" "));
|
||||||
// Establish encrypted communications before reading the first block
|
// Establish encrypted communications before reading the first block
|
||||||
@@ -1388,7 +1409,10 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U
|
|||||||
}
|
}
|
||||||
// Dump data
|
// Dump data
|
||||||
for (byte index = 0; index < 16; index++) {
|
for (byte index = 0; index < 16; index++) {
|
||||||
Serial.print(buffer[index] < 0x10 ? " 0" : " ");
|
if(buffer[index] < 0x10)
|
||||||
|
Serial.print(F(" 0"));
|
||||||
|
else
|
||||||
|
Serial.print(F(" "));
|
||||||
Serial.print(buffer[index], HEX);
|
Serial.print(buffer[index], HEX);
|
||||||
if ((index % 4) == 3) {
|
if ((index % 4) == 3) {
|
||||||
Serial.print(F(" "));
|
Serial.print(F(" "));
|
||||||
@@ -1423,8 +1447,8 @@ void MFRC522::PICC_DumpMifareClassicSectorToSerial(Uid *uid, ///< Pointer to U
|
|||||||
if (firstInGroup) {
|
if (firstInGroup) {
|
||||||
// Print access bits
|
// Print access bits
|
||||||
Serial.print(F(" [ "));
|
Serial.print(F(" [ "));
|
||||||
Serial.print((g[group] >> 2) & 1, DEC); Serial.print(" ");
|
Serial.print((g[group] >> 2) & 1, DEC); Serial.print(F(" "));
|
||||||
Serial.print((g[group] >> 1) & 1, DEC); Serial.print(" ");
|
Serial.print((g[group] >> 1) & 1, DEC); Serial.print(F(" "));
|
||||||
Serial.print((g[group] >> 0) & 1, DEC);
|
Serial.print((g[group] >> 0) & 1, DEC);
|
||||||
Serial.print(F(" ] "));
|
Serial.print(F(" ] "));
|
||||||
if (invertedError) {
|
if (invertedError) {
|
||||||
@@ -1466,12 +1490,18 @@ void MFRC522::PICC_DumpMifareUltralightToSerial() {
|
|||||||
// Dump data
|
// Dump data
|
||||||
for (byte offset = 0; offset < 4; offset++) {
|
for (byte offset = 0; offset < 4; offset++) {
|
||||||
i = page + offset;
|
i = page + offset;
|
||||||
Serial.print(i < 10 ? " " : " "); // Pad with spaces
|
if(i < 10)
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
|
else
|
||||||
|
Serial.print(F(" ")); // Pad with spaces
|
||||||
Serial.print(i);
|
Serial.print(i);
|
||||||
Serial.print(F(" "));
|
Serial.print(F(" "));
|
||||||
for (byte index = 0; index < 4; index++) {
|
for (byte index = 0; index < 4; index++) {
|
||||||
i = 4 * offset + index;
|
i = 4 * offset + index;
|
||||||
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
|
if(buffer[i] < 0x10)
|
||||||
|
Serial.print(F(" 0"));
|
||||||
|
else
|
||||||
|
Serial.print(F(" "));
|
||||||
Serial.print(buffer[i], HEX);
|
Serial.print(buffer[i], HEX);
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
@@ -1695,6 +1725,7 @@ bool MFRC522::MIFARE_UnbrickUidSector(bool logErrors) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
44
MFRC522.h
44
MFRC522.h
@@ -58,13 +58,13 @@
|
|||||||
* MIFARE Ultralight (MF0ICU1):
|
* MIFARE Ultralight (MF0ICU1):
|
||||||
* Has 16 pages of 4 bytes = 64 bytes.
|
* Has 16 pages of 4 bytes = 64 bytes.
|
||||||
* Pages 0 + 1 is used for the 7-byte UID.
|
* Pages 0 + 1 is used for the 7-byte UID.
|
||||||
* Page 2 contains the last chech digit for the UID, one byte manufacturer internal data, and the lock bytes (see http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
|
* Page 2 contains the last check digit for the UID, one byte manufacturer internal data, and the lock bytes (see http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
|
||||||
* Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
|
* Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
|
||||||
* Pages 4-15 are read/write unless blocked by the lock bytes in page 2.
|
* Pages 4-15 are read/write unless blocked by the lock bytes in page 2.
|
||||||
* MIFARE Ultralight C (MF0ICU2):
|
* MIFARE Ultralight C (MF0ICU2):
|
||||||
* Has 48 pages of 4 bytes = 64 bytes.
|
* Has 48 pages of 4 bytes = 192 bytes.
|
||||||
* Pages 0 + 1 is used for the 7-byte UID.
|
* Pages 0 + 1 is used for the 7-byte UID.
|
||||||
* Page 2 contains the last chech digit for the UID, one byte manufacturer internal data, and the lock bytes (see http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
|
* Page 2 contains the last check digit for the UID, one byte manufacturer internal data, and the lock bytes (see http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
|
||||||
* Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
|
* Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
|
||||||
* Pages 4-39 are read/write unless blocked by the lock bytes in page 2.
|
* Pages 4-39 are read/write unless blocked by the lock bytes in page 2.
|
||||||
* Page 40 Lock bytes
|
* Page 40 Lock bytes
|
||||||
@@ -79,8 +79,23 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
// Firmware data for self-test
|
// Firmware data for self-test
|
||||||
// Reference values based on firmware version; taken from 16.1.1 in spec.
|
// Reference values based on firmware version
|
||||||
// Version 1.0
|
// Hint: if needed, you can remove unused self-test data to save flash memory
|
||||||
|
//
|
||||||
|
// Version 0.0 (0x90)
|
||||||
|
// Philips Semiconductors; Preliminary Specification Revision 2.0 - 01 August 2005; 16.1 Sefttest
|
||||||
|
const byte MFRC522_firmware_referenceV0_0[] PROGMEM = {
|
||||||
|
0x00, 0x87, 0x98, 0x0f, 0x49, 0xFF, 0x07, 0x19,
|
||||||
|
0xBF, 0x22, 0x30, 0x49, 0x59, 0x63, 0xAD, 0xCA,
|
||||||
|
0x7F, 0xE3, 0x4E, 0x03, 0x5C, 0x4E, 0x49, 0x50,
|
||||||
|
0x47, 0x9A, 0x37, 0x61, 0xE7, 0xE2, 0xC6, 0x2E,
|
||||||
|
0x75, 0x5A, 0xED, 0x04, 0x3D, 0x02, 0x4B, 0x78,
|
||||||
|
0x32, 0xFF, 0x58, 0x3B, 0x7C, 0xE9, 0x00, 0x94,
|
||||||
|
0xB4, 0x4A, 0x59, 0x5B, 0xFD, 0xC9, 0x29, 0xDF,
|
||||||
|
0x35, 0x96, 0x98, 0x9E, 0x4F, 0x30, 0x32, 0x8D
|
||||||
|
};
|
||||||
|
// Version 1.0 (0x91)
|
||||||
|
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 Self test
|
||||||
const byte MFRC522_firmware_referenceV1_0[] PROGMEM = {
|
const byte MFRC522_firmware_referenceV1_0[] PROGMEM = {
|
||||||
0x00, 0xC6, 0x37, 0xD5, 0x32, 0xB7, 0x57, 0x5C,
|
0x00, 0xC6, 0x37, 0xD5, 0x32, 0xB7, 0x57, 0x5C,
|
||||||
0xC2, 0xD8, 0x7C, 0x4D, 0xD9, 0x70, 0xC7, 0x73,
|
0xC2, 0xD8, 0x7C, 0x4D, 0xD9, 0x70, 0xC7, 0x73,
|
||||||
@@ -91,7 +106,8 @@ const byte MFRC522_firmware_referenceV1_0[] PROGMEM = {
|
|||||||
0x1F, 0xA7, 0xF3, 0x53, 0x14, 0xDE, 0x7E, 0x02,
|
0x1F, 0xA7, 0xF3, 0x53, 0x14, 0xDE, 0x7E, 0x02,
|
||||||
0xD9, 0x0F, 0xB5, 0x5E, 0x25, 0x1D, 0x29, 0x79
|
0xD9, 0x0F, 0xB5, 0x5E, 0x25, 0x1D, 0x29, 0x79
|
||||||
};
|
};
|
||||||
// Version 2.0
|
// Version 2.0 (0x92)
|
||||||
|
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 Self test
|
||||||
const byte MFRC522_firmware_referenceV2_0[] PROGMEM = {
|
const byte MFRC522_firmware_referenceV2_0[] PROGMEM = {
|
||||||
0x00, 0xEB, 0x66, 0xBA, 0x57, 0xBF, 0x23, 0x95,
|
0x00, 0xEB, 0x66, 0xBA, 0x57, 0xBF, 0x23, 0x95,
|
||||||
0xD0, 0xE3, 0x0D, 0x3D, 0x27, 0x89, 0x5C, 0xDE,
|
0xD0, 0xE3, 0x0D, 0x3D, 0x27, 0x89, 0x5C, 0xDE,
|
||||||
@@ -102,6 +118,18 @@ const byte MFRC522_firmware_referenceV2_0[] PROGMEM = {
|
|||||||
0x86, 0x96, 0x83, 0x38, 0xCF, 0x9D, 0x5B, 0x6D,
|
0x86, 0x96, 0x83, 0x38, 0xCF, 0x9D, 0x5B, 0x6D,
|
||||||
0xDC, 0x15, 0xBA, 0x3E, 0x7D, 0x95, 0x3B, 0x2F
|
0xDC, 0x15, 0xBA, 0x3E, 0x7D, 0x95, 0x3B, 0x2F
|
||||||
};
|
};
|
||||||
|
// Clone
|
||||||
|
// Fudan Semiconductor FM17522 (0x88)
|
||||||
|
const byte FM17522_firmware_reference[] PROGMEM = {
|
||||||
|
0x00, 0xD6, 0x78, 0x8C, 0xE2, 0xAA, 0x0C, 0x18,
|
||||||
|
0x2A, 0xB8, 0x7A, 0x7F, 0xD3, 0x6A, 0xCF, 0x0B,
|
||||||
|
0xB1, 0x37, 0x63, 0x4B, 0x69, 0xAE, 0x91, 0xC7,
|
||||||
|
0xC3, 0x97, 0xAE, 0x77, 0xF4, 0x37, 0xD7, 0x9B,
|
||||||
|
0x7C, 0xF5, 0x3C, 0x11, 0x8F, 0x15, 0xC3, 0xD7,
|
||||||
|
0xC1, 0x5B, 0x00, 0x2A, 0xD0, 0x75, 0xDE, 0x9E,
|
||||||
|
0x51, 0x64, 0xAB, 0x3E, 0xE9, 0x15, 0xB5, 0xAB,
|
||||||
|
0x56, 0x9A, 0x98, 0x82, 0x26, 0xEA, 0x2A, 0x62
|
||||||
|
};
|
||||||
|
|
||||||
class MFRC522 {
|
class MFRC522 {
|
||||||
public:
|
public:
|
||||||
@@ -218,8 +246,8 @@ public:
|
|||||||
PICC_CMD_WUPA = 0x52, // 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.
|
PICC_CMD_WUPA = 0x52, // 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.
|
||||||
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
|
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
|
||||||
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
|
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
|
||||||
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 1
|
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
|
||||||
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 1
|
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
|
||||||
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
|
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
|
||||||
// The commands used for MIFARE Classic (from http://www.nxp.com/documents/data_sheet/MF1S503x.pdf, Section 9)
|
// The commands used for MIFARE Classic (from http://www.nxp.com/documents/data_sheet/MF1S503x.pdf, Section 9)
|
||||||
// Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
|
// Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
|
||||||
|
|||||||
49
README.rst
49
README.rst
@@ -28,11 +28,11 @@ The following table shows the typical pin layout used:
|
|||||||
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
||||||
| SPI SS | SDA [3]_ | 10 [2]_ | 53 [2]_ | D10 | 10 | 10 | 10 |
|
| SPI SS | SDA [3]_ | 10 [2]_ | 53 [2]_ | D10 | 10 | 10 | 10 |
|
||||||
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
||||||
| SPI MOSI | MOSI | 11 / ICSP-4 | 52 | D11 | ICSP-4 | 16 | 11 |
|
| SPI MOSI | MOSI | 11 / ICSP-4 | 51 | D11 | ICSP-4 | 16 | 11 |
|
||||||
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
||||||
| SPI MISO | MISO | 12 / ICSP-1 | 51 | D12 | ICSP-1 | 14 | 12 |
|
| SPI MISO | MISO | 12 / ICSP-1 | 50 | D12 | ICSP-1 | 14 | 12 |
|
||||||
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
||||||
| SPI SCK | SCK | 13 / ICSP-3 | 50 | D13 | ICSP-3 | 15 | 13 |
|
| SPI SCK | SCK | 13 / ICSP-3 | 52 | D13 | ICSP-3 | 15 | 13 |
|
||||||
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
+-----------+----------+-------------+---------+---------+---------------+-----------+--------+
|
||||||
|
|
||||||
.. [1] Configurable, typically defined as RST_PIN in sketch/program.
|
.. [1] Configurable, typically defined as RST_PIN in sketch/program.
|
||||||
@@ -82,13 +82,54 @@ Protocols
|
|||||||
|
|
||||||
2. The reader and the tags communicate using a 13.56 MHz electromagnetic field.
|
2. The reader and the tags communicate using a 13.56 MHz electromagnetic field.
|
||||||
|
|
||||||
* The protocol is defined in ISO/IEC 14443-3:2011 Part 3.
|
* The protocol is defined in ISO/IEC 14443-3:2011 Part 3 Type A.
|
||||||
|
|
||||||
* Details are found in chapter 6 *"Type A – Initialization and anticollision"*.
|
* Details are found in chapter 6 *"Type A – Initialization and anticollision"*.
|
||||||
|
|
||||||
* See http://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf for a free version
|
* See http://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf for a free version
|
||||||
of the final draft (which might be outdated in some areas).
|
of the final draft (which might be outdated in some areas).
|
||||||
|
|
||||||
|
* The reader do not support ISO/IEC 14443-3 Type B.
|
||||||
|
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
-------
|
||||||
|
|
||||||
|
* **I don't get input from reader** or **WARNING: Communication failure, is the MFRC522 properly connected?**
|
||||||
|
|
||||||
|
#. Check your connection, see `Pin Layout`_ .
|
||||||
|
#. Check voltage. Most breakouts work with 3.3V.
|
||||||
|
#. The SPI only works with 3.3V, most breakouts seems 5V tollerant, but try a level shifter.
|
||||||
|
|
||||||
|
|
||||||
|
* **Sometimes I get timeouts** or **tag/card sometimes not work.**
|
||||||
|
|
||||||
|
#. Try other site of the antenna.
|
||||||
|
#. Try to decrease distance between MFRC522.
|
||||||
|
#. Increase antenna gain per firmware: ``mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);``
|
||||||
|
#. Use better power supply.
|
||||||
|
#. Hardware corrupted, most products are from china and sometimes the quality is really low. Contact your seller.
|
||||||
|
|
||||||
|
|
||||||
|
* **My tag/card doesn't work.**
|
||||||
|
|
||||||
|
#. Distance between antenna and token too huge (>1cm).
|
||||||
|
#. You got wrong PICC. Is it really 13.56MGhz? Is it really a Mifare Type A?
|
||||||
|
#. NFC tokens are not supported. Some may work.
|
||||||
|
#. Animal marker are not supported. They use other frequency.
|
||||||
|
#. Hardware corrupted, most products are from china and sometimes the quality is really low. Contact your seller.
|
||||||
|
|
||||||
|
* **My mobile phone doesn't recognize the MFRC522** or **my MFRC522 can't read data from other MFRC522**
|
||||||
|
|
||||||
|
#. Card simmulation is not supported.
|
||||||
|
#. Communication with mobile phones is not supported.
|
||||||
|
#. Peer to peer communication is not supported.
|
||||||
|
|
||||||
|
* **I need more features.**
|
||||||
|
|
||||||
|
#. If software: code it and make a pull request.
|
||||||
|
#. If hardware: buy a more expensive like PN532 (supports NFC and many more, but costs about $15)
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ void loop() {
|
|||||||
// Ask personal data: Family name
|
// Ask personal data: Family name
|
||||||
Serial.println(F("Type Family name, ending with #"));
|
Serial.println(F("Type Family name, ending with #"));
|
||||||
len=Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial
|
len=Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial
|
||||||
for (byte i = len; i < 30; i++) buffer[i] = '\s'; // pad with spaces
|
for (byte i = len; i < 30; i++) buffer[i] = ' '; // pad with spaces
|
||||||
|
|
||||||
block = 1;
|
block = 1;
|
||||||
//Serial.println(F("Authenticating using key A..."));
|
//Serial.println(F("Authenticating using key A..."));
|
||||||
@@ -106,7 +106,7 @@ void loop() {
|
|||||||
// Ask personal data: First name
|
// Ask personal data: First name
|
||||||
Serial.println(F("Type First name, ending with #"));
|
Serial.println(F("Type First name, ending with #"));
|
||||||
len=Serial.readBytesUntil('#', (char *) buffer, 20) ; // read first name from serial
|
len=Serial.readBytesUntil('#', (char *) buffer, 20) ; // read first name from serial
|
||||||
for (byte i = len; i < 20; i++) buffer[i] = '\s'; // pad with spaces
|
for (byte i = len; i < 20; i++) buffer[i] = ' '; // pad with spaces
|
||||||
|
|
||||||
block = 4;
|
block = 4;
|
||||||
//Serial.println(F("Authenticating using key A..."));
|
//Serial.println(F("Authenticating using key A..."));
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
},
|
},
|
||||||
"exclude": "doc",
|
"exclude": "doc",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "atmelavr"
|
"platforms": ["atmelavr", "ststm32"]
|
||||||
}
|
}
|
||||||
|
|||||||
10
library.properties
Normal file
10
library.properties
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name=MFRC522
|
||||||
|
#date as version - no leading zero
|
||||||
|
version=2015.9.4
|
||||||
|
author=GithubCommunity
|
||||||
|
maintainer=miguelbalboa
|
||||||
|
sentence=Arduino RFID Library for MFRC522 (SPI)
|
||||||
|
paragraph=Read/Write a RFID Card or Tag using the ISO/IEC 14443A/MIFARE interface.
|
||||||
|
category=Communication
|
||||||
|
url=https://github.com/miguelbalboa/rfid
|
||||||
|
architectures=avr,STM32F1
|
||||||
Reference in New Issue
Block a user