forked from M-Labs/artiq
1
0
Fork 0

pdq2: redo program serialization, cleanup

This commit is contained in:
Robert Jördens 2016-02-21 17:34:18 +01:00
parent 294eac19fe
commit 7c246b3559
1 changed files with 26 additions and 41 deletions

View File

@ -23,12 +23,13 @@ class Segment:
def __init__(self): def __init__(self):
self.data = b"" self.data = b""
self.addr = None
def line(self, typ, duration, data, trigger=False, silence=False, def line(self, typ, duration, data, trigger=False, silence=False,
aux=False, shift=0, jump=False, clear=False, wait=False): aux=False, shift=0, jump=False, clear=False, wait=False):
assert len(data) % 2 == 0, data assert len(data) % 2 == 0, data
assert len(data)//2 <= 14 assert len(data)//2 <= 14
#assert dt*(1 << shift) > 1 + len(data)//2 # assert dt*(1 << shift) > 1 + len(data)//2
header = ( header = (
1 + len(data)//2 | (typ << 4) | (trigger << 6) | (silence << 7) | 1 + len(data)//2 | (typ << 4) | (trigger << 6) | (silence << 7) |
(aux << 8) | (shift << 9) | (jump << 13) | (clear << 14) | (aux << 8) | (shift << 9) | (jump << 13) | (clear << 14) |
@ -92,7 +93,7 @@ class Channel:
self.segments = [] self.segments = []
def clear(self): def clear(self):
del self.segments[:] self.segments.clear()
def new_segment(self): def new_segment(self):
segment = Segment() segment = Segment()
@ -149,10 +150,6 @@ class Pdq2:
self.dev.close() self.dev.close()
del self.dev del self.dev
def clear_all(self):
for channel in self.channels:
channel.clear()
def write(self, data): def write(self, data):
logger.debug("> %r", data) logger.debug("> %r", data)
written = self.dev.write(data) written = self.dev.write(data)
@ -172,30 +169,11 @@ class Pdq2:
data = data.replace(self._escape, self._escape + self._escape) data = data.replace(self._escape, self._escape + self._escape)
self.write(data) self.write(data)
def write_channel(self, channel): def flush(self):
self.write_mem(self.channels.index(channel), self.dev.flush()
channel.serialize())
def write_all(self): def program_segments(self, segments, data):
for channel in self.channels: for i, line in enumerate(data):
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
dac_divider = line.get("dac_divider", 1) dac_divider = line.get("dac_divider", 1)
shift = int(log(dac_divider, 2)) shift = int(log(dac_divider, 2))
if 2**shift != dac_divider: if 2**shift != dac_divider:
@ -210,19 +188,26 @@ class Pdq2:
getattr(segment, target)( getattr(segment, target)(
shift=shift, duration=duration, trigger=trigger, shift=shift, duration=duration, trigger=trigger,
**target_data) **target_data)
# 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): def program(self, program, channels=None):
self.clear_all() if channels is None:
for frame_data in program: channels = range(self.num_channels)
self.program_frame(frame_data) chs = [self.channels[i] for i in channels]
self.write_all() 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, aux=1,
jump=True)
for channel, ch in zip(channels, chs):
self.write_mem(channel, ch.serialize())
def ping(self): def ping(self):
return True return True