artiq/artiq/coredevice/ttl.py

207 lines
5.5 KiB
Python
Raw Normal View History

2014-09-12 15:28:02 +08:00
from artiq.language.core import *
from artiq.language.db import *
2014-09-12 15:28:02 +08:00
class TTLOut(AutoDB):
"""RTIO TTL output driver.
This should be used with output-only channels.
:param core: core device
:param channel: channel number
"""
2015-04-14 19:44:45 +08:00
class DBKeys:
core = Device()
channel = Argument()
def build(self):
# in RTIO cycles
self.o_previous_timestamp = int64(0)
2015-04-14 19:44:45 +08:00
@kernel
2015-07-02 04:22:53 +08:00
def set_o(self, o):
syscall("ttl_set_o", now_mu(), self.channel, o)
self.o_previous_timestamp = now_mu()
2014-09-12 15:28:02 +08:00
@kernel
def sync(self):
"""Busy-waits until all programmed level switches have been effected."""
while syscall("rtio_get_counter") < self.o_previous_timestamp:
2014-11-30 00:13:54 +08:00
pass
2014-09-12 15:28:02 +08:00
@kernel
def on(self):
2015-04-14 19:44:45 +08:00
"""Sets the output to a logic high state."""
2015-07-02 04:22:53 +08:00
self.set_o(True)
2014-09-12 15:28:02 +08:00
@kernel
def off(self):
2015-04-14 19:44:45 +08:00
"""Sets the output to a logic low state."""
2015-07-02 04:22:53 +08:00
self.set_o(False)
@kernel
def pulse_mu(self, duration):
"""Pulses the output high for the specified duration
(in machine units)."""
self.on()
delay_mu(duration)
self.off()
2014-09-12 15:28:02 +08:00
@kernel
def pulse(self, duration):
2015-07-02 04:22:53 +08:00
"""Pulses the output high for the specified duration
(in seconds)."""
2014-09-12 15:28:02 +08:00
self.on()
delay(duration)
self.off()
2014-09-13 19:37:57 +08:00
class TTLInOut(AutoDB):
"""RTIO TTL input/output driver.
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
"""
2015-04-14 19:44:45 +08:00
class DBKeys:
core = Device()
channel = Argument()
def build(self):
# in RTIO cycles
self.o_previous_timestamp = int64(0)
self.i_previous_timestamp = int64(0)
2015-04-14 19:44:45 +08:00
@kernel
2015-07-02 04:22:53 +08:00
def set_oe(self, oe):
syscall("ttl_set_oe", now_mu(), self.channel, oe)
@kernel
def output(self):
2015-07-02 04:22:53 +08:00
self.set_oe(True)
@kernel
def input(self):
2015-07-02 04:22:53 +08:00
self.set_oe(False)
@kernel
2015-07-02 04:22:53 +08:00
def set_o(self, o):
syscall("ttl_set_o", now_mu(), self.channel, o)
self.o_previous_timestamp = now_mu()
@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."""
2015-07-02 04:22:53 +08:00
self.set_o(True)
@kernel
def off(self):
"""Sets the output to a logic low state."""
2015-07-02 04:22:53 +08:00
self.set_o(False)
@kernel
def pulse_mu(self, duration):
"""Pulses the output high for the specified duration
(in machine units)."""
self.on()
delay_mu(duration)
self.off()
@kernel
def pulse(self, duration):
2015-07-02 04:22:53 +08:00
"""Pulses the output high for the specified duration
(in seconds)."""
self.on()
delay(duration)
self.off()
2015-04-14 19:44:45 +08:00
@kernel
def _set_sensitivity(self, value):
2015-07-02 04:22:53 +08:00
syscall("ttl_set_sensitivity", now_mu(), self.channel, value)
self.i_previous_timestamp = now_mu()
@kernel
def gate_rising_mu(self, duration):
"""Register rising edge events for the specified duration
(in machine units)."""
self._set_sensitivity(1)
delay_mu(duration)
self._set_sensitivity(0)
@kernel
def gate_falling_mu(self, duration):
"""Register falling edge events for the specified duration
(in machine units)."""
self._set_sensitivity(2)
delay_mu(duration)
self._set_sensitivity(0)
@kernel
def gate_both_mu(self, duration):
"""Register both rising and falling edge events for the specified
duration (in machine units)."""
self._set_sensitivity(3)
delay_mu(duration)
self._set_sensitivity(0)
2014-09-13 19:37:57 +08:00
@kernel
def gate_rising(self, duration):
2015-07-02 04:22:53 +08:00
"""Register rising edge events for the specified duration
(in seconds)."""
2015-04-14 19:44:45 +08:00
self._set_sensitivity(1)
delay(duration)
2015-04-14 19:44:45 +08:00
self._set_sensitivity(0)
@kernel
def gate_falling(self, duration):
2015-07-02 04:22:53 +08:00
"""Register falling edge events for the specified duration
(in seconds)."""
2015-04-14 19:44:45 +08:00
self._set_sensitivity(2)
delay(duration)
2015-04-14 19:44:45 +08:00
self._set_sensitivity(0)
@kernel
2015-07-02 04:22:53 +08:00
def gate_both_mu(self, duration):
"""Register both rising and falling edge events for the specified
2015-07-02 04:22:53 +08:00
duration (in seconds)."""
2015-04-14 19:44:45 +08:00
self._set_sensitivity(3)
delay(duration)
2015-04-14 19:44:45 +08:00
self._set_sensitivity(0)
2014-10-21 23:14:01 +08:00
2014-09-13 19:37:57 +08:00
@kernel
def count(self):
"""Poll the RTIO input during all the previously programmed gate
openings, and returns the number of registered events."""
count = 0
while syscall("ttl_get", self.channel,
self.i_previous_timestamp) >= 0:
count += 1
return count
2014-10-14 15:54:10 +08:00
@kernel
def timestamp(self):
"""Poll the RTIO input and returns an event timestamp, according to
the gating.
If the gate is permanently closed, returns a negative value.
"""
2015-07-02 04:22:53 +08:00
return syscall("ttl_get", self.channel, self.i_previous_timestamp)