2026-02-06 09:52:23 +08:00

83 lines
3.0 KiB
Python

#!/usr/bin/env python3
# Simple GPIO control for AmebaPro3 boot/reset via ASCII commands over CDC-ACM.
import argparse
import time
import serial
from serial import SerialException
from serial.tools import list_ports
def boot_seq(port: str, baud: int):
with serial.Serial(port=port, baudrate=baud, timeout=0.2) as ser:
ser.write(b"BOOT 1\n")
ser.flush()
time.sleep(0.05)
ser.write(b"RESET 0\n")
ser.flush()
time.sleep(0.02)
ser.write(b"BOOT 0\n")
ser.write(b"RESET 0\n") # keep reset asserted; caller can release later
ser.flush()
def reset_seq(port: str, baud: int):
with serial.Serial(port=port, baudrate=baud, timeout=0.2) as ser:
ser.write(b"BOOT 0\n")
ser.write(b"RESET 1\n")
ser.flush()
time.sleep(0.05)
ser.write(b"RESET 0\n")
ser.flush()
time.sleep(0.02)
ser.write(b"RESET 1\n")
ser.flush()
def main():
p = argparse.ArgumentParser(description="Send BOOT/RESET GPIO commands to AmebaPro3 over CDC-ACM")
p.add_argument('-p', '--port', required=True, help='Serial device, e.g., /dev/ttyACM0')
p.add_argument('-B', '--baudrate', type=int, default=115200, help='Baudrate (only for opening port)')
p.add_argument('--boot-seq', action='store_true', help='Drive boot entry sequence via BOOT/RESET commands')
p.add_argument('--reset-seq', action='store_true', help='Drive reset sequence via BOOT/RESET commands')
p.add_argument('--boot', choices=['0', '1'], help='Assert/deassert BOOT line (0=deassert,1=assert)')
p.add_argument('--reset', choices=['0', '1'], help='Assert/deassert RESET line (0=deassert,1=assert)')
p.add_argument('--list', action='store_true', help='List available serial ports and exit')
args = p.parse_args()
if args.list:
for port in list_ports.comports():
print(f"{port.device}: {port.description}")
return
if args.boot_seq:
try:
boot_seq(args.port, args.baudrate)
except SerialException as e:
p.error(f"Open {args.port} failed: {e}. Is another program using the port?")
return
if args.reset_seq:
try:
reset_seq(args.port, args.baudrate)
except SerialException as e:
p.error(f"Open {args.port} failed: {e}. Is another program using the port?")
return
if args.boot is not None or args.reset is not None:
try:
with serial.Serial(port=args.port, baudrate=args.baudrate, timeout=0.2, rtscts=False, dsrdtr=False) as ser:
if args.boot is not None:
ser.write(f"BOOT {args.boot}\n".encode())
if args.reset is not None:
ser.write(f"RESET {args.reset}\n".encode())
ser.flush()
except SerialException as e:
p.error(f"Open {args.port} failed: {e}. Is another program using the port?")
return
p.error("No action specified (use --boot-seq, --reset-seq, or --boot/--reset)")
if __name__ == '__main__':
main()