Esempio n. 1
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    port = None

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        port = open(args.dump, "wb")
    dev = PDQ(url=args.device, dev=port, num_boards=args.boards)
    try:
        if args.reset:
            dev.write(b"")  # flush etx
            dev.set_config(reset=True)
            time.sleep(.1)

        dev.set_crc(0)
        dev.checksum = 0

        simple_server_loop({"pdq": dev}, bind_address_from_args(args),
                           args.port, description="device=" + str(args.device))
    finally:
        dev.close()
Esempio n. 2
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    dev = Client(args.server, args.port, "pdq2")

    freq = dev.get_freq()
    times = np.around(eval(args.times, globals(), {})*freq)
    voltages = eval(args.voltages, globals(), dict(t=times/freq))

    dt = np.diff(times.astype(np.int))
    if args.order:
        tck = interpolate.splrep(times, voltages, k=args.order, s=0)
        u = interpolate.spalde(times, tck)
    else:
        u = voltages[:, None]
    segment = []
    for dti, ui in zip(dt, u):
        segment.append({
            "duration": int(dti),
            "channel_data": [{
                "bias": {
                    "amplitude": [float(uij) for uij in ui]
                }
            }]
        })
    program = [[] for i in range(args.frame)]
    program.append(segment)
    dev.park()
    dev.program(program, [args.channel])
    dev.unpark()
    dev.cmd("TRIGGER", args.free)
Esempio n. 3
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    dev = Client(args.server, args.port, "pdq2")

    if args.reset:
        dev.write(b"\x00\x00")  # flush any escape
        dev.cmd("RESET", True)
        time.sleep(.1)
    dev.cmd("START", False)
    dev.cmd("ARM", False)
    dev.cmd("DCM", args.dcm)
    freq = 100e6 if args.dcm else 50e6
    dev.set_freq(freq)
    times = eval(args.times, globals(), {})
    voltages = eval(args.voltages, globals(), dict(t=times))

    if args.demo:
        for ch, channel in enumerate(dev.channels):
            entry = []
            for fr in range(dev.channels[0].num_frames):
                vi = .1*fr + ch + voltages
                entry.append(channel.segment(times, vi, order=args.order,
                                             end=False, aux=args.aux))
                pi = 2*np.pi*(-.5 + .01*fr + .1*ch + 0*voltages)
                fi = 10e6*times/times[-1]
                channel.segment(2*times, voltages, pi, fi, trigger=False,
                                silence=True, aux=args.aux)
            dev.write_channel(channel, entry)
    elif args.bit:
        v = [-1, 0, -1]
        # for i in range(15):
        #     v.extend([(1 << i) - 1, 1 << i])
        v = np.array(v)*dev.channels[0].max_out/dev.channels[0].max_val
        t = np.arange(len(v))
        for channel in dev.channels:
            s = channel.segment(t, v, order=0, shift=15, stop=False,
                                trigger=False)
            dev.write_channel(channel, [s for i in range(channel.num_frames)])
    else:
        c = dev.channels[args.channel]
        map = [None] * c.num_frames
        map[args.frame] = c.segment(times, voltages, order=args.order,
                                    aux=args.aux)
        dev.write_channel(c, map)

    dev.cmd("START", True)
    dev.cmd("ARM", not args.disarm)
    dev.cmd("TRIGGER", args.free)

    if args.plot:
        from matplotlib import pyplot as plt
        fig, ax = plt.subplots()
        ax.plot(times, voltages, "xk", label="points")
        if args.order > 0:
            spline = interpolate.splrep(times, voltages, k=args.order)
            ttimes = np.arange(0, times[-1], 1/freq)
            vvoltages = interpolate.splev(ttimes, spline)
            ax.plot(ttimes, vvoltages, ",b", label="interpolation")
        fig.savefig(args.plot)
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    incoherent_channels = [False]*4
    if args.disable_coherence:
        for arg in args.disable_coherence:
            ch = int(arg)
            if ch < 0 or ch > 3:
                raise ValueError("channel must be in 0-3")
            incoherent_channels[ch] = True

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        dev = CoherentDdsSim()
    else:
        dev = CoherentDds(addr=args.device, clockFreq=args.clockfreq,
                                    internal_clock=args.internal_clock,
                                    incoherent_channels=incoherent_channels)

    simple_server_loop({"coherentDds": dev}, args.bind, args.port)
Esempio n. 5
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if (not args.print_decoded
            and args.write_vcd is None and args.write_dump is None):
        print("No action selected, use -p, -w and/or -d. See -h for help.")
        sys.exit(1)

    device_mgr = DeviceManager(DeviceDB(args.device_db))
    if args.read_dump:
        with open(args.read_dump, "rb") as f:
            dump = f.read()
    else:
        core_addr = device_mgr.get_desc("core")["arguments"]["host"]
        dump = get_analyzer_dump(core_addr)
    decoded_dump = decode_dump(dump)
    if args.print_decoded:
        print("Log channel:", decoded_dump.log_channel)
        print("DDS one-hot:", decoded_dump.dds_onehot_sel)
        for message in decoded_dump.messages:
            print(message)
    if args.write_vcd:
        with open(args.write_vcd, "w") as f:
            decoded_dump_to_vcd(f, device_mgr.get_device_db(),
                                decoded_dump,
                                uniform_interval=args.vcd_uniform_interval)
    if args.write_dump:
        with open(args.write_dump, "wb") as f:
            f.write(dump)
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    dev = Ddr05Driver(serial=args.serial)

    simple_server_loop({"ddr05": dev}, args.bind, args.port)
Esempio n. 7
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    loop = asyncio.get_event_loop()
    atexit.register(loop.close)

    writer = DBWriter(args.baseurl_db,
                      args.user_db, args.password_db,
                      args.database, args.table)
    writer.start()
    atexit_register_coroutine(writer.stop)

    filter = Filter(args.pattern_file)
    rpc_server = Server({"influxdb_filter": filter}, builtin_terminate=True)
    loop.run_until_complete(rpc_server.start(bind_address_from_args(args),
                                             args.port_control))
    atexit_register_coroutine(rpc_server.stop)

    reader = MasterReader(args.server_master, args.port_master,
                          args.retry_master, filter._filter, writer)
    reader.start()
    atexit_register_coroutine(reader.stop)

    loop.run_until_complete(rpc_server.wait_terminate())
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    if not args.simulation:
        dev = PiezoController(args.device)
    else:
        dev = SimulationPiezoController()

    # Q: Why not use try/finally for port closure?
    # A: We don't want to try to close the serial if sys.exit() is called,
    #    and sys.exit() isn't caught by Exception
    try:
        simple_server_loop({"piezoController": dev}, args.bind, args.port)
    except Exception:
        dev.close()
    else:
        dev.close()
    finally:
        dev.save_setpoints()
Esempio n. 9
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.print_decoded and args.write_vcd is None and args.write_dump is None:
        print("No action selected, use -p, -w and/or -d. See -h for help.")
        sys.exit(1)

    device_mgr = DeviceManager(DeviceDB(args.device_db))
    try:
        if args.read_dump:
            with open(args.read_dump, "rb") as f:
                dump = f.read()
        else:
            comm = device_mgr.get("comm")
            dump = comm.get_analyzer_dump()
        decoded_dump = decode_dump(dump)
        if args.print_decoded:
            print("Log channel:", decoded_dump.log_channel)
            print("DDS one-hot:", decoded_dump.dds_onehot_sel)
            for message in decoded_dump.messages:
                print(message)
        if args.write_vcd:
            with open(args.write_vcd, "w") as f:
                decoded_dump_to_vcd(f, device_mgr.get_device_db(), decoded_dump)
        if args.write_dump:
            with open(args.write_dump, "wb") as f:
                f.write(dump)
    finally:
        device_mgr.close_devices()
Esempio n. 10
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    device_mgr = DeviceManager(DeviceDB(args.device_db))
    try:
        comm = device_mgr.get("comm")
        comm.check_ident()

        if args.action == "read":
            value = comm.flash_storage_read(args.key)
            if not value:
                print("Key {} does not exist".format(args.key))
            else:
                print(value)
        elif args.action == "write":
            for key, value in args.string:
                comm.flash_storage_write(key, value.encode("utf-8"))
            for key, filename in args.file:
                with open(filename, "rb") as fi:
                    comm.flash_storage_write(key, fi.read())
        elif args.action == "delete":
            for key in args.key:
                comm.flash_storage_remove(key)
        elif args.action == "erase":
            comm.flash_storage_erase()
    finally:
        device_mgr.close_devices()
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    product = args.product.lower()
    if args.simulation:
        if product == "tdc001":
            dev = TdcSim()
        elif product == "tpz001":
            dev = TpzSim()
    else:
        if product == "tdc001":
            dev = Tdc(args.device)
        elif product == "tpz001":
            dev = Tpz(args.device)

    try:
        simple_server_loop({product: dev}, args.bind, args.port)
    finally:
        dev.close()
