@@ -126,11 +126,15 @@ def check_status(self):
126126 else :
127127 waits_pending = True
128128
129+ run_status , clock_status = self .read_status ()
130+ return run_status , clock_status , waits_pending
131+
132+ def read_status (self ):
129133 self .prawnblaster .write (b"status\r \n " )
130134 response = self .prawnblaster .readline ().decode ()
131135 match = re .match (r"run-status:(\d) clock-status:(\d)(\r\n)?" , response )
132136 if match :
133- return int (match .group (1 )), int (match .group (2 )), waits_pending
137+ return int (match .group (1 )), int (match .group (2 ))
134138 elif response :
135139 raise Exception (
136140 f"PrawnBlaster is confused: saying '{ response } ' instead of 'run-status:<int> clock-status:<int>'"
@@ -233,6 +237,10 @@ def transition_to_buffered(self, device_name, h5file, initial_values, fresh):
233237 ), f"PrawnBlaster said '{ response } ', expected 'ok'"
234238 self .smart_cache [pseudoclock ][i ] = instruction
235239
240+ if not self .is_master_pseudoclock :
241+ # Start the Prawnblaster and have it wait for a hardware trigger
242+ self .wait_for_trigger ()
243+
236244 # All outputs end on 0
237245 final = {}
238246 for pin in self .out_pins :
@@ -249,6 +257,28 @@ def start_run(self):
249257 # set started = True
250258 self .started = True
251259
260+ def wait_for_trigger (self ):
261+ # Set to wait for trigger:
262+ self .logger .info ("sending hwstart" )
263+ self .prawnblaster .write (b"hwstart\r \n " )
264+ response = self .prawnblaster .readline ().decode ()
265+ assert response == "ok\r \n " , f"PrawnBlaster said '{ response } ', expected 'ok'"
266+
267+ running = False
268+ while not running :
269+ run_status , clock_status = self .read_status ()
270+ # If we are running, great, the PrawnBlaster is waiting for a trigger
271+ if run_status == 2 :
272+ running = True
273+ # if we are not in TRANSITION_TO_RUNNING, then something has gone wrong
274+ # and we should raise an exception
275+ elif run_status != 1 :
276+ raise RuntimeError (f"Prawnblaster did not return an expected status. Status was { run_status } " )
277+ time .sleep (0.01 )
278+
279+ # set started = True
280+ self .started = True
281+
252282 def transition_to_manual (self ):
253283 if self .wait_table is not None :
254284 with h5py .File (self .h5_file , "a" ) as hdf5_file :
@@ -278,11 +308,15 @@ def shutdown(self):
278308 self .prawnblaster .close ()
279309
280310 def abort_buffered (self ):
281- self .prawnblaster .write (b"abort\r \n " )
282- assert self .prawnblaster .readline ().decode () == "ok\r \n "
283- # loop until abort complete
284- while self .check_status ()[0 ] != 5 :
285- time .sleep (0.5 )
311+ if not self .is_master_pseudoclock :
312+ # Only need to send abort signal if we have told the PrawnBlaster to wait
313+ # for a hardware trigger. Otherwise it's just been programmed with
314+ # instructions and there is nothing we need to do to abort.
315+ self .prawnblaster .write (b"abort\r \n " )
316+ assert self .prawnblaster .readline ().decode () == "ok\r \n "
317+ # loop until abort complete
318+ while self .read_status ()[0 ] != 5 :
319+ time .sleep (0.5 )
286320 return True
287321
288322 def abort_transition_to_buffered (self ):
0 commit comments