diff --git a/artiq/coredevice/dds.py b/artiq/coredevice/dds.py index a1247b6cb..823c91f5f 100644 --- a/artiq/coredevice/dds.py +++ b/artiq/coredevice/dds.py @@ -100,15 +100,14 @@ class DDS(AutoContext): # Use soft timing on FUD to prevent conflicts when reprogramming # several channels that need to be turned on at the same time. rt_fud = merge or self.previous_on - ftw = self.frequency_to_ftw(frequency) if self.phase_mode != PHASE_MODE_CONTINUOUS: - phase_per_microcycle = ftw*int64( - self.dds_sysclk.amount*self.core.runtime_env.ref_period) + sysclk_per_microcycle = int(self.dds_sysclk* + self.core.ref_period) else: - phase_per_microcycle = int64(0) + sysclk_per_microcycle = 0 syscall("dds_program", time_to_cycles(now()), self.reg_channel, - ftw, int(phase_offset*2**14), - phase_per_microcycle, + self.frequency_to_ftw(frequency), int(phase_offset*2**14), + sysclk_per_microcycle, rt_fud, self.phase_mode == PHASE_MODE_TRACKING) self.previous_frequency = frequency self.sw.on() diff --git a/artiq/coredevice/runtime.py b/artiq/coredevice/runtime.py index 746892b96..c73d9a603 100644 --- a/artiq/coredevice/runtime.py +++ b/artiq/coredevice/runtime.py @@ -20,7 +20,7 @@ _syscalls = { "rtio_get": "iI:I", "rtio_pileup_count": "i:i", "dds_phase_clear_en": "ib:n", - "dds_program": "IiiiIbb:n", + "dds_program": "Iiiiibb:n", } _chr_to_type = { diff --git a/soc/runtime/dds.c b/soc/runtime/dds.c index ec7239a2a..029cd03da 100644 --- a/soc/runtime/dds.c +++ b/soc/runtime/dds.c @@ -41,22 +41,22 @@ void dds_phase_clear_en(int channel, int phase_clear_en) /* * DDS phase modes: - * - continuous: Set phase_per_microcycle=0 to disable POW alteration. + * - continuous: Set sysclk_per_microcycle=0 to disable POW alteration. * phase_tracking is ignored, set to 0. * Disable phase accumulator clearing prior to programming. - * - absolute: Set phase_per_microcycle to its nominal value + * - absolute: Set sysclk_per_microcycle to its nominal value * and phase_tracking=0. * Enable phase accumulator clearing prior to programming. - * - tracking: Set phase_per_microcycle to its nominal value + * - tracking: Set sysclk_per_microcycle to its nominal value * and phase_tracking=1. * Enable phase accumulator clearing prior to programming. */ void dds_program(long long int timestamp, int channel, - int ftw, int pow, long long int phase_per_microcycle, + unsigned int ftw, unsigned int pow, unsigned int sysclk_per_microcycle, int rt_fud, int phase_tracking) { long long int fud_time; - long long int phase_time_offset; + unsigned int phase_time_offset; rtio_fud_sync(); DDS_WRITE(DDS_GPIO, channel); @@ -71,9 +71,10 @@ void dds_program(long long int timestamp, int channel, fud_time = timestamp; else { fud_time = rtio_get_counter() + 8000; + /* POW is mod 2**14, so wraparound on negative values is OK */ phase_time_offset -= timestamp - fud_time; } - pow += phase_time_offset*phase_per_microcycle; + pow += phase_time_offset*ftw*sysclk_per_microcycle >> 18; DDS_WRITE(DDS_POW0, pow & 0xff); DDS_WRITE(DDS_POW1, (pow >> 8) & 0x3f); diff --git a/soc/runtime/dds.h b/soc/runtime/dds.h index 21db65131..b57adb82b 100644 --- a/soc/runtime/dds.h +++ b/soc/runtime/dds.h @@ -4,7 +4,7 @@ void dds_init(void); void dds_phase_clear_en(int channel, int phase_clear_en); void dds_program(long long int timestamp, int channel, - int ftw, int pow, long long int phase_per_microcycle, + unsigned int ftw, unsigned int pow, unsigned int sysclk_per_microcycle, int rt_fud, int phase_tracking); #endif /* __DDS_H */