Skip to content

Commit 01f2a3e

Browse files
Merged in novatech_phase_mode_fix (pull request #78)
Fix issue #37: incorrect transition to manual/buffered semantics for novatech.
2 parents 9b6e047 + 8928c64 commit 01f2a3e

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

NovaTechDDS9M.py

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)