devices/dds_core: support realtime FUD and zero-length pulse collapsing

This commit is contained in:
Sebastien Bourdeauducq 2014-09-12 15:36:17 +08:00
parent a60e6237bf
commit 92efde1e40
1 changed files with 29 additions and 20 deletions

View File

@ -1,35 +1,44 @@
from artiq.language.core import *
from artiq.language.units import *
from artiq.devices import rtio_core
class DDS(AutoContext):
parameters = "dds_sysclk reg_channel rtio_channel"
def build(self):
self._previous_frequency = 0*MHz
self.previous_frequency = 0*MHz
self.sw = rtio_core.RTIOOut(self, channel=self.rtio_channel)
kernel_attr = "_previous_frequency"
@kernel
def _set_frequency(self, frequency):
if self._previous_frequency != frequency:
syscall("rtio_sync", self.rtio_channel) # wait until output is off
syscall("dds_program", self.reg_channel,
int(2**32*frequency/self.dds_sysclk))
self._previous_frequency = frequency
@kernel
def pulse(self, frequency, duration):
self._set_frequency(frequency)
syscall("rtio_set", now(), self.rtio_channel, 1)
delay(duration)
syscall("rtio_set", now(), self.rtio_channel, 0)
kernel_attr = "previous_frequency previous_timestamp"
@kernel
def on(self, frequency):
self._set_frequency(frequency)
syscall("rtio_set", now(), self.rtio_channel, 1)
if self.previous_frequency != frequency:
if self.sw.previous_timestamp != now():
self.sw.sync()
if self.sw.previous_value:
# Channel is already on.
# Precise timing of frequency change is required.
fud_time = now()
else:
# Channel is off.
# Use soft timing on FUD to prevent conflicts when
# reprogramming several channels that need to be turned on at
# the same time.
fud_time = -1
syscall("dds_program", self.reg_channel,
int(2**32*frequency/self.dds_sysclk),
fud_time)
self.previous_frequency = frequency
self.sw.on()
@kernel
def off(self):
syscall("rtio_set", now(), self.rtio_channel, 0)
self.sw.off()
@kernel
def pulse(self, frequency, duration):
self.on(frequency)
delay(duration)
self.off()