forked from M-Labs/artiq
1
0
Fork 0

runtime/dds: send one FUD per command in a batch, compensate POW

This commit is contained in:
Sebastien Bourdeauducq 2015-05-09 17:26:36 +08:00
parent ce4b5739ed
commit 0ca42dbdbe
1 changed files with 20 additions and 16 deletions

View File

@ -6,8 +6,8 @@
#include "dds.h" #include "dds.h"
#define DURATION_WRITE 5 #define DURATION_WRITE 5
#define DURATION_INIT (8*DURATION_WRITE) #define DURATION_INIT (7*DURATION_WRITE) /* not counting FUD */
#define DURATION_PROGRAM (8*DURATION_WRITE) #define DURATION_PROGRAM (8*DURATION_WRITE) /* not counting FUD */
#define DDS_WRITE(addr, data) do { \ #define DDS_WRITE(addr, data) do { \
rtio_o_address_write(addr); \ rtio_o_address_write(addr); \
@ -25,7 +25,7 @@ void dds_init_all(void)
now = rtio_get_counter() + 10000; now = rtio_get_counter() + 10000;
for(i=0;i<DDS_CHANNEL_COUNT;i++) { for(i=0;i<DDS_CHANNEL_COUNT;i++) {
dds_init(now, i); dds_init(now, i);
now += DURATION_INIT; now += DURATION_INIT + DURATION_WRITE; /* + FUD time */
} }
while(rtio_get_counter() < now); while(rtio_get_counter() < now);
} }
@ -50,7 +50,7 @@ void dds_init(long long int timestamp, int channel)
DDS_WRITE(DDS_FUD, 0); DDS_WRITE(DDS_FUD, 0);
} }
static void dds_set_one(long long int now, long long int timestamp, int channel, static void dds_set_one(long long int now, long long int ref_time, int channel,
unsigned int ftw, unsigned int pow, int phase_mode) unsigned int ftw, unsigned int pow, int phase_mode)
{ {
DDS_WRITE(DDS_GPIO, channel); DDS_WRITE(DDS_GPIO, channel);
@ -67,11 +67,19 @@ static void dds_set_one(long long int now, long long int timestamp, int channel,
DDS_WRITE(DDS_FTW2, (ftw >> 16) & 0xff); DDS_WRITE(DDS_FTW2, (ftw >> 16) & 0xff);
DDS_WRITE(DDS_FTW3, (ftw >> 24) & 0xff); DDS_WRITE(DDS_FTW3, (ftw >> 24) & 0xff);
if(phase_mode == PHASE_MODE_TRACKING)
/* We assume that the RTIO clock is DDS SYNCLK */ /* We assume that the RTIO clock is DDS SYNCLK */
pow += (timestamp >> RTIO_FINE_TS_WIDTH)*ftw >> 18; if(phase_mode == PHASE_MODE_TRACKING)
pow += (ref_time >> RTIO_FINE_TS_WIDTH)*ftw >> 18;
if(phase_mode != PHASE_MODE_CONTINUOUS) {
long long int fud_time;
fud_time = now + 2*DURATION_WRITE;
pow -= ((ref_time - fud_time) >> RTIO_FINE_TS_WIDTH)*ftw >> 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);
DDS_WRITE(DDS_FUD, 0);
} }
struct dds_set_params { struct dds_set_params {
@ -83,7 +91,7 @@ struct dds_set_params {
static int batch_mode; static int batch_mode;
static int batch_count; static int batch_count;
static long long int batch_fud_time; static long long int batch_ref_time;
static struct dds_set_params batch[DDS_MAX_BATCH]; static struct dds_set_params batch[DDS_MAX_BATCH];
void dds_batch_enter(long long int timestamp) void dds_batch_enter(long long int timestamp)
@ -92,7 +100,7 @@ void dds_batch_enter(long long int timestamp)
exception_raise(EID_DDS_BATCH_ERROR); exception_raise(EID_DDS_BATCH_ERROR);
batch_mode = 1; batch_mode = 1;
batch_count = 0; batch_count = 0;
batch_fud_time = timestamp; batch_ref_time = timestamp;
} }
void dds_batch_exit(void) void dds_batch_exit(void)
@ -103,13 +111,13 @@ void dds_batch_exit(void)
if(!batch_mode) if(!batch_mode)
exception_raise(EID_DDS_BATCH_ERROR); exception_raise(EID_DDS_BATCH_ERROR);
rtio_chan_sel_write(RTIO_DDS_CHANNEL); rtio_chan_sel_write(RTIO_DDS_CHANNEL);
now = batch_fud_time - batch_count*DURATION_PROGRAM; /* + FUD time */
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
for(i=0;i<batch_count;i++) { for(i=0;i<batch_count;i++) {
dds_set_one(now, batch_fud_time, dds_set_one(now, batch_ref_time,
batch[i].channel, batch[i].ftw, batch[i].pow, batch[i].phase_mode); batch[i].channel, batch[i].ftw, batch[i].pow, batch[i].phase_mode);
now += DURATION_PROGRAM; now += DURATION_PROGRAM + DURATION_WRITE;
} }
DDS_WRITE(DDS_FUD, 0);
batch_mode = 0; batch_mode = 0;
} }
@ -126,11 +134,7 @@ void dds_set(long long int timestamp, int channel,
batch[batch_count].phase_mode = phase_mode; batch[batch_count].phase_mode = phase_mode;
batch_count++; batch_count++;
} else { } else {
long long int now;
rtio_chan_sel_write(RTIO_DDS_CHANNEL); rtio_chan_sel_write(RTIO_DDS_CHANNEL);
dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode); dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode);
now = timestamp;
DDS_WRITE(DDS_FUD, 0);
} }
} }