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)