Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2921bd65019f
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: eb554f86f978
Choose a head ref
  • 3 commits
  • 5 files changed
  • 2 contributors

Commits on Sep 5, 2015

  1. dds: support amplitude tuning on AD9914

    Closes #108
    Raghavendra Srinivas authored and sbourdeauducq committed Sep 5, 2015
    Copy the full SHA
    b3831d3 View commit details
  2. Copy the full SHA
    d621780 View commit details
  3. Copy the full SHA
    eb554f8 View commit details
Showing with 59 additions and 20 deletions.
  1. +20 −5 artiq/coredevice/dds.py
  2. +1 −1 artiq/coredevice/runtime.py
  3. +11 −5 artiq/language/scan.py
  4. +26 −8 soc/runtime/dds.c
  5. +1 −1 soc/runtime/dds.h
25 changes: 20 additions & 5 deletions artiq/coredevice/dds.py
Original file line number Diff line number Diff line change
@@ -89,6 +89,17 @@ def pow_to_turns(self, pow):
word."""
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
def init(self):
"""Resets and initializes the DDS channel.
@@ -117,12 +128,14 @@ def set_phase_mode(self, phase_mode):
self.phase_mode = phase_mode

@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.
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
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 phase: adds an offset, in turns, to the phase.
@@ -132,13 +145,15 @@ def set_mu(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT):
if phase_mode == _PHASE_MODE_DEFAULT:
phase_mode = self.phase_mode
syscall("dds_set", now_mu(), self.channel, frequency,
phase, phase_mode)
phase, phase_mode, amplitude)

@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."""
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):
2 changes: 1 addition & 1 deletion artiq/coredevice/runtime.py
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@
"dds_init": "Ii:n",
"dds_batch_enter": "I:n",
"dds_batch_exit": "n:n",
"dds_set": "Iiiii:n",
"dds_set": "Iiiiii:n",
}


16 changes: 11 additions & 5 deletions artiq/language/scan.py
Original file line number Diff line number Diff line change
@@ -25,10 +25,16 @@
from artiq.language.environment import NoDefault, DefaultMissing


__all__ = ["NoScan", "LinearScan", "RandomScan", "ExplicitScan", "Scannable"]
__all__ = ["ScanObject",
"NoScan", "LinearScan", "RandomScan", "ExplicitScan",
"Scannable"]


class NoScan:
class ScanObject:
pass


class NoScan(ScanObject):
"""A scan object that yields a single value."""
def __init__(self, value):
self.value = value
@@ -45,7 +51,7 @@ def describe(self):
return {"ty": "NoScan", "value": self.value}


class LinearScan:
class LinearScan(ScanObject):
"""A scan object that yields a fixed number of increasing evenly
spaced values in a range."""
def __init__(self, min, max, npoints):
@@ -69,7 +75,7 @@ def describe(self):
"min": self.min, "max": self.max, "npoints": self.npoints}


class RandomScan:
class RandomScan(ScanObject):
"""A scan object that yields a fixed number of randomly ordered evenly
spaced values in a range."""
def __init__(self, min, max, npoints, seed=0):
@@ -85,7 +91,7 @@ def describe(self):
"min": self.min, "max": self.max, "npoints": self.npoints}


class ExplicitScan:
class ExplicitScan(ScanObject):
"""A scan object that yields values from an explicitly defined sequence."""
def __init__(self, sequence):
self.sequence = sequence
34 changes: 26 additions & 8 deletions soc/runtime/dds.c
Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@
/* DAC calibration takes max. 1ms as per datasheet */
#define DURATION_DAC_CAL (147000 << RTIO_FINE_TS_WIDTH)
/* not counting final FUD */
#define DURATION_INIT (10*DURATION_WRITE + DURATION_DAC_CAL)
#define DURATION_PROGRAM (5*DURATION_WRITE) /* not counting FUD */
#define DURATION_INIT (8*DURATION_WRITE + DURATION_DAC_CAL)
#define DURATION_PROGRAM (6*DURATION_WRITE) /* not counting FUD */

#else
#error Unknown DDS configuration
@@ -59,8 +59,17 @@ void dds_init(long long int timestamp, int channel)
#endif
channel <<= 1;
DDS_WRITE(DDS_GPIO, channel);
#ifndef DDS_AD9914
/*
* Resetting a AD9914 intermittently crashes it. It does not produce any
* output until power-cycled.
* Increasing the reset pulse length and the delay until the first write
* to 300ns do not solve the problem.
* The chips seem fine without a reset.
*/
DDS_WRITE(DDS_GPIO, channel | 1); /* reset */
DDS_WRITE(DDS_GPIO, channel);
#endif

#ifdef DDS_AD9858
/*
@@ -94,7 +103,7 @@ void dds_init(long long int timestamp, int channel)
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,
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;

@@ -130,7 +139,8 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
DDS_WRITE(DDS_CFR2, 0x00);
#endif
#ifdef DDS_AD9914
DDS_WRITE(DDS_CFR1L, 0x0008);
/* Disable autoclear phase accumulator and enables OSK. */
DDS_WRITE(DDS_CFR1L, 0x0108);
#endif
pow += continuous_phase_comp[channel];
} else {
@@ -141,7 +151,8 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
DDS_WRITE(DDS_CFR2, 0x40);
#endif
#ifdef DDS_AD9914
DDS_WRITE(DDS_CFR1L, 0x2008);
/* Enable autoclear phase accumulator and enables OSK. */
DDS_WRITE(DDS_CFR1L, 0x2108);
#endif
fud_time = now + 2*DURATION_WRITE;
pow -= (ref_time - fud_time)*DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH);
@@ -156,6 +167,9 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
#endif
#ifdef DDS_AD9914
DDS_WRITE(DDS_POW, pow);
#endif
#ifdef DDS_AD9914
DDS_WRITE(DDS_ASF, amplitude);
#endif
DDS_WRITE(DDS_FUD, 0);
}
@@ -165,6 +179,7 @@ struct dds_set_params {
unsigned int ftw;
unsigned int pow;
int phase_mode;
unsigned int amplitude;
};

static int batch_mode;
@@ -193,14 +208,15 @@ void dds_batch_exit(void)
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
for(i=0;i<batch_count;i++) {
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;
}
batch_mode = 0;
}

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_count >= DDS_MAX_BATCH)
@@ -210,9 +226,11 @@ void dds_set(long long int timestamp, int channel,
batch[batch_count].ftw = ftw;
batch[batch_count].pow = pow;
batch[batch_count].phase_mode = phase_mode;
batch[batch_count].amplitude = amplitude;
batch_count++;
} else {
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);
}
}
2 changes: 1 addition & 1 deletion soc/runtime/dds.h
Original file line number Diff line number Diff line change
@@ -59,6 +59,6 @@ void dds_init(long long int timestamp, int channel);
void dds_batch_enter(long long int timestamp);
void dds_batch_exit(void);
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 */