diff --git a/wled00/wled.cpp b/wled00/wled.cpp index a2a252265c..1244306c45 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -2,6 +2,7 @@ #include "wled.h" #include "wled_ethernet.h" #include +#include "esp_ota_ops.h" #warning WLED-MM GPL-v3. By installing WLED MM you implicitly accept the terms! @@ -501,6 +502,8 @@ void WLED::setup() #ifdef WLED_RELEASE_NAME USER_PRINTF(" WLEDMM_%s %s, build %s.\n", versionString, releaseString, TOSTRING(VERSION)); // WLEDMM specific #endif + const esp_partition_t *boot_partition = esp_ota_get_running_partition(); + USER_PRINTF("Booted from: %s which is %u bytes and type %u subtype %u at address %x\n",boot_partition->label,boot_partition->size,boot_partition->type,boot_partition->subtype,boot_partition->address); #ifdef ARDUINO_ARCH_ESP32 DEBUG_PRINT(F("esp32 ")); diff --git a/wled00/wled_serial.cpp b/wled00/wled_serial.cpp index 76d7fd078e..51c3ff7d50 100644 --- a/wled00/wled_serial.cpp +++ b/wled00/wled_serial.cpp @@ -1,4 +1,5 @@ #include "wled.h" +#include "esp_ota_ops.h" /* * Adalight and TPM2 handler @@ -118,9 +119,32 @@ void handleSerial() return; } else if (next == 'v') { Serial.print("WLED"); Serial.write(' '); Serial.println(VERSION); - } else if (next == 'X') { forceReconnect = true; // WLEDMM - force reconnect via Serial + } else if (next == '^') { + esp_err_t err; + const esp_partition_t *boot_partition = esp_ota_get_boot_partition(); + const esp_partition_t *running_partition = esp_ota_get_running_partition(); + USER_PRINTF("Running on %s and we should have booted from %s. This %s\n",running_partition->label,boot_partition->label,(String(running_partition->label) == String(boot_partition->label))?"is what we expect.":"means OTA messed up!"); + if (String(running_partition->label) == String(boot_partition->label)) { + esp_partition_iterator_t new_boot_partition_iterator = NULL; + if (boot_partition->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0) { + new_boot_partition_iterator = esp_partition_find(ESP_PARTITION_TYPE_APP,ESP_PARTITION_SUBTYPE_APP_OTA_1,"app1"); + } else { + new_boot_partition_iterator = esp_partition_find(ESP_PARTITION_TYPE_APP,ESP_PARTITION_SUBTYPE_APP_OTA_0,"app0"); + } + const esp_partition_t* new_boot_partition = esp_partition_get(new_boot_partition_iterator); + err = esp_ota_set_boot_partition(new_boot_partition); + if (err == ESP_OK) { + USER_PRINTF("Switching boot partitions from %s to %s in 3 seconds!\n",boot_partition->label,new_boot_partition->label); + delay(3000); + esp_restart(); + } else { + USER_PRINTF("Looks like the other app partition (%s) is invalid. Ignoring.\n",new_boot_partition->label); + } + } else { + USER_PRINTF("Looks like the other partion is invalid as we exepected %s but we booted failsafe to %s. Ignoring boot change.\n",boot_partition->label,running_partition->label); + } } else if (next == 'l') { TROYHACKS_LPF = !TROYHACKS_LPF; USER_PRINTF("LP (highs) filter is now %s\n",TROYHACKS_LPF?"On":"Off");