-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #877 from spc-group/delay
Support for DG-645 digital delay/pulse generator
- Loading branch information
Showing
4 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
"""Ophyd definitions for digital delay and pulse generators.""" | ||
|
||
from ophyd import Device, Component as Cpt, EpicsSignal, EpicsSignalRO, Kind | ||
|
||
|
||
__all__ = ["DG645Delay"] | ||
|
||
|
||
class EpicsSignalWithIO(EpicsSignal): | ||
# An EPICS signal that simply uses the DG-645 convention of | ||
# 'AO' being the setpoint and 'AI' being the read-back | ||
|
||
def __init__(self, prefix, **kwargs): | ||
super().__init__(f"{prefix}I", write_pv=f"{prefix}O", **kwargs) | ||
|
||
|
||
class DG645Channel(Device): | ||
reference = Cpt(EpicsSignalWithIO, "ReferenceM", kind=Kind.config) | ||
delay = Cpt(EpicsSignalWithIO, "DelayA", kind=Kind.normal) | ||
|
||
|
||
class DG645Output(Device): | ||
output_mode_ttl = Cpt(EpicsSignal, "OutputModeTtlSS.PROC", kind=Kind.omitted) | ||
output_mode_nim = Cpt(EpicsSignal, "OutputModeNimSS.PROC", kind=Kind.omitted) | ||
polarity = Cpt(EpicsSignalWithIO, "OutputPolarityB", kind=Kind.config) | ||
amplitude = Cpt(EpicsSignalWithIO, "OutputAmpA", kind=Kind.config) | ||
offset = Cpt(EpicsSignalWithIO, "OutputOffsetA", kind=Kind.config) | ||
|
||
|
||
class DG645DelayOutput(DG645Output): | ||
trigger_prescale = Cpt(EpicsSignalWithIO, "TriggerPrescaleL", kind=Kind.config) | ||
trigger_phase = Cpt(EpicsSignalWithIO, "TriggerPhaseL", kind=Kind.config) | ||
|
||
|
||
class DG645Delay(Device): | ||
"""An SRS DG-645 digial delay/pulse generator. | ||
This device has four delayed outputs: AB, CD, EF, GH. | ||
Configuration of the output parameters (e.g. amplitude, polarity) | ||
is done using components ``output_AB``, etc. The individual delays | ||
for the start and end of the output pulse are configured using | ||
individual channels ``channel_A`` etc. | ||
There is also a ``T0`` output which is the reference pulses used | ||
for the remaining delayed outputs. | ||
""" | ||
|
||
# Individual delay channels | ||
channel_A = Cpt(DG645Channel, "A") | ||
channel_B = Cpt(DG645Channel, "B") | ||
channel_C = Cpt(DG645Channel, "C") | ||
channel_D = Cpt(DG645Channel, "D") | ||
channel_E = Cpt(DG645Channel, "E") | ||
channel_F = Cpt(DG645Channel, "F") | ||
channel_G = Cpt(DG645Channel, "G") | ||
channel_H = Cpt(DG645Channel, "H") | ||
|
||
# 2-channel delay outputs | ||
output_T0 = Cpt(DG645Output, "T0", kind=Kind.config) | ||
output_AB = Cpt(DG645DelayOutput, "AB", kind=Kind.config) | ||
output_CD = Cpt(DG645DelayOutput, "CD", kind=Kind.config) | ||
output_EF = Cpt(DG645DelayOutput, "EF", kind=Kind.config) | ||
output_GH = Cpt(DG645DelayOutput, "GH", kind=Kind.config) | ||
|
||
# General settings | ||
label = Cpt(EpicsSignal, "Label", kind=Kind.config) | ||
status = Cpt(EpicsSignalRO, "StatusSI", kind=Kind.omitted) | ||
clear_error = Cpt(EpicsSignal, "StatusClearBO", kind=Kind.omitted) | ||
device_id = Cpt(EpicsSignalRO, "IdentSI", kind=Kind.config) | ||
goto_remote = Cpt(EpicsSignal, "GotoRemoteBO", kind=Kind.omitted) | ||
goto_local = Cpt(EpicsSignal, "GotoLocalBO", kind=Kind.omitted) | ||
reset = Cpt(EpicsSignal, "ResetBO", kind=Kind.omitted) | ||
status_checking = Cpt(EpicsSignal, "StatusCheckingBO", kind=Kind.omitted) | ||
reset_serial = Cpt(EpicsSignal, "IfaceSerialResetBO", kind=Kind.omitted) | ||
serial_state = Cpt(EpicsSignalWithIO, "IfaceSerialStateB", kind=Kind.config) | ||
serial_baud = Cpt(EpicsSignalWithIO, "IfaceSerialBaudM", kind=Kind.config) | ||
reset_gpib = Cpt(EpicsSignal, "IfaceGpibResetBO", kind=Kind.omitted) | ||
gpib_state = Cpt(EpicsSignalWithIO, "IfaceGpibStateB", kind=Kind.config) | ||
gpib_address = Cpt(EpicsSignalWithIO, "IfaceGpibAddrL", kind=Kind.config) | ||
reset_lan = Cpt(EpicsSignal, "IfaceLanResetBO", kind=Kind.omitted) | ||
mac_address = Cpt(EpicsSignalRO, "IfaceMacAddrSI", kind=Kind.config) | ||
lan_state = Cpt(EpicsSignalWithIO, "IfaceLanStateB", kind=Kind.config) | ||
dhcp_state = Cpt(EpicsSignalWithIO, "IfaceDhcpStateB", kind=Kind.config) | ||
autoip_state = Cpt(EpicsSignalWithIO, "IfaceAutoIpStateB", kind=Kind.config) | ||
static_ip_state = Cpt(EpicsSignalWithIO, "IfaceStaticIpStateB", kind=Kind.config) | ||
bare_socket_state = Cpt(EpicsSignalWithIO, "IfaceBareSocketStateB", kind=Kind.config) | ||
telnet_state = Cpt(EpicsSignalWithIO, "IfaceTelnetStateB", kind=Kind.config) | ||
vxi11_state = Cpt(EpicsSignalWithIO, "IfaceVxiStateB", kind=Kind.config) | ||
ip_address = Cpt(EpicsSignalWithIO, "IfaceIpAddrS", kind=Kind.config) | ||
network_mask = Cpt(EpicsSignalWithIO, "IfaceNetMaskS", kind=Kind.config) | ||
gateway = Cpt(EpicsSignalWithIO, "IfaceGatewayS", kind=Kind.config) | ||
|
||
# Trigger control | ||
trigger_source = Cpt(EpicsSignalWithIO, "TriggerSourceM", kind=Kind.config) | ||
trigger_inhibit = Cpt(EpicsSignalWithIO, "TriggerInhibitM", kind=Kind.config) | ||
trigger_level = Cpt(EpicsSignalWithIO, "TriggerLevelA", kind=Kind.config) | ||
trigger_rate = Cpt(EpicsSignalWithIO, "TriggerRateA", kind=Kind.config) | ||
trigger_advanced_mode = Cpt(EpicsSignalWithIO, "TriggerAdvancedModeB", kind=Kind.config) | ||
trigger_holdoff = Cpt(EpicsSignalWithIO, "TriggerHoldoffA", kind=Kind.config) | ||
trigger_prescale = Cpt(EpicsSignalWithIO, "TriggerPrescaleL", kind=Kind.config) | ||
|
||
# Burst settings | ||
burst_mode = Cpt(EpicsSignalWithIO, "BurstModeB", kind=Kind.config) | ||
burst_count = Cpt(EpicsSignalWithIO, "BurstCountL", kind=Kind.config) | ||
burst_mode = Cpt(EpicsSignalWithIO, "BurstConfigB", kind=Kind.config) | ||
burst_delay = Cpt(EpicsSignalWithIO, "BurstDelayA", kind=Kind.config) | ||
burst_period = Cpt(EpicsSignalWithIO, "BurstPeriodA", kind=Kind.config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
""" | ||
test the SRS DG-645 digital delay device support | ||
Hardware is not available so test with best efforts | ||
""" | ||
|
||
from ...tests import IOC_GP | ||
from .. import delay | ||
|
||
PV_PREFIX = f"phony:{IOC_GP}DG645:" | ||
|
||
|
||
def test_dg645_device(): | ||
dg645 = delay.DG645Delay(PV_PREFIX, name="delay") | ||
assert not dg645.connected | ||
|
||
read_names = [ | ||
"channel_A", | ||
"channel_A.delay", | ||
"channel_B", | ||
"channel_B.delay", | ||
"channel_C", | ||
"channel_C.delay", | ||
"channel_D", | ||
"channel_D.delay", | ||
"channel_E", | ||
"channel_E.delay", | ||
"channel_F", | ||
"channel_F.delay", | ||
"channel_G", | ||
"channel_G.delay", | ||
"channel_H", | ||
"channel_H.delay", | ||
] | ||
assert sorted(dg645.read_attrs) == sorted(read_names) | ||
|
||
cfg_names = [ | ||
"autoip_state", | ||
"bare_socket_state", | ||
"burst_count", | ||
"burst_delay", | ||
"burst_mode", | ||
"burst_period", | ||
"channel_A", | ||
"channel_A.reference", | ||
"channel_B", | ||
"channel_B.reference", | ||
"channel_C", | ||
"channel_C.reference", | ||
"channel_D", | ||
"channel_D.reference", | ||
"channel_E", | ||
"channel_E.reference", | ||
"channel_F", | ||
"channel_F.reference", | ||
"channel_G", | ||
"channel_G.reference", | ||
"channel_H", | ||
"channel_H.reference", | ||
"device_id", | ||
"dhcp_state", | ||
"gateway", | ||
"gpib_address", | ||
"gpib_state", | ||
"ip_address", | ||
"label", | ||
"lan_state", | ||
"mac_address", | ||
"network_mask", | ||
"output_AB", | ||
"output_AB.amplitude", | ||
"output_AB.offset", | ||
"output_AB.polarity", | ||
"output_AB.trigger_phase", | ||
"output_AB.trigger_prescale", | ||
"output_CD", | ||
"output_CD.amplitude", | ||
"output_CD.offset", | ||
"output_CD.polarity", | ||
"output_CD.trigger_phase", | ||
"output_CD.trigger_prescale", | ||
"output_EF", | ||
"output_EF.amplitude", | ||
"output_EF.offset", | ||
"output_EF.polarity", | ||
"output_EF.trigger_phase", | ||
"output_EF.trigger_prescale", | ||
"output_GH", | ||
"output_GH.amplitude", | ||
"output_GH.offset", | ||
"output_GH.polarity", | ||
"output_GH.trigger_phase", | ||
"output_GH.trigger_prescale", | ||
"output_T0", | ||
"output_T0.amplitude", | ||
"output_T0.offset", | ||
"output_T0.polarity", | ||
"serial_baud", | ||
"serial_state", | ||
"static_ip_state", | ||
"telnet_state", | ||
"trigger_advanced_mode", | ||
"trigger_holdoff", | ||
"trigger_inhibit", | ||
"trigger_level", | ||
"trigger_prescale", | ||
"trigger_rate", | ||
"trigger_source", | ||
"vxi11_state", | ||
] | ||
assert sorted(dg645.configuration_attrs) == sorted(cfg_names) | ||
|
||
# List all the components | ||
cpt_names = [ | ||
"autoip_state", | ||
"bare_socket_state", | ||
"burst_count", | ||
"burst_delay", | ||
"burst_mode", | ||
"burst_period", | ||
"channel_A", | ||
"channel_B", | ||
"channel_C", | ||
"channel_D", | ||
"channel_E", | ||
"channel_F", | ||
"channel_G", | ||
"channel_H", | ||
"clear_error", | ||
"device_id", | ||
"dhcp_state", | ||
"gateway", | ||
"goto_local", | ||
"goto_remote", | ||
"gpib_address", | ||
"gpib_state", | ||
"ip_address", | ||
"label", | ||
"lan_state", | ||
"mac_address", | ||
"network_mask", | ||
"output_AB", | ||
"output_CD", | ||
"output_EF", | ||
"output_GH", | ||
"output_T0", | ||
"reset", | ||
"reset_gpib", | ||
"reset_lan", | ||
"reset_serial", | ||
"serial_baud", | ||
"serial_state", | ||
"static_ip_state", | ||
"status", | ||
"status_checking", | ||
"telnet_state", | ||
"trigger_advanced_mode", | ||
"trigger_holdoff", | ||
"trigger_inhibit", | ||
"trigger_level", | ||
"trigger_prescale", | ||
"trigger_rate", | ||
"trigger_source", | ||
"vxi11_state", | ||
] | ||
assert sorted(dg645.component_names) == sorted(cpt_names) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters