Skip to content

Commit f0b0b1b

Browse files
committedMar 9, 2016
support for multiple DDS buses (untested)
1 parent 9d1903a commit f0b0b1b

File tree

17 files changed

+264
-162
lines changed

17 files changed

+264
-162
lines changed
 

Diff for: ‎RELEASE_NOTES.rst

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ Release notes
1111
This requires reflashing the runtime and the flash storage filesystem image
1212
or erase and rewrite its entries.
1313
* RTIOCollisionError has been renamed to RTIOCollision
14-
14+
* the new API for DDS batches is:
15+
with self.core_dds.batch:
16+
...
17+
with core_dds a device of type artiq.coredevice.dds.CoreDDS.
18+
The dds_bus device should not be used anymore.

Diff for: ‎artiq/coredevice/analyzer.py

+38-25
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,32 @@ def decode_message(data):
4040

4141

4242
DecodedDump = namedtuple(
43-
"DecodedDump", "log_channel dds_channel dds_onehot_sel messages")
43+
"DecodedDump", "log_channel dds_onehot_sel messages")
4444

4545

4646
def decode_dump(data):
47-
parts = struct.unpack(">IQbbbb", data[:16])
47+
parts = struct.unpack(">IQbbb", data[:15])
4848
(sent_bytes, total_byte_count,
49-
overflow_occured, log_channel, dds_channel, dds_onehot_sel) = parts
49+
overflow_occured, log_channel, dds_onehot_sel) = parts
5050

51-
if sent_bytes + 16 != len(data):
52-
raise ValueError("analyzer dump has incorrect length")
51+
expected_len = sent_bytes + 15
52+
if expected_len != len(data):
53+
raise ValueError("analyzer dump has incorrect length "
54+
"(got {}, expected {})".format(
55+
len(data), expected_len))
5356
if overflow_occured:
5457
logger.warning("analyzer FIFO overflow occured, "
5558
"some messages have been lost")
5659
if total_byte_count > sent_bytes:
5760
logger.info("analyzer ring buffer has wrapped %d times",
5861
total_byte_count//sent_bytes)
5962

60-
position = 16
63+
position = 15
6164
messages = []
6265
for _ in range(sent_bytes//32):
6366
messages.append(decode_message(data[position:position+32]))
6467
position += 32
65-
return DecodedDump(log_channel,
66-
dds_channel, bool(dds_onehot_sel),
67-
messages)
68+
return DecodedDump(log_channel, bool(dds_onehot_sel), messages)
6869

6970

7071
def vcd_codes():
@@ -299,21 +300,31 @@ def get_vcd_log_channels(log_channel, messages):
299300
return vcd_log_channels
300301

301302

302-
def get_ref_period(devices):
303+
def get_single_device_argument(devices, module, cls, argument):
303304
ref_period = None
304305
for desc in devices.values():
305306
if isinstance(desc, dict) and desc["type"] == "local":
306-
if (desc["module"] == "artiq.coredevice.core"
307-
and desc["class"] == "Core"):
307+
if (desc["module"] == module
308+
and desc["class"] == cls):
308309
if ref_period is None:
309-
ref_period = desc["arguments"]["ref_period"]
310+
ref_period = desc["arguments"][argument]
310311
else:
311-
return None # more than one core device found
312+
return None # more than one device found
312313
return ref_period
313314

314315

316+
def get_ref_period(devices):
317+
return get_single_device_argument(devices, "artiq.coredevice.core",
318+
"Core", "ref_period")
319+
320+
321+
def get_dds_sysclk(devices):
322+
return get_single_device_argument(devices, "artiq.coredevice.core",
323+
"CoreDDS", "sysclk")
324+
325+
315326
def create_channel_handlers(vcd_manager, devices, ref_period,
316-
dds_channel, dds_onehot_sel):
327+
dds_sysclk, dds_onehot_sel):
317328
channel_handlers = dict()
318329
for name, desc in sorted(devices.items(), key=itemgetter(0)):
319330
if isinstance(desc, dict) and desc["type"] == "local":
@@ -327,19 +338,17 @@ def create_channel_handlers(vcd_manager, devices, ref_period,
327338
channel_handlers[channel] = TTLClockGenHandler(vcd_manager, name, ref_period)
328339
if (desc["module"] == "artiq.coredevice.dds"
329340
and desc["class"] in {"AD9858", "AD9914"}):
330-
sysclk = desc["arguments"]["sysclk"]
331-
dds_channel_ddsbus = desc["arguments"]["channel"]
332-
if dds_channel in channel_handlers:
333-
dds_handler = channel_handlers[dds_channel]
341+
dds_bus_channel = desc["arguments"]["bus_channel"]
342+
dds_channel = desc["arguments"]["channel"]
343+
if dds_bus_channel in channel_handlers:
344+
dds_handler = channel_handlers[dds_bus_channel]
334345
if dds_handler.dds_type != desc["class"]:
335346
raise ValueError("All DDS channels must have the same type")
336-
if dds_handler.sysclk != sysclk:
337-
raise ValueError("All DDS channels must have the same sysclk")
338347
else:
339348
dds_handler = DDSHandler(vcd_manager, desc["class"],
340-
dds_onehot_sel, sysclk)
341-
channel_handlers[dds_channel] = dds_handler
342-
dds_handler.add_dds_channel(name, dds_channel_ddsbus)
349+
dds_sysclk, dds_onehot_sel)
350+
channel_handlers[dds_bus_channel] = dds_handler
351+
dds_handler.add_dds_channel(name, dds_channel)
343352
return channel_handlers
344353

345354

@@ -355,12 +364,16 @@ def decoded_dump_to_vcd(fileobj, devices, dump):
355364
else:
356365
logger.warning("unable to determine core device ref_period")
357366
ref_period = 1e-9 # guess
367+
dds_sysclk = get_dds_sysclk(devices)
368+
if dds_sysclk is None:
369+
logger.warning("unable to determine DDS sysclk")
370+
dds_sysclk = 3e9 # guess
358371

359372
messages = sorted(dump.messages, key=get_message_time)
360373

361374
channel_handlers = create_channel_handlers(
362375
vcd_manager, devices, ref_period,
363-
dump.dds_channel, dump.dds_onehot_sel)
376+
dds_sysclk, dump.dds_onehot_sel)
364377
vcd_log_channels = get_vcd_log_channels(dump.log_channel, messages)
365378
channel_handlers[dump.log_channel] = LogHandler(vcd_manager, vcd_log_channels)
366379
slack = vcd_manager.get_channel("rtio_slack", 64)

