Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Litronlasertiming#6090 #12

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dg645Sup/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DB += dg645_logic.db
DB += dg645_delay.db
DB += dg645_width.db
DB += dg645_delay_width_shared.db
DB += litron.db

#=======================================
include $(TOP)/configure/RULES
144 changes: 144 additions & 0 deletions dg645Sup/litron.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
record(calc, "$(P)$(R)$(chan1=A)DLAYSCAL")
{
field(DESC, "Scaled raw value of ADELAY")
field(INPA, "$(P)$(R)$(chan1=A)DelayAI CP MS") # This is raw value scaled to 'us'
field(INPB, "1e6")
field(CALC, "A*B")
field(EGU, "us")
}

record(calc, "$(P)$(R)$(chan2=C)DLAYSCAL")
{
field(DESC, "Scaled raw value of CDELAY")
field(INPA, "$(P)$(R)$(chan2=C)DelayAI CP MS")
field(INPB, "1e6")
field(CALC, "A*B")
field(EGU, "us")
}

record(calc, "$(P)$(R)SUMMED_DELAY")
{
field(DESC, "Add dA & dC")
field(INPA, "$(P)$(R)$(chan1=A)DLAYSCAL CP MS")
field(INPB, "$(P)$(R)$(chan2=C)DLAYSCAL CP MS")
field(CALC, "A+B") # Add ADELAY & CDELAY
field(EGU, "us")
}

record(ai, "$(P)$(R)OFFSET")
{
field(DESC, "User Offset")
field(VAL, "0")
field(EGU, "us")
}

record(ai, "$(P)$(R)DELAY")
{
field(DESC, "User Delay")
field(VAL, "0")
field(EGU, "us")
}

record(calc, "$(P)$(R)SUMMED_VALUE")
{
field(DESC, "Add Delay Offset")
field(INPA, "$(P)$(R)DELAY CP")
field(INPB, "$(P)$(R)OFFSET CP")
field(CALC, "A+B") # Add DELAY & OFFSET
field(EGU, "us")
}

record(mbbo, "$(P)$(R)MODE")
{
field(DESC, "Device Mode. auto|1|2")
field(ZRST, "auto")
field(ONST, "1")
field(TWST, "2")
field(FLNK, "$(P)$(R)_MODEAUTOCHECK") # When mode changes then check if in mode auto
field(PINI, "YES")
field(VAL, "0")
}

record(calcout, "$(P)$(R)_MODEAUTOCHECK")
{
field(DESC, "Mode Auto Error Check")
field(INPA, "$(P)$(R)MODE")
field(INPB, "$(P)$(R)DELAY")
field(INPC, "$(P)$(R)OFFSET")
field(CALC, "A=1?A:(A=2?A:(B>ABS(C)?1:2))")
# If mode is 1 or 2 then return 1 or 2
# Else if DELAY > OFFSET return 1 else 2
field(OUT, "$(P)$(R)SET_MODE PP")
}

record(longout, "$(P)$(R)SET_MODE") # Send command to device to load settings from specified slot
{
field(DESC, "Load Settings from slot 0(default) - 9")
field(EGU, "")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT)) RECALL") # *RCL
}

record(calc, "$(P)$(R)_MODE1CHECK")
{
field(DESC, "Mode 1 Error Check")
field(INPA, "$(P)$(R)$(chan2=C)DLAYSCAL CP")
field(INPB, "$(P)$(R)SUMMED_VALUE CP")
field(CALC, "(A+B)>39900||B<0")
# If delay + summed_val bigger than 39900 or summed_val less than 0 then error
}

record(calc, "$(P)$(R)_MODE2CHECK")
{
field(DESC, "Mode 2 Error Check")
field(INPA, "$(P)$(R)$(chan2=C)DLAYSCAL CP")
field(INPB, "$(P)$(R)SUMMED_VALUE CP")
field(CALC, "B>39900||(A+B)<=0")
# If delay + summed_val less than or equal to 0 or summed_val bigger than 39900 then error
}

record(calc, "$(P)$(R)_BOTHCHECKS")
{
field(DESC, "Mode 1 & 2 Error Check")
field(INPA, "$(P)$(R)SET_MODE CP")
field(INPB, "$(P)$(R)_MODE1CHECK CP")
field(INPC, "$(P)$(R)_MODE2CHECK CP")
field(CALC, "(A=1)?B:C")
# If mode is 1 return _MODE1CHECK else _MODE2CHECK
}

record(calcout, "$(P)$(R)ERROR")
{
field(DESC, "Check Modes")
field(INPA, "$(P)$(R)SET_MODE CP")
field(INPB, "$(P)$(R)_BOTHCHECKS")
field(CALC, "A=0||B") # If no error then write delay when set
field(OOPT, "When Zero")
field(OUT, "$(P)$(R)_WRITE_DELAY PP")
field(DOPT, "Use OCAL")
field(OCAL, "1")
}

