forked from M-Labs/artiq
differentiate phaser modes
This commit is contained in:
parent
31663556b8
commit
a20087848d
|
@ -190,7 +190,7 @@ class Phaser:
|
||||||
|
|
||||||
def __init__(self, dmgr, channel_base, miso_delay=1, tune_fifo_offset=True,
|
def __init__(self, dmgr, channel_base, miso_delay=1, tune_fifo_offset=True,
|
||||||
clk_sel=0, sync_dly=0, dac=None, trf0=None, trf1=None,
|
clk_sel=0, sync_dly=0, dac=None, trf0=None, trf1=None,
|
||||||
core_device="core"):
|
mode="base", core_device="core"):
|
||||||
self.channel_base = channel_base
|
self.channel_base = channel_base
|
||||||
self.core = dmgr.get(core_device)
|
self.core = dmgr.get(core_device)
|
||||||
# TODO: auto-align miso-delay in phy
|
# TODO: auto-align miso-delay in phy
|
||||||
|
@ -230,6 +230,8 @@ class Phaser:
|
||||||
if debug:
|
if debug:
|
||||||
print("gw_rev:", gw_rev)
|
print("gw_rev:", gw_rev)
|
||||||
self.core.break_realtime()
|
self.core.break_realtime()
|
||||||
|
is_base = gw_rev == 1
|
||||||
|
is_miqro = gw_rev == 2
|
||||||
delay(.1*ms) # slack
|
delay(.1*ms) # slack
|
||||||
|
|
||||||
# allow a few errors during startup and alignment since boot
|
# allow a few errors during startup and alignment since boot
|
||||||
|
@ -350,32 +352,33 @@ class Phaser:
|
||||||
|
|
||||||
channel.set_servo(profile=0, enable=0, hold=1)
|
channel.set_servo(profile=0, enable=0, hold=1)
|
||||||
|
|
||||||
# test oscillators and DUC
|
if is_base:
|
||||||
for i in range(len(channel.oscillator)):
|
# test oscillators and DUC
|
||||||
oscillator = channel.oscillator[i]
|
for i in range(len(channel.oscillator)):
|
||||||
asf = 0
|
oscillator = channel.oscillator[i]
|
||||||
if i == 0:
|
asf = 0
|
||||||
asf = 0x7fff
|
if i == 0:
|
||||||
# 6pi/4 phase
|
asf = 0x7fff
|
||||||
oscillator.set_amplitude_phase_mu(asf=asf, pow=0xc000, clr=1)
|
# 6pi/4 phase
|
||||||
|
oscillator.set_amplitude_phase_mu(asf=asf, pow=0xc000, clr=1)
|
||||||
|
delay(1*us)
|
||||||
|
# 3pi/4
|
||||||
|
channel.set_duc_phase_mu(0x6000)
|
||||||
|
channel.set_duc_cfg(select=0, clr=1)
|
||||||
|
self.duc_stb()
|
||||||
|
delay(.1*ms) # settle link, pipeline and impulse response
|
||||||
|
data = channel.get_dac_data()
|
||||||
delay(1*us)
|
delay(1*us)
|
||||||
# 3pi/4
|
channel.oscillator[0].set_amplitude_phase_mu(asf=0, pow=0xc000,
|
||||||
channel.set_duc_phase_mu(0x6000)
|
clr=1)
|
||||||
channel.set_duc_cfg(select=0, clr=1)
|
delay(.1*ms)
|
||||||
self.duc_stb()
|
sqrt2 = 0x5a81 # 0x7fff/sqrt(2)
|
||||||
delay(.1*ms) # settle link, pipeline and impulse response
|
data_i = data & 0xffff
|
||||||
data = channel.get_dac_data()
|
data_q = (data >> 16) & 0xffff
|
||||||
delay(1*us)
|
# allow ripple
|
||||||
channel.oscillator[0].set_amplitude_phase_mu(asf=0, pow=0xc000,
|
if (data_i < sqrt2 - 30 or data_i > sqrt2 or
|
||||||
clr=1)
|
abs(data_i - data_q) > 2):
|
||||||
delay(.1*ms)
|
raise ValueError("DUC+oscillator phase/amplitude test failed")
|
||||||
sqrt2 = 0x5a81 # 0x7fff/sqrt(2)
|
|
||||||
data_i = data & 0xffff
|
|
||||||
data_q = (data >> 16) & 0xffff
|
|
||||||
# allow ripple
|
|
||||||
if (data_i < sqrt2 - 30 or data_i > sqrt2 or
|
|
||||||
abs(data_i - data_q) > 2):
|
|
||||||
raise ValueError("DUC+oscillator phase/amplitude test failed")
|
|
||||||
|
|
||||||
if is_baseband:
|
if is_baseband:
|
||||||
continue
|
continue
|
||||||
|
@ -826,6 +829,7 @@ class PhaserChannel:
|
||||||
self.trf_mmap = TRF372017(trf).get_mmap()
|
self.trf_mmap = TRF372017(trf).get_mmap()
|
||||||
|
|
||||||
self.oscillator = [PhaserOscillator(self, osc) for osc in range(5)]
|
self.oscillator = [PhaserOscillator(self, osc) for osc in range(5)]
|
||||||
|
self.miqro = Miqro(self)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def get_dac_data(self) -> TInt32:
|
def get_dac_data(self) -> TInt32:
|
||||||
|
@ -1139,7 +1143,7 @@ class PhaserChannel:
|
||||||
for data in [b0, b1, a1, offset]:
|
for data in [b0, b1, a1, offset]:
|
||||||
self.phaser.write16(addr, data)
|
self.phaser.write16(addr, data)
|
||||||
addr += 2
|
addr += 2
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_iir(self, profile, kp, ki=0., g=0., x_offset=0., y_offset=0.):
|
def set_iir(self, profile, kp, ki=0., g=0., x_offset=0., y_offset=0.):
|
||||||
"""Set servo profile IIR coefficients.
|
"""Set servo profile IIR coefficients.
|
||||||
|
@ -1269,3 +1273,10 @@ class PhaserOscillator:
|
||||||
raise ValueError("amplitude out of bounds")
|
raise ValueError("amplitude out of bounds")
|
||||||
pow = int32(round(phase*(1 << 16)))
|
pow = int32(round(phase*(1 << 16)))
|
||||||
self.set_amplitude_phase_mu(asf, pow, clr)
|
self.set_amplitude_phase_mu(asf, pow, clr)
|
||||||
|
|
||||||
|
|
||||||
|
class Miqro:
|
||||||
|
def __init__(self, channel):
|
||||||
|
self.channel = channel
|
||||||
|
self.base_addr = (self.channel.phaser.channel_base + 1 +
|
||||||
|
self.channel.index) << 8
|
||||||
|
|
|
@ -559,6 +559,7 @@ class PeripheralManager:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def process_phaser(self, rtio_offset, peripheral):
|
def process_phaser(self, rtio_offset, peripheral):
|
||||||
|
mode = peripheral.get("mode", "base")
|
||||||
self.gen("""
|
self.gen("""
|
||||||
device_db["{name}"] = {{
|
device_db["{name}"] = {{
|
||||||
"type": "local",
|
"type": "local",
|
||||||
|
@ -567,11 +568,14 @@ class PeripheralManager:
|
||||||
"arguments": {{
|
"arguments": {{
|
||||||
"channel_base": 0x{channel:06x},
|
"channel_base": 0x{channel:06x},
|
||||||
"miso_delay": 1,
|
"miso_delay": 1,
|
||||||
|
"mode": "{mode}"
|
||||||
}}
|
}}
|
||||||
}}""",
|
}}""",
|
||||||
name=self.get_name("phaser"),
|
name=self.get_name("phaser"),
|
||||||
|
mode=mode,
|
||||||
channel=rtio_offset)
|
channel=rtio_offset)
|
||||||
return 5
|
rtio_channels = {"base": 5, "miqro": 3}[mode]
|
||||||
|
return rtio_channels
|
||||||
|
|
||||||
def process_hvamp(self, rtio_offset, peripheral):
|
def process_hvamp(self, rtio_offset, peripheral):
|
||||||
hvamp_name = self.get_name("hvamp")
|
hvamp_name = self.get_name("hvamp")
|
||||||
|
|
|
@ -709,11 +709,11 @@ class Phaser(_EEM):
|
||||||
) for pol in "pn"]
|
) for pol in "pn"]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_std(cls, target, eem, mode, iostandard=default_iostandard):
|
def add_std(cls, target, eem, mode="base", iostandard=default_iostandard):
|
||||||
cls.add_extension(target, eem, iostandard=iostandard)
|
cls.add_extension(target, eem, iostandard=iostandard)
|
||||||
|
|
||||||
if mode == "phaser":
|
if mode == "base":
|
||||||
phy = phaser.Phaser(
|
phy = phaser.Base(
|
||||||
target.platform.request("phaser{}_ser_p".format(eem)),
|
target.platform.request("phaser{}_ser_p".format(eem)),
|
||||||
target.platform.request("phaser{}_ser_n".format(eem)))
|
target.platform.request("phaser{}_ser_n".format(eem)))
|
||||||
target.submodules += phy
|
target.submodules += phy
|
||||||
|
|
|
@ -28,7 +28,7 @@ class DDSChannel(Module):
|
||||||
[Cat(i.a, i.clr, i.p) for i in self.dds.i])
|
[Cat(i.a, i.clr, i.p) for i in self.dds.i])
|
||||||
|
|
||||||
|
|
||||||
class Phaser(Module):
|
class Base(Module):
|
||||||
def __init__(self, pins, pins_n):
|
def __init__(self, pins, pins_n):
|
||||||
self.rtlink = rtlink.Interface(
|
self.rtlink = rtlink.Interface(
|
||||||
rtlink.OInterface(data_width=8, address_width=8,
|
rtlink.OInterface(data_width=8, address_width=8,
|
||||||
|
|
Loading…
Reference in New Issue