forked from M-Labs/artiq
1
0
Fork 0

coredevice: rename rtio to ttl, integrated in+out driver, loopback on the same pin in tests

This commit is contained in:
Sebastien Bourdeauducq 2015-05-02 10:35:21 +08:00
parent 62669f9ff2
commit 65b4b7bb12
9 changed files with 121 additions and 111 deletions

View File

@ -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:

View File

@ -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",

View File

@ -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))

View File

@ -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 = []

View File

@ -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()

View File

@ -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}
},
}

View File

@ -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

View File

@ -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

View File

@ -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}
},