record(seq, "$(P)$(R)_WRITE_DELAY")
{
field(DESC, "Update Delay")
field(VAL, "0")

# 1) Units set
field(LNK1, "$(P)$(R)$(chan1=A)DELAYUNIT:SP")
field(DO1, "2")
# 2) Set t0
field(LNK2, "$(P)$(R)$(chan1=A)REFERENCE:SP")
field(DO2, "0")
# 3) Set delay A
field(LNK3, "$(P)$(R)$(chan1=A)DelayWriteAO")
field(DOL3, "$(P)$(R)SUMMED_VALUE")
# 4) Send
field(LNK4, "$(P)$(R)$(chan1=A)DELAYBUTTON")
field(DO4, "1")
# 5) *CLS (StatusClearBO)
field(LNK5, "$(P)$(R)StatusClearBO")
field(DO5, "1")

field(SELM, "All")
}
88 changes: 88 additions & 0 deletions system_tests/tests/dg645_llt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import unittest

from parameterized import parameterized
from utils.channel_access import ChannelAccess
from utils.ioc_launcher import ProcServLauncher, get_default_ioc_dir
from utils.test_modes import TestModes
from utils.testing import get_running_lewis_and_ioc

DEVICE_PREFIX = "DG645_01"
EMULATOR_NAME = "Dg645"

IOCS = [
{
"name": DEVICE_PREFIX,
"directory": get_default_ioc_dir("DG645"),
"macros": {
"APPLICATION": "LITRON",
},
"emulator": EMULATOR_NAME,
"ioc_launcher_class": ProcServLauncher,
},
]

TEST_MODES = [TestModes.DEVSIM]


class Dg645LLTTests(unittest.TestCase):
"""
Tests for the Dg645 Litron Laser Timing Control IOC.
"""

def setUp(self):
self._lewis, self._ioc = get_running_lewis_and_ioc(EMULATOR_NAME, DEVICE_PREFIX)
self.ca = ChannelAccess(device_prefix=DEVICE_PREFIX)

def test_Summed_Value(self):
self.ca.set_pv_value("OFFSET", 10)
self.ca.set_pv_value("DELAY", 20)
self.ca.assert_that_pv_is("SUMMED_VALUE", 30)

def test_Summed_Delay(self):
self.ca.set_pv_value("ADLAYSCAL", 10)
self.ca.set_pv_value("CDLAYSCAL", 20)
self.ca.set_pv_value("ADELAYBUTTON", 1)
self.ca.set_pv_value("CDELAYBUTTON", 1)
self.ca.assert_that_pv_is("SUMMED_DELAY", 30)

def test_Mode_Zero_Change_Mode_To_One(self):
self.ca.set_pv_value("DELAY", 10)
self.ca.set_pv_value("OFFSET", 5)
self.ca.set_pv_value("MODE", "auto")
self.ca.assert_that_pv_is("SET_MODE", 1)

def test_Mode_Zero_Change_Mode_To_Two(self):
self.ca.set_pv_value("DELAY", 5)
self.ca.set_pv_value("OFFSET", 5)
self.ca.set_pv_value("MODE", "auto")
self.ca.assert_that_pv_is("SET_MODE", 2)

@parameterized.expand([(0, 39900, 100, 1), (40000, 0, 0, 1), (10, -1, 0, 1), (10, -5, 5, 0)])
def test_Mode_One_Error_Check(self, cdelay, delay, offset, err):
self.ca.set_pv_value("CDELAY:SP", cdelay)
self.ca.set_pv_value("CDELAYUNIT:SP", "us")
self.ca.set_pv_value("CDELAYBUTTON", 1)
self.ca.set_pv_value("OFFSET", offset)
self.ca.set_pv_value("DELAY", delay)
self.ca.set_pv_value("MODE", "1")
self.ca.set_pv_value("ERROR.PROC", "1")
self.ca.assert_that_pv_is("ERROR", err)

@parameterized.expand(
[
(0, 40000, 0, 1),
(40000, 0, 0, 0),
(0, 0, 0, 1),
(10, -1, 0, 0),
(10, -5, -6, 1),
]
)
def test_Mode_Two_Error_Check(self, cdelay, delay, offset, err):
self.ca.set_pv_value("CDELAY:SP", cdelay)
self.ca.set_pv_value("CDELAYUNIT:SP", "us")
self.ca.set_pv_value("CDELAYBUTTON", 1)
self.ca.set_pv_value("OFFSET", offset)
self.ca.set_pv_value("DELAY", delay)
self.ca.set_pv_value("MODE", "2")
self.ca.set_pv_value("ERROR.PROC", "1")
self.ca.assert_that_pv_is("ERROR", err)
Loading