Esempio n. 12
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    if os.name == "nt":
        loop = asyncio.ProactorEventLoop()
        asyncio.set_event_loop(loop)
    else:
        loop = asyncio.get_event_loop()
    atexit.register(lambda: loop.close())

    ddb = FlatFileDB(args.ddb)
    pdb = FlatFileDB(args.pdb)
    rtr = Notifier(dict())
    log = Log(1000)

    if args.git:
        repo_backend = GitBackend(args.repository)
    else:
        repo_backend = FilesystemBackend(args.repository)
    repository = Repository(repo_backend, log.log)
    atexit.register(repository.close)
    repository.scan_async()

    worker_handlers = {
        "get_device": ddb.get,
        "get_parameter": pdb.get,
        "set_parameter": pdb.set,
        "update_rt_results": lambda mod: process_mod(rtr, mod),
        "log": log.log
    }
    scheduler = Scheduler(get_last_rid() + 1, worker_handlers, repo_backend)
    worker_handlers["scheduler_submit"] = scheduler.submit
    scheduler.start()
    atexit.register(lambda: loop.run_until_complete(scheduler.stop()))

    server_control = Server({
        "master_ddb": ddb,
        "master_pdb": pdb,
        "master_schedule": scheduler,
        "master_repository": repository
    })
    loop.run_until_complete(server_control.start(
        args.bind, args.port_control))
    atexit.register(lambda: loop.run_until_complete(server_control.stop()))

    server_notify = Publisher({
        "schedule": scheduler.notifier,
        "devices": ddb.data,
        "parameters": pdb.data,
        "rt_results": rtr,
        "explist": repository.explist,
        "log": log.data
    })
    loop.run_until_complete(server_notify.start(
        args.bind, args.port_notify))
    atexit.register(lambda: loop.run_until_complete(server_notify.stop()))

    loop.run_forever()
Esempio n. 13
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    device_mgr = DeviceManager(DeviceDB(args.device_db))
    try:
        comm = device_mgr.get("comm")
        comm.check_ident()
        print(comm.get_log(), end="")
    finally:
        device_mgr.close_devices()
Esempio n. 14
0
def main():
    # initialize application
    args = get_argparser().parse_args()
    init_logger(args)

    app = QtWidgets.QApplication([])
    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)
    atexit.register(loop.close)
    smgr = state.StateManager(args.db_file)

    datasets_sub = models.LocalModelManager(datasets.Model)

    # initialize main window
    main_window = MainWindow()
    smgr.register(main_window)
    status_bar = QtWidgets.QStatusBar()
    main_window.setStatusBar(status_bar)
    mdi_area = MdiArea()
    mdi_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
    mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
    main_window.setCentralWidget(mdi_area)

    d_results = results.ResultsBrowser(datasets_sub)
    smgr.register(d_results)

    d_applets = applets.AppletsDock(main_window, datasets_sub)
    atexit_register_coroutine(d_applets.stop)
    smgr.register(d_applets)

    d_datasets = datasets.DatasetsDock(datasets_sub)
    smgr.register(d_datasets)

    main_window.setCentralWidget(d_results)
    main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_applets)
    main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_datasets)

    # load/initialize state
    if os.name == "nt":
        # HACK: show the main window before creating applets.
        # Otherwise, the windows of those applets that are in detached
        # QDockWidgets fail to be embedded.
        main_window.show()

    smgr.load()

    if args.PATH:
        d_results.select(args.PATH)

    smgr.start()
    atexit_register_coroutine(smgr.stop)

    # run
    main_window.show()
    loop.run_until_complete(main_window.exit_request.wait())
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    delay_gen = None
    if not args.simulation:
        delay_gen = Driver().init_single_pci_card()
        delay_gen.set_clock_source(ClockSource.external_80_mhz)

    timing = PulsePickerTiming(delay_gen, args.allow_long_pulses)
    simple_server_loop({"timing": timing}, args.bind, args.port)
Esempio n. 16
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    if args.simulation:
        lda = Ldasim()
    else:
        lda = Lda(args.device, args.product)
    try:
        simple_server_loop({"lda": lda},
                           args.bind, args.port)
    finally:
        lda.close()
Esempio n. 17
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if args.trapDacDevice is None or args.trapRFDevice is None:
        print("You need to specify --trapDacDevice and --trapRFDevice"
              "arguments. Use --help for more information.")
        sys.exit(1)

    dev = TrapDac(addr_dc_iface=args.trapDacDevice, addr_rf_iface=args.trapRFDevice)
        
    simple_server_loop({"trapDac": dev}, args.bind, args.port)
Esempio n. 18
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    dev = Novatech409B(args.device if not args.simulation else None)
    try:
        simple_server_loop(
            {"novatech409b": dev}, args.bind, args.port)
    finally:
        dev.close()
