401 lines
11 KiB
C++
401 lines
11 KiB
C++
/****************************************************************************************************************************
|
|
ESP_DoubleResetDetector.h
|
|
For ESP8266 / ESP32 boards
|
|
|
|
ESP_DoubleResetDetector is a library for the ESP8266/Arduino platform
|
|
to enable trigger configure mode by resetting ESP32 / ESP8266 twice.
|
|
|
|
Forked from DataCute https://github.com/datacute/DoubleResetDetector
|
|
|
|
Built by Khoi Hoang https://github.com/khoih-prog/ESP_DoubleResetDetector
|
|
Licensed under MIT license
|
|
Version: 1.3.2
|
|
|
|
Version Modified By Date Comments
|
|
------- ----------- ---------- -----------
|
|
1.0.0 K Hoang 15/12/2019 Initial coding
|
|
1.0.1 K Hoang 30/12/2019 Now can use EEPROM or SPIFFS for both ESP8266 and ESP32. RTC still OK for ESP8266
|
|
1.0.2 K Hoang 10/04/2020 Fix bug by left-over cpp file and in example.
|
|
1.0.3 K Hoang 13/05/2020 Update to use LittleFS for ESP8266 core 2.7.1+
|
|
1.1.0 K Hoang 04/12/2020 Add support to LittleFS for ESP32 using LITTLEFS Library
|
|
1.1.1 K Hoang 28/12/2020 Suppress all possible compiler warnings
|
|
1.1.2 K Hoang 10/10/2021 Update `platform.ini` and `library.json`
|
|
1.2.0 K Hoang 26/11/2021 Auto detect ESP32 core and use either built-in LittleFS or LITTLEFS library
|
|
1.2.1 K Hoang 26/11/2021 Fix compile error for ESP32 core v1.0.5-
|
|
1.3.0 K Hoang 10/02/2022 Add support to new ESP32-S3
|
|
1.3.1 K Hoang 04/03/2022 Add waitingForDRD() function to signal in DRD wating period
|
|
1.3.2 K Hoang 09/09/2022 Fix ESP32 chipID for example ConfigOnDoubleReset
|
|
*****************************************************************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#ifndef ESP_DoubleResetDetector_H
|
|
#define ESP_DoubleResetDetector_H
|
|
|
|
#ifndef DOUBLERESETDETECTOR_DEBUG
|
|
#define DOUBLERESETDETECTOR_DEBUG false
|
|
#endif
|
|
|
|
#if defined(ARDUINO) && (ARDUINO >= 100)
|
|
#include <Arduino.h>
|
|
#else
|
|
#include <WProgram.h>
|
|
#endif
|
|
|
|
#ifndef ESP_DOUBLE_RESET_DETECTOR_VERSION
|
|
#define ESP_DOUBLE_RESET_DETECTOR_VERSION "ESP_DoubleResetDetector v1.3.2"
|
|
|
|
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_MAJOR 1
|
|
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_MINOR 3
|
|
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_PATCH 2
|
|
|
|
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_INT 1003002
|
|
#endif
|
|
|
|
#define ESP_DOUBLERESETDETECTOR_VERSION ESP_DOUBLE_RESET_DETECTOR_VERSION
|
|
|
|
//#define ESP_DRD_USE_EEPROM false
|
|
//#define ESP_DRD_USE_LITTLEFS false
|
|
//#define ESP_DRD_USE_SPIFFS false
|
|
//#define ESP8266_DRD_USE_RTC false //true
|
|
|
|
#ifdef ESP32
|
|
#if (!ESP_DRD_USE_EEPROM && !ESP_DRD_USE_SPIFFS && !ESP_DRD_USE_LITTLEFS)
|
|
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
#warning Neither EEPROM, SPIFFS nor LittleFS selected. Default to EEPROM
|
|
#endif
|
|
|
|
#ifdef ESP_DRD_USE_EEPROM
|
|
#undef ESP_DRD_USE_EEPROM
|
|
#define ESP_DRD_USE_EEPROM true
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef ESP8266
|
|
#if (!ESP8266_DRD_USE_RTC && !ESP_DRD_USE_EEPROM && !ESP_DRD_USE_SPIFFS && !ESP_DRD_USE_LITTLEFS)
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
#warning Neither RTC, EEPROM, LITTLEFS nor SPIFFS selected. Default to EEPROM
|
|
#endif
|
|
|
|
#ifdef ESP_DRD_USE_EEPROM
|
|
#undef ESP_DRD_USE_EEPROM
|
|
#define ESP_DRD_USE_EEPROM true
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
//default to use EEPROM, otherwise, use LITTLEFS (higher priority), then SPIFFS
|
|
#if ESP_DRD_USE_EEPROM
|
|
#include <EEPROM.h>
|
|
|
|
#define FLAG_DATA_SIZE 4
|
|
|
|
#ifndef EEPROM_SIZE
|
|
#define EEPROM_SIZE 512
|
|
#endif
|
|
|
|
#ifndef EEPROM_START
|
|
#define EEPROM_START 256
|
|
#endif
|
|
|
|
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
|
|
|
#include <FS.h>
|
|
|
|
#ifdef ESP32
|
|
|
|
#if ESP_DRD_USE_LITTLEFS
|
|
// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h
|
|
//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2)
|
|
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
#warning Using ESP32 Core 1.0.6 or 2.0.0+
|
|
#endif
|
|
|
|
// The library has been merged into esp32 core from release 1.0.6
|
|
#include <LittleFS.h>
|
|
|
|
#define FileFS LittleFS
|
|
#define FS_Name "LittleFS"
|
|
#else
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
#warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library
|
|
#endif
|
|
|
|
// The library has been merged into esp32 core from release 1.0.6
|
|
#include <LITTLEFS.h> // https://github.com/lorol/LITTLEFS
|
|
|
|
#define FileFS LITTLEFS
|
|
#define FS_Name "LittleFS"
|
|
#endif
|
|
#else
|
|
#include "SPIFFS.h"
|
|
// ESP32 core 1.0.4 still uses SPIFFS
|
|
#define FileFS SPIFFS
|
|
#endif
|
|
|
|
#else
|
|
// From ESP8266 core 2.7.1
|
|
#include <LittleFS.h>
|
|
|
|
#if ESP_DRD_USE_LITTLEFS
|
|
#define FileFS LittleFS
|
|
#else
|
|
#define FileFS SPIFFS
|
|
#endif
|
|
|
|
#endif // #if ESP_DRD_USE_EEPROM
|
|
|
|
|
|
|
|
#define DRD_FILENAME "/drd.dat"
|
|
|
|
#endif //#if ESP_DRD_USE_EEPROM
|
|
|
|
|
|
|
|
#define DOUBLERESETDETECTOR_FLAG_SET 0xD0D01234
|
|
#define DOUBLERESETDETECTOR_FLAG_CLEAR 0xD0D04321
|
|
|
|
class DoubleResetDetector
|
|
{
|
|
public:
|
|
DoubleResetDetector(int timeout, int address)
|
|
{
|
|
#if ESP_DRD_USE_EEPROM
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.printf("EEPROM size = %d, start = %d\n", EEPROM_SIZE, EEPROM_START);
|
|
#endif
|
|
|
|
EEPROM.begin(EEPROM_SIZE);
|
|
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
|
// LittleFS / SPIFFS code
|
|
if (!FileFS.begin())
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
|
|
#if ESP_DRD_USE_LITTLEFS
|
|
Serial.println("LittleFS failed!. Please use SPIFFS or EEPROM.");
|
|
#else
|
|
Serial.println("SPIFFS failed!. Please use LittleFS or EEPROM.");
|
|
#endif
|
|
|
|
#endif
|
|
}
|
|
#else
|
|
#ifdef ESP8266
|
|
//RTC only for ESP8266
|
|
#endif
|
|
#endif
|
|
|
|
this->timeout = timeout * 1000;
|
|
this->address = address;
|
|
doubleResetDetected = false;
|
|
waitingForDoubleReset = false;
|
|
};
|
|
|
|
bool detectDoubleReset()
|
|
{
|
|
doubleResetDetected = detectRecentlyResetFlag();
|
|
|
|
if (doubleResetDetected)
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("doubleResetDetected");
|
|
#endif
|
|
|
|
clearRecentlyResetFlag();
|
|
}
|
|
else
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("No doubleResetDetected");
|
|
#endif
|
|
|
|
setRecentlyResetFlag();
|
|
waitingForDoubleReset = true;
|
|
}
|
|
|
|
return doubleResetDetected;
|
|
|
|
};
|
|
|
|
bool waitingForDRD()
|
|
{
|
|
return waitingForDoubleReset;
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
if (waitingForDoubleReset && millis() > timeout)
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Stop doubleResetDetecting");
|
|
#endif
|
|
|
|
stop();
|
|
}
|
|
};
|
|
|
|
void stop()
|
|
{
|
|
clearRecentlyResetFlag();
|
|
waitingForDoubleReset = false;
|
|
};
|
|
|
|
bool doubleResetDetected;
|
|
|
|
|
|
private:
|
|
uint32_t DOUBLERESETDETECTOR_FLAG;
|
|
unsigned long timeout;
|
|
int address;
|
|
bool waitingForDoubleReset;
|
|
|
|
bool detectRecentlyResetFlag()
|
|
{
|
|
#if (ESP_DRD_USE_EEPROM)
|
|
EEPROM.get(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
|
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG;
|
|
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.printf("EEPROM Flag read = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
|
#endif
|
|
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
|
// LittleFS / SPIFFS code
|
|
if (FileFS.exists(DRD_FILENAME))
|
|
{
|
|
// if config file exists, load
|
|
File file = FileFS.open(DRD_FILENAME, "r");
|
|
|
|
if (!file)
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Loading config file failed");
|
|
#endif
|
|
}
|
|
|
|
file.readBytes((char *) &DOUBLERESETDETECTOR_FLAG, sizeof(DOUBLERESETDETECTOR_FLAG));
|
|
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG;
|
|
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
|
|
#if ESP_DRD_USE_LITTLEFS
|
|
Serial.printf("LittleFS Flag read = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
|
#else
|
|
Serial.printf("SPIFFS Flag read = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
file.close();
|
|
}
|
|
#else
|
|
#ifdef ESP8266
|
|
//RTC only for ESP8266
|
|
ESP.rtcUserMemoryRead(address, &doubleResetDetectorFlag, sizeof(doubleResetDetectorFlag));
|
|
#endif
|
|
#endif
|
|
|
|
doubleResetDetected = (doubleResetDetectorFlag == DOUBLERESETDETECTOR_FLAG_SET);
|
|
return doubleResetDetected;
|
|
};
|
|
|
|
void setRecentlyResetFlag()
|
|
{
|
|
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG_SET;
|
|
|
|
DOUBLERESETDETECTOR_FLAG = DOUBLERESETDETECTOR_FLAG_SET;
|
|
|
|
#if (ESP_DRD_USE_EEPROM)
|
|
EEPROM.put(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
|
EEPROM.commit();
|
|
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
delay(1000);
|
|
EEPROM.get(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
|
|
|
Serial.printf("SetFlag write = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
|
#endif
|
|
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
|
// LittleFS / SPIFFS code
|
|
File file = FileFS.open(DRD_FILENAME, "w");
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Saving config file...");
|
|
#endif
|
|
|
|
if (file)
|
|
{
|
|
file.write((uint8_t *) &DOUBLERESETDETECTOR_FLAG, sizeof(DOUBLERESETDETECTOR_FLAG));
|
|
file.close();
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Saving config file OK");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Saving config file failed");
|
|
#endif
|
|
}
|
|
#else
|
|
#ifdef ESP8266
|
|
//RTC only for ESP8266
|
|
ESP.rtcUserMemoryWrite(address, &doubleResetDetectorFlag, sizeof(doubleResetDetectorFlag));
|
|
#endif
|
|
#endif
|
|
};
|
|
|
|
|
|
void clearRecentlyResetFlag()
|
|
{
|
|
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG_CLEAR;
|
|
DOUBLERESETDETECTOR_FLAG = DOUBLERESETDETECTOR_FLAG_CLEAR;
|
|
|
|
#if (ESP_DRD_USE_EEPROM)
|
|
//DOUBLERESETDETECTOR_FLAG = DOUBLERESETDETECTOR_FLAG_CLEAR;
|
|
EEPROM.put(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
|
EEPROM.commit();
|
|
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
delay(1000);
|
|
EEPROM.get(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
|
|
|
Serial.printf("ClearFlag write = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
|
#endif
|
|
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
|
// LittleFS / SPIFFS code
|
|
File file = FileFS.open(DRD_FILENAME, "w");
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Saving config file...");
|
|
#endif
|
|
|
|
if (file)
|
|
{
|
|
file.write((uint8_t *) &DOUBLERESETDETECTOR_FLAG, sizeof(DOUBLERESETDETECTOR_FLAG));
|
|
file.close();
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Saving config file OK");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if (DOUBLERESETDETECTOR_DEBUG)
|
|
Serial.println("Saving config file failed");
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
#ifdef ESP8266
|
|
//RTC only for ESP8266
|
|
ESP.rtcUserMemoryWrite(address, &doubleResetDetectorFlag, sizeof(doubleResetDetectorFlag));
|
|
#endif
|
|
#endif
|
|
};
|
|
|
|
uint32_t doubleResetDetectorFlag;
|
|
};
|
|
#endif // ESP_DoubleResetDetector_H
|