#!/usr/bin/env python3 import subprocess import time from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pathlib import Path from threading import Thread def get_args(): parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument("firmware", help="File for writing to esp32 flash") parser.add_argument("-g", "--glob", action="store", default="ttyUSB*", help="Pattern to match port names") return parser.parse_args() def flash(port, firmware): """ Write firmware at offset 0x1000 """ cmd = [ "esptool.py", "-p", port, "-b", "921600", "write_flash", "-z", "0x1000", firmware, ] print("Flashing", port) try: subprocess.run( cmd, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL, check=True ) except subprocess.CalledProcessError: print("Failed to flash device", port) else: print("Done with", port) def get_tty(): return set(Path("/dev").glob(GLOB)) def observer(input_file): last_devs = get_tty() while True: current_devs = get_tty() diff = current_devs - last_devs last_devs = current_devs if diff: for port in diff: Thread(target=flash, args=(port, input_file)).start() time.sleep(1) if __name__ == "__main__": args = get_args() GLOB = args.glob try: observer(args.firmware) except KeyboardInterrupt: print("\rExit") """ esptool.py esp32 \ -p /dev/ttyUSB0 \ -b 460800 \ --before=default_reset \ --after=hard_reset write_flash \ --flash_mode dio \ --flash_freq 40m \ --flash_size 4MB \ 0x1000 bootloader/bootloader.bin \ 0x10000 micropython.bin \ 0x8000 partition_table/partition-table.bin """