Diff for: ‎artiq/coredevice/core.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def shorten_path(path):
2222
lines = [shorten_path(path) for path in diagnostic.render(colored=colored)]
2323
return "\n".join(lines)
2424

25-
colors_supported = (os.name == 'posix')
25+
colors_supported = os.name == "posix"
2626
class _DiagnosticEngine(diagnostic.Engine):
2727
def render_diagnostic(self, diagnostic):
2828
sys.stderr.write(_render_diagnostic(diagnostic, colored=colors_supported) + "\n")
@@ -49,6 +49,7 @@ def cache_get(key: TStr) -> TList(TInt32):
4949
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
5050
raise NotImplementedError("syscall not simulated")
5151

52+
5253
class Core:
5354
"""Core device driver.
5455

Diff for: ‎artiq/coredevice/dds.py

+33-25
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,52 @@
1111

1212

1313
@syscall
14-
def dds_init(time_mu: TInt64, channel: TInt32) -> TNone:
14+
def dds_init(time_mu: TInt64, bus_channel: TInt32, channel: TInt32) -> TNone:
1515
raise NotImplementedError("syscall not simulated")
1616

1717
@syscall
18-
def dds_batch_enter(time_mu: TInt64) -> TNone:
18+
def dds_set(time_mu: TInt64, bus_channel: TInt32, channel: TInt32, ftw: TInt32,
19+
pow: TInt32, phase_mode: TInt32, amplitude: TInt32) -> TNone:
1920
raise NotImplementedError("syscall not simulated")
2021

2122
@syscall
22-
def dds_batch_exit() -> TNone:
23+
def dds_batch_enter(time_mu: TInt64) -> TNone:
2324
raise NotImplementedError("syscall not simulated")
2425

2526
@syscall
26-
def dds_set(time_mu: TInt64, channel: TInt32, ftw: TInt32,
27-
pow: TInt32, phase_mode: TInt32, amplitude: TInt32) -> TNone:
27+
def dds_batch_exit() -> TNone:
2828
raise NotImplementedError("syscall not simulated")
2929

3030

3131
class _BatchContextManager:
32-
def __init__(self, dds_bus):
33-
self.dds_bus = dds_bus
32+
def __init__(self, core_dds):
33+
self.core_dds = core_dds
34+
self.core = self.core_dds.core
3435

3536
@kernel
3637
def __enter__(self):
37-
self.dds_bus.batch_enter()
38+
self.core_dds.dds_batch_enter()
3839

3940
@kernel
4041
def __exit__(self, type, value, traceback):
41-
self.dds_bus.batch_exit()
42+
self.core_dds.dds_batch_exit()
4243

4344

44-
class DDSBus:
45-
"""Core device Direct Digital Synthesis (DDS) bus batching driver.
45+
class CoreDDS:
46+
"""Core device Direct Digital Synthesis (DDS) driver.
47+
48+
Gives access to the DDS functionality of the core device.
4649
47-
Manages batching of DDS commands on a DDS shared bus."""
48-
def __init__(self, dmgr):
49-
self.core = dmgr.get("core")
50+
:param sysclk: DDS system frequency. The DDS system clock must be a
51+
phase-locked multiple of the RTIO clock.
52+
"""
53+
def __init__(self, dmgr, sysclk, core_device="core"):
54+
self.core = dmgr.get(core_device)
55+
self.sysclk = sysclk
5056
self.batch = _BatchContextManager(self)
5157

5258
@kernel
53-
def batch_enter(self):
59+
def dds_batch_enter(self):
5460
"""Starts a DDS command batch. All DDS commands are buffered
5561
after this call, until ``batch_exit`` is called.
5662
@@ -59,26 +65,27 @@ def batch_enter(self):
5965
dds_batch_enter(now_mu())
6066

6167
@kernel
62-
def batch_exit(self):
68+
def dds_batch_exit(self):
6369
"""Ends a DDS command batch. All buffered DDS commands are issued
6470
on the bus."""
6571
dds_batch_exit()
6672

6773

6874
class _DDSGeneric:
69-
"""Core device Direct Digital Synthesis (DDS) driver.
75+
"""Core device Direct Digital Synthesis (DDS) channel driver.
7076
7177
Controls one DDS channel managed directly by the core device's runtime.
7278
7379
This class should not be used directly, instead, use the chip-specific
7480
drivers such as ``AD9858`` and ``AD9914``.
7581
76-
:param sysclk: DDS system frequency.
82+
:param bus: name of the DDS bus device that this DDS is connected to.
7783
:param channel: channel number of the DDS device to control.
7884
"""
79-
def __init__(self, dmgr, sysclk, channel):
80-
self.core = dmgr.get("core")
81-
self.sysclk = sysclk
85+
def __init__(self, dmgr, sysclk, bus_channel, channel, core_dds_device="core_dds"):
86+
self.core_dds = dmgr.get(core_dds_device)
87+
self.core = self.core_dds.core
88+
self.bus_channel = bus_channel
8289
self.channel = channel
8390
self.phase_mode = PHASE_MODE_CONTINUOUS
8491

@@ -87,14 +94,14 @@ def frequency_to_ftw(self, frequency):
8794
"""Returns the frequency tuning word corresponding to the given
8895
frequency.
8996
"""
90-
return round(int(2, width=64)**32*frequency/self.sysclk)
97+
return round(int(2, width=64)**32*frequency/self.core_dds.sysclk)
9198

9299
@portable
93100
def ftw_to_frequency(self, ftw):
94101
"""Returns the frequency corresponding to the given frequency tuning
95102
word.
96103
"""
97-
return ftw*self.sysclk/int(2, width=64)**32
104+
return ftw*self.core_dds.sysclk/int(2, width=64)**32
98105

99106
@portable
100107
def turns_to_pow(self, turns):
@@ -124,7 +131,7 @@ def init(self):
124131
"""Resets and initializes the DDS channel.
125132
126133
The runtime does this for all channels upon core device startup."""
127-
dds_init(now_mu(), self.channel)
134+
dds_init(now_mu(), self.bus_channel, self.channel)
128135

129136
@kernel
130137
def set_phase_mode(self, phase_mode):
@@ -163,7 +170,8 @@ def set_mu(self, frequency, phase=0, phase_mode=_PHASE_MODE_DEFAULT,
163170
"""
164171
if phase_mode == _PHASE_MODE_DEFAULT:
165172
phase_mode = self.phase_mode
166-
dds_set(now_mu(), self.channel, frequency, phase, phase_mode, amplitude)
173+
dds_set(now_mu(), self.bus_channel, self.channel,
174+
frequency, phase, phase_mode, amplitude)
167175

168176
@kernel
169177
def set(self, frequency, phase=0.0, phase_mode=_PHASE_MODE_DEFAULT,

Diff for: ‎artiq/gateware/targets/kc705.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ def __init__(self, cpu_type="or1k", **kwargs):
204204
self.submodules += phy
205205
rtio_channels.append(rtio.Channel.from_phy(phy))
206206

207-
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
208-
self.config["DDS_CHANNEL_COUNT"] = 8
207+
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
208+
self.config["RTIO_DDS_COUNT"] = 1
209+
self.config["DDS_CHANNELS_PER_BUS"] = 8
209210
self.config["DDS_AD9858"] = True
210211
phy = dds.AD9858(platform.request("dds"), 8)
211212
self.submodules += phy
@@ -277,8 +278,9 @@ def __init__(self, cpu_type="or1k", **kwargs):
277278
rtio_channels.append(rtio.Channel.from_phy(
278279
phy, ofifo_depth=128, ififo_depth=128))
279280

280-
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
281-
self.config["DDS_CHANNEL_COUNT"] = 11
281+
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
282+
self.config["RTIO_DDS_COUNT"] = 1
283+
self.config["DDS_CHANNELS_PER_BUS"] = 11
282284
self.config["DDS_AD9914"] = True
283285
self.config["DDS_ONEHOT_SEL"] = True
284286
phy = dds.AD9914(platform.request("dds"), 11, onehot=True)
@@ -331,8 +333,9 @@ def __init__(self, cpu_type="or1k", **kwargs):
331333
self.submodules += phy
332334
rtio_channels.append(rtio.Channel.from_phy(phy))
333335

334-
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
335-
self.config["DDS_CHANNEL_COUNT"] = 12
336+
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
337+
self.config["RTIO_DDS_COUNT"] = 1
338+
self.config["DDS_CHANNELS_PER_BUS"] = 12
336339
self.config["DDS_AD9914"] = True
337340
self.config["DDS_ONEHOT_SEL"] = True
338341
phy = dds.AD9914(platform.request("dds"), 12, onehot=True)

Diff for: ‎artiq/gateware/targets/pipistrello.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,9 @@ def __init__(self, cpu_type="or1k", **kwargs):
215215
rtio_channels.append(rtio.Channel.from_phy(
216216
phy, ofifo_depth=256, ififo_depth=256))
217217

218-
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
219-
self.config["DDS_CHANNEL_COUNT"] = 8
218+
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
219+
self.config["RTIO_DDS_COUNT"] = 1
220+
self.config["DDS_CHANNELS_PER_BUS"] = 8
220221
self.config["DDS_AD9858"] = True
221222
dds_pins = platform.request("dds")
222223
self.comb += dds_pins.p.eq(0)

Diff for: ‎artiq/gui/moninj.py

+20-8
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ def set_value(self, value, oe, override):
118118

119119

120120
class _DDSWidget(QtWidgets.QFrame):
121-
def __init__(self, channel, sysclk, title):
121+
def __init__(self, bus_channel, channel, sysclk, title):
122+
self.bus_channel = bus_channel
122123
self.channel = channel
123124
self.sysclk = sysclk
124125

@@ -146,13 +147,14 @@ def __init__(self, channel, sysclk, title):
146147
self.set_value(0)
147148

148149
def set_value(self, ftw):
149-
frequency = ftw*self.sysclk/2**32
150+
frequency = ftw*self.sysclk()/2**32
150151
self._value.setText("<font size=\"6\">{:.7f} MHz</font>"
151152
.format(float(frequency)/1e6))
152153

153154

154155
class _DeviceManager:
155156
def __init__(self, send_to_device, init):
157+
self.dds_sysclk = 0
156158
self.send_to_device = send_to_device
157159
self.ddb = dict()
158160
self.ttl_cb = lambda: None
@@ -162,6 +164,9 @@ def __init__(self, send_to_device, init):
162164
for k, v in init.items():
163165
self[k] = v
164166

167+
def get_dds_sysclk(self):
168+
return self.dds_sysclk
169+
165170
def __setitem__(self, k, v):
166171
if k in self.ttl_widgets:
167172
del self[k]
@@ -181,12 +186,15 @@ def __setitem__(self, k, v):
181186
self.ttl_widgets[k] = _TTLWidget(
182187
channel, self.send_to_device, force_out, title)
183188
self.ttl_cb()
189+
if (v["module"] == "artiq.coredevice.dds"
190+
and v["class"] == "CoreDDS"):
191+
self.dds_sysclk = v["arguments"]["sysclk"]
184192
if (v["module"] == "artiq.coredevice.dds"
185193
and v["class"] in {"AD9858", "AD9914"}):
194+
bus_channel = v["arguments"]["bus_channel"]
186195
channel = v["arguments"]["channel"]
187-
sysclk = v["arguments"]["sysclk"]
188196
self.dds_widgets[channel] = _DDSWidget(
189-
channel, sysclk, title)
197+
bus_channel, channel, self.get_dds_sysclk, title)
190198
self.dds_cb()
191199
except KeyError:
192200
pass
@@ -275,19 +283,23 @@ def datagram_received(self, data, addr):
275283
"is not present yet")
276284
return
277285
try:
278-
ttl_levels, ttl_oes, ttl_overrides = \
279-
struct.unpack(">QQQ", data[:8*3])
286+
hlen = 8*3+4
287+
(ttl_levels, ttl_oes, ttl_overrides,
288+
dds_rtio_first_channel, dds_channels_per_bus) = \
289+
struct.unpack(">QQQHH", data[:hlen])
280290
for w in self.dm.ttl_widgets.values():
281291
channel = w.channel
282292
w.set_value(ttl_levels & (1 << channel),
283293
ttl_oes & (1 << channel),
284294
ttl_overrides & (1 << channel))
285-
dds_data = data[8*3:]
295+
dds_data = data[hlen:]
286296
ndds = len(dds_data)//4
287297
ftws = struct.unpack(">" + "I"*ndds, dds_data)
288298
for w in self.dm.dds_widgets.values():
299+
offset = (dds_channels_per_bus*w.bus_channel
300+
+ w.channel-dds_rtio_first_channel)
289301
try:
290-
ftw = ftws[w.channel]
302+
ftw = ftws[offset]
291303
except KeyError:
292304
pass
293305
else:

Diff for: ‎artiq/runtime/analyzer.c

-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ struct analyzer_header {
1212
unsigned long long int total_byte_count;
1313
unsigned char overflow_occured;
1414
unsigned char log_channel;
15-
unsigned char dds_channel;
1615
unsigned char dds_onehot_sel;
1716
} __attribute__((packed));
1817

@@ -72,7 +71,6 @@ void analyzer_start(void)
7271

7372
analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read();
7473
analyzer_header.log_channel = CONFIG_RTIO_LOG_CHANNEL;
75-
analyzer_header.dds_channel = CONFIG_RTIO_DDS_CHANNEL;
7674
#ifdef CONFIG_DDS_ONEHOT_SEL
7775
analyzer_header.dds_onehot_sel = 1;
7876
#else

Diff for: ‎artiq/runtime/bridge.c

+18-12
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ static void rtio_output_blind(int channel, int addr, int data)
1616
rtio_o_we_write(1);
1717
}
1818

19-
static void dds_write(int addr, int data)
19+
static void dds_write(int bus_channel, int addr, int data)
2020
{
21-
rtio_output_blind(CONFIG_RTIO_DDS_CHANNEL, addr, data);
21+
rtio_output_blind(bus_channel, addr, data);
2222
}
2323

24-
static int dds_read(int addr)
24+
static int dds_read(int bus_channel, int addr)
2525
{
2626
int r;
2727

@@ -31,7 +31,7 @@ static int dds_read(int addr)
3131
#ifdef CONFIG_DDS_AD9914
3232
#define DDS_READ_FLAG 256
3333
#endif
34-
dds_write(addr | DDS_READ_FLAG, 0);
34+
dds_write(bus_channel, addr | DDS_READ_FLAG, 0);
3535
while(rtio_i_status_read() & RTIO_I_STATUS_EMPTY);
3636
r = rtio_i_data_read();
3737
rtio_i_re_write(1);
@@ -75,16 +75,18 @@ void bridge_main(void)
7575
struct msg_brg_dds_sel *msg;
7676

7777
msg = (struct msg_brg_dds_sel *)umsg;
78-
dds_write(DDS_GPIO, msg->channel << 1);
78+
dds_write(msg->bus_channel, DDS_GPIO, msg->channel << 1);
7979
mailbox_acknowledge();
8080
break;
8181
}
8282
case MESSAGE_TYPE_BRG_DDS_RESET: {
8383
unsigned int g;
84+
struct msg_brg_dds_reset *msg;
8485

85-
g = dds_read(DDS_GPIO);
86-
dds_write(DDS_GPIO, g | 1);
87-
dds_write(DDS_GPIO, g);
86+
msg = (struct msg_brg_dds_reset *)umsg;
87+
g = dds_read(msg->bus_channel, DDS_GPIO);
88+
dds_write(msg->bus_channel, DDS_GPIO, g | 1);
89+
dds_write(msg->bus_channel, DDS_GPIO, g);
8890

8991
mailbox_acknowledge();
9092
break;
@@ -95,22 +97,26 @@ void bridge_main(void)
9597

9698
msg = (struct msg_brg_dds_read_request *)umsg;
9799
rmsg.type = MESSAGE_TYPE_BRG_DDS_READ_REPLY;
98-
rmsg.data = dds_read(msg->address);
100+
rmsg.data = dds_read(msg->bus_channel, msg->address);
99101
mailbox_send_and_wait(&rmsg);
100102
break;
101103
}
102104
case MESSAGE_TYPE_BRG_DDS_WRITE: {
103105
struct msg_brg_dds_write *msg;
104106

105107
msg = (struct msg_brg_dds_write *)umsg;
106-
dds_write(msg->address, msg->data);
108+
dds_write(msg->bus_channel, msg->address, msg->data);
107109
mailbox_acknowledge();
108110
break;
109111
}
110-
case MESSAGE_TYPE_BRG_DDS_FUD:
111-
dds_write(DDS_FUD, 0);
112+
case MESSAGE_TYPE_BRG_DDS_FUD: {
113+
struct msg_brg_dds_fud *msg;
114+
115+
msg = (struct msg_brg_dds_fud *)umsg;
116+
dds_write(msg->bus_channel, DDS_FUD, 0);
112117
mailbox_acknowledge();
113118
break;
119+
}
114120
default:
115121
mailbox_acknowledge();
116122
break;

