@@ -42,11 +42,29 @@ class NovaTechDDS9M(IntermediateDevice):
4242 clock_limit = 9990 # This is a realistic estimate of the max clock rate (100us for TS/pin10 processing to load next value into buffer and 100ns pipeline delay on pin 14 edge to update output values)
4343
4444 @set_passed_properties (
45- property_names = {'connection_table_properties' : ['com_port' , 'baud_rate' , 'default_baud_rate' , 'update_mode' , 'synchronous_first_line_repeat' , 'phase_mode' ]}
46- )
47- def __init__ (self , name , parent_device ,
48- com_port = "" , baud_rate = 115200 , default_baud_rate = None , update_mode = 'synchronous' , synchronous_first_line_repeat = False , phase_mode = 'default' , ** kwargs ):
49-
45+ property_names = {
46+ 'connection_table_properties' : [
47+ 'com_port' ,
48+ 'baud_rate' ,
49+ 'default_baud_rate' ,
50+ 'update_mode' ,
51+ 'synchronous_first_line_repeat' ,
52+ 'phase_mode' ,
53+ ]
54+ }
55+ )
56+ def __init__ (
57+ self ,
58+ name ,
59+ parent_device ,
60+ com_port = "" ,
61+ baud_rate = 115200 ,
62+ default_baud_rate = None ,
63+ update_mode = 'synchronous' ,
64+ synchronous_first_line_repeat = False ,
65+ phase_mode = 'continuous' ,
66+ ** kwargs
67+ ):
5068 IntermediateDevice .__init__ (self , name , parent_device , ** kwargs )
5169 self .BLACS_connection = '%s,%s' % (com_port , str (baud_rate ))
5270
@@ -59,8 +77,8 @@ def __init__(self, name, parent_device,
5977 if not default_baud_rate in bauds and default_baud_rate is not None :
6078 raise LabscriptError ('default_baud_rate must be one of {0} or None (to indicate no default)' .format (list (bauds )))
6179
62- if not phase_mode in ['default' , ' aligned' , 'continuous' ]:
63- raise LabscriptError ('phase_mode must be \' default \' , \' aligned\' or \' continuous\' ' )
80+ if not phase_mode in ['aligned' , 'continuous' ]:
81+ raise LabscriptError ('phase_mode must be \' aligned\' or \' continuous\' ' )
6482
6583 self .update_mode = update_mode
6684 self .phase_mode = phase_mode
@@ -251,7 +269,7 @@ def initialise_GUI(self):
251269 connection_object = self .settings ['connection_table' ].find_by_name (self .device_name )
252270 connection_table_properties = connection_object .properties
253271
254- self .phase_mode = connection_table_properties .get ('phase_mode' , 'default ' )
272+ self .phase_mode = connection_table_properties .get ('phase_mode' , 'continuous ' )
255273
256274 self .com_port = connection_table_properties .get ('com_port' , None )
257275 self .baud_rate = connection_table_properties .get ('baud_rate' , None )
@@ -327,10 +345,14 @@ def init(self):
327345
328346 # Set phase mode method
329347 phase_mode_commands = {
330- 'default' : b'm 0' ,
331348 'aligned' : b'm a' ,
332349 'continuous' : b'm n' ,
333350 }
351+
352+ # Backward compat for shots compiled with phase_mode='default', which was based
353+ # on a misunderstanding of the working of the device and never did anything.
354+ phase_mode_commands ['default' ] = phase_mode_commands ['continuous' ]
355+
334356 self .phase_mode_command = phase_mode_commands [self .phase_mode ]
335357
336358 self .connection .write (b'e d\r \n ' )
@@ -346,6 +368,12 @@ def init(self):
346368 if self .connection .readline () != b"OK\r \n " :
347369 raise Exception ('Error: Failed to execute command: "I a"' )
348370
371+ # Ensure we are in single-tone mode:
372+ self .connection .write (b'm 0\r \n ' )
373+ if self .connection .readline () != b"OK\r \n " :
374+ raise Exception ('Error: Failed to execute command: "m 0"' )
375+
376+ # Set the phase mode:
349377 self .connection .write (b'%s\r \n ' % self .phase_mode_command )
350378 if self .connection .readline () != b"OK\r \n " :
351379 raise Exception ('Error: Failed to execute command: "%s"' % self .phase_mode .decode ('utf8' ))
@@ -412,15 +440,19 @@ def program_static(self,channel,type,value):
412440
413441 def transition_to_buffered (self ,device_name ,h5file ,initial_values ,fresh ):
414442
415- # Pretty please reset your memory pointer to zero:
443+ # The "double clutch" trick: switching to table mode and back again, before
444+ # going into table mode for real, is observed empirically to resolve an
445+ # off-by-one error in table mode in some circumstances. Presumably it resets the
446+ # memory pointer of the device to zero (though it is a mystery why it would not
447+ # be zero already at this point)
416448
417449 # Transition to table mode:
418450 self .connection .write (b'm t\r \n ' )
419451 self .connection .readline ()
420452 # And back to manual mode
421- self .connection .write (b'%s \r \n ' % self . phase_mode_command )
453+ self .connection .write (b'm 0 \r \n ' )
422454 if self .connection .readline () != b"OK\r \n " :
423- raise Exception ('Error: Failed to execute command: "%s"' % self . phase_mode_command . decode ( 'utf8' ) )
455+ raise Exception ('Error: Failed to execute command: "m 0"' )
424456
425457
426458 # Store the initial values in case we have to abort and restore them:
@@ -525,9 +557,9 @@ def abort_buffered(self):
525557 return self .transition_to_manual (True )
526558
527559 def transition_to_manual (self ,abort = False ):
528- self .connection .write (b'%s \r \n ' % self . phase_mode_command )
560+ self .connection .write (b'm 0 \r \n ' )
529561 if self .connection .readline () != b"OK\r \n " :
530- raise Exception ('Error: Failed to execute command: "%s"' % self . phase_mode_command . decode ( 'utf8' ) )
562+ raise Exception ('Error: Failed to execute command: "m 0"' )
531563 self .connection .write (b'I a\r \n ' )
532564 if self .connection .readline () != b"OK\r \n " :
533565 raise Exception ('Error: Failed to execute command: "I a"' )
0 commit comments