Skip to content

Commit 2d7a72c

Browse files
committed
Add ability to program prawnblaster via binary block command
1 parent e1f3d32 commit 2d7a72c

File tree

1 file changed

+56
-20
lines changed

1 file changed

+56
-20
lines changed

labscript_devices/PrawnBlaster/blacs_workers.py

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -292,27 +292,63 @@ def transition_to_buffered(self, device_name, h5file, initial_values, fresh):
292292

293293
# Program instructions
294294
for pseudoclock, pulse_program in enumerate(pulse_programs):
295-
for i, instruction in enumerate(pulse_program):
296-
if i == len(self.smart_cache[pseudoclock]):
297-
# Pad the smart cache out to be as long as the program:
298-
self.smart_cache[pseudoclock].append(None)
299-
300-
# Only program instructions that differ from what's in the smart cache:
301-
if self.smart_cache[pseudoclock][i] != instruction:
302-
self.prawnblaster.write(
303-
b"set %d %d %d %d\r\n"
304-
% (
305-
pseudoclock,
306-
i,
307-
instruction["half_period"],
308-
instruction["reps"],
295+
# check if it is more efficient to fully refresh
296+
if not fresh and self.smart_cache[pseudoclock] is not None:
297+
# get more convenient handles to smart cache arrays
298+
curr_inst = self.smart_cache[pseudoclock]
299+
300+
# if arrays aren't of same shape, only compare up to smaller array size
301+
n_curr = len(curr_inst)
302+
n_new = len(pulse_program)
303+
if n_curr > n_new:
304+
# technically don't need to reprogram current elements beyond end of new elements
305+
new_inst = np.sum(curr_inst[:n_new] != pulse_program)
306+
elif n_curr < n_new:
307+
n_diff = n_new - n_curr
308+
val_diffs = np.sum(curr_inst != pulse_program[:n_curr])
309+
new_inst = val_diffs + n_diff
310+
else:
311+
new_inst = np.sum(curr_inst != inst)
312+
313+
if new_inst / total_inst > 0.1:
314+
fresh = True
315+
316+
if fresh or self.smart_cache[pseudoclock] is None:
317+
print('programming from scratch')
318+
self.prawnblaster.write(b"setb %d %d %d\r\n" % (pseudoclock, 0, len(pulse_program)))
319+
serial_buffer = b''
320+
for i in range(0, len(pulse_program)):
321+
serial_buffer += struct.pack('<I', pulse_program[i]['half_period'])
322+
serial_buffer += struct.pack('<I', pulse_program[i]['reps'])
323+
self.prawnblaster.write(serial_buffer)
324+
response = self.prawnblaster.readline().decode()
325+
assert (
326+
response == "ok\r\n"
327+
), f"PrawnBlaster said '{response}', expected 'ok'"
328+
self.smart_cache[pseudoclock] = pulse_program
329+
else:
330+
print('incremental programming')
331+
for i, instruction in enumerate(pulse_program):
332+
if i == len(self.smart_cache[pseudoclock]):
333+
# Pad the smart cache out to be as long as the program:
334+
self.smart_cache[pseudoclock].append(None)
335+
336+
# Only program instructions that differ from what's in the smart cache:
337+
if self.smart_cache[pseudoclock][i] != instruction:
338+
self.prawnblaster.write(
339+
b"set %d %d %d %d\r\n"
340+
% (
341+
pseudoclock,
342+
i,
343+
instruction["half_period"],
344+
instruction["reps"],
345+
)
309346
)
310-
)
311-
response = self.prawnblaster.readline().decode()
312-
assert (
313-
response == "ok\r\n"
314-
), f"PrawnBlaster said '{response}', expected 'ok'"
315-
self.smart_cache[pseudoclock][i] = instruction
347+
response = self.prawnblaster.readline().decode()
348+
assert (
349+
response == "ok\r\n"
350+
), f"PrawnBlaster said '{response}', expected 'ok'"
351+
self.smart_cache[pseudoclock][i] = instruction
316352

317353
if not self.is_master_pseudoclock:
318354
# Start the Prawnblaster and have it wait for a hardware trigger

0 commit comments

Comments
 (0)