diff --git a/artiq/examples/kasli_basic/repository/kasli_tester.py b/artiq/examples/kasli_basic/repository/kasli_tester.py new file mode 100644 index 000000000..8b199bc93 --- /dev/null +++ b/artiq/examples/kasli_basic/repository/kasli_tester.py @@ -0,0 +1,141 @@ +import sys +import select + +from artiq.experiment import * + + +def chunker(seq, size): + res = [] + for el in seq: + res.append(el) + if len(res) == size: + yield res + res = [] + if res: + yield res + + +def is_enter_pressed() -> TBool: + if select.select([sys.stdin,], [], [], 0.0)[0]: + sys.stdin.read(1) + return True + else: + return False + + +class KasliTester(EnvExperiment): + def build(self): + self.setattr_device("core") + + self.leds = dict() + self.ttl_outs = dict() + self.ttl_ins = dict() + + ddb = self.get_device_db() + for name, desc in ddb.items(): + if isinstance(desc, dict) and desc["type"] == "local": + module, cls = desc["module"], desc["class"] + if (module, cls) == ("artiq.coredevice.ttl", "TTLOut"): + dev = self.get_device(name) + if "led" in name: # guess + self.leds[name] = dev + else: + self.ttl_outs[name] = dev + elif (module, cls) == ("artiq.coredevice.ttl", "TTLInOut"): + self.ttl_ins[name] = self.get_device(name) + + # Remove Urukul control signals from TTL outs (tested separately) + ddb = self.get_device_db() + for name, desc in ddb.items(): + if isinstance(desc, dict) and desc["type"] == "local": + module, cls = desc["module"], desc["class"] + if ((module, cls) == ("artiq.coredevice.ad9910", "AD9910") + or (module, cls) == ("artiq.coredevice.ad9912", "AD9912")): + sw_device = desc["arguments"]["sw_device"] + del self.ttl_outs[sw_device] + if (module, cls) == ("artiq.coredevice.urukul", "CPLD"): + io_update_device = desc["arguments"]["io_update_device"] + del self.ttl_outs[io_update_device] + + # Sort everything by RTIO channel number + self.leds = sorted(self.leds.items(), key=lambda x: x[1].channel) + self.ttl_outs = sorted(self.ttl_outs.items(), key=lambda x: x[1].channel) + self.ttl_ins = sorted(self.ttl_ins.items(), key=lambda x: x[1].channel) + + @kernel + def test_led(self, led): + while not is_enter_pressed(): + self.core.break_realtime() + # do not fill the FIFOs too much to avoid long response times + t = now_mu() - self.core.seconds_to_mu(0.2) + while self.core.get_rtio_counter_mu() < t: + pass + for i in range(3): + led.pulse(100*ms) + delay(100*ms) + + def test_leds(self): + print("*** Testing LEDs.") + print("Check for blinking. Press ENTER when done.") + + for led_name, led_dev in self.leds: + print("Testing LED: {}".format(led_name)) + self.test_led(led_dev) + + @kernel + def test_ttl_out_chunk(self, ttl_chunk): + while not is_enter_pressed(): + self.core.break_realtime() + for _ in range(50000): + i = 0 + for ttl in ttl_chunk: + i += 1 + for _ in range(i): + ttl.pulse(1*us) + delay(1*us) + delay(10*us) + + def test_ttl_outs(self): + print("*** Testing TTL outputs.") + print("Outputs are tested in groups of 4. Touch each TTL connector") + print("with the oscilloscope probe tip, and check that the number of") + print("pulses corresponds to its number in the group.") + print("Press ENTER when done.") + + ttl_outs = list(self.ttl_outs) + for ttl_chunk in chunker(ttl_outs, 4): + print("Testing TTL outputs: {}.".format(", ".join(name for name, dev in ttl_chunk))) + self.test_ttl_out_chunk([dev for name, dev in ttl_chunk]) + + @kernel + def test_ttl_in(self, ttl_out, ttl_in): + n = 42 + self.core.break_realtime() + with parallel: + ttl_in.gate_rising(1*ms) + with sequential: + delay(50*us) + for _ in range(n): + ttl_out.pulse(2*us) + delay(2*us) + return ttl_in.count() == n + + def test_ttl_ins(self): + print("*** Testing TTL inputs.") + + ttl_out_name, ttl_out_dev = next(iter(self.ttl_outs)) + for ttl_in_name, ttl_in_dev in self.ttl_ins: + print("Connect {} to {}. Press ENTER when done." + .format(ttl_out_name, ttl_in_name)) + input() + if self.test_ttl_in(ttl_out_dev, ttl_in_dev): + print("PASSED") + else: + print("FAILED") + + def run(self): + print("****** Kasli system tester ******") + print("") + self.test_leds() + self.test_ttl_outs() + self.test_ttl_ins()