diff --git a/C5_Py_Flasher/bins/bootloader.bin b/C5_Py_Flasher/bins/bootloader.bin new file mode 100644 index 0000000..a677b57 Binary files /dev/null and b/C5_Py_Flasher/bins/bootloader.bin differ diff --git a/C5_Py_Flasher/bins/esp32_marauder_v1_8_1_20250722_esp32c5_devkit.bin b/C5_Py_Flasher/bins/esp32_marauder_v1_8_1_20250722_esp32c5_devkit.bin new file mode 100644 index 0000000..371ded7 Binary files /dev/null and b/C5_Py_Flasher/bins/esp32_marauder_v1_8_1_20250722_esp32c5_devkit.bin differ diff --git a/C5_Py_Flasher/bins/partitions.bin b/C5_Py_Flasher/bins/partitions.bin new file mode 100644 index 0000000..21800fa Binary files /dev/null and b/C5_Py_Flasher/bins/partitions.bin differ diff --git a/C5_Py_Flasher/c5_flasher.py b/C5_Py_Flasher/c5_flasher.py new file mode 100644 index 0000000..64225ff --- /dev/null +++ b/C5_Py_Flasher/c5_flasher.py @@ -0,0 +1,164 @@ +# === ESP32-C5 Auto Flasher Script By: AWOK === + +import sys +import subprocess +import os +import platform # Placeholder for possible OS checks +import glob +import time +import shutil +import argparse + +def ensure_package(pkg): + try: + __import__(pkg if pkg != 'gitpython' else 'git') + except ImportError: + print(f"Installing missing package: {pkg}") + subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--upgrade', pkg]) + +try: + import serial.tools.list_ports +except ImportError: + ensure_package('pyserial') +try: + import esptool +except ImportError: + ensure_package('esptool') +try: + from colorama import Fore, Style +except ImportError: + ensure_package('colorama') + +# Dependency check and install if needed +REQUIRED_PACKAGES = [ + 'pyserial', + 'esptool', + 'colorama' +] + +def ensure_requirements(): + for pkg in REQUIRED_PACKAGES: + ensure_package(pkg) +ensure_requirements() + +# Finds the first file from a list of possible names in the bins folder +def find_file(name_options, bins_dir): + for name in name_options: + files = glob.glob(os.path.join(bins_dir, name)) + if files: + return files[0] + return None + +def main(): + parser = argparse.ArgumentParser(description="ESP32-C5 Auto Flasher (bins subdir)") + parser.parse_args() + + bins_dir = os.path.join(os.path.dirname(__file__), 'bins') + if not os.path.isdir(bins_dir): + print(Fore.RED + f"Bins directory not found: {bins_dir}\nPlease create a 'bins' folder with your .bin files." + Style.RESET_ALL) + exit(1) + + # Logo and splash, both centered and purple + terminal_width = shutil.get_terminal_size((100, 20)).columns + def center(text): return text.center(terminal_width) + logo_lines = [ + " @@@@@@ ", + " @@@@@@@@ @@@@@ @@@@ ", + " @@@ @@@@@@@ @@@ @@@@@@@@ ", + " @@@@@@@@@@@@@ @@@@@ @@@ @@@@ @@@ ", + " @@@ @@@@@ @@@ @@@@@@ @@@ ", + " @@@ @@@ @@ @@@@ @@@ ", + " @@@@@@@@@@@@ @@ @ @@@ @@@ @@ ", + " @@@ @@@@@ @@ @@@ @@ @@@@@@@@@@@@@@ ", + " @@@ @@@ @@ @@@ @@@@@ @@@@", + " @@@ @@ @@@@ @@@ @@@", + " @@@@@ @@ @@@@ @@@", + " @@@@@@ @@ @@ @ @@@ @@@@ ", + " @@@ @@ @@ @ @@@@@@ ", + " @@@ @@ @@@ @@ @@@@@@@@@@@@@@@ ", + "@@@ @@@@ @ @@@@ @@@@@ @@@ @ @@@@ @@@ @@@ ", + "@@@ @@@@@@@ @@@ @@@@@@@@@@@@@@@@@@@ @@ @@@ @@@ ", + "@@@ @@@@@ @@@ @@@@@ @@@@ @@@@ @@@@@@@@@@ @@@@ @@@ ", + "@@@@ @@@@@@@@@@@@@@@@ @@@ @@@ @@ @@@@@@@@@@@@ @@@ ", + " @@@@ @@@@@@@@@@@@@@@@ @@@ @@ @@@@@@@@@@@@ @@@ ", + " @@@@@@ @@@@@ @@@ @@ @ @@ @@ @@@@ @@@@ ", + " @@@@@@@@@@@@@ @@@ @@ @@ @@ @@@@@@@@@@@ ", + " @@@@@@@@@@@@ @@@ @@ @@@ @ @@@@@@@@ ", + " @@ @@ @@@ @@ @@@ ", + " @ @@ @@ @@@ ", + " @@@ @@@ ", + " @@@ ", + "" + ] + splash_lines = [ + "-- ESP32 C5 Flasher --", + "By AWOK", + "Inspired from LordSkeletonMans ESP32 FZEasyFlasher", + "Shout out to JCMK for the inspiration on setting up the C5", + "" + ] + print(Fore.MAGENTA + "\n" + "\n".join(center(line) for line in logo_lines + splash_lines) + Style.RESET_ALL) + + # Wait for ESP32 device to show up as a new serial port + existing_ports = set([port.device for port in serial.tools.list_ports.comports()]) + print(Fore.YELLOW + "Waiting for ESP32-C5 device to be connected..." + Style.RESET_ALL) + while True: + current_ports = set([port.device for port in serial.tools.list_ports.comports()]) + new_ports = current_ports - existing_ports + if new_ports: + serial_port = new_ports.pop() + break + time.sleep(0.5) + print(Fore.GREEN + f"Detected ESP32-C5 on port: {serial_port}" + Style.RESET_ALL) + + # Find bin files for each firmware component + bootloader = find_file(['bootloader.bin'], bins_dir) + partitions = find_file(['partition-table.bin', 'partitions.bin'], bins_dir) + ota_data = find_file(['ota_data_initial.bin'], bins_dir) + + # Main firmware: largest bin in the folder that's not bootloader, partition, or OTA + all_bins = glob.glob(os.path.join(bins_dir, "*.bin")) + exclude = {bootloader, partitions, ota_data} + firmware_bins = [f for f in all_bins if f not in exclude and os.path.isfile(f)] + if not firmware_bins: + print(Fore.RED + "No application firmware .bin file found in the 'bins' folder!" + Style.RESET_ALL) + exit(1) + app_bin = max(firmware_bins, key=lambda f: os.path.getsize(f)) + + # Print summary, ask for confirmation before flashing + print(Fore.CYAN + f"\nBootloader: {bootloader or 'NOT FOUND'}") + print(f"Partitions: {partitions or 'NOT FOUND'}") + print(f"OTA Data: {ota_data or 'NOT FOUND'}") + print(f"App (main): {app_bin}\n" + Style.RESET_ALL) + if not (bootloader and partitions): + print(Fore.RED + "Missing bootloader or partition table. Both are required for a complete flash!" + Style.RESET_ALL) + exit(1) + confirm = input(Fore.YELLOW + "Ready to flash these files to ESP32-C5? (y/N): " + Style.RESET_ALL) + if confirm.strip().lower() != 'y': + print("Aborting.") + exit(0) + + # Flash using esptool, with offsets for C5 + esptool_args = [ + '--chip', 'esp32c5', + '--port', serial_port, + '--baud', '921600', + '--before', 'default_reset', + '--after', 'hard_reset', + 'write_flash', '-z', + '0x2000', bootloader, + '0x8000', partitions, + ] + if ota_data: + esptool_args += ['0xd000', ota_data] + esptool_args += ['0x10000', app_bin] + + print(Fore.YELLOW + "Flashing ESP32-C5 with bootloader, partition table, and application..." + Style.RESET_ALL) + try: + esptool.main(esptool_args) + print(Fore.GREEN + "Flashing complete!" + Style.RESET_ALL) + except Exception as e: + print(Fore.RED + f"Flashing failed: {e}" + Style.RESET_ALL) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/esp32_marauder/configs.h b/esp32_marauder/configs.h index 7f2af3c..c5a4ca8 100644 --- a/esp32_marauder/configs.h +++ b/esp32_marauder/configs.h @@ -30,7 +30,7 @@ //#define MARAUDER_CARDPUTER //// END BOARD TARGETS - #define MARAUDER_VERSION "v1.8.0" + #define MARAUDER_VERSION "v1.8.1" #define GRAPH_REFRESH 100