forked from M-Labs/artiq
1
0
Fork 0

dds: fix phase modes

This commit is contained in:
Sebastien Bourdeauducq 2014-12-09 13:50:33 +08:00
parent 9628e1d013
commit 059608d1fd
4 changed files with 14 additions and 14 deletions

View File

@ -100,15 +100,14 @@ class DDS(AutoContext):
# Use soft timing on FUD to prevent conflicts when reprogramming # Use soft timing on FUD to prevent conflicts when reprogramming
# several channels that need to be turned on at the same time. # several channels that need to be turned on at the same time.
rt_fud = merge or self.previous_on rt_fud = merge or self.previous_on
ftw = self.frequency_to_ftw(frequency)
if self.phase_mode != PHASE_MODE_CONTINUOUS: if self.phase_mode != PHASE_MODE_CONTINUOUS:
phase_per_microcycle = ftw*int64( sysclk_per_microcycle = int(self.dds_sysclk*
self.dds_sysclk.amount*self.core.runtime_env.ref_period) self.core.ref_period)
else: else:
phase_per_microcycle = int64(0) sysclk_per_microcycle = 0
syscall("dds_program", time_to_cycles(now()), self.reg_channel, syscall("dds_program", time_to_cycles(now()), self.reg_channel,
ftw, int(phase_offset*2**14), self.frequency_to_ftw(frequency), int(phase_offset*2**14),
phase_per_microcycle, sysclk_per_microcycle,
rt_fud, self.phase_mode == PHASE_MODE_TRACKING) rt_fud, self.phase_mode == PHASE_MODE_TRACKING)
self.previous_frequency = frequency self.previous_frequency = frequency
self.sw.on() self.sw.on()

View File

@ -20,7 +20,7 @@ _syscalls = {
"rtio_get": "iI:I", "rtio_get": "iI:I",
"rtio_pileup_count": "i:i", "rtio_pileup_count": "i:i",
"dds_phase_clear_en": "ib:n", "dds_phase_clear_en": "ib:n",
"dds_program": "IiiiIbb:n", "dds_program": "Iiiiibb:n",
} }
_chr_to_type = { _chr_to_type = {

View File

@ -41,22 +41,22 @@ void dds_phase_clear_en(int channel, int phase_clear_en)
/* /*
* DDS phase modes: * 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. * phase_tracking is ignored, set to 0.
* Disable phase accumulator clearing prior to programming. * 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. * and phase_tracking=0.
* Enable phase accumulator clearing prior to programming. * 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. * and phase_tracking=1.
* Enable phase accumulator clearing prior to programming. * Enable phase accumulator clearing prior to programming.
*/ */
void dds_program(long long int timestamp, int channel, 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) int rt_fud, int phase_tracking)
{ {
long long int fud_time; long long int fud_time;
long long int phase_time_offset; unsigned int phase_time_offset;
rtio_fud_sync(); rtio_fud_sync();
DDS_WRITE(DDS_GPIO, channel); DDS_WRITE(DDS_GPIO, channel);
@ -71,9 +71,10 @@ void dds_program(long long int timestamp, int channel,
fud_time = timestamp; fud_time = timestamp;
else { else {
fud_time = rtio_get_counter() + 8000; fud_time = rtio_get_counter() + 8000;
/* POW is mod 2**14, so wraparound on negative values is OK */
phase_time_offset -= timestamp - fud_time; 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_POW0, pow & 0xff);
DDS_WRITE(DDS_POW1, (pow >> 8) & 0x3f); DDS_WRITE(DDS_POW1, (pow >> 8) & 0x3f);

View File

@ -4,7 +4,7 @@
void dds_init(void); void dds_init(void);
void dds_phase_clear_en(int channel, int phase_clear_en); void dds_phase_clear_en(int channel, int phase_clear_en);
void dds_program(long long int timestamp, int channel, 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); int rt_fud, int phase_tracking);
#endif /* __DDS_H */ #endif /* __DDS_H */