mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Add ESP32 QuickPowerCycle control
This commit is contained in:
parent
eab612871c
commit
c37dde93c2
@ -99,12 +99,3 @@ uint32_t ESP_getSketchSize(void)
|
||||
}
|
||||
return sketchsize;
|
||||
}
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void DisableBrownout(void)
|
||||
{
|
||||
// https://github.com/espressif/arduino-esp32/issues/863#issuecomment-347179737
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector
|
||||
}
|
||||
|
@ -31,8 +31,6 @@
|
||||
//
|
||||
// ESP32
|
||||
//
|
||||
#define ESP_flashReadHeader(offset, data, size) ESP32_flashRead(offset, data, size)
|
||||
#define ESP_flashRead(offset, data, size) ESP32_flashRead(offset, data, size)
|
||||
String ESP_getResetReason(void);
|
||||
uint32_t ESP_ResetInfoReason(void);
|
||||
uint32_t ESP_getBootVersion(void);
|
||||
@ -41,7 +39,6 @@ uint32_t ESP_getFlashChipId();
|
||||
uint32_t ESP_getChipId();
|
||||
String String_ESP_getChipId();
|
||||
uint32_t ESP_getSketchSize();
|
||||
void DisableBrownout(void);
|
||||
|
||||
// Analog
|
||||
inline void analogWrite(uint8_t pin, int val)
|
||||
|
@ -253,7 +253,7 @@ typedef struct {
|
||||
const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017)
|
||||
const uint8_t MAX_TUYA_FUNCTIONS = 16;
|
||||
|
||||
struct SYSCFG {
|
||||
struct {
|
||||
uint16_t cfg_holder; // 000 v6 header
|
||||
uint16_t cfg_size; // 002
|
||||
unsigned long save_flag; // 004
|
||||
|
@ -305,7 +305,7 @@ uint16_t GetCfgCrc16(uint8_t *bytes, uint32_t size)
|
||||
uint16_t GetSettingsCrc(void)
|
||||
{
|
||||
// Fix miscalculation if previous Settings was 3584 and current Settings is 4096 between 0x06060007 and 0x0606000A
|
||||
uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(SYSCFG);
|
||||
uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(Settings);
|
||||
return GetCfgCrc16((uint8_t*)&Settings, size);
|
||||
}
|
||||
|
||||
@ -325,7 +325,7 @@ uint32_t GetCfgCrc32(uint8_t *bytes, uint32_t size)
|
||||
|
||||
uint32_t GetSettingsCrc32(void)
|
||||
{
|
||||
return GetCfgCrc32((uint8_t*)&Settings, sizeof(SYSCFG) -4); // Skip crc32
|
||||
return GetCfgCrc32((uint8_t*)&Settings, sizeof(Settings) -4); // Skip crc32
|
||||
}
|
||||
|
||||
void SettingsSaveAll(void)
|
||||
@ -351,7 +351,11 @@ void UpdateQuickPowerCycle(bool update)
|
||||
uint32_t pc_register;
|
||||
uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES;
|
||||
|
||||
#ifdef ESP8266
|
||||
ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
#else
|
||||
QPCRead(&pc_register, sizeof(pc_register));
|
||||
#endif
|
||||
if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AB0)) {
|
||||
uint32_t counter = ((pc_register & 0xF) << 1) & 0xF;
|
||||
if (0 == counter) { // 4 power cycles in a row
|
||||
@ -359,16 +363,24 @@ void UpdateQuickPowerCycle(bool update)
|
||||
EspRestart(); // And restart
|
||||
} else {
|
||||
pc_register = 0xFFA55AB0 | counter;
|
||||
#ifdef ESP8266
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
#else
|
||||
QPCWrite(&pc_register, sizeof(pc_register));
|
||||
#endif
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter);
|
||||
}
|
||||
}
|
||||
else if (pc_register != 0xFFA55ABF) {
|
||||
pc_register = 0xFFA55ABF;
|
||||
#ifdef ESP8266
|
||||
// Assume flash is default all ones and setting a bit to zero does not need an erase
|
||||
if (ESP.flashEraseSector(pc_location)) {
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
}
|
||||
#else
|
||||
QPCWrite(&pc_register, sizeof(pc_register));
|
||||
#endif
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset"));
|
||||
}
|
||||
}
|
||||
@ -501,13 +513,13 @@ void SettingsSave(uint8_t rotate)
|
||||
} else {
|
||||
Settings.cfg_timestamp++;
|
||||
}
|
||||
Settings.cfg_size = sizeof(SYSCFG);
|
||||
Settings.cfg_size = sizeof(Settings);
|
||||
Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade
|
||||
Settings.cfg_crc32 = GetSettingsCrc32();
|
||||
|
||||
#ifdef ESP8266
|
||||
if (ESP.flashEraseSector(settings_location)) {
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
}
|
||||
|
||||
if (!stop_flash_rotate && rotate) {
|
||||
@ -516,12 +528,12 @@ void SettingsSave(uint8_t rotate)
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(Settings));
|
||||
#else // ESP32
|
||||
SettingsSaveMain(&Settings, sizeof(SYSCFG));
|
||||
SettingsWrite(&Settings, sizeof(Settings));
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "Saved, " D_COUNT " %d, " D_BYTES " %d"), Settings.save_flag, sizeof(Settings));
|
||||
#endif // ESP8266
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG));
|
||||
|
||||
settings_crc32 = Settings.cfg_crc32;
|
||||
}
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
@ -530,8 +542,9 @@ void SettingsSave(uint8_t rotate)
|
||||
|
||||
void SettingsLoad(void)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
// Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
|
||||
struct SYSCFGH {
|
||||
struct {
|
||||
uint16_t cfg_holder; // 000
|
||||
uint16_t cfg_size; // 002
|
||||
unsigned long save_flag; // 004
|
||||
@ -543,7 +556,7 @@ void SettingsLoad(void)
|
||||
uint16_t cfg_holder = 0;
|
||||
for (uint32_t i = 0; i < CFG_ROTATES; i++) {
|
||||
flash_location--;
|
||||
ESP_flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
bool valid = false;
|
||||
if (Settings.version > 0x06000000) {
|
||||
bool almost_valid = (Settings.cfg_crc32 == GetSettingsCrc32());
|
||||
@ -554,7 +567,7 @@ void SettingsLoad(void)
|
||||
if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder
|
||||
valid = (cfg_holder == Settings.cfg_holder);
|
||||
} else {
|
||||
ESP_flashReadHeader((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
|
||||
ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(_SettingsH));
|
||||
valid = (Settings.cfg_holder == _SettingsH.cfg_holder);
|
||||
}
|
||||
if (valid) {
|
||||
@ -566,13 +579,16 @@ void SettingsLoad(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay(1);
|
||||
}
|
||||
if (settings_location > 0) {
|
||||
ESP_flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
|
||||
}
|
||||
#else // ESP32
|
||||
SettingsRead(&Settings, sizeof(Settings));
|
||||
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded, " D_COUNT " %lu"), Settings.save_flag);
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
#ifndef FIRMWARE_MINIMAL
|
||||
if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h
|
||||
@ -683,10 +699,10 @@ void SettingsDefault(void)
|
||||
|
||||
void SettingsDefaultSet1(void)
|
||||
{
|
||||
memset(&Settings, 0x00, sizeof(SYSCFG));
|
||||
memset(&Settings, 0x00, sizeof(Settings));
|
||||
|
||||
Settings.cfg_holder = (uint16_t)CFG_HOLDER;
|
||||
Settings.cfg_size = sizeof(SYSCFG);
|
||||
Settings.cfg_size = sizeof(Settings);
|
||||
// Settings.save_flag = 0;
|
||||
Settings.version = VERSION;
|
||||
// Settings.bootcount = 0;
|
||||
@ -695,7 +711,7 @@ void SettingsDefaultSet1(void)
|
||||
|
||||
void SettingsDefaultSet2(void)
|
||||
{
|
||||
memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16);
|
||||
memset((char*)&Settings +16, 0x00, sizeof(Settings) -16);
|
||||
|
||||
Settings.flag.stop_flash_rotate = APP_FLASH_CYCLE;
|
||||
Settings.flag.global_state = APP_ENABLE_LEDLINK;
|
||||
@ -1064,7 +1080,7 @@ void SettingsDelta(void)
|
||||
|
||||
#ifdef ESP8266
|
||||
if (Settings.version < 0x06000000) {
|
||||
Settings.cfg_size = sizeof(SYSCFG);
|
||||
Settings.cfg_size = sizeof(Settings);
|
||||
Settings.cfg_crc = GetSettingsCrc();
|
||||
}
|
||||
if (Settings.version < 0x06000002) {
|
||||
@ -1148,7 +1164,7 @@ void SettingsDelta(void)
|
||||
Settings.param[P_OVER_TEMP] = ENERGY_OVERTEMP;
|
||||
}
|
||||
if (Settings.version < 0x06060007) {
|
||||
memset((char*)&Settings +0xE00, 0x00, sizeof(SYSCFG) -0xE00);
|
||||
memset((char*)&Settings +0xE00, 0x00, sizeof(Settings) -0xE00);
|
||||
}
|
||||
if (Settings.version < 0x06060008) {
|
||||
// Move current tuya dimmer range to the new param.
|
||||
|
@ -22,6 +22,39 @@
|
||||
#include <nvs.h>
|
||||
#include <rom/rtc.h>
|
||||
|
||||
void NvmLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READONLY, &handle);
|
||||
size_t size = nSettingsLen;
|
||||
nvs_get_blob(handle, sName, pSettings, &size);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void NvmSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READWRITE, &handle);
|
||||
nvs_set_blob(handle, sName, pSettings, nSettingsLen);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void NvmErase(const char *sNvsName)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READWRITE, &handle);
|
||||
nvs_erase_all(handle);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void SettingsErase(uint8_t type)
|
||||
{
|
||||
if (1 == type) // SDK parameter area
|
||||
@ -34,75 +67,39 @@ void SettingsErase(uint8_t type)
|
||||
{
|
||||
}
|
||||
|
||||
noInterrupts();
|
||||
nvs_handle handle;
|
||||
nvs_open("main", NVS_READWRITE, &handle);
|
||||
nvs_erase_all(handle);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
NvmErase("main");
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " t=%d"), type);
|
||||
}
|
||||
|
||||
void SettingsLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen)
|
||||
void SettingsRead(void *data, size_t size)
|
||||
{
|
||||
noInterrupts();
|
||||
nvs_handle handle;
|
||||
size_t size;
|
||||
nvs_open(sNvsName, NVS_READONLY, &handle);
|
||||
size = nSettingsLen;
|
||||
nvs_get_blob(handle, sName, pSettings, &size);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
NvmLoad("main", "Settings", data, size);
|
||||
}
|
||||
|
||||
void SettingsSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen)
|
||||
void SettingsWrite(const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READWRITE, &handle);
|
||||
nvs_set_blob(handle, sName, pSettings, nSettingsLen);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
NvmSave("main", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void ESP32_flashRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
{
|
||||
SettingsLoad("main", "Settings", data, size);
|
||||
}
|
||||
|
||||
void ESP32_flashReadHeader(uint32_t offset, uint32_t *data, size_t size)
|
||||
{
|
||||
SettingsLoad("main", "SettingsH", data, size);
|
||||
}
|
||||
|
||||
void SettingsSaveMain(const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsSave("main", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
/*
|
||||
void SettingsLoadMain(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("main", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void SettingsLoadMainH(void *pSettingsH, unsigned nSettingsLenH)
|
||||
{
|
||||
SettingsLoad("main", "SettingsH", pSettingsH, nSettingsLenH);
|
||||
}
|
||||
*/
|
||||
|
||||
void SettingsLoadUpg(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("upg", "Settings", pSettings, nSettingsLen);
|
||||
NvmLoad("upg", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void SettingsLoadUpgH(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("upg", "SettingsH", pSettings, nSettingsLen);
|
||||
NvmLoad("upg", "SettingsH", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void QPCRead(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
NvmLoad("qpc", "pcreg", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void QPCWrite(const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
NvmSave("qpc", "pcreg", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
//
|
||||
@ -174,4 +171,17 @@ void CmndBlockedLoop(void)
|
||||
*/
|
||||
}
|
||||
|
||||
//
|
||||
// ESP32 specific
|
||||
//
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void DisableBrownout(void)
|
||||
{
|
||||
// https://github.com/espressif/arduino-esp32/issues/863#issuecomment-347179737
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector
|
||||
}
|
||||
|
||||
#endif // ESP32
|
||||
|
@ -18,11 +18,6 @@
|
||||
#define ESP_getSketchSize() ESP.getSketchSize()
|
||||
#define ESP_getChipId() ESP.getChipId()
|
||||
//
|
||||
// we need different ESP_flashRead for ESP32
|
||||
//
|
||||
#define ESP_flashReadHeader(offset, data, size) ESP.flashRead(offset, data, size)
|
||||
#define ESP_flashRead(offset, data, size) ESP.flashRead(offset, data, size)
|
||||
//
|
||||
// UDP
|
||||
#define PortUdp_write(p,n) PortUdp.write(p, n)
|
||||
//
|
||||
|
@ -312,7 +312,7 @@ void DebugCfgDump(char* parms)
|
||||
char *p;
|
||||
|
||||
uint8_t *buffer = (uint8_t *) &Settings;
|
||||
maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS);
|
||||
maxrow = ((sizeof(Settings)+CFG_COLS)/CFG_COLS);
|
||||
|
||||
uint16_t srow = strtol(parms, &p, 16) / CFG_COLS;
|
||||
uint16_t mrow = strtol(p, &p, 10);
|
||||
@ -356,7 +356,7 @@ void DebugCfgPeek(char* parms)
|
||||
char *p;
|
||||
|
||||
uint16_t address = strtol(parms, &p, 16);
|
||||
if (address > sizeof(SYSCFG)) address = sizeof(SYSCFG) -4;
|
||||
if (address > sizeof(Settings)) address = sizeof(Settings) -4;
|
||||
address = (address >> 2) << 2;
|
||||
|
||||
uint8_t *buffer = (uint8_t *) &Settings;
|
||||
@ -381,7 +381,7 @@ void DebugCfgPoke(char* parms)
|
||||
char *p;
|
||||
|
||||
uint16_t address = strtol(parms, &p, 16);
|
||||
if (address > sizeof(SYSCFG)) address = sizeof(SYSCFG) -4;
|
||||
if (address > sizeof(Settings)) address = sizeof(Settings) -4;
|
||||
address = (address >> 2) << 2;
|
||||
|
||||
uint32_t data = strtol(p, &p, 16);
|
||||
|
Loading…
x
Reference in New Issue
Block a user