138 lines
5.1 KiB
Python
138 lines
5.1 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 build_littlefs(data_dir, output_file, size="1572864"):
|
|
"""Build LittleFS image from data directory"""
|
|
|
|
# Try to find mklittlefs tool
|
|
mklittlefs_paths = [
|
|
"mklittlefs.exe",
|
|
os.path.expanduser("~/.platformio/packages/tool-mklittlefs/mklittlefs.exe"),
|
|
"C:/Users/%USERNAME%/.platformio/packages/tool-mklittlefs/mklittlefs.exe"
|
|
]
|
|
|
|
mklittlefs = None
|
|
for path in mklittlefs_paths:
|
|
if os.path.exists(path):
|
|
mklittlefs = path
|
|
break
|
|
|
|
if not mklittlefs:
|
|
print("mklittlefs.exe not found. Install via: pip install platformio")
|
|
print("Or download from: https://github.com/earlephilhower/mklittlefs/releases")
|
|
return False
|
|
|
|
cmd = [mklittlefs, "-c", data_dir, "-s", size, "-p", "256", "-b", "4096", output_file]
|
|
|
|
print(f"Building LittleFS image...")
|
|
print(f"Command: {' '.join(cmd)}")
|
|
|
|
try:
|
|
subprocess.run(cmd, check=True)
|
|
print(f"LittleFS image created: {output_file}")
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to build LittleFS: {e}")
|
|
return False
|
|
|
|
def upload_littlefs(port, littlefs_path, address="6750208"):
|
|
"""Upload LittleFS partition using esptool (matches PlatformIO exactly)"""
|
|
|
|
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",
|
|
address, littlefs_path
|
|
]
|
|
|
|
print(f"Uploading LittleFS to {port} at address {address}...")
|
|
print(f"Command: {' '.join(cmd)}")
|
|
|
|
try:
|
|
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
|
print("LittleFS 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_littlefs(env="waveshare"):
|
|
"""Find PlatformIO-built LittleFS image"""
|
|
pio_littlefs = f".pio/build/{env}/littlefs.bin"
|
|
if os.path.exists(pio_littlefs):
|
|
return pio_littlefs
|
|
return None
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='Build and upload LittleFS partition')
|
|
parser.add_argument('--port', '-p', help='Serial port (auto-detect if not specified)')
|
|
parser.add_argument('--data-dir', '-d', default='data', help='Data directory (default: data)')
|
|
parser.add_argument('--address', '-a', default='6750208', help='Flash address (default: 6750208)')
|
|
parser.add_argument('--size', '-s', default='1572864', help='Partition size (default: 1572864)')
|
|
parser.add_argument('--image', '-i', help='Use existing LittleFS image file')
|
|
parser.add_argument('--env', '-e', default='waveshare', help='PlatformIO environment (default: waveshare)')
|
|
parser.add_argument('--build-only', action='store_true', help='Only build image, do not upload')
|
|
parser.add_argument('--auto', action='store_true', help='Auto-detect PlatformIO-built LittleFS image')
|
|
|
|
args = parser.parse_args()
|
|
|
|
port = args.port or find_serial_port()
|
|
|
|
# Auto-detect PlatformIO-built LittleFS or use specified image
|
|
if args.auto or (not args.image and not args.data_dir):
|
|
pio_littlefs = find_platformio_littlefs(args.env)
|
|
if pio_littlefs:
|
|
littlefs_image = pio_littlefs
|
|
print(f"✅ Using PlatformIO-built LittleFS: {littlefs_image}")
|
|
else:
|
|
print(f"❌ No PlatformIO LittleFS found for environment '{args.env}'")
|
|
print(f"Run: npm run web:uploadfs (or pio run -t uploadfs -e {args.env})")
|
|
sys.exit(1)
|
|
elif args.image:
|
|
littlefs_image = args.image
|
|
if not os.path.exists(littlefs_image):
|
|
print(f"❌ LittleFS image not found: {littlefs_image}")
|
|
sys.exit(1)
|
|
else:
|
|
# Build from data directory
|
|
littlefs_image = "littlefs.bin"
|
|
if not os.path.exists(args.data_dir):
|
|
print(f"❌ Data directory not found: {args.data_dir}")
|
|
sys.exit(1)
|
|
|
|
if not build_littlefs(args.data_dir, littlefs_image, args.size):
|
|
sys.exit(1)
|
|
|
|
if args.build_only:
|
|
print(f"LittleFS image built: {littlefs_image}")
|
|
sys.exit(0)
|
|
|
|
# Upload LittleFS
|
|
success = upload_littlefs(port, littlefs_image, args.address)
|
|
sys.exit(0 if success else 1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |