forked from M-Labs/artiq
pdq2: redo program serialization, cleanup
This commit is contained in:
parent
294eac19fe
commit
7c246b3559
|
@ -23,12 +23,13 @@ class Segment:
|
|||
|
||||
def __init__(self):
|
||||
self.data = b""
|
||||
self.addr = None
|
||||
|
||||
def line(self, typ, duration, data, trigger=False, silence=False,
|
||||
aux=False, shift=0, jump=False, clear=False, wait=False):
|
||||
assert len(data) % 2 == 0, data
|
||||
assert len(data)//2 <= 14
|
||||
#assert dt*(1 << shift) > 1 + len(data)//2
|
||||
# assert dt*(1 << shift) > 1 + len(data)//2
|
||||
header = (
|
||||
1 + len(data)//2 | (typ << 4) | (trigger << 6) | (silence << 7) |
|
||||
(aux << 8) | (shift << 9) | (jump << 13) | (clear << 14) |
|
||||
|
@ -92,7 +93,7 @@ class Channel:
|
|||
self.segments = []
|
||||
|
||||
def clear(self):
|
||||
del self.segments[:]
|
||||
self.segments.clear()
|
||||
|
||||
def new_segment(self):
|
||||
segment = Segment()
|
||||
|
@ -149,10 +150,6 @@ class Pdq2:
|
|||
self.dev.close()
|
||||
del self.dev
|
||||
|
||||
def clear_all(self):
|
||||
for channel in self.channels:
|
||||
channel.clear()
|
||||
|
||||
def write(self, data):
|
||||
logger.debug("> %r", data)
|
||||
written = self.dev.write(data)
|
||||
|
@ -172,30 +169,11 @@ class Pdq2:
|
|||
data = data.replace(self._escape, self._escape + self._escape)
|
||||
self.write(data)
|
||||
|
||||
def write_channel(self, channel):
|
||||
self.write_mem(self.channels.index(channel),
|
||||
channel.serialize())
|
||||
def flush(self):
|
||||
self.dev.flush()
|
||||
|
||||
def write_all(self):
|
||||
for channel in self.channels:
|
||||
self.write_mem(self.channels.index(channel),
|
||||
channel.serialize())
|
||||
|
||||
def write_table(self, channel):
|
||||
# no segment placement
|
||||
# no segment writing
|
||||
self.write_mem(channel, self.channels[channel].table())
|
||||
|
||||
def write_segment(self, channel, segment):
|
||||
# no collision check
|
||||
s = self.channels[channel].segments[segment]
|
||||
self.write_mem(channel, s.data, s.adr)
|
||||
|
||||
def program_frame(self, frame_data):
|
||||
segments = [c.new_segment() for c in self.channels]
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=10, aux=1)
|
||||
for i, line in enumerate(frame_data): # segments are concatenated
|
||||
def program_segments(self, segments, data):
|
||||
for i, line in enumerate(data):
|
||||
dac_divider = line.get("dac_divider", 1)
|
||||
shift = int(log(dac_divider, 2))
|
||||
if 2**shift != dac_divider:
|
||||
|
@ -210,19 +188,26 @@ class Pdq2:
|
|||
getattr(segment, target)(
|
||||
shift=shift, duration=duration, trigger=trigger,
|
||||
**target_data)
|
||||
|
||||
def program(self, program, channels=None):
|
||||
if channels is None:
|
||||
channels = range(self.num_channels)
|
||||
chs = [self.channels[i] for i in channels]
|
||||
for channel in chs:
|
||||
channel.clear()
|
||||
for frame in program:
|
||||
segments = [c.new_segment() for c in chs]
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=1, aux=1)
|
||||
self.program_segments(segments, frame)
|
||||
# append an empty line to stall the memory reader before jumping
|
||||
# through the frame table (`wait` does not prevent reading
|
||||
# the next line)
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=1,
|
||||
jump=True, aux=1)
|
||||
return segments
|
||||
|
||||
def program(self, program):
|
||||
self.clear_all()
|
||||
for frame_data in program:
|
||||
self.program_frame(frame_data)
|
||||
self.write_all()
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=1, aux=1,
|
||||
jump=True)
|
||||
for channel, ch in zip(channels, chs):
|
||||
self.write_mem(channel, ch.serialize())
|
||||
|
||||
def ping(self):
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue