From 92efde1e406c5af54bee888f0da34daaa2cd2076 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 12 Sep 2014 15:36:17 +0800 Subject: [PATCH] devices/dds_core: support realtime FUD and zero-length pulse collapsing --- artiq/devices/dds_core.py | 49 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/artiq/devices/dds_core.py b/artiq/devices/dds_core.py index fd94a8cea..e842f38a8 100644 --- a/artiq/devices/dds_core.py +++ b/artiq/devices/dds_core.py @@ -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()