Diff for: ‎artiq/runtime/bridge_ctl.c

+12-7
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,33 @@ void brg_ttlo(int n, int value)
4343
mailbox_send_and_wait(&msg);
4444
}
4545

46-
void brg_ddssel(int channel)
46+
void brg_ddssel(int bus_channel, int channel)
4747
{
4848
struct msg_brg_dds_sel msg;
4949

5050
msg.type = MESSAGE_TYPE_BRG_DDS_SEL;
51+
msg.bus_channel = bus_channel;
5152
msg.channel = channel;
5253
mailbox_send_and_wait(&msg);
5354
}
5455

55-
void brg_ddsreset(void)
56+
void brg_ddsreset(int bus_channel)
5657
{
57-
struct msg_base msg;
58+
struct msg_brg_dds_reset msg;
5859

5960
msg.type = MESSAGE_TYPE_BRG_DDS_RESET;
61+
msg.bus_channel = bus_channel;
6062
mailbox_send_and_wait(&msg);
6163
}
6264

63-
unsigned int brg_ddsread(unsigned int address)
65+
unsigned int brg_ddsread(int bus_channel, unsigned int address)
6466
{
6567
struct msg_brg_dds_read_request msg;
6668
struct msg_brg_dds_read_reply *rmsg;
6769
unsigned int r;
6870

6971
msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST;
72+
msg.bus_channel = bus_channel;
7073
msg.address = address;
7174
mailbox_send(&msg);
7275
while(1) {
@@ -82,20 +85,22 @@ unsigned int brg_ddsread(unsigned int address)
8285
}
8386
}
8487

85-
void brg_ddswrite(unsigned int address, unsigned int data)
88+
void brg_ddswrite(int bus_channel, unsigned int address, unsigned int data)
8689
{
8790
struct msg_brg_dds_write msg;
8891

8992
msg.type = MESSAGE_TYPE_BRG_DDS_WRITE;
93+
msg.bus_channel = bus_channel;
9094
msg.address = address;
9195
msg.data = data;
9296
mailbox_send_and_wait(&msg);
9397
}
9498

95-
void brg_ddsfud(void)
99+
void brg_ddsfud(int bus_channel)
96100
{
97-
struct msg_base msg;
101+
struct msg_brg_dds_fud msg;
98102

99103
msg.type = MESSAGE_TYPE_BRG_DDS_FUD;
104+
msg.bus_channel = bus_channel;
100105
mailbox_send_and_wait(&msg);
101106
}

Diff for: ‎artiq/runtime/bridge_ctl.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ void brg_start(void);
66
void brg_ttloe(int n, int value);
77
void brg_ttlo(int n, int value);
88

9-
void brg_ddssel(int channel);
10-
void brg_ddsreset(void);
11-
unsigned int brg_ddsread(unsigned int address);
12-
void brg_ddswrite(unsigned int address, unsigned int data);
13-
void brg_ddsfud(void);
9+
void brg_ddssel(int bus_channel, int channel);
10+
void brg_ddsreset(int bus_channel);
11+
unsigned int brg_ddsread(int bus_channel, unsigned int address);
12+
void brg_ddswrite(int bus_channel, unsigned int address, unsigned int data);
13+
void brg_ddsfud(int bus_channel);
1414

1515
#endif /* __BRIDGE_CTL_H */

Diff for: ‎artiq/runtime/dds.c

+12-7
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
#endif
2727

2828
#define DDS_WRITE(addr, data) do { \
29-
rtio_output(now, CONFIG_RTIO_DDS_CHANNEL, addr, data); \
29+
rtio_output(now, bus_channel, addr, data); \
3030
now += DURATION_WRITE; \
3131
} while(0)
3232

