Software support for Mirny is quite rough at the moment (associated issue: https://github.com/m-labs/artiq/issues/1421).
Try this (somewhat embarrassing) code as a starting point:
Sample 1:
from artiq.experiment import *
class Test(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("mirny0_cpld")
self.setattr_device("mirny0_ch0")
@rpc(flags={"async"})
def p(self, *p):
print([hex(_) for _ in p])
@kernel
def run(self):
self.core.reset()
self.core.break_realtime()
m = self.mirny0_cpld
m0 = self.mirny0_ch0
#while True:
# m.write_reg(2, 0b1111)
# self.p(m.read_reg(2))
# delay(10*ms)
m.init()
m0.init()
m0.set_att_mu(255)
m0.sw.on()
# https://www.analog.com/media/en/technical-documentation/user-guides/EV-ADF5356SD1Z-UG-1087.pdf
m0.write(0x0000000d)
m0.write(0x000015fc)
m0.write(0x0061200b)
m0.write(0x00c026ba)
m0.write(0x2719fcc9)
m0.write(0x15596568)
m0.write(0x060000e7)
if False:
m0.write(0x35c30846) # div 64, -4dBm
else:
m0.write(0x35030076) # div 1, 5dBm
m0.write(0x00800025)
m0.write(0x32008b84)
m0.write(0x00000003)
m0.write(0x00000012)
m0.write(0x06c00001)
delay(10*ms)
m0.write(0x003006b0)
delay(10*ms)
assert m0.read_muxout()
Sample 2:
from artiq.experiment import *
from regdesc.devices import adf5356
class TestMirny(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("mirny0_ch0")
self.ch = self.mirny0_ch0
self.cpld = self.ch.cpld
self.clk_sel = 0
self.f_ref = [100, 10, 125, 10][self.clk_sel] * MHz
self.reg = adf5356.Device()
init_reg(self.reg)
@kernel
def run(self):
self.core.reset()
self.core.break_realtime()
m = self.cpld
m0 = self.ch
m.init()
m.write_reg(1, 0)
m0.init()
m.write_reg(1, (self.clk_sel<<4))
m0.set_att_mu(0)
m0.sw.on()
m0.write(self.reg.r13.storage)
m0.write(self.reg.r12.storage)
m0.write(self.reg.r11.storage)
m0.write(self.reg.r10.storage)
m0.write(self.reg.r9.storage)
m0.write(self.reg.r8.storage)
m0.write(self.reg.r7.storage)
m0.write(self.reg.r6.storage)
m0.write(self.reg.r5.storage)
m0.write(self.reg.r4.storage)
m0.write(self.reg.r3.storage)
m0.write(self.reg.r2.storage)
m0.write(self.reg.r1.storage)
delay(10*ms)
m0.write(self.reg.r0.storage)
delay(10*ms)
print(m0.read_muxout())
print_pll(self.f_ref, self.reg)
delay(100*ms)
print(m.read_reg(1))
# delay(4*s)
# m0.sw.off()
@rpc
def init_reg(reg):
reg.r13.storage = 0xd
reg.r12.storage = 0x15fc
reg.r11.storage = 0x61200b
reg.r10.storage = 0xc026ba
reg.r9.storage = 0x2719fcc9
reg.r8.storage = 0x15596568
reg.r7.storage = 0x60000e7
reg.r6.storage = 0x35c30846
reg.r5.storage = 0x800025
reg.r4.storage = 0x32008b84
reg.r3.storage = 0x3
reg.r2.storage = 0x12
reg.r1.storage = 0x6c00001
reg.r0.storage = 0x3006b0
# reg.r4.r_doubler = 1
# reg.r4.r_divider = 0
# reg.r0.int_value = 305
# reg.r1.main_frac_value = 0
# reg.r2.aux_frac_lsb_value = 0
# reg.r13.aux_frac_msb_value = 0
# reg.r2.aux_mod_lsb_value = 1
# reg.r13.aux_mod_msb_value = 0
@rpc
def print_pll(f_ref, reg):
from pprint import pprint
print("f_ref:", f_ref/MHz, "MHz")
print("f_pfd:", reg.f_pfd(f_ref)/MHz, "MHz")
print("f_vco:", reg.f_vco(f_ref)/MHz, "MHz")
print("f_outA:", reg.f_outA(f_ref)/MHz, "MHz")
pprint(reg.pll_params())
pprint(reg.r_params())
Sample 3:
from artiq.experiment import *
from artiq.language.units import ns, us
class TestComm(EnvExperiment):
def build(self):
self.setattr_device("core")
self.mirny = self.get_device("mirny0_cpld")
@kernel
def init(self):
self.core.break_realtime()
self.mirny.init()
# reg1 = 0b0000 # enable all PLLs
# reg1 |= 0 << 4 # Clock source = OSC
# reg1 |= 0 << 6 # divide-by-one
# reg1 |= 0 << 7 # disable attenuator reset
# reg1 |= 0 << 8 # FSEN_N = 1
# self.mirny.write_reg(1, reg1)
self.mirny.write_reg(2, 0xF)
# PLL registers for Fout = 156.25 MHz with 100 MHz reference
# FVCO = 5 GHz div = 32
# Regs are listed in the descending order R12..R0
pll_regs = [
0x1041C,
0x61300B,
0xC01F7A,
0x15153CC9,
0x102D0428,
0x120000E7,
0x35A140F6,
0x800025,
0x32008B84,
0x3,
0x12,
0x1,
0x200640
]
for pll_idx in range(4):
for r in pll_regs:
self.core.break_realtime()
self.mirny.write_ext(4+pll_idx, 32, r)
@kernel
def set_channel_rf_switch(self, channel, value):
self.core.break_realtime()
val = self.mirny.read_reg(2)
self.core.break_realtime()
val &= ~(1 << channel)
val |= ((value & 0x1) << channel)
self.mirny.write_reg(2, val)
@kernel
def test_rf_switch_channel(self, channel):
self.core.break_realtime()
self.mirny.write_reg(2, ~(0x1 << channel))
delay(500*ms)
self.mirny.write_reg(2, 0xF)
def test_rf_switch(self):
print("RF SWITCH TEST")
print("*"*80)
for i in range(4):
input("\tConnect channel {}".format(i))
self.set_channel_rf_switch(i, 0x0)
input("\tContinue? [ENTER]")
self.set_channel_rf_switch(i, 0x1)
@kernel
def set_att_channel(self, channel, value):
self.core.break_realtime()
self.mirny.set_att_mu(channel, value)
@kernel
def test_att_channel(self, channel):
for a in [0, 1, 2, 3, 4]:
self.core.break_realtime()
self.mirny.set_att_mu(channel, a)
delay(1*s)
def test_att(self):
print("ATTENUATION TEST")
print("*"*80)
for i in range(4):
input("\tConnect channel {}".format(i))
self.test_att_channel(i)
def run(self):
self.init()
self.test_rf_switch()
self.test_att()