diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 0629de523..dcc60cc55 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,7 @@ -/* 6.1.1.13 20180828 +/* 6.1.1.14 20180830 + * Add boot loop detection and try to fix + * + * 6.1.1.13 20180828 * Fix 6.1.1.12 regression of Mem and Var default handling (#3618) * Optimizations * Change define USE_ALL_SENSORS to USE_SENSORS as it doesn't contain all sensors due to duplicate I2C addresses diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 3d63f73f5..107710678 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -236,6 +236,7 @@ #define D_CMND_SERIALSEND "SerialSend" #define D_CMND_SERIALDELIMITER "SerialDelimiter" #define D_CMND_BAUDRATE "Baudrate" +#define D_LOG_SOME_SETTINGS_RESET "Some settings have been reset" // Commands xdrv_01_mqtt.ino #define D_CMND_MQTTHOST "MqttHost" diff --git a/sonoff/settings.h b/sonoff/settings.h index 618ef0b54..6eabc5c7c 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -94,7 +94,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t spare28 : 1; uint32_t spare29 : 1; uint32_t spare30 : 1; - uint32_t spare31 : 1; + uint32_t user_esp8285_enable : 1; // bit 31 (v6.1.1.13) }; } SysBitfield3; @@ -341,7 +341,9 @@ struct RTCMEM { unsigned long energy_kWhtotal; // 008 unsigned long pulse_counter[MAX_COUNTERS]; // 00C power_t power; // 01C - // 020 next free location + uint8_t fast_reboot_count; // 020 + uint8_t spare_021[3]; // 021 + // 024 next free location } RtcSettings; struct TIME_T { diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index f93df0059..3a1dc14c6 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -85,6 +85,7 @@ typedef unsigned long power_t; // Power (Relay) type #define STATES 20 // Number of states per second using 50 mSec interval #define IMMINENT_RESET_FACTOR 10 // Factor to extent button hold time for imminent Reset to default 40 seconds using KEY_HOLD_TIME of 40 +#define BOOT_LOOP_TIME 10 // Number of seconds to stop detecting boot loops #define SYSLOG_TIMER 600 // Seconds to restore syslog_level #define SERIALLOG_TIMER 600 // Seconds to disable SerialLog #define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 8cd69e4cc..1bcf365b0 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1567,6 +1567,11 @@ void PerformEverySecond() { uptime++; + if (BOOT_LOOP_TIME == uptime) { + RtcSettings.fast_reboot_count = 0; + RtcSettingsSave(); + } + if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands SetDevicePower(1, SRC_RETRY); // Sync with default power on state microcontroller being Light ON and Fan OFF SetDevicePower(power, SRC_RETRY); // Set required power on state @@ -2313,7 +2318,7 @@ void GpioInit() pin[i] = 99; } for (byte i = 0; i < MAX_GPIO_PIN; i++) { - mpin = my_module.gp.io[i]; + mpin = ValidGPIO(i, my_module.gp.io[i]); // snprintf_P(log_data, sizeof(log_data), PSTR("DBG: gpio pin %d, mpin %d"), i, mpin); // AddLog(LOG_LEVEL_DEBUG); @@ -2323,7 +2328,7 @@ void GpioInit() bitSet(switch_no_pullup, mpin - GPIO_SWT1_NP); mpin -= (GPIO_SWT1_NP - GPIO_SWT1); } - if ((mpin >= GPIO_KEY1_NP) && (mpin < (GPIO_KEY1_NP + MAX_KEYS))) { + else if ((mpin >= GPIO_KEY1_NP) && (mpin < (GPIO_KEY1_NP + MAX_KEYS))) { bitSet(key_no_pullup, mpin - GPIO_KEY1_NP); mpin -= (GPIO_KEY1_NP - GPIO_KEY1); } @@ -2486,6 +2491,10 @@ void setup() { byte idx; + RtcSettingsLoad(); + RtcSettings.fast_reboot_count++; + RtcSettingsSave(); + Serial.begin(baudrate); delay(10); Serial.println(); @@ -2517,10 +2526,25 @@ void setup() save_data_counter = Settings.save_data; sleep = Settings.sleep; - if ((resetInfo.reason == REASON_WDT_RST) || (resetInfo.reason == REASON_EXCEPTION_RST) || (resetInfo.reason == REASON_SOFT_WDT_RST) || OsWatchBlockedLoop()) { - for (byte i = 0; i < MAX_RULE_SETS; i++) { - if (bitRead(Settings.rule_stop, i)) { bitWrite(Settings.rule_enabled, i, 0); } + // Disable functionality as possible cause of fast reboot within BOOT_LOOP_TIME seconds (Exception or WDT) + if (RtcSettings.fast_reboot_count > 1) { // Restart twice + Settings.flag3.user_esp8285_enable = 0; // Disable ESP8285 Generic GPIOs interfering with flash SPI + if (RtcSettings.fast_reboot_count > 2) { // Restart 3 times + for (byte i = 0; i < MAX_RULE_SETS; i++) { + if (bitRead(Settings.rule_stop, i)) { + bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop + } + } } + if (RtcSettings.fast_reboot_count > 3) { // Restarted 4 times + Settings.rule_enabled = 0; // Disable all rules + } + if (RtcSettings.fast_reboot_count > 4) { // Restarted 5 times + Settings.module = SONOFF_BASIC; // Use default module + Settings.last_module = SONOFF_BASIC; // Use default module + } + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcSettings.fast_reboot_count); + AddLog(LOG_LEVEL_DEBUG); } Settings.bootcount++; diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index f351b547d..72634caa1 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x0601010D +#define VERSION 0x0601010E #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support.ino b/sonoff/support.ino index 87cd49edb..8cc064fe5 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -717,6 +717,15 @@ void ShowSource(int source) } } +uint8_t ValidGPIO(uint8_t pin, uint8_t gpio) +{ + uint8_t result = gpio; + if ((WEMOS == Settings.module) && (!Settings.flag3.user_esp8285_enable)) { + if ((pin == 9) || (pin == 10)) { result = GPIO_NONE; } // Disable possible flash GPIO9 and GPIO10 + } + return result; +} + /*********************************************************************************************\ * Sleep aware time scheduler functions borrowed from ESPEasy \*********************************************************************************************/ diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index 64c138a56..c919c8f43 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -789,7 +789,7 @@ void HandleModuleConfiguration() page += FPSTR(HTTP_SCRIPT_MODULE3); for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if (GPIO_USER == cmodule.gp.io[i]) { + if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("sk(%d,%d);"), my_module.gp.io[i], i); // g0 - g16 page += mqtt_data; } @@ -803,10 +803,10 @@ void HandleModuleConfiguration() page.replace(F("{mt"), stemp); page += F("
"); for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if (GPIO_USER == cmodule.gp.io[i]) { + if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { snprintf_P(stemp, 3, PINS_WEMOS +i*2); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(""), - (WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i); + (WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(9==i)? "ESP8285" :(10==i)? "ESP8285" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i); page += mqtt_data; } } diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index 229b55d69..0652f3b53 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -457,7 +457,7 @@ boolean TimerCommand() } if (XdrvMailbox.payload == 2) { Settings.flag3.timers_enable = !Settings.flag3.timers_enable; - } + } } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag3.timers_enable));
%s " D_GPIO "%d %s