Add ESP32 QuickPowerCycle control

This commit is contained in:
Theo Arends 2020-04-19 15:36:04 +02:00
parent eab612871c
commit c37dde93c2
7 changed files with 100 additions and 91 deletions

View File

@ -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
}

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)
//

View File

@ -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);