146 lines
5.5 KiB
Python
146 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
import argparse
|
|
|
|
def find_serial_port():
|
|
"""Auto-detect ESP32 serial port"""
|
|
try:
|
|
import serial.tools.list_ports
|
|
ports = serial.tools.list_ports.comports()
|
|
for port in ports:
|
|
if 'USB' in port.description or 'Serial' in port.description:
|
|
return port.device
|
|
except ImportError:
|
|
pass
|
|
return "COM17" # fallback
|
|
|
|
def upload_firmware(port, firmware_path, bootloader_path=None, partitions_path=None, boot_app0_path=None):
|
|
"""Upload firmware using esptool"""
|
|
|
|
# ESP32-S3 flash addresses (from PlatformIO)
|
|
bootloader_addr = "0x0000"
|
|
partitions_addr = "0x8000"
|
|
boot_app0_addr = "0xe000"
|
|
firmware_addr = "0x10000"
|
|
|
|
cmd = [
|
|
"python", "-m", "esptool",
|
|
"--chip", "esp32s3",
|
|
"--port", port,
|
|
"--baud", "115200",
|
|
"--before", "default_reset",
|
|
"--after", "hard_reset",
|
|
"write_flash", "-z",
|
|
"--flash_mode", "dio",
|
|
"--flash_freq", "80m",
|
|
"--flash_size", "8MB"
|
|
]
|
|
|
|
# Add bootloader if provided
|
|
if bootloader_path and os.path.exists(bootloader_path):
|
|
cmd.extend([bootloader_addr, bootloader_path])
|
|
|
|
# Add partitions if provided
|
|
if partitions_path and os.path.exists(partitions_path):
|
|
cmd.extend([partitions_addr, partitions_path])
|
|
|
|
# Add boot_app0 if provided
|
|
if boot_app0_path and os.path.exists(boot_app0_path):
|
|
cmd.extend([boot_app0_addr, boot_app0_path])
|
|
|
|
# Add firmware
|
|
cmd.extend([firmware_addr, firmware_path])
|
|
|
|
print(f"Uploading firmware to {port}...")
|
|
print(f"Command: {' '.join(cmd)}")
|
|
|
|
try:
|
|
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
|
print("Upload successful!")
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Upload failed: {e}")
|
|
print(f"Error output: {e.stderr}")
|
|
return False
|
|
|
|
def find_platformio_files(build_dir=".pio/build/waveshare"):
|
|
"""Find PlatformIO build files automatically"""
|
|
files = {}
|
|
|
|
# Firmware
|
|
firmware_path = os.path.join(build_dir, "firmware.bin")
|
|
if os.path.exists(firmware_path):
|
|
files['firmware'] = firmware_path
|
|
|
|
# Bootloader
|
|
bootloader_path = os.path.join(build_dir, "bootloader.bin")
|
|
if os.path.exists(bootloader_path):
|
|
files['bootloader'] = bootloader_path
|
|
|
|
# Partitions
|
|
partitions_path = os.path.join(build_dir, "partitions.bin")
|
|
if os.path.exists(partitions_path):
|
|
files['partitions'] = partitions_path
|
|
|
|
# boot_app0 (framework file)
|
|
boot_app0_paths = [
|
|
os.path.expanduser("~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin"),
|
|
"C:/Users/%USERNAME%/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin"
|
|
]
|
|
|
|
for path in boot_app0_paths:
|
|
if os.path.exists(path):
|
|
files['boot_app0'] = path
|
|
break
|
|
|
|
return files
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='Upload firmware via esptool')
|
|
parser.add_argument('--port', '-p', help='Serial port (auto-detect if not specified)')
|
|
parser.add_argument('--firmware', '-f', help='Firmware binary path (auto-detect from PlatformIO if not specified)')
|
|
parser.add_argument('--bootloader', '-b', help='Bootloader binary path (auto-detect from PlatformIO if not specified)')
|
|
parser.add_argument('--partitions', '-pt', help='Partitions binary path (auto-detect from PlatformIO if not specified)')
|
|
parser.add_argument('--boot-app0', '-ba', help='boot_app0 binary path (auto-detect from PlatformIO if not specified)')
|
|
parser.add_argument('--auto', '-a', action='store_true', help='Auto-detect all files from PlatformIO build')
|
|
parser.add_argument('--env', '-e', default='waveshare', help='PlatformIO environment (default: waveshare)')
|
|
|
|
args = parser.parse_args()
|
|
|
|
port = args.port or find_serial_port()
|
|
|
|
# Auto-detect files if requested or if firmware not specified
|
|
if args.auto or not args.firmware:
|
|
build_dir = f".pio/build/{args.env}"
|
|
print(f"Auto-detecting PlatformIO build files from {build_dir}...")
|
|
pio_files = find_platformio_files(build_dir)
|
|
|
|
firmware_path = args.firmware or pio_files.get('firmware')
|
|
bootloader_path = args.bootloader or pio_files.get('bootloader')
|
|
partitions_path = args.partitions or pio_files.get('partitions')
|
|
boot_app0_path = args.boot_app0 or pio_files.get('boot_app0')
|
|
|
|
print(f"Found files:")
|
|
print(f" Firmware: {firmware_path}")
|
|
print(f" Bootloader: {bootloader_path}")
|
|
print(f" Partitions: {partitions_path}")
|
|
print(f" boot_app0: {boot_app0_path}")
|
|
print()
|
|
else:
|
|
firmware_path = args.firmware
|
|
bootloader_path = args.bootloader
|
|
partitions_path = args.partitions
|
|
boot_app0_path = args.boot_app0
|
|
|
|
if not firmware_path or not os.path.exists(firmware_path):
|
|
print(f"Firmware file not found: {firmware_path}")
|
|
print("Run: npm run build")
|
|
sys.exit(1)
|
|
|
|
success = upload_firmware(port, firmware_path, bootloader_path, partitions_path, boot_app0_path)
|
|
sys.exit(0 if success else 1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |