diff --git a/Makefile b/Makefile deleted file mode 100644 index e802c2c..0000000 --- a/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# This is a project Makefile. It is assumed the directory this Makefile resides in is a -# project subdirectory. -# - -PROJECT_NAME := odroid-go-multi-firmware -PROJECT_VER := $(shell date "+%Y%m%d")-$(shell git rev-parse --short HEAD) - -include $(IDF_PATH)/make/project.mk - diff --git a/README.md b/README.md index a9e6ec2..86dfba9 100644 --- a/README.md +++ b/README.md @@ -2,31 +2,43 @@ Odroid-go-multi-firmware is an improvement of the official Odroid GO firmware. It allows you to keep multiple applications installed in the flash and switch instantly between them. You can think of it as a multi-boot loader. +# Usage +Holding **B** while powering up the device will bring you to the boot menu. + + # Installation -Follow these instructions: https://wiki.odroid.com/odroid_go/firmware_update but use the .img provided here. +_Note: There is no risk in flashing your Odroid GO. You can always recover and return to the stock firmware by following ODROID's guide (method 2 below)._ + +### Method 1: Self-installer + +This is the easiest method, no need for drivers or flashing software. But it isn't as well tested. -*Note: To preserve your flashed applications when upgrading you can ignore the ERASE step.* +1. Copy the file `odroid-go-multi-firmware-XXX.fw` to your sdcard in the folder `/odroid/firmware` +2. Power up your device while holding B +3. Flash the self-installer and run it -To access the boot menu you then hold **B** while booting, as before. -_Note: There is no risk in flashing your Odroid GO and you can easily return to the stock firmware by following the instructions again using their official .img file._ +### Method 2: USB flashing + +Follow these instructions: https://wiki.odroid.com/odroid_go/firmware_update but use the .img provided here. + +_Note: If you are familiar with esptool, you just have to flash `odroid-go-multi-firmware-XXX.fw` to offset 0x0._ # Compilation -The official esp-idf version 3.1 or newer is required and you need to apply the following patches (found in tools/patches): +The official esp-idf version 3.1 or newer is required and to improve SD Card support you should this patch: -- esp-idf-partition-patch.diff -- esp-idf-sdcard-patch.diff +- tools/patches/esp-idf-sdcard-patch.diff _Note: Those patches do not introduce breaking changes to non-GO (standard ESP32) projects and can safely be applied to your global esp-idf installation._ - ## Build Steps: -1. Compile firmware: `make -j4` or `idf.py build` -2. And finally: - - To produce .img: `./mkimg.sh` - - To flash and debug: `make flash monitor` +1. Compile firmware: `idf.py build` +2. And then: + - To produce image files: `python tools/pack.py` + - To flash and debug: `idf.py flash monitor` + # Technical information diff --git a/main/component.mk b/main/component.mk deleted file mode 100644 index d6fcb43..0000000 --- a/main/component.mk +++ /dev/null @@ -1,11 +0,0 @@ -# -# Main component makefile. -# -# This Makefile can be left empty. By default, it will take the sources in the -# src/ directory, compile them and link them into lib(subdirectory_name).a -# in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# - -SRCDIRS = . ugui -CFLAGS += -DPROJECT_VER="\"$(PROJECT_VER)\"" diff --git a/main/input.c b/main/input.c index 4042364..f2d001f 100644 --- a/main/input.c +++ b/main/input.c @@ -108,7 +108,7 @@ static void input_task(void *arg) switch (debounce[i] & 0x03) { case 0x00: - gamepad_state &= (1 << i); + gamepad_state &= ~(1 << i); break; case 0x03: diff --git a/main/main.c b/main/main.c index 3bf1254..3f8f12f 100644 --- a/main/main.c +++ b/main/main.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -30,7 +29,6 @@ #include "ugui/ugui.h" -extern void esp_partition_reload_table(void); #define MFW_NVS_PARTITION "mfw_nvs" #define MFW_DATA_PARTITION "mfw_data" @@ -41,28 +39,28 @@ extern void esp_partition_reload_table(void); #define APP_MAGIC 0x1207 -#define APP_SORT_OFFSET 0b0000 -#define APP_SORT_SEQUENCE 0b0010 -#define APP_SORT_DESCRIPTION 0b0100 -#define APP_SORT_MAX 0b0101 -#define APP_SORT_DIR_ASC 0b0000 -#define APP_SORT_DIR_DESC 0b0001 +#define APP_SORT_OFFSET 0b0000 +#define APP_SORT_SEQUENCE 0b0010 +#define APP_SORT_DESCRIPTION 0b0100 +#define APP_SORT_MAX 0b0101 +#define APP_SORT_DIR_ASC 0b0000 +#define APP_SORT_DIR_DESC 0b0001 -#define FLASH_BLOCK_SIZE (64 * 1024) -#define ERASE_BLOCK_SIZE (4 * 1024) +#define FLASH_BLOCK_SIZE (64 * 1024) +#define ERASE_BLOCK_SIZE (4 * 1024) -#define APP_NVS_SIZE 0x3000 +#define APP_NVS_SIZE 0x3000 -#define FIRMWARE_HEADER_SIZE (24) -#define FIRMWARE_DESCRIPTION_SIZE (40) -#define FIRMWARE_PARTS_MAX (20) -#define FIRMWARE_TILE_WIDTH (86) -#define FIRMWARE_TILE_HEIGHT (48) +#define FIRMWARE_HEADER_SIZE (24) +#define FIRMWARE_DESCRIPTION_SIZE (40) +#define FIRMWARE_PARTS_MAX (20) +#define FIRMWARE_TILE_WIDTH (86) +#define FIRMWARE_TILE_HEIGHT (48) #define FIRMWARE_PATH SDCARD_BASE_PATH "/odroid/firmware" -#define BATTERY_VMAX 420 -#define BATTERY_VMIN 330 +#define BATTERY_VMAX (4.20f) +#define BATTERY_VMIN (3.30f) #define ITEM_COUNT (4) @@ -155,42 +153,24 @@ static esp_err_t sdcardret; static nvs_handle nvs_h; -static int batteryPercent = 0; - -static void battery_task(void *arg) +static float read_battery(void) { - // Some of that code is from Odroid GO Arduino library. Added rolling average for better results - esp_adc_cal_characteristics_t adc_cal; - adc1_config_width(ADC_WIDTH_BIT_12); - adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); - esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_cal); - - const int count = 128; - uint32_t samples[count]; - uint32_t loops = 0; + static esp_adc_cal_characteristics_t adc_cal; + static float batteryVoltage = -1; - while(1) + if (batteryVoltage < 0) { - samples[loops % count] = adc1_get_raw((adc1_channel_t) ADC1_CHANNEL_0); - - uint32_t total = 0; - for (int i = 0; i < count; i++) - { - total += samples[i]; - } - - double voltage = (double) esp_adc_cal_raw_to_voltage(total / count, &adc_cal) * 2 / 1000; - - batteryPercent = 101 - (101 / pow(1 + pow(1.33 * ((int)(voltage * 100) - BATTERY_VMIN) - / (BATTERY_VMAX - BATTERY_VMIN), 4.5), 3)); + adc1_config_width(ADC_WIDTH_BIT_12); + adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); + esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_cal); + batteryVoltage = esp_adc_cal_raw_to_voltage(adc1_get_raw(ADC1_CHANNEL_0), &adc_cal) * 2.f / 1000.f; + } - if (batteryPercent >= 100) - batteryPercent = 100; + batteryVoltage += esp_adc_cal_raw_to_voltage(adc1_get_raw(ADC1_CHANNEL_0), &adc_cal) * 2.f / 1000.f; + batteryVoltage /= 2; - if (++loops > count) - vTaskDelay(25); - } + return batteryVoltage; } @@ -360,30 +340,6 @@ static void cleanup_and_restart(void) } -static void boot_application(void) -{ - ESP_LOGI(__func__, "Booting application."); - - // Set firmware active - const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, - ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL); - if (partition == NULL) - { - DisplayError("NO BOOT PART ERROR"); - indicate_error(); - } - - esp_err_t err = esp_ota_set_boot_partition(partition); - if (err != ESP_OK) - { - DisplayError("BOOT SET ERROR"); - indicate_error(); - } - - cleanup_and_restart(); -} - - static int sort_app_table_by_offset(const void * a, const void * b) { if ( (*(odroid_app_t*)a).startOffset < (*(odroid_app_t*)b).startOffset ) return -1; @@ -511,15 +467,11 @@ static void write_app_table() } -static void write_partition_table(const odroid_partition_t *parts, size_t count, size_t flashOffset) +static void write_partition_table(const odroid_app_t *app) { esp_partition_info_t partitionTable[ESP_PARTITION_TABLE_MAX_ENTRIES]; size_t nextPart = 0; - assert(count < ESP_PARTITION_TABLE_MAX_ENTRIES); - assert(parts && flashOffset >= firstAppOffset); - - // Read table if (spi_flash_read(ESP_PARTITION_TABLE_OFFSET, &partitionTable, sizeof(partitionTable)) != ESP_OK) { DisplayError("PART TABLE READ ERROR"); @@ -537,46 +489,95 @@ static void write_partition_table(const odroid_partition_t *parts, size_t count, if (part->pos.offset >= firstAppOffset) continue; partitionTable[nextPart++] = *part; + ESP_LOGI(__func__, "Keeping partition #%d '%s'", nextPart - 1, part->label); } - ESP_LOGI(__func__, "nextPart=%d, flashOffset=%#08x", nextPart, flashOffset); - - // Append app's partitions - for (int i = 0; i < count; ++i) + // Append app's partitions, if any + if (app) { - esp_partition_info_t* part = &partitionTable[nextPart++]; - part->magic = ESP_PARTITION_MAGIC; - part->type = parts[i].type; - part->subtype = parts[i].subtype; - part->pos.offset = flashOffset; - part->pos.size = parts[i].length; - memcpy(&part->label, parts[i].label, 16); - part->flags = parts[i].flags; - - flashOffset += parts[i].length; + size_t flashOffset = app->startOffset; + + for (int i = 0; i < app->parts_count && i < ESP_PARTITION_TABLE_MAX_ENTRIES; ++i) + { + esp_partition_info_t* part = &partitionTable[nextPart++]; + part->magic = ESP_PARTITION_MAGIC; + part->type = app->parts[i].type; + part->subtype = app->parts[i].subtype; + part->pos.offset = flashOffset; + part->pos.size = app->parts[i].length; + memcpy(&part->label, app->parts[i].label, 16); + part->flags = app->parts[i].flags; + + flashOffset += app->parts[i].length; + + ESP_LOGI(__func__, "Added partition #%d '%s'", nextPart - 1, part->label); + } } - // Mark remaining entries as invalid + // We must fill the rest with 0xFF, the boot loader checks magic = 0xFFFF, type = 0xFF, subtype = 0xFF while (nextPart < ESP_PARTITION_TABLE_MAX_ENTRIES) { - partitionTable[nextPart++].magic = 0xFFFF; + memset(&partitionTable[nextPart++], 0xFF, sizeof(esp_partition_info_t)); } - // Erase partition table if (spi_flash_erase_range(ESP_PARTITION_TABLE_OFFSET, ERASE_BLOCK_SIZE) != ESP_OK) { DisplayError("PART TABLE ERASE ERROR"); indicate_error(); } - // Write new table if (spi_flash_write(ESP_PARTITION_TABLE_OFFSET, partitionTable, sizeof(partitionTable)) != ESP_OK) { DisplayError("PART TABLE WRITE ERROR"); indicate_error(); } - esp_partition_reload_table(); + // esp_partition_reload_table(); +} + + +static void boot_application(odroid_app_t *app) +{ + ESP_LOGI(__func__, "Booting application."); + + if (app) + { + DisplayMessage("Updating partitions ..."); + write_partition_table(app); + } + + DisplayMessage("Setting boot partition ..."); + +// This is the correct way of doing things, but we must patch esp-idf to allow us to reload the partition table +// So, now, instead we just write the OTA partition ourselves. It is always the same (boot app OTA+0). +#if 0 + const esp_partition_t *partition = esp_partition_find_first( + ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL); + + if (!partition) + { + DisplayError("NO BOOT PART ERROR"); + indicate_error(); + } + + esp_err_t err = esp_ota_set_boot_partition(partition); + if (err != ESP_OK) + { + DisplayError("BOOT SET ERROR"); + indicate_error(); + } +#else + uint32_t ota_data[8] = {1, 0, 0, 0, 0, 0, 0xFFFFFFFFU, 0x4743989A}; + + if (spi_flash_erase_range(0xD000, 0x1000) != ESP_OK + || spi_flash_write(0xD000, &ota_data, sizeof(ota_data)) != ESP_OK) + { + DisplayError("BOOT SET ERROR"); + indicate_error(); + } +#endif + + cleanup_and_restart(); } @@ -795,16 +796,6 @@ bool firmware_get_info(const char* filename, odroid_fw_t* outData) } -void flash_utility() -{ - // Code to flash utility.bin. - // Because leaving it in flash_firmware results in multiple copies being flashed. - //FILE* util = fopen("/sd/odroid/utility.bin", "rb"); - //util_part.type = ESP_PARTITION_TYPE_APP; - //util_part.subtype = ESP_PARTITION_SUBTYPE_APP_TEST; -} - - void flash_firmware(const char* fullPath) { ESP_LOGD(__func__, "HEAP=%#010x", esp_get_free_heap_size()); @@ -1027,11 +1018,7 @@ void flash_firmware(const char* fullPath) if (btn == ODROID_INPUT_B) return; } - // Write partition table - write_partition_table(app->parts, app->parts_count, app->startOffset); - - // boot firmware - boot_application(); + boot_application(app); } @@ -1067,7 +1054,9 @@ static void ui_draw_indicators(int page, int totalPages) UG_PutString(4, 4, tempstring); // Battery indicator - sprintf(tempstring, "%d%%", batteryPercent); + int percent = (read_battery() - BATTERY_VMIN) / (BATTERY_VMAX - BATTERY_VMIN) * 100.f; + percent = percent > 100 ? 100 : ((percent < 0) ? 0 : percent); + sprintf(tempstring, "%d%%", percent); UG_PutString(SCREEN_WIDTH - (9 * strlen(tempstring)) - 4, 4, tempstring); } @@ -1343,8 +1332,6 @@ static void start_normal(void) } nvs_get_i32(nvs_h, "display_order", &displayOrder); - xTaskCreate(&battery_task, "battery_task", 4096, NULL, 5, NULL); - fwInfoBuffer = safe_alloc(sizeof(odroid_fw_t)); dataBuffer = safe_alloc(FLASH_BLOCK_SIZE); @@ -1384,13 +1371,7 @@ static void start_normal(void) else if (btn == ODROID_INPUT_A) { ui_draw_title("ODROID-GO", PROJECT_VER); - DisplayMessage("Updating partitions ..."); - - odroid_app_t *app = &apps[currentItem]; - write_partition_table(app->parts, app->parts_count, app->startOffset); - - DisplayMessage("Setting boot partition ..."); - boot_application(); + boot_application(apps + currentItem); } else if (btn == ODROID_INPUT_SELECT) { @@ -1426,39 +1407,46 @@ static void start_normal(void) {5, "Restart System", true} }; - int choice = ui_choose_dialog(options, 6, true); - char* fileName; + odroid_app_t *app = &apps[currentItem]; + char *fileName; + size_t offset; - switch(choice) { + switch (ui_choose_dialog(options, 6, true)) + { case 0: // Install from SD Card - fileName = ui_choose_file(FIRMWARE_PATH); - if (fileName) { + if ((fileName = ui_choose_file(FIRMWARE_PATH))) { flash_firmware(fileName); free(fileName); } break; case 1: // Remove selected app - memmove(&apps[currentItem], &apps[currentItem + 1], - (apps_max - currentItem) * sizeof(odroid_app_t)); + memmove(app, app + 1, (apps_max - currentItem) * sizeof(odroid_app_t)); apps_count--; write_app_table(); break; case 2: // Erase selected app's NVS - write_partition_table(apps[currentItem].parts, - apps[currentItem].parts_count, apps[currentItem].startOffset); - if (nvs_flash_erase() == ESP_OK) { - DisplayNotification("Operation successful!"); - queuedBtn = input_wait_for_button_press(100); - } else { - DisplayNotification("An error has occurred!"); - queuedBtn = input_wait_for_button_press(200); + offset = app->startOffset; + for (int i = 0; i < app->parts_count; i++) + { + odroid_partition_t *part = &app->parts[i]; + if (part->type == 1 && part->subtype == ESP_PARTITION_SUBTYPE_DATA_NVS) + { + if (spi_flash_erase_range(offset, part->length) == ESP_OK) + DisplayNotification("Operation successful!"); + else + DisplayNotification("An error has occurred!"); + } + offset += part->length; } + queuedBtn = input_wait_for_button_press(200); break; case 3: // Erase all apps memset(apps, 0xFF, apps_max * sizeof(odroid_app_t)); apps_count = 0; + currentItem = 0; + app = &apps[0]; write_app_table(); - write_partition_table(NULL, 0, 0); + write_partition_table(NULL); break; case 4: // Format SD Card ui_draw_title("Format SD Card", PROJECT_VER); @@ -1494,7 +1482,7 @@ static void start_normal(void) DisplayNotification("Press B again to boot last app."); queuedBtn = input_wait_for_button_press(100); if (queuedBtn == ODROID_INPUT_B) { - boot_application(); + boot_application(NULL); } } } @@ -1503,18 +1491,33 @@ static void start_normal(void) static void start_install(void) { - const esp_partition_t *current = esp_ota_get_running_partition(); - size_t addr = current->address - 0x10000; - size_t size = 0x10000 + current->size; - void *data = safe_alloc(size); + ui_draw_title("Multi-firmware Installer", ""); + + for (int i = 5; i > 0; --i) + { + sprintf(tempstring, "Installing in %d seconds...", i); + DisplayMessage(tempstring); + vTaskDelay(pdMS_TO_TICKS(1000)); + } - // if (!user_confirm_flash_erase) + DisplayMessage("Installing..."); + + const esp_partition_t *payload = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "payload"); + + // We could fall back to copying the current partition and creating the partition table + // ourselves but we'd be missing the calibration data. Might handle this later... + if (!payload) { - // reboot to factory + DisplayError("CORRUPT INSTALLER ERROR"); + indicate_error(); } + size_t size = ALIGN_ADDRESS(payload->size, FLASH_BLOCK_SIZE); + void *data = safe_alloc(size); + // We must copy the data to RAM first because our data address space is full, can't mmap - if (spi_flash_read(addr, data, size) != ESP_OK) + if (spi_flash_read(payload->address, data, payload->size) != ESP_OK) { DisplayError("PART TABLE WRITE ERROR"); indicate_error(); diff --git a/mkimg.sh b/mkimg.sh deleted file mode 100644 index 84f0123..0000000 --- a/mkimg.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -RELEASE=`date +%Y%m%d`; -BINNAME=odroid-go-multi-firmware - -./tools/mkimg.py "odroid-go-multi-firmware-$RELEASE.img" \ - 0x1000 build/bootloader/bootloader.bin \ - 0x8000 build/partitions.bin \ - 0xf000 build/phy_init_data.bin \ - 0x10000 build/$BINNAME.bin #\ - #0xE0000 dummy.bin diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 383f9a9..58a8a7d 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -104,27 +104,8 @@ CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY= CONFIG_SPIRAM_OCCUPY_HSPI_HOST= CONFIG_SPIRAM_OCCUPY_VSPI_HOST=y -# -# PSRAM clock and cs IO for ESP32-DOWD -# -CONFIG_D0WD_PSRAM_CLK_IO=17 -CONFIG_D0WD_PSRAM_CS_IO=16 -# -# PSRAM clock and cs IO for ESP32-D2WD -# -CONFIG_D2WD_PSRAM_CLK_IO=9 -CONFIG_D2WD_PSRAM_CS_IO=10 - -# -# PSRAM clock and cs IO for ESP32-PICO -# -CONFIG_PICO_PSRAM_CS_IO=10 -CONFIG_MEMMAP_TRACEMEM= -CONFIG_MEMMAP_TRACEMEM_TWOBANKS= -CONFIG_ESP32_TRAX= -CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_MAIN_TASK_STACK_SIZE=12288 CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= diff --git a/tools/mkfw.py b/tools/mkfw.py index bfe45cc..b578dd9 100644 --- a/tools/mkfw.py +++ b/tools/mkfw.py @@ -20,6 +20,7 @@ def readfile(filepath): fw_size = 0 fw_part = 0 +fw_next_ota = 16 # First OTA partition pos = 4 while pos < len(sys.argv): @@ -30,8 +31,10 @@ def readfile(filepath): filename = sys.argv[pos + 4] pos += 5 - if not subtype: - subtype = 16 + fw_part # OTA starts at 16 + if partype == 0: + if not subtype: + subtype = fw_next_ota + fw_next_ota = subtype + 1 data = readfile(filename) real_size = max(size, math.ceil(len(data) / 0x10000) * 0x10000) diff --git a/tools/mkimg.py b/tools/mkimg.py deleted file mode 100644 index e8fd4d1..0000000 --- a/tools/mkimg.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -import sys, math, zlib, struct - -def readfile(filepath): - with open(filepath, "rb") as f: return f.read() - -if len(sys.argv) < 4: - exit("usage: mkimg.py image_filename offset binary [...]") - -imageName = sys.argv[1] -imageData = bytearray(b"\xFF" * (16 * 1024 * 1024)) -imageSize = 0 -pos = 2 - -while pos < len(sys.argv): - offset = int(sys.argv[pos+0], 0) - fileName = sys.argv[pos+1] - fileData = readfile(fileName) - fileSize = len(fileData) - pos += 2 - - for x in range(0, fileSize): - imageData[offset + x] = fileData[x] - - if (offset + fileSize) > imageSize: - imageSize = offset + fileSize - - print("offset=%d, fileName='%s', fileSize=%d" % (offset, fileName, fileSize)) - -fp = open(imageName, "wb") -fp.write(imageData[:imageSize]) -fp.close() - -print("%s successfully created.\n" % imageName) - diff --git a/tools/pack.py b/tools/pack.py new file mode 100644 index 0000000..c601b2f --- /dev/null +++ b/tools/pack.py @@ -0,0 +1,44 @@ +import subprocess +import datetime +import sys +import os + +PROJECT_NAME = "odroid-go-multi-firmware" +PROJECT_VER = datetime.datetime.now().strftime("%Y%m%d") +PROJECT_BIN = "build/%s.bin" % PROJECT_NAME +PROJECT_IMG = "%s-%s.img" % (PROJECT_NAME, PROJECT_VER) + +if not os.path.isfile(PROJECT_BIN): + exit("You should run `idf.py .build` first!") + +def readfile(filepath): + with open(filepath, "rb") as f: + return f.read() + + +print("Creating img file %s...\n" % PROJECT_IMG) + +# TO DO: Read the partitions.csv instead... +with open(PROJECT_IMG, "wb") as fp: + fp.write(b"\xFF" * 0x10000) + fp.seek(0x1000) + fp.write(readfile("build/bootloader/bootloader.bin")) + fp.seek(0x8000) + fp.write(readfile("build/partition_table/partition-table.bin")) + fp.seek(0xF000) + fp.write(readfile("build/phy_init_data.bin")) + fp.seek(0x10000) + fp.write(readfile(PROJECT_BIN)) + + +print("Creating the .fw file...") + +subprocess.run([ + sys.executable, + "tools/mkfw.py", + ("%s-%s.fw" % (PROJECT_NAME, PROJECT_VER)), "Multi-fw installer", PROJECT_BIN, # BIN as tile :) + "1", "231", "0", "payload", PROJECT_IMG, # Put payload first because we might overwrite that part during install + "0", "0", "0", "installer", PROJECT_BIN, # +], check=True) + +print("all done!") diff --git a/tools/patches/esp-idf-partition-patch.diff b/tools/patches/esp-idf-partition-patch.diff index d3c478e..161dd6e 100644 --- a/tools/patches/esp-idf-partition-patch.diff +++ b/tools/patches/esp-idf-partition-patch.diff @@ -1,16 +1,3 @@ -diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h -index f3d5a424a..980f165c6 100644 ---- a/components/spi_flash/include/esp_partition.h -+++ b/components/spi_flash/include/esp_partition.h -@@ -104,6 +104,8 @@ typedef struct { - bool encrypted; /*!< flag is set to true if partition is encrypted */ - } esp_partition_t; - -+void esp_partition_reload_table(); -+ - /** - * @brief Find partition based on one or more parameters - * diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index 400329199..1b6ab8be8 100644 --- a/components/spi_flash/partition.c diff --git a/tools/patches/esp-idf-sdcard-patch.diff b/tools/patches/esp-idf-sdcard-patch.diff index 75d7016..185f2b6 100644 --- a/tools/patches/esp-idf-sdcard-patch.diff +++ b/tools/patches/esp-idf-sdcard-patch.diff @@ -2,15 +2,6 @@ diff --git a/components/driver/sdspi_host.c b/components/driver/sdspi_host.c index e823ee7fa..79aef3130 100644 --- a/components/driver/sdspi_host.c +++ b/components/driver/sdspi_host.c -@@ -278,7 +278,7 @@ esp_err_t sdspi_host_init_slot(int slot, const sdspi_slot_config_t* slot_config) - // Initialize SPI bus - esp_err_t ret = spi_bus_initialize((spi_host_device_t)slot, &buscfg, - slot_config->dma_channel); -- if (ret != ESP_OK) { -+ if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { - ESP_LOGD(TAG, "spi_bus_initialize failed with rc=0x%x", ret); - return ret; - } @@ -623,6 +623,8 @@ static esp_err_t poll_cmd_response(int slot, sdspi_hw_cmd_t *cmd) static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd, uint8_t *data, uint32_t rx_length)