forked from M-Labs/artiq
coredevice: rename rtio to ttl, integrated in+out driver, loopback on the same pin in tests
This commit is contained in:
parent
62669f9ff2
commit
65b4b7bb12
|
@ -1,7 +1,7 @@
|
|||
from artiq.language.core import *
|
||||
from artiq.language.db import *
|
||||
from artiq.language.units import *
|
||||
from artiq.coredevice import rtio
|
||||
from artiq.coredevice import ttl
|
||||
|
||||
|
||||
PHASE_MODE_DEFAULT = -1
|
||||
|
@ -14,7 +14,7 @@ class DDS(AutoDB):
|
|||
"""Core device Direct Digital Synthesis (DDS) driver.
|
||||
|
||||
Controls DDS devices managed directly by the core device's runtime. It also
|
||||
uses a RTIO channel (through :class:`artiq.coredevice.rtio.RTIOOut`) to
|
||||
uses a RTIO TTL channel (through :class:`artiq.coredevice.ttl.TTLOut`) to
|
||||
control a RF switch that gates the output of the DDS device.
|
||||
|
||||
:param dds_sysclk: DDS system frequency, used for computing the frequency
|
||||
|
@ -34,7 +34,7 @@ class DDS(AutoDB):
|
|||
self.previous_on = False
|
||||
self.previous_frequency = 0*MHz
|
||||
self.set_phase_mode(PHASE_MODE_CONTINUOUS)
|
||||
self.sw = rtio.RTIOOut(core=self.core, channel=self.rtio_switch)
|
||||
self.sw = ttl.TTLOut(core=self.core, channel=self.rtio_switch)
|
||||
|
||||
@portable
|
||||
def frequency_to_ftw(self, frequency):
|
||||
|
@ -93,7 +93,7 @@ class DDS(AutoDB):
|
|||
self.set_phase_mode(phase_mode)
|
||||
|
||||
if self.previous_frequency != frequency:
|
||||
merge = self.sw.previous_timestamp == time_to_cycles(now())
|
||||
merge = self.sw.o_previous_timestamp == time_to_cycles(now())
|
||||
if not merge:
|
||||
self.sw.sync()
|
||||
# Channel is already on:
|
||||
|
|
|
@ -14,7 +14,7 @@ llvm.initialize_all_asmprinters()
|
|||
_syscalls = {
|
||||
"watchdog_set": "i:i",
|
||||
"watchdog_clear": "i:n",
|
||||
"rtio_set_o": "Iii:n",
|
||||
"rtio_set_o": "Iib:n",
|
||||
"rtio_set_oe": "Iib:n",
|
||||
"rtio_set_sensitivity": "Iii:n",
|
||||
"rtio_get_counter": "n:I",
|
||||
|
|
|
@ -2,26 +2,21 @@ from artiq.language.core import *
|
|||
from artiq.language.db import *
|
||||
|
||||
|
||||
class LLRTIOOut(AutoDB):
|
||||
"""Low-level RTIO output driver.
|
||||
class LLTTLOut(AutoDB):
|
||||
"""Low-level RTIO TTL output driver.
|
||||
|
||||
Allows setting RTIO outputs at arbitrary times, without time unit
|
||||
conversion.
|
||||
Allows setting RTIO TTL outputs at arbitrary times, without time
|
||||
unit conversion.
|
||||
|
||||
This is meant to be used mostly in drivers; consider using
|
||||
``RTIOOut`` instead.
|
||||
``TTLOut`` instead.
|
||||
|
||||
This should be used with output-only channels.
|
||||
"""
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
channel = Argument()
|
||||
|
||||
def build(self):
|
||||
self._set_oe()
|
||||
|
||||
@kernel
|
||||
def _set_oe(self):
|
||||
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, True)
|
||||
|
||||
@kernel
|
||||
def set_o(self, t, value):
|
||||
"""Sets the output value of the RTIO channel.
|
||||
|
@ -37,7 +32,7 @@ class LLRTIOOut(AutoDB):
|
|||
|
||||
:param t: timestamp in RTIO cycles (64-bit integer).
|
||||
"""
|
||||
self.set_o(t, 1)
|
||||
self.set_o(t, True)
|
||||
|
||||
@kernel
|
||||
def off(self, t):
|
||||
|
@ -45,19 +40,13 @@ class LLRTIOOut(AutoDB):
|
|||
|
||||
:param t: timestamp in RTIO cycles (64-bit integer).
|
||||
"""
|
||||
self.set_o(t, 0)
|
||||
self.set_o(t, False)
|
||||
|
||||
|
||||
class RTIOOut(AutoDB):
|
||||
"""RTIO output driver.
|
||||
class TTLOut(AutoDB):
|
||||
"""RTIO TTL output driver.
|
||||
|
||||
Configures the corresponding RTIO channel as output on the core device and
|
||||
provides functions to set its level.
|
||||
|
||||
This driver supports zero-length transition suppression. For example, if
|
||||
two pulses are emitted back-to-back with no delay between them, they will
|
||||
be merged into a single pulse with a duration equal to the sum of the
|
||||
durations of the original pulses.
|
||||
This should be used with output-only channels.
|
||||
|
||||
:param core: core device
|
||||
:param channel: channel number
|
||||
|
@ -66,39 +55,31 @@ class RTIOOut(AutoDB):
|
|||
core = Device()
|
||||
channel = Argument()
|
||||
|
||||
|
||||
def build(self):
|
||||
self.previous_timestamp = int64(0) # in RTIO cycles
|
||||
self._set_oe()
|
||||
# in RTIO cycles
|
||||
self.o_previous_timestamp = int64(0)
|
||||
|
||||
@kernel
|
||||
def _set_oe(self):
|
||||
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, True)
|
||||
|
||||
@kernel
|
||||
def _set_o(self, value):
|
||||
syscall("rtio_set_o", time_to_cycles(now()), self.channel, value)
|
||||
self.previous_timestamp = time_to_cycles(now())
|
||||
def _set_o(self, o):
|
||||
syscall("rtio_set_o", time_to_cycles(now()), self.channel, o)
|
||||
self.o_previous_timestamp = time_to_cycles(now())
|
||||
|
||||
@kernel
|
||||
def sync(self):
|
||||
"""Busy-waits until all programmed level switches have been effected.
|
||||
|
||||
This function is useful to synchronize CPU-controlled devices (such as
|
||||
the AD9858 DDS bus) with related RTIO controls (such as RF switches at
|
||||
the output of the DDS).
|
||||
"""
|
||||
while syscall("rtio_get_counter") < self.previous_timestamp:
|
||||
"""Busy-waits until all programmed level switches have been effected."""
|
||||
while syscall("rtio_get_counter") < self.o_previous_timestamp:
|
||||
pass
|
||||
|
||||
@kernel
|
||||
def on(self):
|
||||
"""Sets the output to a logic high state."""
|
||||
self._set_o(1)
|
||||
self._set_o(True)
|
||||
|
||||
@kernel
|
||||
def off(self):
|
||||
"""Sets the output to a logic low state."""
|
||||
self._set_o(0)
|
||||
self._set_o(False)
|
||||
|
||||
@kernel
|
||||
def pulse(self, duration):
|
||||
|
@ -108,12 +89,20 @@ class RTIOOut(AutoDB):
|
|||
self.off()
|
||||
|
||||
|
||||
class RTIOIn(AutoDB):
|
||||
"""RTIO input driver.
|
||||
class TTLInOut(AutoDB):
|
||||
"""RTIO TTL input/output driver.
|
||||
|
||||
Configures the corresponding RTIO channel as input on the core device and
|
||||
provides functions to analyze the incoming signal, with real-time gating
|
||||
to prevent overflows.
|
||||
In output mode, provides functions to set the logic level on the signal.
|
||||
|
||||
In input mode, provides functions to analyze the incoming signal, with
|
||||
real-time gating to prevent overflows.
|
||||
|
||||
RTIO TTLs supports zero-length transition suppression. For example, if
|
||||
two pulses are emitted back-to-back with no delay between them, they will
|
||||
be merged into a single pulse with a duration equal to the sum of the
|
||||
durations of the original pulses.
|
||||
|
||||
This should be used with bidirectional channels.
|
||||
|
||||
:param core: core device
|
||||
:param channel: channel number
|
||||
|
@ -123,17 +112,54 @@ class RTIOIn(AutoDB):
|
|||
channel = Argument()
|
||||
|
||||
def build(self):
|
||||
self.previous_timestamp = int64(0) # in RTIO cycles
|
||||
self._set_oe()
|
||||
# in RTIO cycles
|
||||
self.o_previous_timestamp = int64(0)
|
||||
self.i_previous_timestamp = int64(0)
|
||||
|
||||
@kernel
|
||||
def _set_oe(self):
|
||||
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, False)
|
||||
def _set_oe(self, oe):
|
||||
syscall("rtio_set_oe", time_to_cycles(now()), self.channel, oe)
|
||||
|
||||
@kernel
|
||||
def output(self):
|
||||
self._set_oe(True)
|
||||
|
||||
@kernel
|
||||
def input(self):
|
||||
self._set_oe(False)
|
||||
|
||||
@kernel
|
||||
def _set_o(self, o):
|
||||
syscall("rtio_set_o", time_to_cycles(now()), self.channel, o)
|
||||
self.o_previous_timestamp = time_to_cycles(now())
|
||||
|
||||
@kernel
|
||||
def sync(self):
|
||||
"""Busy-waits until all programmed level switches have been effected."""
|
||||
while syscall("rtio_get_counter") < self.o_previous_timestamp:
|
||||
pass
|
||||
|
||||
@kernel
|
||||
def on(self):
|
||||
"""Sets the output to a logic high state."""
|
||||
self._set_o(True)
|
||||
|
||||
@kernel
|
||||
def off(self):
|
||||
"""Sets the output to a logic low state."""
|
||||
self._set_o(False)
|
||||
|
||||
@kernel
|
||||
def pulse(self, duration):
|
||||
"""Pulses the output high for the specified duration."""
|
||||
self.on()
|
||||
delay(duration)
|
||||
self.off()
|
||||
|
||||
@kernel
|
||||
def _set_sensitivity(self, value):
|
||||
syscall("rtio_set_sensitivity", time_to_cycles(now()), self.channel, value)
|
||||
self.previous_timestamp = time_to_cycles(now())
|
||||
self.i_previous_timestamp = time_to_cycles(now())
|
||||
|
||||
@kernel
|
||||
def gate_rising(self, duration):
|
||||
|
@ -162,7 +188,8 @@ class RTIOIn(AutoDB):
|
|||
"""Poll the RTIO input during all the previously programmed gate
|
||||
openings, and returns the number of registered events."""
|
||||
count = 0
|
||||
while syscall("rtio_get", self.channel, self.previous_timestamp) >= 0:
|
||||
while syscall("rtio_get", self.channel,
|
||||
self.i_previous_timestamp) >= 0:
|
||||
count += 1
|
||||
return count
|
||||
|
||||
|
@ -174,4 +201,4 @@ class RTIOIn(AutoDB):
|
|||
If the gate is permanently closed, returns a negative value.
|
||||
"""
|
||||
return cycles_to_time(syscall("rtio_get", self.channel,
|
||||
self.previous_timestamp))
|
||||
self.i_previous_timestamp))
|
|
@ -1,7 +1,7 @@
|
|||
from artiq.language.core import *
|
||||
from artiq.language.db import *
|
||||
from artiq.language.units import *
|
||||
from artiq.coredevice import rtio
|
||||
from artiq.coredevice import ttl
|
||||
|
||||
|
||||
frame_setup = 20*ns
|
||||
|
@ -162,13 +162,13 @@ class CompoundPDQ2(AutoDB):
|
|||
|
||||
def build(self):
|
||||
self.pdq2s = [self.dbh.get_device(d) for d in self.pdq2_devices]
|
||||
self.trigger = rtio.LLRTIOOut(
|
||||
self.trigger = ttl.LLTTLOut(
|
||||
core=self.core, channel=self.rtio_trigger)
|
||||
self.frame0 = rtio.LLRTIOOut(
|
||||
self.frame0 = ttl.LLTTLOut(
|
||||
core=self.core, channel=self.rtio_frame[0])
|
||||
self.frame1 = rtio.LLRTIOOut(
|
||||
self.frame1 = ttl.LLTTLOut(
|
||||
core=self.core, channel=self.rtio_frame[1])
|
||||
self.frame2 = rtio.LLRTIOOut(
|
||||
self.frame2 = ttl.LLTTLOut(
|
||||
core=self.core, channel=self.rtio_frame[2])
|
||||
|
||||
self.frames = []
|
||||
|
|
|
@ -5,7 +5,7 @@ from fractions import Fraction
|
|||
|
||||
from artiq import *
|
||||
from artiq.language.units import DimensionError
|
||||
from artiq.coredevice import comm_tcp, core, runtime_exceptions, rtio
|
||||
from artiq.coredevice import comm_tcp, core, runtime_exceptions, ttl
|
||||
from artiq.sim import devices as sim_devices
|
||||
|
||||
|
||||
|
@ -281,8 +281,7 @@ class ExecutionCase(unittest.TestCase):
|
|||
class _RTIOLoopback(AutoDB):
|
||||
class DBKeys:
|
||||
core = Device()
|
||||
i = Device()
|
||||
o = Device()
|
||||
io = Device()
|
||||
npulses = Argument()
|
||||
|
||||
def report(self, n):
|
||||
|
@ -290,13 +289,15 @@ class _RTIOLoopback(AutoDB):
|
|||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.io.output()
|
||||
delay(1*us)
|
||||
with parallel:
|
||||
self.io.gate_rising(10*us)
|
||||
with sequential:
|
||||
for i in range(self.npulses):
|
||||
delay(25*ns)
|
||||
self.o.pulse(25*ns)
|
||||
self.i.gate_rising(10*us)
|
||||
self.report(self.i.count())
|
||||
self.io.pulse(25*ns)
|
||||
self.report(self.io.count())
|
||||
|
||||
|
||||
class _RTIOUnderflow(AutoDB):
|
||||
|
@ -335,8 +336,7 @@ class RTIOCase(unittest.TestCase):
|
|||
coredev = core.Core(comm=comm)
|
||||
uut = _RTIOLoopback(
|
||||
core=coredev,
|
||||
i=rtio.RTIOIn(core=coredev, channel=0),
|
||||
o=rtio.RTIOOut(core=coredev, channel=2),
|
||||
io=ttl.TTLInOut(core=coredev, channel=0),
|
||||
npulses=npulses
|
||||
)
|
||||
uut.run()
|
||||
|
@ -350,7 +350,7 @@ class RTIOCase(unittest.TestCase):
|
|||
coredev = core.Core(comm=comm)
|
||||
uut = _RTIOUnderflow(
|
||||
core=coredev,
|
||||
o=rtio.RTIOOut(core=coredev, channel=2)
|
||||
o=ttl.TTLOut(core=coredev, channel=2)
|
||||
)
|
||||
with self.assertRaises(runtime_exceptions.RTIOUnderflow):
|
||||
uut.run()
|
||||
|
@ -363,7 +363,7 @@ class RTIOCase(unittest.TestCase):
|
|||
coredev = core.Core(comm=comm)
|
||||
uut = _RTIOSequenceError(
|
||||
core=coredev,
|
||||
o=rtio.RTIOOut(core=coredev, channel=2)
|
||||
o=ttl.TTLOut(core=coredev, channel=2)
|
||||
)
|
||||
with self.assertRaises(runtime_exceptions.RTIOSequenceError):
|
||||
uut.run()
|
||||
|
|
|
@ -14,33 +14,15 @@
|
|||
|
||||
"pmt0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOIn",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 0}
|
||||
},
|
||||
"pmt1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOIn",
|
||||
"arguments": {"channel": 1}
|
||||
},
|
||||
|
||||
"ttl0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 2}
|
||||
},
|
||||
"ttl1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"arguments": {"channel": 3}
|
||||
},
|
||||
"ttl2": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"arguments": {"channel": 4}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -11,17 +11,18 @@ class RTIOSkew(Experiment, AutoDB):
|
|||
class DBKeys:
|
||||
core = Device()
|
||||
pmt0 = Device()
|
||||
ttl0 = Device()
|
||||
rtio_skew = Result()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.pmt0.output()
|
||||
delay(1*us)
|
||||
with parallel:
|
||||
self.pmt0.gate_rising(10*us)
|
||||
with sequential:
|
||||
delay(5*us)
|
||||
out_t = now()
|
||||
self.ttl0.pulse(5*us)
|
||||
self.pmt0.pulse(5*us)
|
||||
in_t = self.pmt0.timestamp()
|
||||
if in_t < 0*s:
|
||||
raise PulseNotReceived
|
||||
|
|
|
@ -3,10 +3,10 @@ Core drivers reference
|
|||
|
||||
These drivers are for peripherals closely integrated into the core device, which do not use the controller mechanism.
|
||||
|
||||
:mod:`artiq.coredevice.rtio` module
|
||||
:mod:`artiq.coredevice.ttl` module
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: artiq.coredevice.rtio
|
||||
.. automodule:: artiq.coredevice.ttl
|
||||
:members:
|
||||
|
||||
:mod:`artiq.coredevice.dds` module
|
||||
|
|
|
@ -14,39 +14,39 @@
|
|||
|
||||
"pmt0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOIn",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 0}
|
||||
},
|
||||
"pmt1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOIn",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 1}
|
||||
},
|
||||
|
||||
"ttl0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 2}
|
||||
},
|
||||
"ttl1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 3}
|
||||
},
|
||||
"ttl2": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 4}
|
||||
},
|
||||
"led": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.rtio",
|
||||
"class": "RTIOOut",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLOut",
|
||||
"arguments": {"channel": 18}
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue