diff --git a/.gitignore b/.gitignore index 49359a587..f9c30939b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ .gcc-flags.json .vscode sonoff/user_config_override.h +.vscode/c_cpp_properties.json +.vscode/launch.json diff --git a/README.md b/README.md index 55db531b1..07372cdd6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.12.0b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **5.12.0c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/lib/readme.txt b/lib/readme.txt new file mode 100644 index 000000000..dbadc3d63 --- /dev/null +++ b/lib/readme.txt @@ -0,0 +1,36 @@ + +This directory is intended for the project specific (private) libraries. +PlatformIO will compile them to static libraries and link to executable file. + +The source code of each library should be placed in separate directory, like +"lib/private_lib/[here are source files]". + +For example, see how can be organized `Foo` and `Bar` libraries: + +|--lib +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| |--Foo +| | |- Foo.c +| | |- Foo.h +| |- readme.txt --> THIS FILE +|- platformio.ini +|--src + |- main.c + +Then in `src/main.c` you should use: + +#include +#include + +// rest H/C/CPP code + +PlatformIO will find your libraries automatically, configure preprocessor's +include paths and build them. + +More information about PlatformIO Library Dependency Finder +- http://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index c228c4e6d..c8a55101a 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,5 +1,7 @@ /* 5.12.0c * Fix intermittent exception when dns lookup is used while sleep is enabled + * Fix 5.4.0 regression turning off single press after button hold during 4x hold time + * Fix possible wifi connection problem by erasing sdk configuration parameters * * 5.12.0b * Add serial debug info diff --git a/sonoff/settings.ino b/sonoff/settings.ino index f77955ebd..c702d16c2 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -185,14 +185,11 @@ void SetFlashModeDout() eboot_command_read(&ebcmd); address = ebcmd.args[0]; _buffer = new uint8_t[FLASH_SECTOR_SIZE]; - if (SPI_FLASH_RESULT_OK == spi_flash_read(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE)) { + + if (ESP.flashRead(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE)) { if (_buffer[2] != 3) { // DOUT _buffer[2] = 3; - noInterrupts(); - if (SPI_FLASH_RESULT_OK == spi_flash_erase_sector(address / FLASH_SECTOR_SIZE)) { - spi_flash_write(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE); - } - interrupts(); + if (ESP.flashEraseSector(address / FLASH_SECTOR_SIZE)) ESP.flashWrite(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE); } } delete[] _buffer; @@ -256,15 +253,11 @@ void SettingsSave(byte rotate) } } Settings.save_flag++; - noInterrupts(); - spi_flash_erase_sector(settings_location); - spi_flash_write(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - interrupts(); + ESP.flashEraseSector(settings_location); + ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); if (!stop_flash_rotate && rotate) { for (byte i = 1; i < CFG_ROTATES; i++) { - noInterrupts(); - spi_flash_erase_sector(settings_location -i); // Delete previous configurations by resetting to 0xFF - interrupts(); + ESP.flashEraseSector(settings_location -i); // Delete previous configurations by resetting to 0xFF delay(1); } } @@ -289,10 +282,8 @@ void SettingsLoad() settings_location = SETTINGS_LOCATION +1; for (byte i = 0; i < CFG_ROTATES; i++) { settings_location--; - noInterrupts(); - spi_flash_read(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - spi_flash_read((settings_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); - interrupts(); + ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + ESP.flashRead((settings_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); // snprintf_P(log_data, sizeof(log_data), PSTR("Cnfg: Check at %X with count %d and holder %X"), settings_location -1, _SettingsH.save_flag, _SettingsH.cfg_holder); // AddLog(LOG_LEVEL_DEBUG); @@ -307,15 +298,10 @@ void SettingsLoad() AddLog(LOG_LEVEL_DEBUG); if (Settings.cfg_holder != CFG_HOLDER) { // Auto upgrade - noInterrupts(); - spi_flash_read((SETTINGS_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - spi_flash_read((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); - if (Settings.save_flag < _SettingsH.save_flag) - spi_flash_read((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - interrupts(); - if ((Settings.cfg_holder != CFG_HOLDER) || (Settings.version >= 0x04020000)) { - SettingsDefault(); - } + ESP.flashRead((SETTINGS_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + ESP.flashRead((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); + if (Settings.save_flag < _SettingsH.save_flag) ESP.flashRead((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + if ((Settings.cfg_holder != CFG_HOLDER) || (Settings.version >= 0x04020000)) SettingsDefault(); } settings_hash = GetSettingsHash(); @@ -323,25 +309,33 @@ void SettingsLoad() RtcSettingsLoad(); } -void SettingsErase() +void SettingsErase(uint8_t type) { - SpiFlashOpResult result; + /* + 0 = Erase from program end until end of physical flash + 1 = Erase SDK parameter area at end of linker memory model (0x0FDxxx - 0x0FFFFF) solving possible wifi errors + */ + + bool result; uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1; uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE; + if (1 == type) { + _sectorStart = SETTINGS_LOCATION +2; // SDK parameter area above EEPROM area (0x0FDxxx - 0x0FFFFF) + _sectorEnd = SETTINGS_LOCATION +5; + } + boolean _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart); AddLog(LOG_LEVEL_DEBUG); for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) { - noInterrupts(); - result = spi_flash_erase_sector(_sector); - interrupts(); + result = ESP.flashEraseSector(_sector); if (_serialoutput) { Serial.print(F(D_LOG_APPLICATION D_ERASED_SECTOR " ")); Serial.print(_sector); - if (SPI_FLASH_RESULT_OK == result) { + if (result) { Serial.println(F(" " D_OK)); } else { Serial.println(F(" " D_ERROR)); @@ -352,6 +346,27 @@ void SettingsErase() } } +// Copied from 2.4.0 as 2.3.0 is incomplete +bool SettingsEraseConfig(void) { + const size_t cfgSize = 0x4000; + size_t cfgAddr = ESP.getFlashChipSize() - cfgSize; + + for (size_t offset = 0; offset < cfgSize; offset += SPI_FLASH_SEC_SIZE) { + if (!ESP.flashEraseSector((cfgAddr + offset) / SPI_FLASH_SEC_SIZE)) { + return false; + } + } + return true; +} + +void SettingsSdkErase() +{ + WiFi.disconnect(true); // Delete SDK wifi config + SettingsErase(1); + SettingsEraseConfig(); + delay(1000); +} + void SettingsDump(char* parms) { #define CFG_COLS 16 diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index f0ba58af8..5a669cff0 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -170,7 +170,7 @@ uint8_t blinkstate = 0; // LED state uint8_t blockgpio0 = 4; // Block GPIO0 for 4 seconds after poweron to workaround Wemos D1 RTS circuit uint8_t lastbutton[MAX_KEYS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states -uint8_t holdbutton[MAX_KEYS] = { 0 }; // Timer for button hold +uint16_t holdbutton[MAX_KEYS] = { 0 }; // Timer for button hold uint8_t multiwindow[MAX_KEYS] = { 0 }; // Max time between button presses to record press count uint8_t multipress[MAX_KEYS] = { 0 }; // Number of button presses within multiwindow uint8_t lastwallswitch[MAX_SWITCHES]; // Last wall switch states @@ -1475,7 +1475,8 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len) snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command , D_JSON_RESET_AND_RESTARTING); break; case 2: - restart_flag = 212; + case 3: + restart_flag = 210 + payload; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESET "\":\"" D_JSON_ERASE ", " D_JSON_RESET_AND_RESTARTING "\"}")); break; default: @@ -2370,9 +2371,12 @@ void StateLoop() } } if (restart_flag && (backlog_pointer == backlog_index)) { - if (212 == restart_flag) { - SettingsErase(); - restart_flag--; + if (213 == restart_flag) { + SettingsSdkErase(); // Erase flash SDK parameters + restart_flag = 2; + } else if (212 == restart_flag) { + SettingsErase(0); // Erase all flash from program end to end of physical flash + restart_flag = 211; } if (211 == restart_flag) { SettingsDefault(); diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 77fc08997..63d5e3c63 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -160,7 +160,7 @@ void WifiWpsStatusCallback(wps_cb_status status); //#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) #ifndef ARDUINO_ESP8266_RELEASE -#define ARDUINO_ESP8266_RELEASE "STAGED" +#define ARDUINO_ESP8266_RELEASE "STAGE" #endif #endif // _SONOFF_POST_H_ \ No newline at end of file diff --git a/sonoff/support.ino b/sonoff/support.ino index f8c706a31..bca8532be 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -558,10 +558,11 @@ void WifiBegin(uint8_t flag) #ifdef ARDUINO_ESP8266_RELEASE_2_3_0 // (!strncmp_P(ESP.getSdkVersion(),PSTR("1.5.3"),5)) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, PSTR(D_PATCH_ISSUE_2186)); - WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186 + WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186 #endif - WiFi.disconnect(); + WiFi.disconnect(true); // Delete SDK wifi config + delay(200); WiFi.mode(WIFI_STA); // Disable AP mode if (Settings.sleep) { WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times @@ -697,6 +698,7 @@ void WifiCheck(uint8_t param) if (WIFI_SMARTCONFIG == wifi_config_type) { WiFi.stopSmartConfig(); } + SettingsSdkErase(); restart_flag = 2; } } else {