forked from M-Labs/artiq
add set_window(), clean up api
This commit is contained in:
parent
27e3c044ed
commit
c5c5c30617
|
@ -51,6 +51,9 @@ PHASER_ADDR_SERVO_DATA_BASE = 0x32
|
||||||
PHASER_ADDR_MIQRO_MEM_ADDR = 0x72
|
PHASER_ADDR_MIQRO_MEM_ADDR = 0x72
|
||||||
PHASER_ADDR_MIQRO_MEM_DATA = 0x74
|
PHASER_ADDR_MIQRO_MEM_DATA = 0x74
|
||||||
|
|
||||||
|
# Miqro profile memory select
|
||||||
|
PHASER_MIQRO_SEL_PROFILE = 1 << 14
|
||||||
|
|
||||||
PHASER_SEL_DAC = 1 << 0
|
PHASER_SEL_DAC = 1 << 0
|
||||||
PHASER_SEL_TRF0 = 1 << 1
|
PHASER_SEL_TRF0 = 1 << 1
|
||||||
PHASER_SEL_TRF1 = 1 << 2
|
PHASER_SEL_TRF1 = 1 << 2
|
||||||
|
@ -1405,8 +1408,7 @@ class Miqro:
|
||||||
for pro in range(32):
|
for pro in range(32):
|
||||||
self.set_profile_mu(osc, pro, 0, 0, 0)
|
self.set_profile_mu(osc, pro, 0, 0, 0)
|
||||||
delay(20*us)
|
delay(20*us)
|
||||||
self.set_window_mu(
|
self.set_window_mu(start=0, iq=[0], rate=1, shift=0, order=0, head=0, tail=1)
|
||||||
start=0, data=[[0, 0]], rate=1, shift=0, order=0, head=0, tail=1)
|
|
||||||
self.pulse(window=0, profiles=[0])
|
self.pulse(window=0, profiles=[0])
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
@ -1416,8 +1418,8 @@ class Miqro:
|
||||||
if profile >= 32:
|
if profile >= 32:
|
||||||
raise ValueError("invalid profile index")
|
raise ValueError("invalid profile index")
|
||||||
self.channel.phaser.write16(PHASER_ADDR_MIQRO_MEM_ADDR,
|
self.channel.phaser.write16(PHASER_ADDR_MIQRO_MEM_ADDR,
|
||||||
(self.channel.index << 15) | (1 << 14) | (oscillator << 6) |
|
(self.channel.index << 15) | PHASER_MIQRO_SEL_PROFILE |
|
||||||
(profile << 1))
|
(oscillator << 6) | (profile << 1))
|
||||||
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA, ftw)
|
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA, ftw)
|
||||||
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA,
|
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA,
|
||||||
(asf & 0xffff) | (pow << 16))
|
(asf & 0xffff) | (pow << 16))
|
||||||
|
@ -1433,10 +1435,10 @@ class Miqro:
|
||||||
self.set_profile_mu(oscillator, profile, ftw, asf, pow)
|
self.set_profile_mu(oscillator, profile, ftw, asf, pow)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_window_mu(self, start, data, rate=1, shift=0, order=0, head=0, tail=0):
|
def set_window_mu(self, start, iq, rate=1, shift=0, order=3, head=1, tail=1):
|
||||||
if start >= 1 << 10:
|
if start >= 1 << 10:
|
||||||
raise ValueError("start out of bouncs")
|
raise ValueError("start out of bouncs")
|
||||||
if len(data) >= 1 << 10:
|
if len(iq) >= 1 << 10:
|
||||||
raise ValueError("window length out of bounds")
|
raise ValueError("window length out of bounds")
|
||||||
if rate < 1 or rate > 1 << 12:
|
if rate < 1 or rate > 1 << 12:
|
||||||
raise ValueError("rate out of bounds")
|
raise ValueError("rate out of bounds")
|
||||||
|
@ -1447,18 +1449,35 @@ class Miqro:
|
||||||
self.channel.phaser.write16(PHASER_ADDR_MIQRO_MEM_ADDR,
|
self.channel.phaser.write16(PHASER_ADDR_MIQRO_MEM_ADDR,
|
||||||
(self.channel.index << 15) | start)
|
(self.channel.index << 15) | start)
|
||||||
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA,
|
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA,
|
||||||
((start + 1 + len(data)) & 0x3ff)
|
((start + 1 + len(iq)) & 0x3ff) |
|
||||||
| ((rate - 1) << 10)
|
((rate - 1) << 10) |
|
||||||
| (shift << 22)
|
(shift << 22) |
|
||||||
| (order << 28)
|
(order << 28) |
|
||||||
| ((head & 1) << 30)
|
((head & 1) << 30) |
|
||||||
| ((tail & 1) << 31)
|
((tail & 1) << 31)
|
||||||
)
|
)
|
||||||
for d in data:
|
for iqi in iq:
|
||||||
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA,
|
self.channel.phaser.write32(PHASER_ADDR_MIQRO_MEM_DATA, iqi)
|
||||||
(d[0] & 0xffff) | (d[1] << 16))
|
delay(10*us) # slack for long windows
|
||||||
delay(10*us)
|
return (start + 1 + len(iq)) & 0x3ff
|
||||||
return (start + 1 + len(data)) & 0x3ff
|
|
||||||
|
@kernel
|
||||||
|
def set_window(self, start, iq, period=4*ns, order=3, head=1, tail=1):
|
||||||
|
rate = int32(round(period/(4*ns)))
|
||||||
|
gain = 1.
|
||||||
|
for _ in range(order):
|
||||||
|
gain *= rate
|
||||||
|
shift = 0
|
||||||
|
while gain >= 2.:
|
||||||
|
shift += 1
|
||||||
|
gain *= .5
|
||||||
|
scale = ((1 << 15) - 1)/gain
|
||||||
|
iq_mu = [
|
||||||
|
(int32(round(iqi[0]*scale)) & 0xffff) |
|
||||||
|
(int32(round(iqi[1]*scale)) << 16)
|
||||||
|
for iqi in iq
|
||||||
|
]
|
||||||
|
self.set_window_mu(start, iq_mu, rate, shift, order, head, tail)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def encode(self, window, profiles, data):
|
def encode(self, window, profiles, data):
|
||||||
|
@ -1477,17 +1496,20 @@ class Miqro:
|
||||||
idx = 0
|
idx = 0
|
||||||
data[word] |= profile << idx
|
data[word] |= profile << idx
|
||||||
idx += 5
|
idx += 5
|
||||||
return word
|
return word + 1
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def pulse_mu(self, data):
|
def pulse_mu(self, data):
|
||||||
for word in range(len(data) - 1, -1, -1):
|
word = len(data)
|
||||||
rtio_output(self.base_addr + word, data[word])
|
delay_mu(-8*word) # back shift to align
|
||||||
|
while word > 0:
|
||||||
delay_mu(8)
|
delay_mu(8)
|
||||||
|
word -= 1
|
||||||
|
# final write sets pulse stb
|
||||||
|
rtio_output(self.base_addr + word, data[word])
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def pulse(self, window, profiles):
|
def pulse(self, window, profiles):
|
||||||
data = [0, 0, 0]
|
data = [0, 0, 0]
|
||||||
words = self.encode(window, profiles, data)
|
words = self.encode(window, profiles, data)
|
||||||
delay_mu(-8*words)
|
self.pulse_mu(data[:words])
|
||||||
self.pulse_mu(data[:words + 1])
|
|
||||||
|
|
Loading…
Reference in New Issue