33-
void dds_init(long long int timestamp, int channel)
33+
void dds_init(long long int timestamp, int bus_channel, int channel)
3434
{
3535
long long int now;
3636

@@ -84,7 +84,8 @@ void dds_init(long long int timestamp, int channel)
8484
* to continuous phase mode. */
8585
static unsigned int continuous_phase_comp[CONFIG_DDS_CHANNEL_COUNT];
8686

87-
static void dds_set_one(long long int now, long long int ref_time, unsigned int channel,
87+
static void dds_set_one(long long int now, long long int ref_time,
88+
unsigned int bus_channel, unsigned int channel,
8889
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
8990
{
9091
unsigned int channel_enc;
@@ -157,6 +158,7 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
157158
}
158159

159160
struct dds_set_params {
161+
int bus_channel;
160162
int channel;
161163
unsigned int ftw;
162164
unsigned int pow;
@@ -189,28 +191,31 @@ void dds_batch_exit(void)
189191
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
190192
for(i=0;i<batch_count;i++) {
191193
dds_set_one(now, batch_ref_time,
192-
batch[i].channel, batch[i].ftw, batch[i].pow, batch[i].phase_mode,
194+
batch[i].bus_channel, batch[i].channel,
195+
batch[i].ftw, batch[i].pow, batch[i].phase_mode,
193196
batch[i].amplitude);
194197
now += DURATION_PROGRAM + DURATION_WRITE;
195198
}
196199
batch_mode = 0;
197200
}
198201

199-
void dds_set(long long int timestamp, int channel,
202+
void dds_set(long long int timestamp, int bus_channel, int channel,
200203
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
201204
{
202205
if(batch_mode) {
203206
if(batch_count >= DDS_MAX_BATCH)
204207
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
205208
/* timestamp parameter ignored (determined by batch) */
209+
batch[batch_count].bus_channel = bus_channel;
206210
batch[batch_count].channel = channel;
207211
batch[batch_count].ftw = ftw;
208212
batch[batch_count].pow = pow;
209213
batch[batch_count].phase_mode = phase_mode;
210214
batch[batch_count].amplitude = amplitude;
211215
batch_count++;
212216
} else {
213-
dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode,
214-
amplitude);
217+
dds_set_one(timestamp - DURATION_PROGRAM, timestamp,
218+
bus_channel, channel,
219+
ftw, pow, phase_mode, amplitude);
215220
}
216221
}

Diff for: ‎artiq/runtime/messages.h

+14
Original file line numberDiff line numberDiff line change
@@ -150,23 +150,37 @@ struct msg_brg_ttl_out {
150150

151151
struct msg_brg_dds_sel {
152152
int type;
153+
int bus_channel;
153154
int channel;
154155
};
155156

157+
struct msg_brg_dds_reset {
158+
int type;
159+
int bus_channel;
160+
};
161+
156162
struct msg_brg_dds_read_request {
157163
int type;
164+
int bus_channel;
158165
unsigned int address;
159166
};
160167

161168
struct msg_brg_dds_read_reply {
162169
int type;
170+
int bus_channel;
163171
unsigned int data;
164172
};
165173

166174
struct msg_brg_dds_write {
167175
int type;
176+
int bus_channel;
168177
unsigned int address;
169178
unsigned int data;
170179
};
171180

181+
struct msg_brg_dds_fud {
182+
int type;
183+
int bus_channel;
184+
};
185+
172186
#endif /* __MESSAGES_H */

Diff for: ‎artiq/runtime/moninj.c

+14-8
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ struct monitor_reply {
3636
long long int ttl_levels;
3737
long long int ttl_oes;
3838
long long int ttl_overrides;
39-
unsigned int dds_ftws[CONFIG_DDS_CHANNEL_COUNT];
40-
};
39+
unsigned short int dds_rtio_first_channel;
40+
unsigned short int dds_channels_per_bus;
41+
unsigned int dds_ftws[CONFIG_RTIO_DDS_COUNT*CONFIG_DDS_CHANNELS_PER_BUS];
42+
} __attribute__((packed));
4143

4244
static void moninj_monitor(const ip_addr_t *addr, u16_t port)
4345
{
4446
struct monitor_reply reply;
45-
int i;
47+
int i, j;
4648
struct pbuf *reply_p;
4749

4850
reply.ttl_levels = 0;
@@ -64,11 +66,15 @@ static void moninj_monitor(const ip_addr_t *addr, u16_t port)
6466
reply.ttl_overrides |= 1LL << i;
6567
}
6668

67-
rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
68-
for(i=0;i<CONFIG_DDS_CHANNEL_COUNT;i++) {
69-
rtio_moninj_mon_probe_sel_write(i);
70-
rtio_moninj_mon_value_update_write(1);
71-
reply.dds_ftws[i] = rtio_moninj_mon_value_read();
69+
reply.dds_rtio_first_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL;
70+
reply.dds_channels_per_bus = CONFIG_DDS_CHANNELS_PER_BUS;
71+
for(j=0;j<CONFIG_RTIO_DDS_COUNT;j++) {
72+
rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_FIRST_DDS_CHANNEL+j);
73+
for(i=0;i<CONFIG_DDS_CHANNELS_PER_BUS;i++) {
74+
rtio_moninj_mon_probe_sel_write(i);
75+
rtio_moninj_mon_value_update_write(1);
76+
reply.dds_ftws[CONFIG_DDS_CHANNELS_PER_BUS*j+i] = rtio_moninj_mon_value_read();
77+
}
7278
}
7379

7480
reply_p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct monitor_reply), PBUF_RAM);

Diff for: ‎artiq/runtime/test_mode.c

+68-44
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,28 @@ static void ttlo(char *n, char *value)
104104
brg_ttlo(n2, value2);
105105
}
106106

107+
static int bus_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL;
108+
109+
static void ddsbus(char *n)
110+
{
111+
char *c;
112+
unsigned int n2;
113+
114+
if(*n == 0) {
115+
printf("ddsbus <n>\n");
116+
return;
117+
}
118+
119+
n2 = strtoul(n, &c, 0);
120+
if(*c != 0) {
121+
printf("incorrect bus channel\n");
122+
return;
123+
}
124+
125+
bus_channel = n2;
126+
}
127+
128+
107129
static void ddssel(char *n)
108130
{
109131
char *c;
@@ -123,7 +145,7 @@ static void ddssel(char *n)
123145
#ifdef CONFIG_DDS_ONEHOT_SEL
124146
n2 = 1 << n2;
125147
#endif
126-
brg_ddssel(n2);
148+
brg_ddssel(bus_channel, n2);
127149
}
128150

129151
static void ddsw(char *addr, char *value)
@@ -147,7 +169,7 @@ static void ddsw(char *addr, char *value)
147169
return;
148170
}
149171

150-
brg_ddswrite(addr2, value2);
172+
brg_ddswrite(bus_channel, addr2, value2);
151173
}
152174

153175
static void ddsr(char *addr)
@@ -167,16 +189,16 @@ static void ddsr(char *addr)
167189
}
168190

169191
#ifdef CONFIG_DDS_AD9858
170-
printf("0x%02x\n", brg_ddsread(addr2));
192+
printf("0x%02x\n", brg_ddsread(bus_channel, addr2));
171193
#endif
172194
#ifdef CONFIG_DDS_AD9914
173-
printf("0x%04x\n", brg_ddsread(addr2));
195+
printf("0x%04x\n", brg_ddsread(bus_channel, addr2));
174196
#endif
175197
}
176198

177199
static void ddsfud(void)
178200
{
179-
brg_ddsfud();
201+
brg_ddsfud(bus_channel);
180202
}
181203

182204
static void ddsftw(char *n, char *ftw)
@@ -203,36 +225,36 @@ static void ddsftw(char *n, char *ftw)
203225
#ifdef CONFIG_DDS_ONEHOT_SEL
204226
n2 = 1 << n2;
205227
#endif
206-
brg_ddssel(n2);
228+
brg_ddssel(bus_channel, n2);
207229

208230
#ifdef CONFIG_DDS_AD9858
209-
brg_ddswrite(DDS_FTW0, ftw2 & 0xff);
210-
brg_ddswrite(DDS_FTW1, (ftw2 >> 8) & 0xff);
211-
brg_ddswrite(DDS_FTW2, (ftw2 >> 16) & 0xff);
212-
brg_ddswrite(DDS_FTW3, (ftw2 >> 24) & 0xff);
231+
brg_ddswrite(bus_channel, DDS_FTW0, ftw2 & 0xff);
232+
brg_ddswrite(bus_channel, DDS_FTW1, (ftw2 >> 8) & 0xff);
233+
brg_ddswrite(bus_channel, DDS_FTW2, (ftw2 >> 16) & 0xff);
234+
brg_ddswrite(bus_channel, DDS_FTW3, (ftw2 >> 24) & 0xff);
213235
#endif
214236
#ifdef CONFIG_DDS_AD9914
215-
brg_ddswrite(DDS_FTWL, ftw2 & 0xffff);
216-
brg_ddswrite(DDS_FTWH, (ftw2 >> 16) & 0xffff);
237+
brg_ddswrite(bus_channel, DDS_FTWL, ftw2 & 0xffff);
238+
brg_ddswrite(bus_channel, DDS_FTWH, (ftw2 >> 16) & 0xffff);
217239
#endif
218240

219-
brg_ddsfud();
241+
brg_ddsfud(bus_channel);
220242
}
221243

222244
static void ddsreset(void)
223245
{
224-
brg_ddsreset();
246+
brg_ddsreset(bus_channel);
225247
}
226248

227249
#ifdef CONFIG_DDS_AD9858
228250
static void ddsinit(void)
229251
{
230-
brg_ddsreset();
231-
brg_ddswrite(DDS_CFR0, 0x78);
232-
brg_ddswrite(DDS_CFR1, 0x00);
233-
brg_ddswrite(DDS_CFR2, 0x00);
234-
brg_ddswrite(DDS_CFR3, 0x00);
235-
brg_ddsfud();
252+
brg_ddsreset(bus_channel);
253+
brg_ddswrite(bus_channel, DDS_CFR0, 0x78);
254+
brg_ddswrite(bus_channel, DDS_CFR1, 0x00);
255+
brg_ddswrite(bus_channel, DDS_CFR2, 0x00);
256+
brg_ddswrite(bus_channel, DDS_CFR3, 0x00);
257+
brg_ddsfud(bus_channel);
236258
}
237259
#endif
238260

@@ -241,17 +263,17 @@ static void ddsinit(void)
241263
{
242264
long long int t;
243265

244-
brg_ddsreset();
245-
brg_ddswrite(DDS_CFR1H, 0x0000); /* Enable cosine output */
246-
brg_ddswrite(DDS_CFR2L, 0x8900); /* Enable matched latency */
247-
brg_ddswrite(DDS_CFR2H, 0x0080); /* Enable profile mode */
248-
brg_ddswrite(DDS_ASF, 0x0fff); /* Set amplitude to maximum */
249-
brg_ddswrite(DDS_CFR4H, 0x0105); /* Enable DAC calibration */
250-
brg_ddswrite(DDS_FUD, 0);
266+
brg_ddsreset(bus_channel);
267+
brg_ddswrite(bus_channel, DDS_CFR1H, 0x0000); /* Enable cosine output */
268+
brg_ddswrite(bus_channel, DDS_CFR2L, 0x8900); /* Enable matched latency */
269+
brg_ddswrite(bus_channel, DDS_CFR2H, 0x0080); /* Enable profile mode */
270+
brg_ddswrite(bus_channel, DDS_ASF, 0x0fff); /* Set amplitude to maximum */
271+
brg_ddswrite(bus_channel, DDS_CFR4H, 0x0105); /* Enable DAC calibration */
272+
brg_ddswrite(bus_channel, DDS_FUD, 0);
251273
t = clock_get_ms();
252274
while(clock_get_ms() < t + 2);
253-
brg_ddswrite(DDS_CFR4H, 0x0005); /* Disable DAC calibration */
254-
brg_ddsfud();
275+
brg_ddswrite(bus_channel, DDS_CFR4H, 0x0005); /* Disable DAC calibration */
276+
brg_ddsfud(bus_channel);
255277
}
256278
#endif
257279

@@ -265,34 +287,34 @@ static void do_ddstest_one(unsigned int i)
265287
unsigned int f, g, j;
266288

267289
#ifdef CONFIG_DDS_ONEHOT_SEL
268-
brg_ddssel(1 << i);
290+
brg_ddssel(bus_channel, 1 << i);
269291
#else
270-
brg_ddssel(i);
292+
brg_ddssel(bus_channel, i);
271293
#endif
272294
ddsinit();
273295

