mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
[MFRC522] Speed-up detecting cards + make error recovery more stable
This commit is contained in:
+26
-19
@@ -291,7 +291,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
|
||||
* See 9.3.3.6 / table 98 in https://www.nxp.com/docs/en/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.
|
||||
@@ -302,7 +302,7 @@ uint8_t MFRC522::PCD_GetAntennaGain() {
|
||||
|
||||
/**
|
||||
* Set the MFRC522 Receiver Gain (RxGain) to value specified by given mask.
|
||||
* See 9.3.3.6 / table 98 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf
|
||||
* See 9.3.3.6 / table 98 in https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
|
||||
* NOTE: Given mask is scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved bits.
|
||||
*/
|
||||
void MFRC522::PCD_SetAntennaGain(uint8_t mask) {
|
||||
@@ -314,7 +314,7 @@ void MFRC522::PCD_SetAntennaGain(uint8_t mask) {
|
||||
|
||||
/**
|
||||
* Performs a self-test of the MFRC522
|
||||
* See 16.1.1 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf
|
||||
* See 16.1.1 in https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
|
||||
*
|
||||
* @return Whether or not the test passed. Or false if no firmware reference is available.
|
||||
*/
|
||||
@@ -368,21 +368,28 @@ bool MFRC522::PCD_PerformSelfTest() {
|
||||
|
||||
// Pick the appropriate reference values
|
||||
const uint8_t *reference;
|
||||
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
|
||||
reference = MFRC522_firmware_referenceV1_0;
|
||||
break;
|
||||
case 0x92: // Version 2.0
|
||||
reference = MFRC522_firmware_referenceV2_0;
|
||||
break;
|
||||
default: // Unknown version
|
||||
return false; // abort test
|
||||
switch(version) {
|
||||
// Fudan Semiconductor clone:
|
||||
case 0xb2: // FM17522
|
||||
reference = FM17522_firmware_referenceB2;
|
||||
break;
|
||||
case 0x88: // FM17522
|
||||
reference = FM17522_firmware_reference88;
|
||||
break;
|
||||
case 0x89: // FM17522E
|
||||
reference = FM17522E_firmware_reference;
|
||||
break;
|
||||
case 0x90: // Version 0.0
|
||||
reference = MFRC522_firmware_referenceV0_0;
|
||||
break;
|
||||
case 0x91: // Version 1.0
|
||||
reference = MFRC522_firmware_referenceV1_0;
|
||||
break;
|
||||
case 0x92: // Version 2.0
|
||||
reference = MFRC522_firmware_referenceV2_0;
|
||||
break;
|
||||
default: // Unknown version
|
||||
return false; // abort test
|
||||
}
|
||||
|
||||
// Verify that the results match up to our expectations
|
||||
@@ -868,7 +875,7 @@ MFRC522::StatusCode MFRC522::PICC_HaltA() {
|
||||
/**
|
||||
* Executes the MFRC522 MFAuthent command.
|
||||
* This command manages MIFARE authentication to enable a secure communication to any MIFARE Mini, MIFARE 1K and MIFARE 4K card.
|
||||
* The authentication is described in the MFRC522 datasheet section 10.3.1.9 and http://www.nxp.com/documents/data_sheet/MF1S503x.pdf section 10.1.
|
||||
* The authentication is described in the MFRC522 datasheet section 10.3.1.9 and https://www.nxp.com/docs/en/data-sheet/MF1S503x.pdf section 10.1.
|
||||
* 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.
|
||||
|
||||
+25
-3
@@ -64,7 +64,7 @@ const uint8_t MFRC522_firmware_referenceV2_0[] PROGMEM = {
|
||||
};
|
||||
// Clone
|
||||
// Fudan Semiconductor FM17522 (0x88)
|
||||
const uint8_t FM17522_firmware_reference[] PROGMEM = {
|
||||
const uint8_t FM17522_firmware_reference88[] 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,
|
||||
@@ -74,6 +74,28 @@ const uint8_t FM17522_firmware_reference[] PROGMEM = {
|
||||
0x51, 0x64, 0xAB, 0x3E, 0xE9, 0x15, 0xB5, 0xAB,
|
||||
0x56, 0x9A, 0x98, 0x82, 0x26, 0xEA, 0x2A, 0x62
|
||||
};
|
||||
// Another "FM17522" ic form Aliexpress
|
||||
const uint8_t FM17522_firmware_referenceB2[] PROGMEM = {
|
||||
0x00, 0xeb, 0x44, 0x85, 0xfa, 0x9a, 0x78, 0x01,
|
||||
0x74, 0xe5, 0x1c, 0x7a, 0x0a, 0xa0, 0x71, 0xe1,
|
||||
0xf3, 0xfa, 0x96, 0x6d, 0x28, 0xa1, 0x34, 0x46,
|
||||
0x3a, 0x1c, 0x32, 0x96, 0xb9, 0xe6, 0x44, 0x87,
|
||||
0x0a, 0x45, 0x98, 0xa9, 0x36, 0x60, 0x89, 0x0f,
|
||||
0x06, 0x9b, 0x7b, 0x17, 0xb3, 0x0c, 0x1a, 0x6c,
|
||||
0x1a, 0xae, 0x2c, 0xac, 0x0e, 0x6f, 0x2e, 0x02,
|
||||
0x2b, 0xcb, 0x8a, 0xb2, 0x45, 0xdd, 0x7e, 0x3c
|
||||
};
|
||||
// Fudan Semiconductor FM17522E (0x89)
|
||||
const uint8_t FM17522E_firmware_reference[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x00, 0x04, 0xcc, 0xc8, 0x00,
|
||||
0x10, 0x04, 0x00, 0xc0, 0x00, 0x90, 0x00, 0x20,
|
||||
0x00, 0x00, 0x23, 0x00, 0x38, 0x06, 0x01, 0x33,
|
||||
0x98, 0xf3, 0x80, 0x06, 0xc0, 0xf9, 0x80, 0x08,
|
||||
0x27, 0x04, 0x23, 0x82, 0x21, 0x12, 0xf9, 0xc7
|
||||
};
|
||||
|
||||
class MFRC522 {
|
||||
public:
|
||||
@@ -173,7 +195,7 @@ public:
|
||||
};
|
||||
|
||||
// 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
|
||||
// Described in 9.3.3.6 / table 98 of the datasheet at https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
|
||||
enum PCD_RxGain : uint8_t {
|
||||
RxGain_18dB = 0x00 << 4, // 000b - 18 dB, minimum
|
||||
RxGain_23dB = 0x01 << 4, // 001b - 23 dB
|
||||
@@ -210,7 +232,7 @@ public:
|
||||
PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
|
||||
PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
|
||||
PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
|
||||
// The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
|
||||
// The commands used for MIFARE Ultralight (from https://www.nxp.com/docs/en/data-sheet/MF0ICU1.pdf, Section 8.6)
|
||||
// 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 uint8_t page to the PICC.
|
||||
};
|
||||
|
||||
@@ -195,7 +195,7 @@ lib_extra_dirs =
|
||||
; ESP_IDF 5.5.0
|
||||
[core_esp32_IDF5_5_0__3_2_0_LittleFS]
|
||||
platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/3722/framework-arduinoespressif32-all-release_v5.5-eefeb2bb.zip
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/3725/framework-arduinoespressif32-all-release_v5.5-eefeb2bb.zip
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/3627/framework-arduinoespressif32-all-release_v5.5-5d572003.zip
|
||||
build_flags = -DESP32_STAGE
|
||||
-DESP_IDF_VERSION_MAJOR=5
|
||||
|
||||
@@ -101,7 +101,7 @@ board_build.filesystem = littlefs
|
||||
lib_ignore = ${esp32_always.lib_ignore}
|
||||
ESP32_ping
|
||||
ESP32 BLE Arduino
|
||||
${core_esp32_IDF5_4_1__3_2_0_LittleFS.lib_ignore}
|
||||
${esp32_base_idf5.lib_ignore}
|
||||
|
||||
|
||||
[esp32_IRExt_LittleFS_ETH]
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
[esp32s3_common_LittleFS]
|
||||
extends = esp32_base_idf5
|
||||
extends = esp32_base_idf5_5
|
||||
lib_ignore = ${esp32_common_LittleFS_ETH.lib_ignore}
|
||||
ESP32_ping
|
||||
${esp32_base_idf5.lib_ignore}
|
||||
build_flags = ${esp32_base_idf5.build_flags}
|
||||
${esp32_base_idf5_5.lib_ignore}
|
||||
build_flags = ${esp32_base_idf5_5.build_flags}
|
||||
; -mtext-section-literals
|
||||
-DFEATURE_ARDUINO_OTA=1
|
||||
-DFEATURE_ETHERNET=1
|
||||
-DUSE_LITTLEFS
|
||||
-DESP32S3
|
||||
extra_scripts = ${esp32_base_idf5.extra_scripts}
|
||||
build_unflags = ${esp32_base_idf5.build_unflags}
|
||||
extra_scripts = ${esp32_base_idf5_5.extra_scripts}
|
||||
build_unflags = ${esp32_base_idf5_5.build_unflags}
|
||||
-fexceptions
|
||||
board_build.filesystem = littlefs
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ boolean Plugin_111(uint8_t function, struct EventStruct *event, String& string)
|
||||
{
|
||||
auto& dev = Device[++deviceCount];
|
||||
dev.Number = PLUGIN_ID_111;
|
||||
dev.Type = DEVICE_TYPE_SPI2;
|
||||
dev.Type = DEVICE_TYPE_SPI3;
|
||||
dev.VType = Sensor_VType::SENSOR_TYPE_ULONG;
|
||||
dev.ValueCount = 1;
|
||||
dev.SendDataOption = true;
|
||||
@@ -59,9 +59,23 @@ boolean Plugin_111(uint8_t function, struct EventStruct *event, String& string)
|
||||
{
|
||||
event->String1 = formatGpioName_output(F("CS PIN")); // P111_CS_PIN
|
||||
event->String2 = formatGpioName_output_optional(F("RST PIN ")); // P111_RST_PIN
|
||||
event->String3 = formatGpioName_input_optional(F("IRQ PIN ")); // P111_IRQ_PIN
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_SHOW_GPIO_DESCR:
|
||||
{
|
||||
string = event->String1;
|
||||
string += concat(F("CS: "), formatGpioLabel(CONFIG_PIN1, false));
|
||||
string += event->String1;
|
||||
string += concat(F("RST: "), formatGpioLabel(CONFIG_PIN2, false));
|
||||
string += event->String1;
|
||||
string += concat(F("IRQ: "), formatGpioLabel(CONFIG_PIN3, false));
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PLUGIN_SET_DEFAULTS:
|
||||
{
|
||||
P111_REMOVALTIMEOUT = 500; // Default 500 msec reset delay
|
||||
@@ -70,8 +84,17 @@ boolean Plugin_111(uint8_t function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormSubHeader(F("Options"));
|
||||
P111_data_struct *P111_data = static_cast<P111_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
if (nullptr != P111_data) {
|
||||
uint8_t v{};
|
||||
const String version = P111_data->PCD_getVersion(v);
|
||||
if (v != 0 && v != 0xFF) {
|
||||
addRowLabel(F("Reader Version"));
|
||||
addHtml(version);
|
||||
}
|
||||
}
|
||||
|
||||
addFormSubHeader(F("Options"));
|
||||
{
|
||||
const __FlashStringHelper *removaltype[] = {
|
||||
F("None"),
|
||||
|
||||
@@ -26,6 +26,8 @@ void P111_data_struct::init() {
|
||||
|
||||
if (mfrc522 != nullptr) {
|
||||
mfrc522->PCD_Init(); // Initialize MFRC522 reader
|
||||
mfrc522->PCD_WriteRegister(MFRC522::ComIEnReg, 0b10100000); // enable receiver interrupt
|
||||
mfrc522->PCD_WriteRegister(MFRC522::DivIEnReg, 0x80); // Set as CMOS output pin
|
||||
initPhase = P111_initPhases::Ready;
|
||||
}
|
||||
}
|
||||
@@ -116,10 +118,15 @@ bool P111_data_struct::reset(int8_t csPin,
|
||||
if ((resetPin != -1) &&
|
||||
(initPhase == P111_initPhases::Ready)) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("MFRC522: Reset on pin: ");
|
||||
log += resetPin;
|
||||
addLogMove(LOG_LEVEL_INFO, log);
|
||||
addLogMove(
|
||||
LOG_LEVEL_INFO,
|
||||
concat(F("MFRC522: Reset on pin: "), resetPin));
|
||||
}
|
||||
|
||||
init();
|
||||
return true;
|
||||
|
||||
// FIXME TD-er: Remove the rest of this function.
|
||||
pinMode(resetPin, OUTPUT);
|
||||
digitalWrite(resetPin, LOW);
|
||||
timeToWait = 100;
|
||||
@@ -140,6 +147,8 @@ bool P111_data_struct::reset(int8_t csPin,
|
||||
digitalWrite(csPin, LOW);
|
||||
|
||||
mfrc522->PCD_Init(csPin, resetPin); // Init MFRC522 module
|
||||
mfrc522->PCD_WriteRegister(MFRC522::ComIEnReg, 0b10100000); // enable receiver interrupt
|
||||
mfrc522->PCD_WriteRegister(MFRC522::DivIEnReg, 0x80); // Set as CMOS output pin
|
||||
|
||||
// If you set Antenna Gain to Max it will increase reading distance
|
||||
mfrc522->PCD_SetAntennaGain(mfrc522->RxGain_max);
|
||||
@@ -226,8 +235,10 @@ bool P111_data_struct::plugin_ten_per_second(struct EventStruct *event) {
|
||||
}
|
||||
|
||||
counter++; // This variable replaces a static variable in the original implementation
|
||||
const bool ComIrqReg_bits = (mfrc522->PCD_ReadRegister(MFRC522::ComIrqReg) & (1<<5)) != 0;
|
||||
mfrc522->PCD_WriteRegister(MFRC522::ComIrqReg, 0x34);
|
||||
|
||||
if (counter == 3) { // Only every 3rd 0.1 second we do a read
|
||||
if (counter >= 10 || ComIrqReg_bits) { // Only every 3rd 0.1 second we do a read
|
||||
counter = 0;
|
||||
|
||||
uint32_t key = P111_NO_KEY;
|
||||
@@ -300,4 +311,45 @@ bool P111_data_struct::plugin_fifty_per_second() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
String P111_data_struct::PCD_getVersion(uint8_t& v) {
|
||||
v = 0xFF;
|
||||
if (mfrc522) {
|
||||
v = mfrc522->PCD_ReadRegister(MFRC522::VersionReg);
|
||||
if (v != 0xFF && v != 0) {
|
||||
// Human readable version.
|
||||
String res = concat(formatToHex(v, 2), F(" = "));
|
||||
switch(v) {
|
||||
case 0xb2:
|
||||
res += F("FM17522_1");
|
||||
break;
|
||||
case 0x88:
|
||||
res += F("FM17522");
|
||||
break;
|
||||
case 0x89:
|
||||
res += F("FM17522E");
|
||||
break;
|
||||
case 0x90:
|
||||
res += F("v0.0");
|
||||
break;
|
||||
case 0x91:
|
||||
res += F("v1.0");
|
||||
break;
|
||||
case 0x92:
|
||||
res += F("v2.0");
|
||||
break;
|
||||
case 0x12:
|
||||
res += F("counterfeit chip");
|
||||
break;
|
||||
default:
|
||||
res += F("(unknown)");
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
|
||||
#endif // ifdef USES_P111
|
||||
|
||||
@@ -39,6 +39,8 @@ struct P111_data_struct : public PluginTaskData_base {
|
||||
bool plugin_ten_per_second(struct EventStruct *event);
|
||||
bool plugin_fifty_per_second();
|
||||
|
||||
String PCD_getVersion(uint8_t& v);
|
||||
|
||||
private:
|
||||
|
||||
MFRC522 *mfrc522 = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user