Skip to content

Commit

Permalink
Husky triggering updates.
Browse files Browse the repository at this point in the history
1. Allow SAD to generate triggers when not armed (i.e. after the ADC
capture is done).
2. Retrieve timestamped trigger times (when using multiple triggers).
  • Loading branch information
jpcrypt committed Jul 27, 2023
1 parent 3a94d8d commit 3abe847
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
ADDR_IOREAD = 59
ADDR_EDGE_TRIGGER = 113
ADDR_SOFTPOWER_CONTROL = 115
ADDR_NUM_TRIGGERS_STAT = 117
ADDR_NUM_TRIGGERS_DATA = 118

# API aliases for the TIO settings
_tio_alias = {
Expand Down Expand Up @@ -1158,6 +1160,55 @@ def edges_seen(self):
"""
return int.from_bytes(self.cwe.oa.sendMessage(CODE_READ, ADDR_EDGE_TRIGGER, Validate=False, maxResp=2), byteorder='little')

def get_trigger_times(self):
"""Retrieve the timestamped trigger times.
When multiple triggers occur, the number of ADC clock cycles between
successive triggers is recorded. Up to 1024 triggers can be
timestamped. The counter for each timestamp is 32-bits wide; overflows
are noted. Recorded triggers are automatically reset when the scope is
armed.
"""
if self._trigger_times_empty():
return None
else:
if self._trigger_times_overflow():
scope_logger.warning('Trigger times FIFO overflowed (too many triggers occured).')
self.cwe.oa.sendMessage(CODE_WRITE, ADDR_NUM_TRIGGERS_STAT, [1]) # clears the overflow flag
times = []
while not self._trigger_times_empty():
self.cwe.oa.sendMessage(CODE_WRITE, ADDR_NUM_TRIGGERS_DATA, [1])
raw = int.from_bytes(self.cwe.oa.sendMessage(CODE_READ, ADDR_NUM_TRIGGERS_DATA, Validate=False, maxResp=4), byteorder='little')
if raw == 2**32-1 and len(times): # don't care about overflow on first entry
scope_logger.error('Trigger times counter overflowed (more than 2**32 cycles between successive triggers).')
else:
times.append(raw)
if self._trigger_times_underflow():
scope_logger.error('Internal error: trigger times FIFO underflowed.')
return times[1:]


def _trigger_times_empty(self):
if self.cwe.oa.sendMessage(CODE_READ, ADDR_NUM_TRIGGERS_STAT, Validate=False, maxResp=1)[0] & 1:
return True
else:
return False

def _trigger_times_overflow(self):
if self.cwe.oa.sendMessage(CODE_READ, ADDR_NUM_TRIGGERS_STAT, Validate=False, maxResp=1)[0] & 2:
return True
else:
return False

def _trigger_times_underflow(self):
if self.cwe.oa.sendMessage(CODE_READ, ADDR_NUM_TRIGGERS_STAT, Validate=False, maxResp=1)[0] & 4:
return True
else:
return False





class SADTrigger(util.DisableNewAttr):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,8 @@ def fpga_mode(self):

@fpga_mode.setter
def fpga_mode(self, setting):
if not setting in range(0, 11):
raise ValueError("Must be integer in [0, 10]")
if not setting in range(0, 12):
raise ValueError("Must be integer in [0, 11]")
else:
self.oa.sendMessage(CODE_WRITE, ADDR_USERIO_DEBUG_SELECT, [setting])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
ADDR_SAD_SHORT = 107
ADDR_SAD_REF_BASE = 108
ADDR_SAD_VERSION = 114
ADDR_SAD_ALWAYS_ARMED = 116

CODE_READ = 0x80
CODE_WRITE = 0xC0
Expand Down Expand Up @@ -258,6 +259,7 @@ def _dict_repr(self):
rtn['half_pattern'] = self.half_pattern
rtn['multiple_triggers'] = self.multiple_triggers
rtn['num_triggers_seen'] = self.num_triggers_seen
rtn['always_armed'] = self.always_armed
return rtn

def __repr__(self):
Expand Down Expand Up @@ -468,8 +470,7 @@ def triggered(self, val):

@property
def num_triggers_seen(self):
"""SAD module status. Intended for debugging.
Indicates how many triggers were generated by the SAD module;
""" Indicates how many triggers were generated by the SAD module;
gets cleared by setting this (or triggered) to any value or by
re-arming.
"""
Expand All @@ -480,3 +481,19 @@ def num_triggers_seen(self):
def num_triggers_seen(self, val):
self.triggered = val

@property
def always_armed(self):
""" Control whether the SAD module can trigger without the scope being
armed. The intended use is to allow the SAD module to trigger after
the ADC capture has completed, which can be very useful when
calibrating the SAD threshold when using multiple SAD triggers.
"""
if self.oa.sendMessage(CODE_READ, ADDR_SAD_ALWAYS_ARMED, Validate=False, maxResp=1)[0]:
return True
else:
return False

@always_armed.setter
def always_armed(self, val):
self.oa.sendMessage(CODE_WRITE, ADDR_SAD_ALWAYS_ARMED, [val])

0 comments on commit 3abe847

Please sign in to comment.