83 lines
3.0 KiB
Python
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()
|