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
# 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()

View File

@ -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 = {

View File

@ -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);

View File

@ -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 */