Esempio n. 19
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if args.ipaddr is None:
        print("You need to specify a device IP address (-i/--ipaddr) "
              "argument. Use --help for more information.")
        sys.exit(1)

    dev = N8241A(addr=args.ipaddr)

    try:
        simple_server_loop({"N8241A": dev}, args.bind, args.port)
    finally:
        dev.close()
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and (args.trapDacDevice is None or args.trapRFDevice is None):
        print("You need to specify either --simulation or --trapDacDevice and --trapRFDevice"
              "arguments. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        dev = TrapDacSim()
    else:
        dev = TrapDac(addrDCInterface=args.trapDacDevice, addrRFInterface=args.trapRFDevice)
        
    simple_server_loop({"trapDac": dev}, args.bind, args.port)
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        dev = CoherentDdsSim()
    else:
        dev = CoherentDds(addr=args.device, clockFreq=args.clockfreq)
        
    simple_server_loop({"coherentDds": dev}, args.bind, args.port)
Esempio n. 22
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if args.ipaddr is None:
        print("You need to specify -i/--ipaddr"
            "Use --help for more information.")
        sys.exit(1)

    dev = ScpiSynth(addr=args.ipaddr)

    try:
        simple_server_loop({"scpi_synth": dev}, args.bind, args.port)
    finally:
        dev.close()
Esempio n. 23
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    core_addr = DeviceDB(args.device_db).get("core")["arguments"]["host"]
    mgmt = CommMgmt(core_addr)
    try:
        if args.action == "reboot":
            mgmt.reboot()
        elif args.action == "hotswap":
            mgmt.hotswap(args.image.read())
        else:
            print("An action needs to be specified.", file=sys.stderr)
            sys.exit(1)
    finally:
        mgmt.close()
Esempio n. 24
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    core_addr = DeviceDB(args.device_db).get("core")["arguments"]["host"]
    mgmt = CommMgmt(core_addr)
    try:
        if args.action == "set_level":
            mgmt.set_log_level(args.level)
        elif args.action == "set_uart_level":
            mgmt.set_uart_log_level(args.level)
        elif args.action == "clear":
            mgmt.clear_log()
        else:
            print(mgmt.get_log(), end="")
    finally:
        mgmt.close()
Esempio n. 25
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    port = None

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        port = open(args.dump, "wb")
    dev = Pdq2(url=args.device, dev=port)
    try:
        simple_server_loop({"pdq2": dev}, args.bind, args.port,
                           description="device=" + str(args.device))
    finally:
        dev.close()
Esempio n. 26
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.ipaddr is None:
        print("You need to specify either --simulation or -i/--ipaddr "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        dev = RohdeSynthSim()
    else:
        dev = RohdeSynth(addr=args.ipaddr)

    try:
        simple_server_loop({"rohdeSynth": dev}, args.bind, args.port)
    finally:
        dev.close()
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if args.device is None:
        print("You need to specify a -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    dev = QL355(args.device)

    # Q: Why not use try/finally for port closure?
    # A: We don't want to try to close the serial if sys.exit() is called,
    #    and sys.exit() isn't caught by Exception
    try:
        simple_server_loop({"ql355": dev}, bind_address_from_args(args), args.port)
    except Exception:
        dev.close()
    else:
        dev.close()
Esempio n. 28
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.channels is None:
        print("You need to specify either --simulation or -C/--channels "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        daq = DAQmxSim()
    else:
        daq = DAQmx(args.channels,
                    args.clock)

    try:
        simple_server_loop({"pxi6733": daq},
                           args.bind, args.port)
    finally:
        daq.close()
Esempio n. 29
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    client = SSHClient(args.host)

    sftp = client.get_sftp()
    tcpdump = client.spawn_command(
        "/usr/sbin/tcpdump host {device} -w {tmp}/trace.pcap",
        get_pty=True,
        device=args.device)

    try:
        subprocess.check_call(args.command)
    except subprocess.CalledProcessError:
        logger.error("Command failed")

    tcpdump.close()
    sftp.get("{tmp}/trace.pcap".format(tmp=client.tmp), args.file + ".new")
    os.rename(args.file + ".new", args.file)
    logger.info("Pcap file {file} retrieved".format(file=args.file))
Esempio n. 30
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    client = SSHClient(args.host)

    sftp = client.get_sftp()
    tcpdump = client.spawn_command(
        "/usr/sbin/tcpdump host {device} -w {tmp}/trace.pcap", get_pty=True,
        device=args.device)

    try:
        subprocess.check_call(args.command)
    except subprocess.CalledProcessError:
        logger.error("Command failed")

    tcpdump.close()
    sftp.get("{tmp}/trace.pcap".format(tmp=client.tmp),
             args.file + ".new")
    os.rename(args.file + ".new", args.file)
    logger.info("Pcap file {file} retrieved".format(file=args.file))
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    dev = PiezoController(args.device if not args.simulation else None)

    # Q: Why not use try/finally for port closure?
    # A: We don't want to try to close the serial if sys.exit() is called,
    #    and sys.exit() isn't caught by Exception
    try:
        simple_server_loop({"piezoController": dev}, args.bind, args.port)
    except Exception:
        dev.close()
    else:
        dev.close()
    finally:
        dev.save_setpoints()
Esempio n. 32
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    core_addr = DeviceDB(args.device_db).get("core")["arguments"]["host"]
    mgmt = CommMgmt(core_addr)
    try:
        if args.action == "start":
            mgmt.start_profiler(args.interval, args.hits_size, args.edges_size)
        elif args.action == "stop":
            mgmt.stop_profiler()
        elif args.action == "save":
            hits, edges = mgmt.get_profile()
            writer = CallgrindWriter(args.output, args.firmware,
                                     not args.no_compression)
            writer.header()
            for addr, count in hits.items():
                writer.hit(addr, count)
            for (caller, callee), count in edges.items():
                writer.edge(caller, callee, count)
    finally:
        mgmt.close()
Esempio n. 33
0
def run_simple_rpc_server(port, setup_args, interface_name, setup_interface):
    parser = ArgumentParser()

    influxdb_args(parser)
    simple_network_args(parser, port)
    verbosity_args(parser)
    if setup_args:
        setup_args(parser)

    args = parser.parse_args()
    init_logger(args)

    loop = asyncio.get_event_loop()
    atexit.register(loop.close)

    influx_pusher = influxdb_pusher_from_args(args)
    if influx_pusher:
        t = asyncio.ensure_future(influx_pusher.run())
        def stop():
            t.cancel()
            try:
                loop.run_until_complete(t)
            except asyncio.CancelledError:
                pass
        atexit.register(stop)

    interface = setup_interface(args, influx_pusher, loop)

    # Provide a default ping() method, which ARTIQ calls regularly for
    # heartbeating purposes.
    if not hasattr(interface, "ping"):
        setattr(interface, "ping", lambda: True)

    rpc_server = Server({interface_name: interface}, builtin_terminate=True)
    loop.run_until_complete(rpc_server.start(bind_address_from_args(args), args.port))
    atexit_register_coroutine(rpc_server.stop)

    loop.run_until_complete(rpc_server.wait_terminate())
Esempio n. 34
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    loop = asyncio.get_event_loop()
    atexit.register(lambda: loop.close())

    writer = DBWriter(args.baseurl_db, args.user_db, args.password_db,
                      args.database, args.table)
    writer.start()
    atexit.register(lambda: loop.run_until_complete(writer.stop()))

    filter = Filter(args.pattern_file)
    rpc_server = Server({"influxdb_filter": filter}, builtin_terminate=True)
    loop.run_until_complete(rpc_server.start(args.bind, args.bind_port))
    atexit.register(lambda: loop.run_until_complete(rpc_server.stop()))

    reader = MasterReader(args.server_master, args.port_master,
                          args.retry_master, filter._filter, writer)
    reader.start()
    atexit.register(lambda: loop.run_until_complete(reader.stop()))

    loop.run_until_complete(rpc_server.wait_terminate())
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if not args.simulation and args.device is None:
        print("You need to specify either --simulation or -d/--device "
              "argument. Use --help for more information.")
        sys.exit(1)

    if args.simulation:
        if args.product == "TDC001":
            dev = TdcSim()
        elif args.product == "TPZ001":
            dev = TpzSim()
    else:
        if args.product == "TDC001":
            dev = Tdc(args.device)
        elif args.product == "TPZ001":
            dev = Tpz(args.device)

    try:
        simple_server_loop({args.product.lower(): dev}, args.bind, args.port)
    finally:
        dev.close()
Esempio n. 36
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if os.name == "nt":
        loop = asyncio.ProactorEventLoop()
        asyncio.set_event_loop(loop)
    else:
        loop = asyncio.get_event_loop()
    atexit.register(lambda: loop.close())

    ctlmgr = ControllerManager(args.server, args.port, args.retry_master)
    ctlmgr.start()
    atexit.register(lambda: loop.run_until_complete(ctlmgr.stop()))

    class CtlMgrRPC:
        retry_now = ctlmgr.retry_now

    rpc_target = CtlMgrRPC()
    rpc_server = Server({"ctlmgr": rpc_target}, builtin_terminate=True)
    loop.run_until_complete(rpc_server.start(args.bind, args.bind_port))
    atexit.register(lambda: loop.run_until_complete(rpc_server.stop()))

    loop.run_until_complete(rpc_server.wait_terminate())
Esempio n. 37
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    dev = DummyCamera()
    run_server(dev, args)
Esempio n. 38
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    dev = Client(args.server, args.port, "pdq2")
    dev.init()

    if args.reset:
        dev.write(b"\x00\x00")  # flush any escape
        dev.cmd("RESET", True)
        time.sleep(.1)
    dev.cmd("START", False)
    dev.cmd("ARM", False)
    dev.cmd("DCM", args.dcm)
    freq = 100e6 if args.dcm else 50e6
    dev.set_freq(freq)
    num_channels = dev.get_num_channels()
    num_frames = dev.get_num_frames()
    times = eval(args.times, globals(), {})
    voltages = eval(args.voltages, globals(), dict(t=times))

    if args.demo:
        for ch, channel in enumerate(dev.channels):
            entry = []
            for fr in range(dev.channels[0].num_frames):
                vi = .1 * fr + ch + voltages
                entry.append(
                    channel.segment(times,
                                    vi,
                                    order=args.order,
                                    end=False,
                                    aux=args.aux))
                pi = 2 * np.pi * (-.5 + .01 * fr + .1 * ch + 0 * voltages)
                fi = 10e6 * times / times[-1]
                channel.segment(2 * times,
                                voltages,
                                pi,
                                fi,
                                trigger=False,
                                silence=True,
                                aux=args.aux)
            dev.write_channel(channel, entry)
    elif args.bit:
        v = [-1, 0, -1]
        # for i in range(15):
        #     v.extend([(1 << i) - 1, 1 << i])
        v = np.array(v) * dev.channels[0].max_out / dev.channels[0].max_val
        t = np.arange(len(v))
        for channel in dev.channels:
            s = channel.segment(t,
                                v,
                                order=0,
                                shift=15,
                                stop=False,
                                trigger=False)
            dev.write_channel(channel, [s for i in range(channel.num_frames)])
    else:
        c = dev.channels[args.channel]
        map = [None] * c.num_frames
        map[args.frame] = c.segment(times,
                                    voltages,
                                    order=args.order,
                                    aux=args.aux)
        dev.write_channel(c, map)

    dev.cmd("START", True)
    dev.cmd("ARM", not args.disarm)
    dev.cmd("TRIGGER", args.free)

    if args.plot:
        from matplotlib import pyplot as plt
        fig, ax = plt.subplots()
        ax.plot(times, voltages, "xk", label="points")
        if args.order > 0:
            spline = interpolate.splrep(times, voltages, k=args.order)
            ttimes = np.arange(0, times[-1], 1 / freq)
            vvoltages = interpolate.splev(ttimes, spline)
            ax.plot(ttimes, vvoltages, ",b", label="interpolation")
        fig.savefig(args.plot)
Esempio n. 39
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    dev = Client(args.server, args.port, "pdq2")
    dev.init()

    if args.reset:
        dev.flush_escape()
        dev.write_cmd("RESET_EN")
        time.sleep(.1)
    if args.dcm:
        dev.write_cmd("DCM_EN")
        dev.set_freq(100e6)
    elif args.dcm == 0:
        dev.write_cmd("DCM_DIS")
        dev.set_freq(50e6)
    dev.write_cmd("START_DIS")

    num_channels = dev.get_num_channels()
    num_frames = dev.get_num_frames()
    times = eval(args.times, globals(), {})
    voltages = eval(args.voltages, globals(), dict(t=times))

    if args.demo:
        # FIXME
        channels = [args.channel] if args.channel < num_channels \
            else range(num_channels)
        frames = [args.frame] if args.frame < num_frames \
            else range(num_frames)
        for channel in channels:
            f = []
            for frame in frames:
                vi = .1 * frame + channel + voltages
                pi = 2 * np.pi * (.01 * frame + .1 * channel + 0 * voltages)
                fi = 10e6 * times / times[-1]
                f.append(b"".join([
                    dev.frame(times, vi, order=args.order, end=False),
                    dev.frame(2 * times, voltages, pi, fi, trigger=False),
                    # dev.frame(2*times, 0*vi+.1, 0*pi, 0*fi+1e6),
                    # dev.frame(times, 0*vi, order=args.order, silence=True),
                ]))
            board, dac = divmod(channel, dev.num_dacs)
            dev.write_data(dev.add_mem_header(board, dac, dev.map_frames(f)))
    elif args.bit:
        map = [0] * num_frames
        t = np.arange(2 * 16) * 1.
        v = [-1, 0, -1]
        for i in range(15):
            vi = 1 << i
            v.extend([vi - 1, vi])
        v = np.array(v) * dev.get_max_out() / (1 << 15)
        t, v = t[:3], v[:3]
        # print(t, v)
        for channel in range(num_channels):
            dev.multi_frame([(t, v)],
                            channel=channel,
                            order=0,
                            map=map,
                            shift=15,
                            stop=False,
                            trigger=False)
    else:
        tv = [(times, voltages)]
        map = [None] * num_frames
        map[args.frame] = 0
        dev.multi_frame(tv, channel=args.channel, order=args.order, map=map)

    dev.write_cmd("START_EN")
    if not args.disarm:
        dev.write_cmd("ARM_EN")
    if args.free:
        dev.write_cmd("TRIGGER_EN")

    if args.plot:
        from matplotlib import pyplot as plt
        fig, ax0 = plt.subplots()
        ax0.plot(times, voltages, "xk", label="points")
        if args.order:
            spline = interpolate.splrep(times, voltages, k=args.order)
            ttimes = np.arange(0, times[-1], 1 / dev.get_freq())
            vvoltages = interpolate.splev(ttimes, spline)
            ax0.plot(ttimes, vvoltages, ",b", label="interpolation")
        fig.savefig(args.plot)
Esempio n. 40
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    if args.verbose == args.quiet == 0:
        logging.getLogger().setLevel(logging.INFO)

    def build_dir(*path, target=args.target):
        return os.path.join("/tmp/", "artiq_" + target, *path)

    if args.target == "kc705":
        board_type, firmware = "kc705", "runtime"
        variant = "nist_clock" if args.variant is None else args.variant
    elif args.target == "sayma":
        board_type, firmware = "sayma", "runtime"
        variant = "standalone" if args.variant is None else args.variant
    elif args.target == "kasli":
        board_type, firmware = "kasli", "runtime"
        variant = "tester" if args.variant is None else args.variant
    else:
        raise NotImplementedError("unknown target {}".format(args.target))

    board      = args.board.format(board_type=board_type)
    board_file = args.board_file.format(board=board)
    device     = args.device.format(board=board, host=args.host)
    serial     = args.serial.format(board=board)

    client = SSHClient(args.host, args.jump)

    flock_acquired = False
    flock_file = None # GC root
    def lock():
        nonlocal flock_acquired
        nonlocal flock_file

        if not flock_acquired:
            fuser_args = ["fuser", "-u", board_file]
            fuser = client.spawn_command(fuser_args)
            fuser_file = fuser.makefile('r')
            fuser_match = re.search(r"\((.+?)\)", fuser_file.readline())
            if fuser_match and fuser_match.group(1) == os.getenv("USER"):
                logger.info("Lock already acquired by {}".format(os.getenv("USER")))
                flock_acquired = True
                return

            logger.info("Acquiring device lock")
            flock_args = ["flock"]
            if not args.wait:
                flock_args.append("--nonblock")
            flock_args += ["--verbose", board_file]
            flock_args += ["sleep", "86400"]

            flock = client.spawn_command(flock_args, get_pty=True)
            flock_file = flock.makefile('r')
            while not flock_acquired:
                line = flock_file.readline()
                if not line:
                    break
                logger.debug(line.rstrip())
                if line.startswith("flock: executing"):
                    flock_acquired = True
                elif line.startswith("flock: failed"):
                    logger.error("Failed to get lock")
                    sys.exit(1)

    def command(*args, on_failure="Command failed"):
        logger.debug("Running {}".format(" ".join([shlex.quote(arg) for arg in args])))
        try:
            subprocess.check_call(args)
        except subprocess.CalledProcessError:
            logger.error(on_failure)
            sys.exit(1)

    def build(target, *extra_args, output_dir=build_dir(), variant=variant):
        build_args = ["python3", "-m", "artiq.gateware.targets." + target, *extra_args]
        if not args.gateware:
            build_args.append("--no-compile-gateware")
        if variant:
            build_args += ["--variant", variant]
        build_args += ["--output-dir", output_dir]
        command(*build_args, on_failure="Build failed")

    def flash(*steps):
        lock()

        flash_args = ["artiq_flash"]
        for _ in range(args.verbose):
            flash_args.append("-v")
        flash_args += ["-H", args.host]
        if args.jump:
            flash_args += ["-J", args.jump]
        flash_args += ["-t", board_type]
        flash_args += ["-V", variant]
        flash_args += ["-I", "source {}".format(board_file)]
        flash_args += ["--srcbuild", build_dir()]
        flash_args += steps
        command(*flash_args, on_failure="Flashing failed")

    for action in args.actions:
        if action == "build":
            logger.info("Building target")
            if args.target == "sayma":
                build("sayma_rtm", output_dir=build_dir("rtm_gateware"), variant=None)
                build("sayma_amc", "--rtm-csr-csv", build_dir("rtm_gateware", "rtm_csr.csv"))
            else:
                build(args.target)

        elif action == "clean":
            logger.info("Cleaning build directory")
            shutil.rmtree(build_dir(), ignore_errors=True)

        elif action == "reset":
            logger.info("Resetting device")
            flash("start")

        elif action == "flash":
            gateware = ["gateware"] if args.gateware else []

            logger.info("Flashing and booting")
            flash(*gateware, "bootloader", "firmware", "start")

        elif action == "flash+log":
            gateware = ["gateware"] if args.gateware else []

            logger.info("Flashing")
            flash(*gateware, "bootloader", "firmware")

            flterm = client.spawn_command(["flterm", serial, "--output-only"])
            logger.info("Booting")
            flash("start")
            client.drain(flterm)

        elif action == "load":
            logger.info("Loading gateware")
            flash("load")

        elif action == "connect":
            lock()

            transport = client.get_transport()
            transport.set_keepalive(30)

            def forwarder(local_stream, remote_stream):
                try:
                    while True:
                        r, _, _ = select.select([local_stream, remote_stream], [], [])
                        if local_stream in r:
                            data = local_stream.recv(65535)
                            if data == b"":
                                break
                            remote_stream.sendall(data)
                        if remote_stream in r:
                            data = remote_stream.recv(65535)
                            if data == b"":
                                break
                            local_stream.sendall(data)
                except Exception as err:
                    logger.error("Cannot forward on port %s: %s", port, repr(err))
                local_stream.close()
                remote_stream.close()

            def listener(port):
                listener = socket.socket()
                listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                listener.bind(('localhost', port))
                listener.listen(8)
                while True:
                    local_stream, peer_addr = listener.accept()
                    logger.info("Accepting %s:%s and opening SSH channel to %s:%s",
                                *peer_addr, device, port)
                    try:
                        remote_stream = \
                            transport.open_channel('direct-tcpip', (device, port), peer_addr)
                    except Exception:
                        logger.exception("Cannot open channel on port %s", port)
                        continue

                    thread = threading.Thread(target=forwarder, args=(local_stream, remote_stream),
                                              name="forward-{}".format(port), daemon=True)
                    thread.start()

            ports = [1380, 1381, 1382, 1383]
            for port in ports:
                thread = threading.Thread(target=listener, args=(port,),
                                          name="listen-{}".format(port), daemon=True)
                thread.start()

            logger.info("Forwarding ports {} to core device and logs from core device"
                            .format(", ".join(map(str, ports))))
            client.run_command(["flterm", serial, "--output-only"])

        elif action == "hotswap":
            lock()

            logger.info("Hotswapping firmware")
            firmware = build_dir(variant, "software", firmware, firmware + ".bin")

            mgmt = CommMgmt(device)
            mgmt.open(ssh_transport=client.get_transport())
            with open(firmware, "rb") as f:
                mgmt.hotswap(f.read())

        else:
            logger.error("Unknown action {}".format(action))
            sys.exit(1)
Esempio n. 41
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    config = {
        "kasli": {
            "programmer":
            partial(ProgrammerXC7,
                    board="kasli",
                    proxy="bscan_spi_xc7a100t.bit"),
            "def_variant":
            "opticlock",
            "gateware": ("spi0", 0x000000),
            "bootloader": ("spi0", 0x400000),
            "storage": ("spi0", 0x440000),
            "firmware": ("spi0", 0x450000),
        },
        "sayma": {
            "programmer": ProgrammerSayma,
            "def_variant": "standalone",
            "gateware": ("spi0", 0x000000),
            "bootloader": ("spi1", 0x000000),
            "storage": ("spi1", 0x040000),
            "firmware": ("spi1", 0x050000),
            "rtm_gateware": ("spi1", 0x200000),
        },
        "kc705": {
            "programmer":
            partial(ProgrammerXC7,
                    board="kc705",
                    proxy="bscan_spi_xc7k325t.bit"),
            "def_variant":
            "nist_clock",
            "gateware": ("spi0", 0x000000),
            "bootloader": ("spi0", 0xaf0000),
            "storage": ("spi0", 0xb30000),
            "firmware": ("spi0", 0xb40000),
        },
    }[args.target]

    variant = args.variant
    if variant is None:
        variant = config["def_variant"]

    bin_dir = args.dir
    if bin_dir is None:
        bin_name = args.target
        if variant:
            bin_name += "-" + variant
        bin_dir = os.path.join(artiq_dir, "binaries", bin_name)

    if args.host is None:
        client = LocalClient()
    else:
        client = SSHClient(args.host, args.jump)

    programmer = config["programmer"](client,
                                      preinit_script=args.preinit_command)

    def artifact_path(*path_filename):
        if args.srcbuild is None:
            *path, filename = path_filename
            return os.path.join(bin_dir, filename)
        else:
            return os.path.join(args.srcbuild, *path_filename)

    def convert_gateware(bit_filename, header=False):
        bin_handle, bin_filename = tempfile.mkstemp(
            prefix="artiq_", suffix="_" + os.path.basename(bit_filename))
        with open(bit_filename, "rb") as bit_file, \
                open(bin_handle, "wb") as bin_file:
            if header:
                bin_file.write(b"\x00" * 8)
            bit2bin(bit_file, bin_file)
            if header:
                magic = 0x5352544d  # "SRTM", see sayma_rtm target
                length = bin_file.tell() - 8
                bin_file.seek(0)
                bin_file.write(magic.to_bytes(4, byteorder="big"))
                bin_file.write(length.to_bytes(4, byteorder="big"))
        atexit.register(lambda: os.unlink(bin_filename))
        return bin_filename

    for action in args.action:
        if action == "gateware":
            gateware_bin = convert_gateware(
                artifact_path(variant, "gateware", "top.bit"))
            programmer.write_binary(*config["gateware"], gateware_bin)
            if args.target == "sayma" and args.variant != "master":
                rtm_gateware_bin = convert_gateware(artifact_path(
                    "rtm_gateware", "rtm.bit"),
                                                    header=True)
                programmer.write_binary(*config["rtm_gateware"],
                                        rtm_gateware_bin)
        elif action == "bootloader":
            bootloader_bin = artifact_path(variant, "software", "bootloader",
                                           "bootloader.bin")
            programmer.write_binary(*config["bootloader"], bootloader_bin)
        elif action == "storage":
            storage_img = args.storage
            programmer.write_binary(*config["storage"], storage_img)
        elif action == "firmware":
            if variant == "satellite":
                firmware = "satman"
            else:
                firmware = "runtime"

            firmware_fbi = artifact_path(variant, "software", firmware,
                                         firmware + ".fbi")
            programmer.write_binary(*config["firmware"], firmware_fbi)
        elif action == "load":
            if args.target == "sayma":
                rtm_gateware_bit = artifact_path("rtm_gateware", "rtm.bit")
                programmer.load(rtm_gateware_bit, 0)
                gateware_bit = artifact_path(variant, "gateware", "top.bit")
                programmer.load(gateware_bit, 1)
            else:
                gateware_bit = artifact_path(variant, "gateware", "top.bit")
                programmer.load(gateware_bit, 0)
        elif action == "start":
            programmer.start()
        else:
            raise ValueError("invalid action", action)

    if args.dry_run:
        print("\n".join(programmer.script()))
    else:
        programmer.run()
Esempio n. 42
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if args.target == "kc705_dds":
        firmware = "runtime"
    elif args.target == "kc705_drtio_satellite":
        firmware = "satman"
    else:
        raise NotImplementedError("unknown target {}".format(args.target))

    ssh = None
    def get_ssh():
        nonlocal ssh
        if ssh is not None:
            return ssh
        ssh = paramiko.SSHClient()
        ssh.load_system_host_keys()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(args.host)
        return ssh

    sftp = None
    def get_sftp():
        nonlocal sftp
        if sftp is not None:
            return sftp
        sftp = get_ssh().open_sftp()
        return sftp

    rng = Random()
    tmp = "artiq" + "".join([rng.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ") for _ in range(6)])
    env = "bash -c 'export PATH=$HOME/miniconda/bin:$PATH; exec $0 $*' "

    def run_command(cmd, **kws):
        logger.info("Executing {}".format(cmd))
        chan = get_ssh().get_transport().open_session()
        chan.set_combine_stderr(True)
        chan.exec_command(cmd.format(tmp=tmp, env=env, serial=args.serial, ip=args.ip,
                                     firmware=firmware, **kws))
        return chan.makefile()

    def drain(chan):
        while True:
            char = chan.read(1)
            if char == b"":
                break
            sys.stderr.write(char.decode("utf-8", errors='replace'))

    for action in args.actions:
        if action == "build":
            logger.info("Building firmware")
            try:
                subprocess.check_call(["python3",
                                        "-m", "artiq.gateware.targets." + args.target,
                                        "--no-compile-gateware",
                                        "--output-dir",
                                        "/tmp/{target}".format(target=args.target)])
            except subprocess.CalledProcessError:
                logger.error("Build failed")
                sys.exit(1)

        elif action == "boot" or action == "boot+log":
            logger.info("Uploading firmware")
            get_sftp().mkdir("/tmp/{tmp}".format(tmp=tmp))
            get_sftp().put("/tmp/{target}/software/{firmware}/{firmware}.bin"
                                .format(target=args.target, firmware=firmware),
                           "/tmp/{tmp}/{firmware}.bin".format(tmp=tmp, firmware=firmware))

            logger.info("Booting firmware")
            flterm = run_command(
                "{env} python3 flterm.py {serial} " +
                "--kernel /tmp/{tmp}/{firmware}.bin " +
                ("--upload-only" if action == "boot" else "--output-only"))
            artiq_flash = run_command(
                "{env} artiq_flash start")
            drain(flterm)

        elif action == "connect":
            def forwarder(port):
                listener = socket.socket()
                listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                listener.bind(('localhost', port))
                listener.listen(1)
                while True:
                    local_stream, peer_addr = listener.accept()
                    logger.info("Accepting %s:%s and opening SSH channel to %s:%s",
                                *peer_addr, args.ip, port)
                    if get_ssh().get_transport() is None:
                        logger.error("Trying to open a channel before the transport is ready!")
                        continue

                    try:
                        remote_stream = get_ssh().get_transport() \
                            .open_channel('direct-tcpip', (args.ip, port), peer_addr)
                    except Exception as e:
                        logger.exception("Cannot open channel on port %s", port)
                    while True:
                        try:
                            r, w, x = select.select([local_stream, remote_stream], [], [])
                            if local_stream in r:
                                data = local_stream.recv(1024)
                                if data == b"":
                                    break
                                remote_stream.send(data)
                            if remote_stream in r:
                                data = remote_stream.recv(1024)
                                if data == b"":
                                    break
                                local_stream.send(data)
                        except Exception as e:
                            logger.exception("Forward error on port %s", port)
                    local_stream.close()
                    remote_stream.close()

            for port in (1381, 1382):
                thread = threading.Thread(target=forwarder, args=(port,),
                                          name="port-{}".format(port), daemon=True)
                thread.start()

            logger.info("Connecting to device")
            flterm = run_command(
                "{env} python3 flterm.py {serial} --output-only")
            drain(flterm)

        else:
            logger.error("Unknown action {}".format(action))
            sys.exit(1)
Esempio n. 43
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    app = QtGui.QApplication([])
    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)
    atexit.register(lambda: loop.close())

    smgr = StateManager(args.db_file)

    schedule_ctl = AsyncioClient()
    loop.run_until_complete(
        schedule_ctl.connect_rpc(args.server, args.port_control,
                                 "master_schedule"))
    atexit.register(lambda: schedule_ctl.close_rpc())

    win = MainWindow(app, args.server)
    area = dockarea.DockArea()
    smgr.register(area)
    smgr.register(win)
    win.setCentralWidget(area)
    status_bar = QtGui.QStatusBar()
    status_bar.showMessage("Connected to {}".format(args.server))
    win.setStatusBar(status_bar)

    d_explorer = ExplorerDock(win, status_bar, schedule_ctl)
    smgr.register(d_explorer)
    loop.run_until_complete(
        d_explorer.sub_connect(args.server, args.port_notify))
    atexit.register(lambda: loop.run_until_complete(d_explorer.sub_close()))

    d_datasets = DatasetsDock(win, area)
    smgr.register(d_datasets)
    loop.run_until_complete(
        d_datasets.sub_connect(args.server, args.port_notify))
    atexit.register(lambda: loop.run_until_complete(d_datasets.sub_close()))

    if os.name != "nt":
        d_ttl_dds = MonInj()
        loop.run_until_complete(d_ttl_dds.start(args.server, args.port_notify))
        atexit.register(lambda: loop.run_until_complete(d_ttl_dds.stop()))

    if os.name != "nt":
        area.addDock(d_ttl_dds.dds_dock, "top")
        area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
        area.addDock(d_datasets, "above", d_ttl_dds.ttl_dock)
    else:
        area.addDock(d_datasets, "top")
    area.addDock(d_explorer, "above", d_datasets)

    d_schedule = ScheduleDock(status_bar, schedule_ctl)
    loop.run_until_complete(
        d_schedule.sub_connect(args.server, args.port_notify))
    atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close()))

    d_log = LogDock()
    smgr.register(d_log)
    loop.run_until_complete(d_log.sub_connect(args.server, args.port_notify))
    atexit.register(lambda: loop.run_until_complete(d_log.sub_close()))

    dataset_db = AsyncioClient()
    loop.run_until_complete(
        dataset_db.connect_rpc(args.server, args.port_control,
                               "master_dataset_db"))
    atexit.register(lambda: dataset_db.close_rpc())

    def _set_dataset(k, v):
        asyncio.ensure_future(dataset_db.set(k, v))

    def _del_dataset(k):
        asyncio.ensure_future(dataset_db.delete(k))

    d_console = ConsoleDock(d_datasets.get_dataset, _set_dataset, _del_dataset)

    area.addDock(d_console, "bottom")
    area.addDock(d_log, "above", d_console)
    area.addDock(d_schedule, "above", d_log)

    smgr.load()
    smgr.start()
    atexit.register(lambda: loop.run_until_complete(smgr.stop()))
    win.show()
    loop.run_until_complete(win.exit_request.wait())
Esempio n. 44
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    config = {
        "kasli": {
            "programmer":   partial(ProgrammerXC7, board="kasli", proxy="bscan_spi_xc7a100t.bit"),
            "gateware":     ("spi0", 0x000000),
            "bootloader":   ("spi0", 0x400000),
            "storage":      ("spi0", 0x440000),
            "firmware":     ("spi0", 0x450000),
        },
        "sayma": {
            "programmer":   ProgrammerSayma,
            "gateware":     ("spi0", 0x000000),
            "bootloader":   ("spi1", 0x000000),
            "storage":      ("spi1", 0x040000),
            "firmware":     ("spi1", 0x050000),
            "rtm_gateware": ("spi1", 0x200000),
        },
        "metlino": {
            "programmer":   ProgrammerMetlino,
            "gateware":     ("spi0", 0x000000),
            "bootloader":   ("spi1", 0x000000),
            "storage":      ("spi1", 0x040000),
            "firmware":     ("spi1", 0x050000),
        },
        "kc705": {
            "programmer":   partial(ProgrammerXC7, board="kc705", proxy="bscan_spi_xc7k325t.bit"),
            "gateware":     ("spi0", 0x000000),
            "bootloader":   ("spi0", 0xaf0000),
            "storage":      ("spi0", 0xb30000),
            "firmware":     ("spi0", 0xb40000),
        },
    }[args.target]

    bin_dir = args.dir
    if bin_dir is None:
        bin_dir = os.path.join(artiq_dir, "board-support")

    needs_artifacts = any(action in args.action
                          for action in ["gateware", "bootloader", "firmware", "load"])
    variant = args.variant
    if needs_artifacts and variant is None:
        variants = []
        if args.srcbuild:
            for entry in os.scandir(bin_dir):
                if entry.is_dir():
                    variants.append(entry.name)
        else:
            prefix = args.target + "-"
            for entry in os.scandir(bin_dir):
                if entry.is_dir() and entry.name.startswith(prefix):
                    variants.append(entry.name[len(prefix):])
        if args.target == "sayma":
            try:
                variants.remove("rtm_gateware")
            except ValueError:
                pass
        if len(variants) == 0:
            raise FileNotFoundError("no variants found, did you install a board binary package?")
        elif len(variants) == 1:
            variant = variants[0]
        else:
            raise ValueError("more than one variant found for selected board, specify -V. "
                "Found variants: {}".format(" ".join(sorted(variants))))
    if needs_artifacts:
        if args.srcbuild:
            variant_dir = variant
        else:
            variant_dir = args.target + "-" + variant

    if args.host is None:
        client = LocalClient()
    else:
        client = SSHClient(args.host, args.jump)

    programmer = config["programmer"](client, preinit_script=args.preinit_command)

    def artifact_path(this_variant_dir, *path_filename):
        if args.srcbuild:
            # source tree - use path elements to locate file
            return os.path.join(bin_dir, this_variant_dir, *path_filename)
        else:
            # flat tree - all files in the same directory, discard path elements
            *_, filename = path_filename
            return os.path.join(bin_dir, this_variant_dir, filename)

    def convert_gateware(bit_filename, header=False):
        bin_handle, bin_filename = tempfile.mkstemp(
            prefix="artiq_", suffix="_" + os.path.basename(bit_filename))
        with open(bit_filename, "rb") as bit_file, \
                open(bin_handle, "wb") as bin_file:
            if header:
                bin_file.write(b"\x00"*8)
            bit2bin(bit_file, bin_file)
            if header:
                magic = 0x5352544d  # "SRTM", see sayma_rtm target
                length = bin_file.tell() - 8
                bin_file.seek(0)
                bin_file.write(magic.to_bytes(4, byteorder="big"))
                bin_file.write(length.to_bytes(4, byteorder="big"))
        atexit.register(lambda: os.unlink(bin_filename))
        return bin_filename

    for action in args.action:
        if action == "gateware":
            gateware_bin = convert_gateware(
                artifact_path(variant_dir, "gateware", "top.bit"))
            programmer.write_binary(*config["gateware"], gateware_bin)
            if args.target == "sayma" and variant != "master":
                rtm_gateware_bin = convert_gateware(
                    artifact_path("rtm_gateware", "rtm.bit"), header=True)
                programmer.write_binary(*config["rtm_gateware"],
                                        rtm_gateware_bin)
        elif action == "bootloader":
            bootloader_bin = artifact_path(variant_dir, "software", "bootloader", "bootloader.bin")
            programmer.write_binary(*config["bootloader"], bootloader_bin)
        elif action == "storage":
            storage_img = args.storage
            programmer.write_binary(*config["storage"], storage_img)
        elif action == "firmware":
            if variant.endswith("satellite"):
                firmware = "satman"
            else:
                firmware = "runtime"

            firmware_fbi = artifact_path(variant_dir, "software", firmware, firmware + ".fbi")
            programmer.write_binary(*config["firmware"], firmware_fbi)
        elif action == "load":
            if args.target == "sayma":
                rtm_gateware_bit = artifact_path("rtm_gateware", "rtm.bit")
                programmer.load(rtm_gateware_bit, 0)
                gateware_bit = artifact_path(variant_dir, "gateware", "top.bit")
                programmer.load(gateware_bit, 1)
            else:
                gateware_bit = artifact_path(variant_dir, "gateware", "top.bit")
                programmer.load(gateware_bit, 0)
        elif action == "start":
            programmer.start()
        elif action == "erase":
            if args.target == "sayma" or args.target == "metlino":
                programmer.erase_flash("spi0")
                programmer.erase_flash("spi1")
            else:
                programmer.erase_flash("spi0")
        else:
            raise ValueError("invalid action", action)

    if args.dry_run:
        print("\n".join(programmer.script()))
    else:
        programmer.run()
Esempio n. 45
0
    def __init__(self):

        self.args = args = get_argparser().parse_args()
        init_logger(args)

        self.config = load_config(args, "_server")
        self.lasers = self.config["lasers"].keys()

        for laser in self.lasers:
            self.config["lasers"][laser]["lock_ready"] = False

        # connect to hardware
        self.wlm = WLM(args.simulation)
        self.osas = OSAs(self.config["osas"], args.simulation)

        self.exp_min = self.wlm.get_exposure_min()
        self.exp_max = self.wlm.get_exposure_max()
        self.num_ccds = self.wlm.get_num_ccds()

        if self.config["switch"]["type"] == "internal":
            self.switch = self.wlm.get_switch()
        elif self.config["switch"]["type"] == "leoni":
            self.switch = LeoniSwitch(
                self.config["switch"]["ip"], args.simulation)
        else:
            raise ValueError("Unrecognised switch type: {}".format(
                self.config["switch"]["type"]))

        # measurement queue, processed by self.measurement_task
        self.measurement_ids = task_id_generator()
        self.measurements_queued = asyncio.Event()
        self.queue = []

        self.wake_locks = {laser: asyncio.Event() for laser in self.lasers}

        # schedule initial frequency/osa readings all lasers
        self.measurements_queued.set()
        for laser in self.lasers:
            self.queue.append({
                "laser": laser,
                "priority": 0,
                "expiry": time.time(),
                "id": next(self.measurement_ids),
                "get_osa_trace": True,
                "done": asyncio.Event()
            })

        # "notify" interface
        self.laser_db = Notifier(self.config["lasers"])
        self.freq_db = Notifier({laser: {
            "freq": None,
            "status": WLMMeasurementStatus.ERROR,
            "timestamp": 0
        } for laser in self.lasers})
        self.osa_db = Notifier({laser: {
            "trace": None,
            "timestamp": 0
        } for laser in self.lasers})

        self.server_notify = Publisher({
            "laser_db": self.laser_db,  # laser settings
            "freq_db": self.freq_db,  # most recent frequency measurements
            "osa_db": self.osa_db  # most recent osa traces
        })

        # "control" interface
        self.control_interface = ControlInterface(self)
        self.server_control = RPCServer({"control": self.control_interface},
                                        allow_parallel=True)

        self.running = False
Esempio n. 46
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    device_mgr = DeviceManager(DeviceDB(args.device_db))
    try:
        core_addr = DeviceDB(args.device_db).get("core")["arguments"]["host"]
        mgmt = CommMgmt(core_addr)

        if args.tool == "log":
            if args.action == "set_level":
                mgmt.set_log_level(args.level)
            if args.action == "set_uart_level":
                mgmt.set_uart_log_level(args.level)
            if args.action == "clear":
                mgmt.clear_log()
            if args.action == None:
                print(mgmt.get_log(), end="")

        if args.tool == "config":
            if args.action == "read":
                value = mgmt.config_read(args.key)
                if not value:
                    print("Key {} does not exist".format(args.key))
                else:
                    print(value)
            if args.action == "write":
                for key, value in args.string:
                    mgmt.config_write(key, value.encode("utf-8"))
                for key, filename in args.file:
                    with open(filename, "rb") as fi:
                        mgmt.config_write(key, fi.read())
            if args.action == "remove":
                for key in args.key:
                    mgmt.config_remove(key)
            if args.action == "erase":
                mgmt.config_erase()

        if args.tool == "reboot":
            mgmt.reboot()

        if args.tool == "hotswap":
            mgmt.hotswap(args.image.read())

        if args.tool == "profile":
            if args.action == "start":
                mgmt.start_profiler(args.interval, args.hits_size, args.edges_size)
            elif args.action == "stop":
                mgmt.stop_profiler()
            elif args.action == "save":
                hits, edges = mgmt.get_profile()
                writer = CallgrindWriter(args.output, args.firmware, "or1k-linux",
                                         args.compression, args.demangle)
                writer.header()
                for addr, count in hits.items():
                    writer.hit(addr, count)
                for (caller, callee), count in edges.items():
                    writer.edge(caller, callee, count)

        if args.tool == "debug":
            if args.action == "allocator":
                mgmt.debug_allocator()

    finally:
        device_mgr.close_devices()
Esempio n. 47
0
def main():

    args = get_argparser().parse_args()
    init_logger(args)

    servers = {
        idx: {
            "host": ip,
            "notify": 3250,
            "control": 3251
        }
        for idx, ip in enumerate(args.server)
    }

    while True:

        measurements = []

        for _, server in servers.items():
            try:
                client = RPCClient(server["host"], server["control"])
                lasers = client.get_laser_db()
                for laser in lasers:
                    meas = client.get_freq(laser,
                                           age=args.poll_time,
                                           priority=3,
                                           get_osa_trace=False,
                                           blocking=True,
                                           mute=False,
                                           offset_mode=False)
                    status, freq, _ = meas

                    if status != WLMMeasurementStatus.OKAY:
                        logger.info("{}: measurement error")
                        continue

                    f_ref = lasers[laser]["f_ref"]
                    delta = freq - lasers[laser]["f_ref"]
                    measurements.append({
                        "measurement": laser,
                        "fields": {
                            "freq": freq,
                            "f_ref": f_ref,
                            "detuning": delta
                        }
                    })
                    logger.info("{}: freq {} THz, f_ref {} THz, "
                                "detuning {} MHz".format(
                                    laser, freq, f_ref, delta))
            except OSError:
                logger.warning("Error querying server {}".format(server))
            finally:
                client.close_rpc()

        if measurements == []:
            time.sleep(args.poll_time)
            continue

        try:
            influx = influxdb.InfluxDBClient(host="10.255.6.4",
                                             database=args.database,
                                             username="******",
                                             password="******")

            influx.write_points(measurements)
        finally:
            influx.close()
        time.sleep(args.poll_time)
Esempio n. 48
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    if args.target == "kc705_dds" or args.target == "kc705_drtio_master":
        firmware = "runtime"
    elif args.target == "kc705_drtio_satellite":
        firmware = "satman"
    else:
        raise NotImplementedError("unknown target {}".format(args.target))

    client = SSHClient(args.host)
    substs = {
        "env": "bash -c 'export PATH=$HOME/miniconda/bin:$PATH; exec $0 $*' ",
        "serial": args.serial,
        "firmware": firmware,
    }

    for action in args.actions:
        if action == "build":
            logger.info("Building firmware")
            try:
                subprocess.check_call([
                    "python3", "-m", "artiq.gateware.targets." + args.target,
                    "--no-compile-gateware", "--output-dir",
                    "/tmp/{target}".format(target=args.target)
                ])
            except subprocess.CalledProcessError:
                logger.error("Build failed")
                sys.exit(1)

        elif action == "clean":
            logger.info("Cleaning build directory")
            target_dir = "/tmp/{target}".format(target=args.target)
            if os.path.isdir(target_dir):
                shutil.rmtree(target_dir)

        elif action == "reset":
            logger.info("Resetting device")
            client.run_command(
                "{env} artiq_flash start" +
                (" --target-file " + args.config if args.config else ""),
                **substs)

        elif action == "boot" or action == "boot+log":
            logger.info("Uploading firmware")
            client.get_sftp().put(
                "/tmp/{target}/software/{firmware}/{firmware}.bin".format(
                    target=args.target, firmware=firmware),
                "{tmp}/{firmware}.bin".format(tmp=client.tmp,
                                              firmware=firmware))

            logger.info("Booting firmware")
            flterm = client.spawn_command(
                "{env} python3 flterm.py {serial} " +
                "--kernel {tmp}/{firmware}.bin " +
                ("--upload-only" if action == "boot" else "--output-only"),
                **substs)
            artiq_flash = client.spawn_command(
                "{env} artiq_flash start" +
                (" --target-file " + args.config if args.config else ""),
                **substs)
            client.drain(flterm)

        elif action == "connect":
            transport = client.get_transport()

            def forwarder(local_stream, remote_stream):
                try:
                    while True:
                        r, _, _ = select.select([local_stream, remote_stream],
                                                [], [])
                        if local_stream in r:
                            data = local_stream.recv(65535)
                            if data == b"":
                                break
                            remote_stream.sendall(data)
                        if remote_stream in r:
                            data = remote_stream.recv(65535)
                            if data == b"":
                                break
                            local_stream.sendall(data)
                except Exception as err:
                    logger.error("Cannot forward on port %s: %s", port,
                                 repr(err))
                local_stream.close()
                remote_stream.close()

            def listener(port):
                listener = socket.socket()
                listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                listener.bind(('localhost', port))
                listener.listen(8)
                while True:
                    local_stream, peer_addr = listener.accept()
                    logger.info(
                        "Accepting %s:%s and opening SSH channel to %s:%s",
                        *peer_addr, args.device, port)
                    if client.get_transport() is None:
                        logger.error(
                            "Trying to open a channel before the transport is ready!"
                        )
                        continue

                    try:
                        remote_stream = \
                            transport.open_channel('direct-tcpip', (args.device, port), peer_addr)
                    except Exception:
                        logger.exception("Cannot open channel on port %s",
                                         port)
                        continue

                    thread = threading.Thread(target=forwarder,
                                              args=(local_stream,
                                                    remote_stream),
                                              name="forward-{}".format(port),
                                              daemon=True)
                    thread.start()

            for port in (1380, 1381, 1382, 1383):
                thread = threading.Thread(target=listener,
                                          args=(port, ),
                                          name="listen-{}".format(port),
                                          daemon=True)
                thread.start()

            logger.info("Connecting to device")
            client.run_command(
                "{env} python3 flterm.py {serial} --output-only", **substs)

        elif action == "hotswap":
            logger.info("Hotswapping firmware")
            try:
                subprocess.check_call([
                    "python3", "-m", "artiq.frontend.artiq_coreboot",
                    "hotswap",
                    "/tmp/{target}/software/{firmware}/{firmware}.bin".format(
                        target=args.target, firmware=firmware)
                ])
            except subprocess.CalledProcessError:
                logger.error("Build failed")
                sys.exit(1)

        else:
            logger.error("Unknown action {}".format(action))
            sys.exit(1)
Esempio n. 49
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)
    if args.verbose == args.quiet == 0:
        logging.getLogger().setLevel(logging.INFO)

    def build_dir(*path, target=args.target):
        return os.path.join("/tmp/", "artiq_" + target, *path)

    if args.target == "kc705":
        board_type, firmware = "kc705", "runtime"
        variant = "nist_clock" if args.variant is None else args.variant
    elif args.target == "sayma":
        board_type, firmware = "sayma", "runtime"
        variant = "standalone" if args.variant is None else args.variant
    elif args.target == "kasli":
        board_type, firmware = "kasli", "runtime"
        variant = "tester" if args.variant is None else args.variant
    else:
        raise NotImplementedError("unknown target {}".format(args.target))

    board = args.board.format(board_type=board_type)
    board_file = args.board_file.format(board=board)
    device = args.device.format(board=board, host=args.host)
    serial = args.serial.format(board=board)

    client = SSHClient(args.host, args.jump)

    flock_acquired = False
    flock_file = None  # GC root

    def lock():
        nonlocal flock_acquired
        nonlocal flock_file

        if not flock_acquired:
            fuser_args = ["fuser", "-u", board_file]
            fuser = client.spawn_command(fuser_args)
            fuser_file = fuser.makefile('r')
            fuser_match = re.search(r"\((.+?)\)", fuser_file.readline())
            if fuser_match and fuser_match.group(1) == os.getenv("USER"):
                logger.info("Lock already acquired by {}".format(
                    os.getenv("USER")))
                flock_acquired = True
                return

            logger.info("Acquiring device lock")
            flock_args = ["flock"]
            if not args.wait:
                flock_args.append("--nonblock")
            flock_args += ["--verbose", board_file]
            flock_args += ["sleep", "86400"]

            flock = client.spawn_command(flock_args, get_pty=True)
            flock_file = flock.makefile('r')
            while not flock_acquired:
                line = flock_file.readline()
                if not line:
                    break
                logger.debug(line.rstrip())
                if line.startswith("flock: executing"):
                    flock_acquired = True
                elif line.startswith("flock: failed"):
                    logger.error("Failed to get lock")
                    sys.exit(1)

    def command(*args, on_failure="Command failed"):
        logger.debug("Running {}".format(" ".join(
            [shlex.quote(arg) for arg in args])))
        try:
            subprocess.check_call(args)
        except subprocess.CalledProcessError:
            logger.error(on_failure)
            sys.exit(1)

    def build(target, *extra_args, output_dir=build_dir(), variant=variant):
        build_args = [
            "python3", "-m", "artiq.gateware.targets." + target, *extra_args
        ]
        if not args.gateware:
            build_args.append("--no-compile-gateware")
        if variant:
            build_args += ["--variant", variant]
        build_args += ["--output-dir", output_dir]
        command(*build_args, on_failure="Build failed")

    def flash(*steps):
        lock()

        flash_args = ["artiq_flash"]
        for _ in range(args.verbose):
            flash_args.append("-v")
        flash_args += ["-H", args.host]
        if args.jump:
            flash_args += ["-J", args.jump]
        flash_args += ["-t", board_type]
        flash_args += ["-V", variant]
        flash_args += ["-I", "source {}".format(board_file)]
        flash_args += ["--srcbuild", build_dir()]
        flash_args += steps
        command(*flash_args, on_failure="Flashing failed")

    for action in args.actions:
        if action == "build":
            logger.info("Building target")
            if args.target == "sayma":
                build("sayma_rtm",
                      output_dir=build_dir("rtm_gateware"),
                      variant=None)
                build("sayma_amc", "--rtm-csr-csv",
                      build_dir("rtm_gateware", "rtm_csr.csv"))
            else:
                build(args.target)

        elif action == "clean":
            logger.info("Cleaning build directory")
            shutil.rmtree(build_dir(), ignore_errors=True)

        elif action == "reset":
            logger.info("Resetting device")
            flash("start")

        elif action == "flash":
            gateware = ["gateware"] if args.gateware else []

            logger.info("Flashing and booting")
            flash(*gateware, "bootloader", "firmware", "start")

        elif action == "flash+log":
            gateware = ["gateware"] if args.gateware else []

            logger.info("Flashing")
            flash(*gateware, "bootloader", "firmware")

            flterm = client.spawn_command(["flterm", serial, "--output-only"])
            logger.info("Booting")
            flash("start")
            client.drain(flterm)

        elif action == "load":
            logger.info("Loading gateware")
            flash("load")

        elif action == "connect":
            lock()

            transport = client.get_transport()
            transport.set_keepalive(30)

            def forwarder(local_stream, remote_stream):
                try:
                    while True:
                        r, _, _ = select.select([local_stream, remote_stream],
                                                [], [])
                        if local_stream in r:
                            data = local_stream.recv(65535)
                            if data == b"":
                                break
                            remote_stream.sendall(data)
                        if remote_stream in r:
                            data = remote_stream.recv(65535)
                            if data == b"":
                                break
                            local_stream.sendall(data)
                except Exception as err:
                    logger.error("Cannot forward on port %s: %s", port,
                                 repr(err))
                local_stream.close()
                remote_stream.close()

            def listener(port):
                listener = socket.socket()
                listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                listener.bind(('localhost', port))
                listener.listen(8)
                while True:
                    local_stream, peer_addr = listener.accept()
                    logger.info(
                        "Accepting %s:%s and opening SSH channel to %s:%s",
                        *peer_addr, device, port)
                    try:
                        remote_stream = \
                            transport.open_channel('direct-tcpip', (device, port), peer_addr)
                    except Exception:
                        logger.exception("Cannot open channel on port %s",
                                         port)
                        continue

                    thread = threading.Thread(target=forwarder,
                                              args=(local_stream,
                                                    remote_stream),
                                              name="forward-{}".format(port),
                                              daemon=True)
                    thread.start()

            ports = [1380, 1381, 1382, 1383]
            for port in ports:
                thread = threading.Thread(target=listener,
                                          args=(port, ),
                                          name="listen-{}".format(port),
                                          daemon=True)
                thread.start()

            logger.info(
                "Forwarding ports {} to core device and logs from core device".
                format(", ".join(map(str, ports))))
            client.run_command(["flterm", serial, "--output-only"])

        elif action == "hotswap":
            lock()

            logger.info("Hotswapping firmware")
            firmware = build_dir(variant, "software", firmware,
                                 firmware + ".bin")

            mgmt = CommMgmt(device)
            mgmt.open(ssh_transport=client.get_transport())
            with open(firmware, "rb") as f:
                mgmt.hotswap(f.read())

        else:
            logger.error("Unknown action {}".format(action))
            sys.exit(1)
Esempio n. 50
0
def main():
    args = get_argparser().parse_args()
    init_logger(args)

    config = {
        "kc705": {
            "programmer":
            partial(ProgrammerXC7,
                    board="kc705",
                    proxy="bscan_spi_xc7k325t.bit"),
            "variants": ["nist_clock", "nist_qc2"],
            "gateware": ("spi0", 0x000000),
            "bootloader": ("spi0", 0xaf0000),
            "storage": ("spi0", 0xb30000),
            "firmware": ("spi0", 0xb40000),
        },
        "kasli": {
            "programmer":
            partial(ProgrammerXC7,
                    board="kasli",
                    proxy="bscan_spi_xc7a100t.bit"),
            "variants": ["opticlock", "master", "satellite"],
            "gateware": ("spi0", 0x000000),
            "bootloader": ("spi0", 0x400000),
            "storage": ("spi0", 0x440000),
            "firmware": ("spi0", 0x450000),
        },
        "sayma": {
            "programmer": ProgrammerSayma,
            "variants": ["standalone", "master", "satellite"],
            "gateware": ("spi0", 0x000000),
            "bootloader": ("spi1", 0x000000),
            "storage": ("spi1", 0x040000),
            "firmware": ("spi1", 0x050000),
        },
    }[args.target]

    variant = args.variant
    if "variants" in config:
        if variant is not None and variant not in config["variants"]:
            raise SystemExit("Invalid variant for this board")
        if variant is None:
            variant = config["variants"][0]

    bin_dir = args.dir
    if bin_dir is None:
        bin_name = args.target
        if variant:
            bin_name += "-" + variant
        bin_dir = os.path.join(artiq_dir, "binaries", bin_name)

    if args.host is None:
        client = LocalClient()
    else:
        client = SSHClient(args.host)

    programmer = config["programmer"](client,
                                      preinit_script=args.preinit_command)

    def artifact_path(*path_filename):
        if args.srcbuild is None:
            *path, filename = path_filename
            return os.path.join(bin_dir, filename)
        else:
            return os.path.join(args.srcbuild, *path_filename)

    try:
        for action in args.action:
            if action == "gateware":
                gateware_bin = artifact_path("gateware", "top.bin")
                if not os.access(gateware_bin, os.R_OK):
                    bin_handle, gateware_bin = tempfile.mkstemp()
                    gateware_bit = artifact_path("gateware", "top.bit")
                    with open(gateware_bit,
                              "rb") as bit_file, open(bin_handle,
                                                      "wb") as bin_file:
                        bit2bin(bit_file, bin_file)
                    atexit.register(lambda: os.unlink(gateware_bin))

                programmer.write_binary(*config["gateware"], gateware_bin)
            elif action == "bootloader":
                bootloader_bin = artifact_path("software", "bootloader",
                                               "bootloader.bin")
                programmer.write_binary(*config["bootloader"], bootloader_bin)
            elif action == "storage":
                storage_img = args.storage
                programmer.write_binary(*config["storage"], storage_img)
            elif action == "firmware":
                if variant == "satellite":
                    firmware = "satman"
                else:
                    firmware = "runtime"

                firmware_fbi = artifact_path("software", firmware,
                                             firmware + ".fbi")
                programmer.write_binary(*config["firmware"], firmware_fbi)
            elif action == "load":
                if args.target == "sayma":
                    rtm_gateware_bit = artifact_path("rtm_gateware", "rtm.bit")
                    programmer.load(rtm_gateware_bit, 0)
                    gateware_bit = artifact_path("gateware", "top.bit")
                    programmer.load(gateware_bit, 1)
                else:
                    gateware_bit = artifact_path("gateware", "top.bit")
                    programmer.load(gateware_bit, 0)
            elif action == "start":
                programmer.start()
            else:
                raise ValueError("invalid action", action)
    except FileNotFoundError as e:
        raise SystemExit(e)

    if args.dry_run:
        print("\n".join(programmer.script()))
    else:
        programmer.run()