From 871e4d74fcd37461275ee53879d31a2e49578685 Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 9 Jan 2021 21:52:32 +0100 Subject: [PATCH 1/7] support for the PN5180 low power card detection (LPCD) wake-up the board from deep sleep just by adding a card on the PN5180 reader --- README.md | 31 ++--- src/main.cpp | 212 +++++++++++++++++++++++++++++++---- src/settings-lolin32.h | 2 + src/settings-lolin_d32.h | 2 + src/settings-lolin_d32_pro.h | 2 + src/settings.h | 3 +- 6 files changed, 214 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 72f8dbf..14410b0 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Advantages SD-MMC (1 bit) over SPI: So why using SPI if SD-MMC seems to be better? The primary problem of SD-MMC is: you cannot choose different GPIOs. That doesn't sound bad but this can (depending on the uSD-card-reader-module) be a problem because maybe GPIO2 is pulled HIGH to 3.3V by a 10k-resistor. For example this is the case when using the reader-module named above in hardware-setup. It's a problem because if GPIO2 is pulled high at boot, ESP32 doesn't enter flash-mode. As soon as flash-mode is entered, it's no longer a problem. However, this behaviour can be an issue if ESP32 is deeply "burried" in Tonuino's enclosure and you want to update its firmware. But fortunately there's a way to bypass this problem: remove the [pullup-resistor shown in the picture](https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/pictures/Pullup-removal.jpg). It can be removed safely because if MMC-mode is set, pullup is done in software using `pinMode(2, INPUT_PULLUP);`. ## RFID: RC522 or PN5180? -RC522 is so to say the Tonuino-standard. It's cheap and works, but RFID-tag has to be placed near the reader. PN5180 instead has better RFID range/sensitivity and can read ISO-15693 / iCode SLIX2-tags aka 'Tonies' (you need a password to read Tonies). Disadvantages: is a bit more expensive and needs more GPIOs (6/7 instead of 4). Refer PN5180's wire-section below for further informations. Hint: if using 3.3V make sure to connect PN5180 to +5V AND 3.3V. Sounds weird but it's necessary. +RC522 is so to say the Tonuino-standard. It's cheap and works, but RFID-tag has to be placed near the reader. PN5180 instead has better RFID range/sensitivity and can read ISO-15693 / iCode SLIX2-tags aka 'Tonies' (you need a password to read Tonies). You can also wake-up the board with the card. Disadvantages: is a bit more expensive and needs more GPIOs (6/7 instead of 4). Refer PN5180's wire-section below for further informations. Hint: if using 3.3V make sure to connect PN5180 to +5V AND 3.3V. Sounds weird but it's necessary. ## 3.3 or 5V? * Why 3.3V? Because: if you plan to use battery-mode with a LiPo, there's no 5 V available (unless USB is connected). @@ -214,19 +214,22 @@ In this case RFID-reader + SD-reader share SPI's SCK, MISO and MOSI. But make su ## Wiring (PN5180 instead of MFRC522) different to above -PN5180 reader needs two more pins, RESET and BUSY. Double check pin-conflicts! `RFID_READER_TYPE_PN5180` needs to be enabled to use this feature. Make sure to disable `RFID_READER_TYPE_MFRC522` if doing so! - -| ESP32 (GPIO) | Hardware | Pin | Comment | -| ------------- | --------------------- | ------ | ------------------------------------------------------------ | -| 3.3 V | PN5180 RFID-reader | 3.3V | Connect directly to GPIO 17 for power-saving when uC is off | -| 5 / 3.3 V | PN5180 RFID-reader | 5V | Don't forget to connect this pin the same way as 3.3V | -| GND | PN5180 RFID-reader | GND | | -| 21 | PN5180 RFID-reader | CS/SDA | Same as MFRC522. Don't share with SD! | -| 23 | PN5180 RFID-reader | MOSI | Same as MFRC522 | -| 19 | PN5180 RFID-reader | MISO | Same as MFRC522 | -| 18 | PN5180 RFID-reader | SCK | Same as MFRC522 | -| 16 | PN5180 RFID-reader | BUSY | be aware of SD MISO if running in SPI mode | -| 22 | PN5180 RFID-reader | RST | be aware of Headphone jack PIN | +PN5180 reader needs two/three more pins, RESET and BUSY (IRQ). Double check pin-conflicts! `RFID_READER_TYPE_PN5180` needs to be enabled to use this feature. Make sure to disable `RFID_READER_TYPE_MFRC522` if doing so! +You can enable low power card detection with `PN5180_ENABLE_LPCD`. With low power card detection (LPCD) you can wake-up the board from deep-sleep just by adding a card on the reader. You need a PN5180 firmware >= 4.0. Most china boards comes with older firmware. To flash the latest firmware you can do this with this [project](https://github.com/abidxraihan/PN5180_Updater_ESP32). + +| ESP32 (GPIO) | Hardware | Pin | Comment | +| ------------- | --------------------- | ------ | ----------------------------------------------------------------- | +| 3.3 V | PN5180 RFID-reader | 3.3V | Connect directly to GPIO 17 for power-saving when uC is off | +| 5 / 3.3 V | | 3.3V | For low power card detection mode (LPCD) connect directly to 3.3V | +| 5 / 3.3 V | PN5180 RFID-reader | 5V | Don't forget to connect this pin the same way as 3.3V | +| GND | PN5180 RFID-reader | GND | | +| 21 | PN5180 RFID-reader | CS/SDA | Same as MFRC522. Don't share with SD! | +| 23 | PN5180 RFID-reader | MOSI | Same as MFRC522 | +| 19 | PN5180 RFID-reader | MISO | Same as MFRC522 | +| 18 | PN5180 RFID-reader | SCK | Same as MFRC522 | +| 16 | PN5180 RFID-reader | BUSY | be aware of SD MISO if running in SPI mode | +| 22 | PN5180 RFID-reader | RST | be aware of Headphone jack PIN | +| 39 | PN5180 RFID-reader | IRQ | optional, used for low power card detection (LPCD) | ## Wiring (custom) / different pinout When using a develboard with SD-card-reader already integrated (Lolin D32 Pro, several TTGO-boards), the pinouts described above my not fit. Feel free to change them according your needs. Additionaly some boards may use one or some of the GPIOs I used for their internal purposes and that reason for are maybe not exposed via pin-headers. However, having them exposed doesn't mean they can be used without limits. This is because some GPIOs have to be logical LOW or HIGH at start/boot for example and this is probably not the case when connecting stuff to it. Feel free to adjust the GPIOs proposed by me (but be adviced it could take a while to get it running). If you encounter problems please refer the board's manual first.
diff --git a/src/main.cpp b/src/main.cpp index 646d937..eea3f1e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -228,6 +228,7 @@ char *currentRfidTagId = NULL; unsigned long lastTimeActiveTimestamp = 0; // Timestamp of last user-interaction unsigned long sleepTimerStartTimestamp = 0; // Flag if sleep-timer is active bool gotoSleep = false; // Flag for turning uC immediately into deepsleep +bool sleeping = false; // Flag for turning uC immediately into deepsleep bool lockControls = false; // Flag if buttons and rotary encoder is locked bool bootComplete = false; // Rotary encoder-helper @@ -1865,6 +1866,8 @@ void rfidScanner(void *parameter) { for (;;) { esp_task_wdt_reset(); + if (sleeping) + break; vTaskDelay(10); if ((millis() - lastRfidCheckTimestamp) >= RFID_SCAN_INTERVAL) { // Reset the loop if no new card is present on the sensor/reader. This saves the entire process when idle. @@ -1950,6 +1953,7 @@ void rfidScanner(void *parameter) { } } } + Serial.println("delete RFID scanner task"); vTaskDelete(NULL); } #endif @@ -2290,9 +2294,8 @@ void showLed(void *parameter) { for (uint8_t led = 0; led < numLedsToLight; led++) { if (lockControls) { leds[ledAddress(led)] = CRGB::Red; - } else if (!playProperties.pausePlay) { - // leds[ledAddress(led)].setHue((uint8_t) (85 - ((double) 95 / NUM_LEDS) * led)); // green to red - leds[ledAddress(led)].setHue((uint8_t) ((double) 255 / NUM_LEDS) * led); // Hue-rainbow + } else if (!playProperties.pausePlay) { // Hue-rainbow + leds[ledAddress(led)].setHue((uint8_t) (85 - ((double) 95 / NUM_LEDS) * led)); } } if (playProperties.pausePlay) { @@ -2351,12 +2354,111 @@ void sleepHandler(void) { } } +#ifdef PN5180_ENABLE_LPCD +// goto low power card detection mode +void gotoLPCD() { + static PN5180ISO14443 nfc(RFID_CS, RFID_BUSY, RFID_RST); + nfc.begin(); + // show PN5180 reader version + uint8_t firmwareVersion[2]; + nfc.readEEprom(FIRMWARE_VERSION, firmwareVersion, sizeof(firmwareVersion)); + Serial.print(F("Firmware version=")); + Serial.print(firmwareVersion[1]); + Serial.print("."); + Serial.println(firmwareVersion[0]); + // check firmware version: PN5180 firmware < 4.0 has several bugs preventing the LPCD mode + // you can flash latest firmware with this project: https://github.com/abidxraihan/PN5180_Updater_ESP32 + if (firmwareVersion[1] < 4) { + Serial.println(F("This PN5180 firmware does not work with LPCD!")); + return; + } + Serial.println(F("Prepare PN5180 for LPCD...")); + nfc.reset(); + nfc.clearIRQStatus(0xffffffff); + Serial.println("RFID_IRQ: " + digitalRead(RFID_IRQ)); //reads 0 because IRQ pin pin config is set to active high (eeprom@0x1A) //should read 1 because when interrupt is raised GPIO4 is LOW + Serial.println(F("Reading IRQ-Pin...")); + uint8_t irqPin[1]; + nfc.readEEprom(IRQ_PIN_CONFIG, irqPin, sizeof(irqPin)); + Serial.print(F("irqPin=")); + Serial.println(irqPin[0]); //should read 1 i.e. pin IRQ is high(bolean 1/3.3v) when active(interrupted) + + //=======================================LPCD CONFIG================================================================================ + Serial.println(F("----------------------------------")); + Serial.println(F("start LPCD...")); + + uint8_t data[255]; + uint8_t response[256]; + //1. Set Fieldon time LPCD_FIELD_ON_TIME (0x36) + uint8_t fieldOn = 0xF0;//0x## -> ##(base 10) x 8μs + 62 μs + data[0] = fieldOn; + nfc.writeEEprom(0x36, data, 1); + nfc.readEEprom(0x36, response, 1); + fieldOn = response[0]; + Serial.print(F("LPCD-fieldOn time: ")); + Serial.println(fieldOn, HEX); + + //2. Set threshold level AGC_LPCD_THRESHOLD @ EEPROM 0x37 + uint8_t threshold = 0x03; + data[0] = threshold; + nfc.writeEEprom(0x37, data, 1); + nfc.readEEprom(0x37, response, 1); + threshold = response[0]; + Serial.print(F("LPCD-threshold: ")); + Serial.println(threshold, HEX); + + //4. Select LPCD mode LPCD_REFVAL_GPO_CONTROL (0x38) + uint8_t lpcdMode = 0x01; // 1 = LPCD SELF CALIBRATION + // 0 = LPCD AUTO CALIBRATION (this mode does not work, should look more into it, no reason why it shouldn't work) + data[0] = lpcdMode; + nfc.writeEEprom(0x38, data, 1); + nfc.readEEprom(0x38, response, 1); + lpcdMode = response[0]; + Serial.print(F("lpcdMode: ")); + Serial.println(lpcdMode, HEX); + + // LPCD_GPO_TOGGLE_BEFORE_FIELD_ON (0x39) + uint8_t beforeFieldOn = 0xF0; + data[0] = beforeFieldOn; + nfc.writeEEprom(0x39, data, 1); + nfc.readEEprom(0x39, response, 1); + beforeFieldOn = response[0]; + Serial.print(F("beforeFieldOn: ")); + Serial.println(beforeFieldOn, HEX); + + // LPCD_GPO_TOGGLE_AFTER_FIELD_ON (0x3A) + uint8_t afterFieldOn = 0xF0; + data[0] = afterFieldOn; + nfc.writeEEprom(0x3A, data, 1); + nfc.readEEprom(0x3A, response, 1); + afterFieldOn = response[0]; + Serial.print(F("afterFieldOn: ")); + Serial.println(afterFieldOn, HEX); + delay(100); + nfc.clearIRQStatus(0xffffffff); + Serial.print(F("PN5180 IRQ PIN: ")); Serial.println(digitalRead(RFID_IRQ)); + // turn on LPCD + uint16_t wakeupCounterInMs = 0x3FF; // must be in the range of 0x0 - 0xA82. max wake-up time is 2960 ms. + if (nfc.switchToLPCD(wakeupCounterInMs)) { + Serial.println(F("switch to low power card detection: success")); + // configure wakeup pin for deep-sleep wake-up, use ext1 + esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH); + // freeze pin states in deep sleep + gpio_hold_en(gpio_num_t(RFID_CS)); // CS/NSS + gpio_hold_en(gpio_num_t(RFID_RST)); // RST + gpio_deep_sleep_hold_en(); + } else { + Serial.println(F("switchToLPCD failed")); + } +} +#endif // Puts uC to deep-sleep if flag is set void deepSleepManager(void) { if (gotoSleep) { + if (sleeping) + return; + sleeping = true; loggerNl((char *) FPSTR(goToSleepNow), LOGLEVEL_NOTICE); - Serial.flush(); #ifdef MQTT_ENABLE publishMqtt((char *) FPSTR(topicState), "Offline", false); publishMqtt((char *) FPSTR(topicTrackState), "---", false); @@ -2366,10 +2468,22 @@ void deepSleepManager(void) { FastLED.clear(); FastLED.show(); #endif - /*SPI.end(); - spiSD.end();*/ + // SD card goto idle mode + #ifdef SD_MMC_1BIT_MODE + SD_MMC.end(); + #else + /*SPI.end(); + spiSD.end();*/ + #endif + Serial.flush(); + // switch off power digitalWrite(POWER, LOW); delay(200); + #ifdef PN5180_ENABLE_LPCD + // prepare and go to low power card detection mode + gotoLPCD(); + #endif + Serial.println(F("deep-sleep, good night.......")); esp_deep_sleep_start(); } } @@ -3217,8 +3331,6 @@ wl_status_t wifiManager(void) { return WiFi.status(); } -const char mqttTab[] PROGMEM = " MQTT"; -const char ftpTab[] PROGMEM = " FTP"; // Used for substitution of some variables/templates of html-files. Is called by webserver's template-engine String templateProcessor(const String& templ) { @@ -3230,12 +3342,6 @@ String templateProcessor(const String& templ) { return String(ftpUserLength-1); } else if (templ == "FTP_PWD_LENGTH") { return String(ftpPasswordLength-1); - } else if (templ == "SHOW_FTP_TAB") { // Only show FTP-tab if FTP-support was compiled - #ifdef FTP_ENABLE - return (String) FPSTR(ftpTab); - #else - return String(); - #endif } else if (templ == "INIT_LED_BRIGHTNESS") { return String(prefsSettings.getUChar("iLedBrightness", 0)); } else if (templ == "NIGHT_LED_BRIGHTNESS") { @@ -3258,12 +3364,6 @@ String templateProcessor(const String& templ) { return String(prefsSettings.getUInt("vCheckIntv", voltageCheckInterval)); } else if (templ == "MQTT_SERVER") { return prefsSettings.getString("mqttServer", "-1"); - } else if (templ == "SHOW_MQTT_TAB") { // Only show MQTT-tab if MQTT-support was compiled - #ifdef MQTT_ENABLE - return (String) FPSTR(mqttTab); - #else - return String(); - #endif } else if (templ == "MQTT_ENABLE") { if (enableMqtt) { return String("checked=\"checked\""); @@ -3726,11 +3826,70 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, #endif } +#ifdef PN5180_ENABLE_LPCD +// print the wake-up reason +void printWakeUpReason(){ + esp_sleep_wakeup_cause_t wakeup_reason; + + wakeup_reason = esp_sleep_get_wakeup_cause(); + + switch(wakeup_reason) + { + case ESP_SLEEP_WAKEUP_EXT0 : Serial.println(F("Wakeup caused by push button")); break; + case ESP_SLEEP_WAKEUP_EXT1 : Serial.println(F("Wakeup caused by low power card detection")); break; + case ESP_SLEEP_WAKEUP_TIMER : Serial.println(F("Wakeup caused by timer")); break; + case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println(F("Wakeup caused by touchpad")); break; + case ESP_SLEEP_WAKEUP_ULP : Serial.println(F("Wakeup caused by ULP program")); break; + default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break; + } +} + +// wake up from LPCD, check card is present. This works only for ISO-14443 compatible cards +void checCardIsPresentLPCD() { + static PN5180ISO14443 nfc14443(RFID_CS, RFID_BUSY, RFID_RST); + nfc14443.begin(); + nfc14443.reset(); + nfc14443.setupRF(); + if (!nfc14443.isCardPresent()) { + nfc14443.clearIRQStatus(0xffffffff); + Serial.print(F("PN5180 IRQ PIN: ")); Serial.println(digitalRead(RFID_IRQ)); + // turn on LPCD + uint16_t wakeupCounterInMs = 0x3FF; // must be in the range of 0x0 - 0xA82. max wake-up time is 2960 ms. + if (nfc14443.switchToLPCD(wakeupCounterInMs)) { + Serial.println(F("switch to low power card detection: success")); + // configure wakeup pin for deep-sleep wake-up, use ext1 + esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH); + // freeze pin states in deep sleep + gpio_hold_en(gpio_num_t(RFID_CS)); // CS/NSS + gpio_hold_en(gpio_num_t(RFID_RST)); // RST + gpio_deep_sleep_hold_en(); + Serial.println(F("Wakeup caused by low power card detection. RF-field change but no ISO-14443 card on reader")); + Serial.println(F("go to deep-sleep again, sleep well in your Bettgestell.......")); + esp_deep_sleep_start(); + } else { + Serial.println(F("switchToLPCD failed")); + } + } +} +#endif void setup() { Serial.begin(115200); esp_sleep_enable_ext0_wakeup((gpio_num_t) DREHENCODER_BUTTON, 0); - srand(esp_random()); + #ifdef PN5180_ENABLE_LPCD + // disable pin hold from deep sleep (LPCD) + gpio_deep_sleep_hold_dis(); + gpio_hold_dis(gpio_num_t(RFID_CS)); // NSS + gpio_hold_dis(gpio_num_t(RFID_RST)); // RST + pinMode(RFID_IRQ, INPUT); + // check wakeup reason is a card detection + esp_sleep_wakeup_cause_t wakeup_reason; + wakeup_reason = esp_sleep_get_wakeup_cause(); + if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT1) { + checCardIsPresentLPCD(); + } + #endif + srand(esp_random()); pinMode(POWER, OUTPUT); digitalWrite(POWER, HIGH); prefsRfid.begin((char *) FPSTR(prefsRfidNamespace)); @@ -3847,8 +4006,15 @@ void setup() { Serial.println(F(" |_| |___|_|_|_____|_____|_|___|_____| ")); Serial.println(F(" ESP32-version")); Serial.println(F("")); - - // show SD card type + // print wake-up reason + printWakeUpReason(); + #ifdef PN5180_ENABLE_LPCD + // disable pin hold from deep sleep + gpio_deep_sleep_hold_dis(); + gpio_hold_dis(gpio_num_t(RFID_CS)); // NSS + gpio_hold_dis(gpio_num_t(RFID_RST)); // RST + #endif + // show SD card type #ifdef SD_MMC_1BIT_MODE loggerNl((char *) FPSTR(sdMountedMmc1BitMode), LOGLEVEL_NOTICE); uint8_t cardType = SD_MMC.cardType(); diff --git a/src/settings-lolin32.h b/src/settings-lolin32.h index 3a2f9bd..05db922 100644 --- a/src/settings-lolin32.h +++ b/src/settings-lolin32.h @@ -39,6 +39,8 @@ #ifdef RFID_READER_TYPE_PN5180 #define RFID_BUSY 16 // PN5180 BUSY PIN #define RFID_RST 22 // PN5180 RESET PIN + #define RFID_IRQ 39 // PN5180 IRQ PIN (only needed for low power card detection) + #define BUTTON_PIN_BITMASK 0x8000000000// 2^RFID_IRQ in hex #endif // I2S (DAC) #define I2S_DOUT 25 // Digital out (I2S) diff --git a/src/settings-lolin_d32.h b/src/settings-lolin_d32.h index a802681..2b9f85b 100644 --- a/src/settings-lolin_d32.h +++ b/src/settings-lolin_d32.h @@ -39,6 +39,8 @@ #ifdef RFID_READER_TYPE_PN5180 #define RFID_BUSY 16 // PN5180 BUSY PIN #define RFID_RST 22 // PN5180 RESET PIN + #define RFID_IRQ 39 // PN5180 IRQ PIN (only needed for low power card detection) + #define BUTTON_PIN_BITMASK 0x8000000000// 2^RFID_IRQ in hex #endif // I2S (DAC) #define I2S_DOUT 25 // Digital out (I2S) diff --git a/src/settings-lolin_d32_pro.h b/src/settings-lolin_d32_pro.h index ee770b0..f4134f0 100644 --- a/src/settings-lolin_d32_pro.h +++ b/src/settings-lolin_d32_pro.h @@ -34,6 +34,8 @@ #ifdef RFID_READER_TYPE_PN5180 #define RFID_BUSY 16 // PN5180 BUSY PIN #define RFID_RST 22 // PN5180 RESET PIN + #define RFID_IRQ 39 // PN5180 IRQ PIN (only needed for low power card detection) + #define BUTTON_PIN_BITMASK 0x8000000000// 2^RFID_IRQ in hex #endif // I2S (DAC) #define I2S_DOUT 25 // Digital out (I2S) diff --git a/src/settings.h b/src/settings.h index e2d22fd..2d7a0ff 100644 --- a/src/settings.h +++ b/src/settings.h @@ -38,7 +38,8 @@ //################## select RFID reader ############################## #define RFID_READER_TYPE_MFRC522_SPI // use MFRC522 via SPI //#define RFID_READER_TYPE_MFRC522_I2C // use MFRC522 via I2C -//#define RFID_READER_TYPE_PN5180 +//#define RFID_READER_TYPE_PN5180 // use PN5180 +//#define PN5180_ENABLE_LPCD // enable PN5180 low power card detection: wake up on card detection //#################### Various settings ############################## From aa29227a2a767206544190831f2063e67144d499 Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 9 Jan 2021 22:09:05 +0100 Subject: [PATCH 2/7] fix documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14410b0..f8576fc 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ You can enable low power card detection with `PN5180_ENABLE_LPCD`. With low powe | ESP32 (GPIO) | Hardware | Pin | Comment | | ------------- | --------------------- | ------ | ----------------------------------------------------------------- | | 3.3 V | PN5180 RFID-reader | 3.3V | Connect directly to GPIO 17 for power-saving when uC is off | -| 5 / 3.3 V | | 3.3V | For low power card detection mode (LPCD) connect directly to 3.3V | +| 3.3 V | | 3.3V | For low power card detection mode (LPCD) connect directly to 3.3V | | 5 / 3.3 V | PN5180 RFID-reader | 5V | Don't forget to connect this pin the same way as 3.3V | | GND | PN5180 RFID-reader | GND | | | 21 | PN5180 RFID-reader | CS/SDA | Same as MFRC522. Don't share with SD! | From 55b55b6a4c2a046e5c6eb8421392a1ea5f44f68b Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 9 Jan 2021 22:14:19 +0100 Subject: [PATCH 3/7] hint for sleeping flag --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index eea3f1e..bc2c54d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -228,7 +228,7 @@ char *currentRfidTagId = NULL; unsigned long lastTimeActiveTimestamp = 0; // Timestamp of last user-interaction unsigned long sleepTimerStartTimestamp = 0; // Flag if sleep-timer is active bool gotoSleep = false; // Flag for turning uC immediately into deepsleep -bool sleeping = false; // Flag for turning uC immediately into deepsleep +bool sleeping = false; // Flag for turning into deepsleep is in progress bool lockControls = false; // Flag if buttons and rotary encoder is locked bool bootComplete = false; // Rotary encoder-helper From 2f57882aef406892ee27003d62f0672f135c2950 Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 9 Jan 2021 22:16:40 +0100 Subject: [PATCH 4/7] spell check --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bc2c54d..f62d1aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3845,7 +3845,7 @@ void printWakeUpReason(){ } // wake up from LPCD, check card is present. This works only for ISO-14443 compatible cards -void checCardIsPresentLPCD() { +void checkCardIsPresentLPCD() { static PN5180ISO14443 nfc14443(RFID_CS, RFID_BUSY, RFID_RST); nfc14443.begin(); nfc14443.reset(); @@ -3886,7 +3886,7 @@ void setup() { esp_sleep_wakeup_cause_t wakeup_reason; wakeup_reason = esp_sleep_get_wakeup_cause(); if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT1) { - checCardIsPresentLPCD(); + checkCardIsPresentLPCD(); } #endif srand(esp_random()); From fb07ea266bda8aa5cb2ebb1ea3677a78f5614202 Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 16 Jan 2021 23:20:27 +0100 Subject: [PATCH 5/7] move LPCD preparing all the registers into PN5180 library: new function prepareLPCD() --- src/main.cpp | 68 ++++------------------------------------------------ 1 file changed, 4 insertions(+), 64 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f62d1aa..b728776 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2357,7 +2357,7 @@ void sleepHandler(void) { #ifdef PN5180_ENABLE_LPCD // goto low power card detection mode void gotoLPCD() { - static PN5180ISO14443 nfc(RFID_CS, RFID_BUSY, RFID_RST); + static PN5180 nfc(RFID_CS, RFID_BUSY, RFID_RST); nfc.begin(); // show PN5180 reader version uint8_t firmwareVersion[2]; @@ -2369,71 +2369,11 @@ void gotoLPCD() { // check firmware version: PN5180 firmware < 4.0 has several bugs preventing the LPCD mode // you can flash latest firmware with this project: https://github.com/abidxraihan/PN5180_Updater_ESP32 if (firmwareVersion[1] < 4) { - Serial.println(F("This PN5180 firmware does not work with LPCD!")); + Serial.println(F("This PN5180 firmware does not work with LPCD! use firmware >= 4.0")); return; } - Serial.println(F("Prepare PN5180 for LPCD...")); - nfc.reset(); - nfc.clearIRQStatus(0xffffffff); - Serial.println("RFID_IRQ: " + digitalRead(RFID_IRQ)); //reads 0 because IRQ pin pin config is set to active high (eeprom@0x1A) //should read 1 because when interrupt is raised GPIO4 is LOW - Serial.println(F("Reading IRQ-Pin...")); - uint8_t irqPin[1]; - nfc.readEEprom(IRQ_PIN_CONFIG, irqPin, sizeof(irqPin)); - Serial.print(F("irqPin=")); - Serial.println(irqPin[0]); //should read 1 i.e. pin IRQ is high(bolean 1/3.3v) when active(interrupted) - - //=======================================LPCD CONFIG================================================================================ - Serial.println(F("----------------------------------")); - Serial.println(F("start LPCD...")); - - uint8_t data[255]; - uint8_t response[256]; - //1. Set Fieldon time LPCD_FIELD_ON_TIME (0x36) - uint8_t fieldOn = 0xF0;//0x## -> ##(base 10) x 8μs + 62 μs - data[0] = fieldOn; - nfc.writeEEprom(0x36, data, 1); - nfc.readEEprom(0x36, response, 1); - fieldOn = response[0]; - Serial.print(F("LPCD-fieldOn time: ")); - Serial.println(fieldOn, HEX); - - //2. Set threshold level AGC_LPCD_THRESHOLD @ EEPROM 0x37 - uint8_t threshold = 0x03; - data[0] = threshold; - nfc.writeEEprom(0x37, data, 1); - nfc.readEEprom(0x37, response, 1); - threshold = response[0]; - Serial.print(F("LPCD-threshold: ")); - Serial.println(threshold, HEX); - - //4. Select LPCD mode LPCD_REFVAL_GPO_CONTROL (0x38) - uint8_t lpcdMode = 0x01; // 1 = LPCD SELF CALIBRATION - // 0 = LPCD AUTO CALIBRATION (this mode does not work, should look more into it, no reason why it shouldn't work) - data[0] = lpcdMode; - nfc.writeEEprom(0x38, data, 1); - nfc.readEEprom(0x38, response, 1); - lpcdMode = response[0]; - Serial.print(F("lpcdMode: ")); - Serial.println(lpcdMode, HEX); - - // LPCD_GPO_TOGGLE_BEFORE_FIELD_ON (0x39) - uint8_t beforeFieldOn = 0xF0; - data[0] = beforeFieldOn; - nfc.writeEEprom(0x39, data, 1); - nfc.readEEprom(0x39, response, 1); - beforeFieldOn = response[0]; - Serial.print(F("beforeFieldOn: ")); - Serial.println(beforeFieldOn, HEX); - - // LPCD_GPO_TOGGLE_AFTER_FIELD_ON (0x3A) - uint8_t afterFieldOn = 0xF0; - data[0] = afterFieldOn; - nfc.writeEEprom(0x3A, data, 1); - nfc.readEEprom(0x3A, response, 1); - afterFieldOn = response[0]; - Serial.print(F("afterFieldOn: ")); - Serial.println(afterFieldOn, HEX); - delay(100); + Serial.println(F("prepare low power card detection...")); + nfc.prepareLPCD(); nfc.clearIRQStatus(0xffffffff); Serial.print(F("PN5180 IRQ PIN: ")); Serial.println(digitalRead(RFID_IRQ)); // turn on LPCD From 016c59c4a4f4246c6c47578b288d86018339a8cd Mon Sep 17 00:00:00 2001 From: Torsten Stauder Date: Mon, 18 Jan 2021 22:13:08 +0100 Subject: [PATCH 6/7] Slight code-rework for wakeup-feature (PN5180) --- platformio.ini | 2 +- src/logmessages.h | 4 +- src/logmessages_EN.h | 4 +- src/main.cpp | 89 +++++++++++++++++++++----------------------- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/platformio.ini b/platformio.ini index e1c4581..ed58079 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ lib_deps_builtin = SPI Wire lib_deps_external = - https://github.com/schreibfaul1/ESP32-audioI2S.git + https://github.com/schreibfaul1/ESP32-audioI2S.git#edc5f10 https://github.com/madhephaestus/ESP32Encoder.git https://github.com/knolleary/pubsubclient.git https://github.com/biologist79/ESP32FTPServer diff --git a/src/logmessages.h b/src/logmessages.h index 2807243..d94a4d2 100644 --- a/src/logmessages.h +++ b/src/logmessages.h @@ -168,4 +168,6 @@ static const char mqttMsgReceived[] PROGMEM = "MQTT-Nachricht empfangen"; static const char trackPausedAtPos[] PROGMEM = "Titel pausiert bei Position"; static const char freeHeapWithoutFtp[] PROGMEM = "Freier Heap-Speicher vor FTP-Instanzierung"; static const char freeHeapWithFtp[] PROGMEM = "Freier Heap-Speicher nach FTP-Instanzierung"; -static const char freeHeapAfterSetup[] PROGMEM = "Freier Heap-Speicher nach Setup-Routine"; \ No newline at end of file +static const char freeHeapAfterSetup[] PROGMEM = "Freier Heap-Speicher nach Setup-Routine"; +static const char wakeUpRfidNoIso14443[] PROGMEM = "ESP32 wurde vom Kartenleser aus dem Deepsleep aufgeweckt. Allerdings wurde keine ISO-14443-Karte gefunden. Gehe zurück in den Deepsleep..."; +static const char lowPowerCardSuccess[] PROGMEM = "Kartenerkennung via 'low power' erfolgreich durchgeführt"; \ No newline at end of file diff --git a/src/logmessages_EN.h b/src/logmessages_EN.h index 5233a90..b04418b 100644 --- a/src/logmessages_EN.h +++ b/src/logmessages_EN.h @@ -168,4 +168,6 @@ static const char mqttMsgReceived[] PROGMEM = "MQTT-message received"; static const char trackPausedAtPos[] PROGMEM = "Track paused at position"; static const char freeHeapWithoutFtp[] PROGMEM = "Free heap before FTP-allocation"; static const char freeHeapWithFtp[] PROGMEM = "Free heap after FTP-allocation"; -static const char freeHeapAfterSetup[] PROGMEM = "Free heap after setup"; \ No newline at end of file +static const char freeHeapAfterSetup[] PROGMEM = "Free heap after setup"; +static const char wakeUpRfidNoIso14443[] PROGMEM = "Wakeup caused by low power card-detection. RF-field changed but no ISO-14443 card on reader was found. So I'll return back to sleep now..."; +static const char lowPowerCardSuccess[] PROGMEM = "Switch to low power card-detection: success"; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b728776..0479579 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2388,7 +2388,7 @@ void gotoLPCD() { gpio_deep_sleep_hold_en(); } else { Serial.println(F("switchToLPCD failed")); - } + } } #endif @@ -3767,57 +3767,54 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, } #ifdef PN5180_ENABLE_LPCD -// print the wake-up reason -void printWakeUpReason(){ - esp_sleep_wakeup_cause_t wakeup_reason; - - wakeup_reason = esp_sleep_get_wakeup_cause(); - - switch(wakeup_reason) - { - case ESP_SLEEP_WAKEUP_EXT0 : Serial.println(F("Wakeup caused by push button")); break; - case ESP_SLEEP_WAKEUP_EXT1 : Serial.println(F("Wakeup caused by low power card detection")); break; - case ESP_SLEEP_WAKEUP_TIMER : Serial.println(F("Wakeup caused by timer")); break; - case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println(F("Wakeup caused by touchpad")); break; - case ESP_SLEEP_WAKEUP_ULP : Serial.println(F("Wakeup caused by ULP program")); break; - default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break; - } -} + // Print the wake-up reason why ESP32 is awake now + void printWakeUpReason() { + esp_sleep_wakeup_cause_t wakeup_reason; + wakeup_reason = esp_sleep_get_wakeup_cause(); -// wake up from LPCD, check card is present. This works only for ISO-14443 compatible cards -void checkCardIsPresentLPCD() { - static PN5180ISO14443 nfc14443(RFID_CS, RFID_BUSY, RFID_RST); - nfc14443.begin(); - nfc14443.reset(); - nfc14443.setupRF(); - if (!nfc14443.isCardPresent()) { - nfc14443.clearIRQStatus(0xffffffff); - Serial.print(F("PN5180 IRQ PIN: ")); Serial.println(digitalRead(RFID_IRQ)); - // turn on LPCD - uint16_t wakeupCounterInMs = 0x3FF; // must be in the range of 0x0 - 0xA82. max wake-up time is 2960 ms. - if (nfc14443.switchToLPCD(wakeupCounterInMs)) { - Serial.println(F("switch to low power card detection: success")); - // configure wakeup pin for deep-sleep wake-up, use ext1 - esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH); - // freeze pin states in deep sleep - gpio_hold_en(gpio_num_t(RFID_CS)); // CS/NSS - gpio_hold_en(gpio_num_t(RFID_RST)); // RST - gpio_deep_sleep_hold_en(); - Serial.println(F("Wakeup caused by low power card detection. RF-field change but no ISO-14443 card on reader")); - Serial.println(F("go to deep-sleep again, sleep well in your Bettgestell.......")); - esp_deep_sleep_start(); - } else { - Serial.println(F("switchToLPCD failed")); - } + switch(wakeup_reason) { + case ESP_SLEEP_WAKEUP_EXT0 : Serial.println(F("Wakeup caused by push button")); break; + case ESP_SLEEP_WAKEUP_EXT1 : Serial.println(F("Wakeup caused by low power card detection")); break; + case ESP_SLEEP_WAKEUP_TIMER : Serial.println(F("Wakeup caused by timer")); break; + case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println(F("Wakeup caused by touchpad")); break; + case ESP_SLEEP_WAKEUP_ULP : Serial.println(F("Wakeup caused by ULP program")); break; + default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break; + } + } + + // wake up from LPCD, check card is present. This works only for ISO-14443 compatible cards + void checkCardIsPresentLPCD() { + static PN5180ISO14443 nfc14443(RFID_CS, RFID_BUSY, RFID_RST); + nfc14443.begin(); + nfc14443.reset(); + nfc14443.setupRF(); + if (!nfc14443.isCardPresent()) { + nfc14443.clearIRQStatus(0xffffffff); + Serial.print(F("Logic level at PN5180' IRQ-PIN: ")); Serial.println(digitalRead(RFID_IRQ)); + // turn on LPCD + uint16_t wakeupCounterInMs = 0x3FF; // needs to be in the range of 0x0 - 0xA82. max wake-up time is 2960 ms. + if (nfc14443.switchToLPCD(wakeupCounterInMs)) { + loggerNl((char *) FPSTR(lowPowerCardSuccess), LOGLEVEL_INFO); + // configure wakeup pin for deep-sleep wake-up, use ext1 + esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH); + // freeze pin states in deep sleep + gpio_hold_en(gpio_num_t(RFID_CS)); // CS/NSS + gpio_hold_en(gpio_num_t(RFID_RST)); // RST + gpio_deep_sleep_hold_en(); + loggerNl((char *) FPSTR(wakeUpRfidNoIso14443), LOGLEVEL_ERROR); + esp_deep_sleep_start(); + } else { + Serial.println(F("switchToLPCD failed")); + } + } } -} #endif void setup() { Serial.begin(115200); esp_sleep_enable_ext0_wakeup((gpio_num_t) DREHENCODER_BUTTON, 0); #ifdef PN5180_ENABLE_LPCD - // disable pin hold from deep sleep (LPCD) + // disable pin hold from deep sleep (LPCD) gpio_deep_sleep_hold_dis(); gpio_hold_dis(gpio_num_t(RFID_CS)); // NSS gpio_hold_dis(gpio_num_t(RFID_RST)); // RST @@ -3829,7 +3826,7 @@ void setup() { checkCardIsPresentLPCD(); } #endif - srand(esp_random()); + srand(esp_random()); pinMode(POWER, OUTPUT); digitalWrite(POWER, HIGH); prefsRfid.begin((char *) FPSTR(prefsRfidNamespace)); @@ -3949,7 +3946,7 @@ void setup() { // print wake-up reason printWakeUpReason(); #ifdef PN5180_ENABLE_LPCD - // disable pin hold from deep sleep + // disable pin hold from deep sleep gpio_deep_sleep_hold_dis(); gpio_hold_dis(gpio_num_t(RFID_CS)); // NSS gpio_hold_dis(gpio_num_t(RFID_RST)); // RST From eacca13ad3b201ae4b479a441a7c8a0c2a93f0fe Mon Sep 17 00:00:00 2001 From: Torsten Stauder Date: Mon, 18 Jan 2021 22:24:07 +0100 Subject: [PATCH 7/7] Fixing issue if PN5180 is active but without LPCD --- src/main.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0479579..8d9f817 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1953,7 +1953,7 @@ void rfidScanner(void *parameter) { } } } - Serial.println("delete RFID scanner task"); + //Serial.println("deleted RFID scanner-task"); vTaskDelete(NULL); } #endif @@ -3766,22 +3766,22 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, #endif } -#ifdef PN5180_ENABLE_LPCD - // Print the wake-up reason why ESP32 is awake now - void printWakeUpReason() { - esp_sleep_wakeup_cause_t wakeup_reason; - wakeup_reason = esp_sleep_get_wakeup_cause(); - - switch(wakeup_reason) { - case ESP_SLEEP_WAKEUP_EXT0 : Serial.println(F("Wakeup caused by push button")); break; - case ESP_SLEEP_WAKEUP_EXT1 : Serial.println(F("Wakeup caused by low power card detection")); break; - case ESP_SLEEP_WAKEUP_TIMER : Serial.println(F("Wakeup caused by timer")); break; - case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println(F("Wakeup caused by touchpad")); break; - case ESP_SLEEP_WAKEUP_ULP : Serial.println(F("Wakeup caused by ULP program")); break; - default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break; - } +// Print the wake-up reason why ESP32 is awake now +void printWakeUpReason() { + esp_sleep_wakeup_cause_t wakeup_reason; + wakeup_reason = esp_sleep_get_wakeup_cause(); + + switch(wakeup_reason) { + case ESP_SLEEP_WAKEUP_EXT0 : Serial.println(F("Wakeup caused by push button")); break; + case ESP_SLEEP_WAKEUP_EXT1 : Serial.println(F("Wakeup caused by low power card detection")); break; + case ESP_SLEEP_WAKEUP_TIMER : Serial.println(F("Wakeup caused by timer")); break; + case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println(F("Wakeup caused by touchpad")); break; + case ESP_SLEEP_WAKEUP_ULP : Serial.println(F("Wakeup caused by ULP program")); break; + default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break; } +} +#ifdef PN5180_ENABLE_LPCD // wake up from LPCD, check card is present. This works only for ISO-14443 compatible cards void checkCardIsPresentLPCD() { static PN5180ISO14443 nfc14443(RFID_CS, RFID_BUSY, RFID_RST);