From 0f593a17078f680a8f7659b0725efef31ecc95b5 Mon Sep 17 00:00:00 2001 From: Triss Date: Sat, 24 May 2025 01:02:27 +0200 Subject: [PATCH] add python script to change device type in FTDI config EEPROM --- change_device_type.py | 62 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 change_device_type.py diff --git a/change_device_type.py b/change_device_type.py new file mode 100644 index 0000000..8e2c294 --- /dev/null +++ b/change_device_type.py @@ -0,0 +1,62 @@ + +import base64, pyftdi, sys, usb +from pyftdi.eeprom import FtdiEeprom +from pyftdi.misc import hexdump + + +DEFAULT_CONFIG = base64.b64decode(b"AAADBNB/ABCAyAgAAACgErIe0BwAAAAAAAAAAAAAAAAEAAAAYqd+A5/19nT0AQAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWNqnJAQBqbK2IMAAAAAAAAAAAAURPUUE0RTAxAAAAABIDSQBLAEEATABPAEcASQBDAB4DUwBjAGEA\ +bgBhAFEAdQBhAGQAIABTAFEANQAwABwDMQAwADAAMwAwADUAMAAwADAANQA0ADgAMgAAAAAAAAAAAAAAAAAAAAAAAABqPg==") + + +def main(args): + dev = usb.core.find(idVendor=int(args.vendor,0), idProduct=int(args.product,0)) + if dev is None: + print("ERROR: Device not found!", file=sys.stderr) + exit(1) + + eeprom = FtdiEeprom() + try: + eeprom.open(dev) + eeprom.dump_config() + + if args.backup is not None: + args.backup.write(eeprom.data) + return + elif args.variant is None: + print("ERROR: must select a variant!") + exit(1) + + if args.init_with_default: + eeprom.data = DEFAULT_CONFIG + eeprom.set_serial_number("1003%03d0%06d" % (args.variant, random.randint(0,1000000))) + else: + eeprom.set_product_name("ScanaQuad SQ%d" % args.variant) + if args.randomize_serial: + eeprom.set_serial_number("1003%03d0%06d" % (args.variant, random.randint(0,1000000))) + else: + eeprom.set_serial_number(eeprom.serial[:4] + ("%03d"%args.variant) + eeprom.serial[6:]) + + eeprom.commit(dry_run=args.dry_run) + print(hexdump(eeprom.data)) + eeprom.dump_config() + finally: + eeprom.close() + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument('--vendor', default="0x0403", help="USB vendor ID") + parser.add_argument('--product', default="0x7fd0", help="USB product ID") + + grp = parser.add_mutually_exclusive_group(required=True) + grp.add_argument('--backup', type=argparse.FileType('wb'), default=None, help="Back up the existing config (on the device) to this path. Inhibits any further actions of writing the EEPROM.") + grp.add_argument('--variant', choices=[50,100,200], type=int, help="Variant to configure the device as") + + parser.add_argument('--init-with-default', default=False, action='store_true', help="Initialize entire EEPROM with default values (implies --randomize-serial, default off) (CAN BE DANGEROUS! USE ONLY FOR UNBRICKING!)") + parser.add_argument('--randomize-serial', default=False, action='store_true', help="Randomize the device's serial number (default off)") + parser.add_argument('--dry-run', dest='dry_run', default=True, action='store_true', help="Print result of action instead of actually writing to device (default on).") + parser.add_argument('--no-dry-run', '--commit', dest='dry_run', default=True, action='store_false', help="Actually write to device (default is to dry run) (CAN BE DANGEROUS!)") + args = parser.parse_args() + main(args)