mirror of https://github.com/m-labs/artiq.git
parent
2921bd6501
commit
b3831d3387
|
@ -89,6 +89,17 @@ class _DDSGeneric:
|
||||||
word."""
|
word."""
|
||||||
return pow/2**self.pow_width
|
return pow/2**self.pow_width
|
||||||
|
|
||||||
|
@portable
|
||||||
|
def amplitude_to_asf(self, amplitude):
|
||||||
|
"""Returns amplitude scale factor corresponding to given amplitude."""
|
||||||
|
return round(amplitude*0x0fff)
|
||||||
|
|
||||||
|
@portable
|
||||||
|
def asf_to_amplitude(self, asf):
|
||||||
|
"""Returns the amplitude corresponding to the given amplitude scale
|
||||||
|
factor."""
|
||||||
|
return round(amplitude*0x0fff)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def init(self):
|
def init(self):
|
||||||
"""Resets and initializes the DDS channel.
|
"""Resets and initializes the DDS channel.
|
||||||
|
@ -117,12 +128,14 @@ class _DDSGeneric:
|
||||||
self.phase_mode = phase_mode
|
self.phase_mode = phase_mode
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_mu(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT):
|
def set_mu(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT,
|
||||||
|
amplitude=0x0fff):
|
||||||
"""Sets the DDS channel to the specified frequency and phase.
|
"""Sets the DDS channel to the specified frequency and phase.
|
||||||
|
|
||||||
This uses machine units (FTW and POW). The frequency tuning word width
|
This uses machine units (FTW and POW). The frequency tuning word width
|
||||||
is 32, whereas the phase offset word width depends on the type of DDS
|
is 32, whereas the phase offset word width depends on the type of DDS
|
||||||
chip and can be retrieved via the ``pow_width`` attribute.
|
chip and can be retrieved via the ``pow_width`` attribute. The amplitude
|
||||||
|
width is 12.
|
||||||
|
|
||||||
:param frequency: frequency to generate.
|
:param frequency: frequency to generate.
|
||||||
:param phase: adds an offset, in turns, to the phase.
|
:param phase: adds an offset, in turns, to the phase.
|
||||||
|
@ -132,13 +145,15 @@ class _DDSGeneric:
|
||||||
if phase_mode == _PHASE_MODE_DEFAULT:
|
if phase_mode == _PHASE_MODE_DEFAULT:
|
||||||
phase_mode = self.phase_mode
|
phase_mode = self.phase_mode
|
||||||
syscall("dds_set", now_mu(), self.channel, frequency,
|
syscall("dds_set", now_mu(), self.channel, frequency,
|
||||||
phase, phase_mode)
|
phase, phase_mode, amplitude)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set(self, frequency, phase=0.0, phase_mode=_PHASE_MODE_DEFAULT):
|
def set(self, frequency, phase=0.0, phase_mode=_PHASE_MODE_DEFAULT,
|
||||||
|
amplitude=1.0):
|
||||||
"""Like ``set_mu``, but uses Hz and turns."""
|
"""Like ``set_mu``, but uses Hz and turns."""
|
||||||
self.set_mu(self.frequency_to_ftw(frequency),
|
self.set_mu(self.frequency_to_ftw(frequency),
|
||||||
self.turns_to_pow(phase), phase_mode)
|
self.turns_to_pow(phase), phase_mode,
|
||||||
|
self.amplitude_to_asf(amplitude))
|
||||||
|
|
||||||
|
|
||||||
class AD9858(_DDSGeneric):
|
class AD9858(_DDSGeneric):
|
||||||
|
|
|
@ -25,7 +25,7 @@ _syscalls = {
|
||||||
"dds_init": "Ii:n",
|
"dds_init": "Ii:n",
|
||||||
"dds_batch_enter": "I:n",
|
"dds_batch_enter": "I:n",
|
||||||
"dds_batch_exit": "n:n",
|
"dds_batch_exit": "n:n",
|
||||||
"dds_set": "Iiiii:n",
|
"dds_set": "Iiiiii:n",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#define DURATION_DAC_CAL (147000 << RTIO_FINE_TS_WIDTH)
|
#define DURATION_DAC_CAL (147000 << RTIO_FINE_TS_WIDTH)
|
||||||
/* not counting final FUD */
|
/* not counting final FUD */
|
||||||
#define DURATION_INIT (10*DURATION_WRITE + DURATION_DAC_CAL)
|
#define DURATION_INIT (10*DURATION_WRITE + DURATION_DAC_CAL)
|
||||||
#define DURATION_PROGRAM (5*DURATION_WRITE) /* not counting FUD */
|
#define DURATION_PROGRAM (6*DURATION_WRITE) /* not counting FUD */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error Unknown DDS configuration
|
#error Unknown DDS configuration
|
||||||
|
@ -94,7 +94,7 @@ void dds_init(long long int timestamp, int channel)
|
||||||
static unsigned int continuous_phase_comp[DDS_CHANNEL_COUNT];
|
static unsigned int continuous_phase_comp[DDS_CHANNEL_COUNT];
|
||||||
|
|
||||||
static void dds_set_one(long long int now, long long int ref_time, unsigned int channel,
|
static void dds_set_one(long long int now, long long int ref_time, unsigned int channel,
|
||||||
unsigned int ftw, unsigned int pow, int phase_mode)
|
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
|
||||||
{
|
{
|
||||||
unsigned int channel_enc;
|
unsigned int channel_enc;
|
||||||
|
|
||||||
|
@ -130,7 +130,8 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
|
||||||
DDS_WRITE(DDS_CFR2, 0x00);
|
DDS_WRITE(DDS_CFR2, 0x00);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DDS_AD9914
|
#ifdef DDS_AD9914
|
||||||
DDS_WRITE(DDS_CFR1L, 0x0008);
|
/* Disable autoclear phase accumulator and enables OSK. */
|
||||||
|
DDS_WRITE(DDS_CFR1L, 0x0108);
|
||||||
#endif
|
#endif
|
||||||
pow += continuous_phase_comp[channel];
|
pow += continuous_phase_comp[channel];
|
||||||
} else {
|
} else {
|
||||||
|
@ -141,7 +142,8 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
|
||||||
DDS_WRITE(DDS_CFR2, 0x40);
|
DDS_WRITE(DDS_CFR2, 0x40);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DDS_AD9914
|
#ifdef DDS_AD9914
|
||||||
DDS_WRITE(DDS_CFR1L, 0x2008);
|
/* Enable autoclear phase accumulator and enables OSK. */
|
||||||
|
DDS_WRITE(DDS_CFR1L, 0x2108);
|
||||||
#endif
|
#endif
|
||||||
fud_time = now + 2*DURATION_WRITE;
|
fud_time = now + 2*DURATION_WRITE;
|
||||||
pow -= (ref_time - fud_time)*DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH);
|
pow -= (ref_time - fud_time)*DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH);
|
||||||
|
@ -156,6 +158,9 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
|
||||||
#endif
|
#endif
|
||||||
#ifdef DDS_AD9914
|
#ifdef DDS_AD9914
|
||||||
DDS_WRITE(DDS_POW, pow);
|
DDS_WRITE(DDS_POW, pow);
|
||||||
|
#endif
|
||||||
|
#ifdef DDS_AD9914
|
||||||
|
DDS_WRITE(DDS_ASF, amplitude);
|
||||||
#endif
|
#endif
|
||||||
DDS_WRITE(DDS_FUD, 0);
|
DDS_WRITE(DDS_FUD, 0);
|
||||||
}
|
}
|
||||||
|
@ -165,6 +170,7 @@ struct dds_set_params {
|
||||||
unsigned int ftw;
|
unsigned int ftw;
|
||||||
unsigned int pow;
|
unsigned int pow;
|
||||||
int phase_mode;
|
int phase_mode;
|
||||||
|
unsigned int amplitude;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int batch_mode;
|
static int batch_mode;
|
||||||
|
@ -193,14 +199,15 @@ void dds_batch_exit(void)
|
||||||
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
|
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_ref_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,
|
||||||
|
batch[i].amplitude);
|
||||||
now += DURATION_PROGRAM + DURATION_WRITE;
|
now += DURATION_PROGRAM + DURATION_WRITE;
|
||||||
}
|
}
|
||||||
batch_mode = 0;
|
batch_mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dds_set(long long int timestamp, int channel,
|
void dds_set(long long int timestamp, int channel,
|
||||||
unsigned int ftw, unsigned int pow, int phase_mode)
|
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
|
||||||
{
|
{
|
||||||
if(batch_mode) {
|
if(batch_mode) {
|
||||||
if(batch_count >= DDS_MAX_BATCH)
|
if(batch_count >= DDS_MAX_BATCH)
|
||||||
|
@ -210,9 +217,11 @@ void dds_set(long long int timestamp, int channel,
|
||||||
batch[batch_count].ftw = ftw;
|
batch[batch_count].ftw = ftw;
|
||||||
batch[batch_count].pow = pow;
|
batch[batch_count].pow = pow;
|
||||||
batch[batch_count].phase_mode = phase_mode;
|
batch[batch_count].phase_mode = phase_mode;
|
||||||
|
batch[batch_count].amplitude = amplitude;
|
||||||
batch_count++;
|
batch_count++;
|
||||||
} else {
|
} else {
|
||||||
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,
|
||||||
|
amplitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,6 @@ void dds_init(long long int timestamp, int channel);
|
||||||
void dds_batch_enter(long long int timestamp);
|
void dds_batch_enter(long long int timestamp);
|
||||||
void dds_batch_exit(void);
|
void dds_batch_exit(void);
|
||||||
void dds_set(long long int timestamp, int channel,
|
void dds_set(long long int timestamp, int channel,
|
||||||
unsigned int ftw, unsigned int pow, int phase_mode);
|
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude);
|
||||||
|
|
||||||
#endif /* __DDS_H */
|
#endif /* __DDS_H */
|
||||||
|
|
Loading…
Reference in New Issue