274296
for(j=0; j<12; j++) {
275297
f = v[j];
276298
#ifdef CONFIG_DDS_AD9858
277-
brg_ddswrite(DDS_FTW0, f & 0xff);
278-
brg_ddswrite(DDS_FTW1, (f >> 8) & 0xff);
279-
brg_ddswrite(DDS_FTW2, (f >> 16) & 0xff);
280-
brg_ddswrite(DDS_FTW3, (f >> 24) & 0xff);
299+
brg_ddswrite(bus_channel, DDS_FTW0, f & 0xff);
300+
brg_ddswrite(bus_channel, DDS_FTW1, (f >> 8) & 0xff);
301+
brg_ddswrite(bus_channel, DDS_FTW2, (f >> 16) & 0xff);
302+
brg_ddswrite(bus_channel, DDS_FTW3, (f >> 24) & 0xff);
281303
#endif
282304
#ifdef CONFIG_DDS_AD9914
283-
brg_ddswrite(DDS_FTWL, f & 0xffff);
284-
brg_ddswrite(DDS_FTWH, (f >> 16) & 0xffff);
305+
brg_ddswrite(bus_channel, DDS_FTWL, f & 0xffff);
306+
brg_ddswrite(bus_channel, DDS_FTWH, (f >> 16) & 0xffff);
285307
#endif
286308
brg_ddsfud();
287309
#ifdef CONFIG_DDS_AD9858
288-
g = brg_ddsread(DDS_FTW0);
289-
g |= brg_ddsread(DDS_FTW1) << 8;
290-
g |= brg_ddsread(DDS_FTW2) << 16;
291-
g |= brg_ddsread(DDS_FTW3) << 24;
310+
g = brg_ddsread(bus_channel, DDS_FTW0);
311+
g |= brg_ddsread(bus_channel, DDS_FTW1) << 8;
312+
g |= brg_ddsread(bus_channel, DDS_FTW2) << 16;
313+
g |= brg_ddsread(bus_channel, DDS_FTW3) << 24;
292314
#endif
293315
#ifdef CONFIG_DDS_AD9914
294-
g = brg_ddsread(DDS_FTWL);
295-
g |= brg_ddsread(DDS_FTWH) << 16;
316+
g = brg_ddsread(bus_channel, DDS_FTWL);
317+
g |= brg_ddsread(bus_channel, DDS_FTWH) << 16;
296318
#endif
297319
if(g != f)
298320
printf("readback fail on DDS %d, 0x%08x != 0x%08x\n", i, g, f);
@@ -330,7 +352,7 @@ static void ddstest(char *n, char *channel)
330352
do_ddstest_one(channel2);
331353
} else {
332354
for(i=0;i<n2;i++)
333-
for(j=0;j<CONFIG_DDS_CHANNEL_COUNT;j++)
355+
for(j=0;j<CONFIG_DDS_CHANNELS_PER_BUS;j++)
334356
do_ddstest_one(j);
335357
}
336358
}
@@ -542,6 +564,7 @@ static void help(void)
542564
puts("clksrc <n> - select RTIO clock source");
543565
puts("ttloe <n> <v> - set TTL output enable");
544566
puts("ttlo <n> <v> - set TTL output value");
567+
puts("ddsbus <n> - select the DDS bus RTIO channel");
545568
puts("ddssel <n> - select a DDS");
546569
puts("ddsinit - reset, config, FUD DDS");
547570
puts("ddsreset - reset DDS");
@@ -624,6 +647,7 @@ static void do_command(char *c)
624647
else if(strcmp(token, "ttloe") == 0) ttloe(get_token(&c), get_token(&c));
625648
else if(strcmp(token, "ttlo") == 0) ttlo(get_token(&c), get_token(&c));
626649

650+
else if(strcmp(token, "ddsbus") == 0) ddsbus(get_token(&c));
627651
else if(strcmp(token, "ddssel") == 0) ddssel(get_token(&c));
628652
else if(strcmp(token, "ddsw") == 0) ddsw(get_token(&c), get_token(&c));
629653
else if(strcmp(token, "ddsr") == 0) ddsr(get_token(&c));

Diff for: ‎doc/manual/core_device.rst

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ The board has RTIO SPI buses mapped as follows:
8989
| 25 | SPI2_CS_N | SPI2_MOSI | SPI2_MISO | SPI2_CLK |
9090
+--------------+-------------+-------------+-----------+------------+
9191

92+
The DDS bus is on channel 26.
93+
9294

9395
NIST QC2
9496
++++++++

Diff for: ‎examples/master/device_db.pyon

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
"class": "Core",
1515
"arguments": {"ref_period": 1e-9}
1616
},
17+
"core_dds": {
18+
"type": "local",
19+
"module": "artiq.coredevice.dds",
20+
"class": "CoreDDS",
21+
"arguments": {"sysclk": 3e9}
22+
},
1723

1824
"i2c_switch": {
1925
"type": "local",
@@ -121,30 +127,24 @@
121127
"arguments": {"spi_device": "spi0", "ldac_device": "ttl0"}
122128
},
123129

124-
"dds_bus": {
125-
"type": "local",
126-
"module": "artiq.coredevice.dds",
127-
"class": "DDSBus",
128-
"arguments": {}
129-
},
130130
"dds0": {
131131
"type": "local",
132132
"module": "artiq.coredevice.dds",
133133
"class": "AD9914",
134-
"arguments": {"sysclk": 3e9, "channel": 0},
134+
"arguments": {"bus_channel": 26, "channel": 0},
135135
"comment": "Comments work in DDS panel as well"
136136
},
137137
"dds1": {
138138
"type": "local",
139139
"module": "artiq.coredevice.dds",
140140
"class": "AD9914",
141-
"arguments": {"sysclk": 3e9, "channel": 1}
141+
"arguments": {"bus_channel": 26, "channel": 1}
142142
},
143143
"dds2": {
144144
"type": "local",
145145
"module": "artiq.coredevice.dds",
146146
"class": "AD9914",
147-
"arguments": {"sysclk": 3e9, "channel": 2}
147+
"arguments": {"bus_channel": 26, "channel": 2}
148148
},
149149

150150
"qc_q1_0": {

0 commit comments

Comments
 (0)
Please sign in to comment.