diff --git a/LinkamApp/Db/Linkam_T96.db b/LinkamApp/Db/Linkam_T96.db
index 6de88138017646bb6ed49e8982620a5f3dde7788..d3f0172f3c50bd23a1cd49b7ac2f480af5ccd48a 100644
--- a/LinkamApp/Db/Linkam_T96.db
+++ b/LinkamApp/Db/Linkam_T96.db
@@ -15,12 +15,13 @@ record(ao, "$(P)$(T):rampLimit")
{
field(DTYP, "asynFloat64")
field(OUT, "@asyn($(PORT),$(ADDR))RAMP_LIMIT_OUT_VALUE")
- #field(PINI, "YES")
+ field(PINI, "YES")
field(LINR, "NO CONVERSION")
field(PREC, "4")
field(EGU, "Celsius")
field(SCAN, "Passive")
- field(VAL, "22.0")
+ field(VAL, "20.0")
+ field(FLNK, "$(P)$(T):rampLimit_RBV")
}
record(ai, "$(P)$(T):rampLimit_RBV")
@@ -38,12 +39,13 @@ record(ao, "$(P)$(T):rampRate")
{
field(DTYP, "asynFloat64")
field(OUT, "@asyn($(PORT),$(ADDR))RAMP_RATE_OUT_VALUE")
- #field(PINI, "YES")
+ field(PINI, "YES")
field(LINR, "NO CONVERSION")
field(PREC, "4")
field(EGU, "Deg C / min")
field(SCAN, "Passive")
field(VAL, "20.0")
+ field(FLNK, "$(P)$(T):rampRate_RBV")
}
record(ai, "$(P)$(T):rampRate_RBV")
@@ -64,6 +66,8 @@ record(ai, "$(P)$(T):heaterPower_RBV")
field(PINI, "YES")
field(LINR, "NO CONVERSION")
field(PREC, "4")
+ field(HOPR, 100.0)
+ field(LOPR, 0.0)
field(EGU, "Watts")
field(SCAN, "Passive")
}
@@ -72,8 +76,189 @@ record(bo, "$(P)$(T):heating")
{
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR))HEATING_OUT_VALUE")
- #field(PINI, "YES")
+ field(PINI, "YES")
+ field(ZNAM, "Off")
+ field(ONAM, "On")
+ field(VAL, 0)
+}
+
+record(bo, "$(P)$(T):lnpMode")
+{
+ field(DTYP, "asynInt32")
+ field(OUT, "@asyn($(PORT),$(ADDR))LNP_MODE_OUT_VALUE")
+ #!field(PINI, "YES")
+ field(ZNAM, "Manual")
+ field(ONAM, "Auto")
+ field(VAL, 1)
+}
+
+record(longout, "$(P)$(T):lnpSpeed")
+{
+ field(DTYP, "asynInt32")
+ field(OUT, "@asyn($(PORT),$(ADDR))LNP_SPEED_OUT_VALUE")
+ #!field(PINI, "YES")
+ field(OMSL, "closed_loop")
+ field(DRVH, 100)
+ field(DRVL, 0)
+ field(VAL, 0)
+ field(HOPR, 100)
+ field(LOPR, 0)
+ field(EGU, "%")
+}
+
+record(ai, "$(P)$(T):lnpSpeed_RBV")
+{
+ field(DTYP, "asynFloat64")
+ field(INP, "@asyn($(PORT),$(ADDR))LNP_SPEED_IN_VALUE")
+ field(PINI, "YES")
+ field(LINR, "NO CONVERSION")
+ field(PREC, "4")
+ field(HOPR, 100)
+ field(LOPR, 0)
+ field(EGU, "%")
+ field(SCAN, "Passive")
+}
+
+record(bo, "$(P)$(T):vacuum")
+{
+ field(DTYP, "asynInt32")
+ field(OUT, "@asyn($(PORT),$(ADDR))VACUUM_OUT_VALUE")
+ #!field(PINI, "YES")
+ field(ZNAM, "Off")
+ field(ONAM, "On")
+ field(VAL, 0)
+}
+
+record(ao, "$(P)$(T):vacuumLimit")
+{
+ field(DTYP, "asynFloat64")
+ field(OUT, "@asyn($(PORT),$(ADDR))VACUUM_LIMIT_OUT_VALUE")
+ #!field(PINI, "YES")
+ field(LINR, "NO CONVERSION")
+ field(PREC, "4")
+ field(EGU, "mBar")
+ field(SCAN, "Passive")
+ field(VAL, "10.1325")
+ field(FLNK, "$(P)$(T):vacuumLimit_RBV")
+}
+
+record(ai, "$(P)$(T):vacuumLimit_RBV")
+{
+ field(DTYP, "asynFloat64")
+ field(INP, "@asyn($(PORT),$(ADDR))VACUUM_LIMIT_IN_VALUE")
+ field(PINI, "YES")
+ field(LINR, "NO CONVERSION")
+ field(PREC, "4")
+ field(EGU, "mBar")
+ field(SCAN, "Passive")
+}
+
+record(ai, "$(P)$(T):pressure_RBV")
+{
+ field(DTYP, "asynFloat64")
+ field(INP, "@asyn($(PORT),$(ADDR))PRESSURE_IN_VALUE")
+ field(PINI, "YES")
+ field(LINR, "NO CONVERSION")
+ field(PREC, "4")
+ field(EGU, "mBar")
+ field(SCAN, "Passive")
+}
+
+record(longin, "$(P)$(T):controllerConfig_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))CONTROLLER_CONFIG_IN_VALUE")
+ field(PINI, "YES")
+ field(EGU, "N/A")
+ field(SCAN, "Passive")
+}
+
+record(longin, "$(P)$(T):controllerError_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))CONTROLLER_ERROR_IN_VALUE")
+ field(PINI, "YES")
+ field(EGU, "N/A")
+ field(SCAN, "Passive")
+}
+
+record(longin, "$(P)$(T):controllerStatus_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))CONTROLLER_STATUS_IN_VALUE")
+ field(PINI, "YES")
+ field(EGU, "N/A")
+ field(SCAN, "Passive")
+}
+
+record(longin, "$(P)$(T):stageConfig_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STAGE_CONFIG_IN_VALUE")
+ field(PINI, "YES")
+ field(EGU, "N/A")
+ field(SCAN, "Passive")
+}
+
+record(bi, "$(P)$(T):statusError_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_CONTROLLER_ERROR")
+ field(ZNAM, "Ok")
+ field(ONAM, "Error")
+ field(SCAN, "I/O Intr")
+}
+
+record(bi, "$(P)$(T):rampAtLimit_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_RAMP_SETPOINT")
+ field(ZNAM, "No")
+ field(ONAM, "Yes")
+ field(SCAN, "I/O Intr")
+}
+
+record(bi, "$(P)$(T):heating_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_RAMP_STARTED")
field(ZNAM, "Off")
field(ONAM, "On")
- field(VAL, "0")
+ field(SCAN, "I/O Intr")
+}
+
+record(bi, "$(P)$(T):vacuumAtLimit_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_VACUUM_SETPOINT")
+ field(ZNAM, "No")
+ field(ONAM, "Yes")
+ field(SCAN, "I/O Intr")
+}
+
+record(bi, "$(P)$(T):vacuumStatus_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_VACUUM_STARTED")
+ field(ZNAM, "Off")
+ field(ONAM, "On")
+ field(SCAN, "I/O Intr")
+}
+
+record(bi, "$(P)$(T):lnpStatus_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_LNP_COOLING_STARTED")
+ field(ZNAM, "Off")
+ field(ONAM, "On")
+ field(SCAN, "I/O Intr")
+}
+
+record(bi, "$(P)$(T):lnpMode_RBV")
+{
+ field(DTYP, "asynInt32")
+ field(INP, "@asyn($(PORT),$(ADDR))STATUS_LNP_COOLING_AUTO")
+ field(ZNAM, "Manual")
+ field(ONAM, "Auto")
+ field(SCAN, "I/O Intr")
}
diff --git a/LinkamApp/Db/Linkam_T96_settings.req b/LinkamApp/Db/Linkam_T96_settings.req
new file mode 100644
index 0000000000000000000000000000000000000000..d995ad566db6a1511b5d98c9b4bf9e2d43b96c4c
--- /dev/null
+++ b/LinkamApp/Db/Linkam_T96_settings.req
@@ -0,0 +1,11 @@
+$(P)$(T):rampLimit
+$(P)$(T):rampRate
+$(P)$(T):heating
+$(P)$(T):lnpMode
+$(P)$(T):lnpSpeed
+$(P)$(T):vacuum
+$(P)$(T):vacuumLimit
+$(P)$(T):temperature_RBV.SCAN
+$(P)$(T):heaterPower_RBV.SCAN
+$(P)$(T):lnpSpeed_RBV.SCAN
+$(P)$(T):pressure_RBV.SCAN
diff --git a/LinkamApp/op/adl/Linkam_T96.adl b/LinkamApp/op/adl/Linkam_T96.adl
index 161a4bfc838312310b544d992adf50c6f20a7c0c..8282fda43cca27a08ba9bed80645a5b0b6aa1045 100644
--- a/LinkamApp/op/adl/Linkam_T96.adl
+++ b/LinkamApp/op/adl/Linkam_T96.adl
@@ -1,14 +1,14 @@
file {
- name="/home/oxygen40/KPETERSN/Current/Linkam/Linkam/LinkamApp/op/adl/Linkam_T96.adl"
+ name="/home/oxygen40/KPETERSN/Current/9idc_Linkam/Linkam_T96.adl"
version=030111
}
display {
object {
- x=10
- y=37
- width=400
- height=280
+ x=668
+ y=129
+ width=560
+ height=430
}
clr=14
bclr=4
@@ -87,27 +87,151 @@ display {
1a7309,
}
}
+text {
+ object {
+ x=15
+ y=10
+ width=530
+ height=30
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Linkam T96"
+ align="horiz. centered"
+}
+text {
+ object {
+ x=15
+ y=55
+ width=190
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Temperature"
+}
+text {
+ object {
+ x=15
+ y=85
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Ramp Limit"
+}
+text {
+ object {
+ x=15
+ y=115
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Ramp Rate (C/min)"
+}
+text {
+ object {
+ x=15
+ y=175
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Heating"
+}
"text update" {
object {
- x=50
- y=141
- width=150
- height=40
+ x=220
+ y=55
+ width=160
+ height=25
}
monitor {
chan="$(P)$(T):temperature_RBV"
clr=14
bclr=4
}
+ align="horiz. centered"
+ limits {
+ }
+}
+"text update" {
+ object {
+ x=385
+ y=85
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):rampLimit_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ limits {
+ }
+}
+"text update" {
+ object {
+ x=385
+ y=115
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):rampRate_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ limits {
+ }
+}
+"text entry" {
+ object {
+ x=220
+ y=85
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):rampLimit"
+ clr=14
+ bclr=4
+ }
+ limits {
+ }
+}
+"text entry" {
+ object {
+ x=220
+ y=115
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):rampRate"
+ clr=14
+ bclr=4
+ }
limits {
}
}
menu {
object {
- x=227
- y=143
- width=120
- height=35
+ x=385
+ y=55
+ width=160
+ height=25
}
control {
chan="$(P)$(T):temperature_RBV.SCAN"
@@ -115,89 +239,420 @@ menu {
bclr=4
}
}
+text {
+ object {
+ x=15
+ y=145
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Heater Power"
+}
+"text update" {
+ object {
+ x=220
+ y=145
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):heaterPower_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ limits {
+ }
+}
+menu {
+ object {
+ x=385
+ y=145
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):heaterPower_RBV.SCAN"
+ clr=14
+ bclr=4
+ }
+}
+"text update" {
+ object {
+ x=385
+ y=175
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):heating_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ format="string"
+ limits {
+ }
+}
+"related display" {
+ object {
+ x=445
+ y=395
+ width=100
+ height=25
+ }
+ display[0] {
+ label="asyn record"
+ name="asynRecord.adl"
+ args="P=$(P),R=$(R)"
+ }
+ clr=14
+ bclr=4
+ label="-More"
+}
+text {
+ object {
+ x=15
+ y=205
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="LN Pump Mode"
+}
+text {
+ object {
+ x=15
+ y=250
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="LN Pump Speed (%)"
+}
+menu {
+ object {
+ x=220
+ y=205
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):lnpMode.VAL"
+ clr=14
+ bclr=4
+ }
+}
+"text entry" {
+ object {
+ x=220
+ y=265
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):lnpSpeed.VAL"
+ clr=14
+ bclr=4
+ }
+ limits {
+ }
+}
+"text update" {
+ object {
+ x=220
+ y=235
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):lnpSpeed_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ limits {
+ }
+}
+menu {
+ object {
+ x=385
+ y=235
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):lnpSpeed_RBV.SCAN"
+ clr=14
+ bclr=4
+ }
+}
+text {
+ object {
+ x=15
+ y=295
+ width=190
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Pressure (mBar)"
+}
+"text update" {
+ object {
+ x=220
+ y=295
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):pressure_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ limits {
+ }
+}
+menu {
+ object {
+ x=385
+ y=295
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):pressure_RBV.SCAN"
+ clr=14
+ bclr=4
+ }
+}
+text {
+ object {
+ x=15
+ y=325
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Vac Limit (mBar)"
+}
+"text update" {
+ object {
+ x=385
+ y=325
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):vacuumLimit_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ limits {
+ }
+}
+"text entry" {
+ object {
+ x=220
+ y=325
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):vacuumLimit"
+ clr=14
+ bclr=4
+ }
+ limits {
+ }
+}
+text {
+ object {
+ x=15
+ y=355
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Vacuum"
+}
+menu {
+ object {
+ x=220
+ y=355
+ width=160
+ height=25
+ }
+ control {
+ chan="$(P)$(T):vacuum.VAL"
+ clr=14
+ bclr=4
+ }
+}
composite {
object {
- x=138
- y=210
- width=120
- height=42
+ x=220
+ y=175
+ width=160
+ height=25
}
"composite name"=""
children {
- text {
+ "message button" {
object {
- x=153
- y=210
- width=90
- height=20
- }
- "basic attribute" {
- clr=62
+ x=220
+ y=175
+ width=75
+ height=25
}
- "dynamic attribute" {
- vis="if not zero"
- chan="$(P)$(R).CNCT"
- }
- textix="Connected"
- align="horiz. right"
- }
- text {
- object {
- x=138
- y=210
- width=120
- height=20
- }
- "basic attribute" {
- clr=20
- }
- "dynamic attribute" {
- vis="if zero"
- chan="$(P)$(R).CNCT"
+ control {
+ chan="$(P)$(T):heating"
+ clr=0
+ bclr=63
}
- textix="Disconnected"
- align="horiz. right"
+ label="On"
+ release_msg="1"
}
- menu {
+ "message button" {
object {
- x=138
- y=232
- width=120
- height=20
+ x=305
+ y=175
+ width=75
+ height=25
}
control {
- chan="$(P)$(R).CNCT"
- clr=14
- bclr=51
+ chan="$(P)$(T):heating"
+ clr=0
+ bclr=22
}
+ label="Off"
+ release_msg="0"
}
}
}
-text {
+"text update" {
+ object {
+ x=385
+ y=205
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):lnpMode_RBV"
+ clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ format="string"
+ limits {
+ }
+}
+rectangle {
object {
- x=69
- y=12
- width=249
- height=52
+ x=210
+ y=55
+ width=8
+ height=25
}
"basic attribute" {
+ clr=17
+ }
+ "dynamic attribute" {
+ vis="if not zero"
+ calc="A"
+ chan="$(P)$(T):rampAtLimit_RBV"
+ }
+}
+"text update" {
+ object {
+ x=385
+ y=265
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):lnpStatus_RBV"
clr=14
+ bclr=4
+ }
+ align="horiz. centered"
+ format="string"
+ limits {
+ }
+}
+"text update" {
+ object {
+ x=385
+ y=355
+ width=160
+ height=25
+ }
+ monitor {
+ chan="$(P)$(T):vacuumStatus_RBV"
+ clr=14
+ bclr=4
}
- textix="Linkam T96"
align="horiz. centered"
+ format="string"
+ limits {
+ }
+}
+rectangle {
+ object {
+ x=210
+ y=295
+ width=8
+ height=25
+ }
+ "basic attribute" {
+ clr=17
+ }
+ "dynamic attribute" {
+ vis="if not zero"
+ calc="A"
+ chan="$(P)$(T):vacuumAtLimit_RBV"
+ }
+}
+text {
+ object {
+ x=15
+ y=385
+ width=200
+ height=25
+ }
+ "basic attribute" {
+ clr=14
+ }
+ textix="Controller Error"
}
"text update" {
object {
- x=51
- y=100
- width=300
- height=24
+ x=220
+ y=385
+ width=160
+ height=25
}
monitor {
- chan="$(P)$(T):temperature_RBV.NAME"
+ chan="$(P)$(T):statusError_RBV"
clr=14
bclr=4
}
+ align="horiz. centered"
+ format="string"
limits {
}
}
diff --git a/LinkamApp/op/adl/Linkam_T96.ui b/LinkamApp/op/adl/Linkam_T96.ui
new file mode 100644
index 0000000000000000000000000000000000000000..c9e06bb0957f1320fae04690cb1ea94f3df943ae
--- /dev/null
+++ b/LinkamApp/op/adl/Linkam_T96.ui
@@ -0,0 +1,1840 @@
+
+
+MainWindow
+
+
+
+ 668
+ 129
+ 560
+ 430
+
+
+
+
+
+QWidget#centralWidget {background: rgba(187, 187, 187, 255);}
+QPushButton::menu-indicator {image: url(none.png); width: 0}
+
+caTable {
+ font: 10pt;
+ background: cornsilk;
+ alternate-background-color: wheat;
+}
+
+caLineEdit {
+ border-radius: 1px;
+ background: lightyellow;
+ color: black;
+ }
+
+caTextEntry {
+ color: rgb(127, 0, 63);
+ background-color: cornsilk;
+ selection-color: #0a214c;
+ selection-background-color: wheat;
+ border: 1px groove black;
+ border-radius: 1px;
+ padding: 1px;
+}
+
+caTextEntry:focus {
+ padding: 0px;
+ border: 2px groove darkred;
+ border-radius: 1px;
+}
+
+QPushButton {
+ border-color: #00b;
+ border-radius: 2px;
+ padding: 3px;
+ border-width: 1px;
+
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 rgba(224, 239, 255, 255),
+ stop:0.5 rgba(199, 215, 230, 255),
+ stop:1 rgba(184, 214, 236, 255));
+}
+QPushButton:hover {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 rgba(201, 226, 255, 255),
+ stop:0.5 rgba(177, 204, 230, 255),
+ stop:1 rgba(163, 205, 236, 255));
+}
+QPushButton:pressed {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 rgba(174, 219, 255, 255),
+ stop:0.5 rgba(165, 199, 230, 255),
+ stop:1 rgba(134, 188, 236, 255));
+}
+
+QPushButton:disabled {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 rgba(174, 219, 255, 255),
+ stop:0.5 rgba(165, 199, 230, 255),
+ stop:1 rgba(134, 188, 236, 255));
+}
+
+caChoice {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,
+ stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
+}
+
+caChoice > QPushButton {
+ text-align: left;
+ padding: 1px;
+}
+
+/* when font specified, no font sizing is done any more, font: 10pt; is not bad. You could Enable this when you converted from .adl files
+caRelatedDisplay > QPushButton {
+font: 10pt;
+}
+
+caShellCommand > QPushButton {
+font: 10pt;
+}
+*/
+
+caSlider::groove:horizontal {
+border: 1px solid #bbb;
+background: lightgrey;
+height: 20px;
+border-radius: 4px;
+}
+
+caSlider::handle:horizontal {
+background: red;
+border: 1px solid #777;
+width: 13px;
+margin-top: -2px;
+margin-bottom: -2px;
+border-radius: 2px;
+}
+
+
+
+
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Linkam T96
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+ Qt::AlignAbsolute|Qt::AlignHCenter|Qt::AlignVCenter
+
+
+
+ 15
+ 10
+ 530
+ 30
+
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Temperature
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 55
+ 190
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Ramp Limit
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 85
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Ramp Rate (C/min)
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 115
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Heating
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 175
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 220
+ 55
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):temperature_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+ 385
+ 85
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):rampLimit_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+ 385
+ 115
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):rampRate_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+ 220
+ 85
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):rampLimit
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ caLineEdit::Static
+
+
+ decimal
+
+
+
+
+
+ 220
+ 115
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):rampRate
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ caLineEdit::Static
+
+
+ decimal
+
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Heater Power
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 145
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 220
+ 145
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):heaterPower_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+
+ 385
+ 175
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):heating_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ string
+
+
+ caLineEdit::Static
+
+
+
+
+
+ 445
+ 395
+ 100
+ 25
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ -More
+
+
+ Menu
+
+
+ asyn record
+
+
+ asynRecord.adl
+
+
+ P=$(P),R=$(R)
+
+
+ false
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ LN Pump Mode
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 205
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ LN Pump Speed (%)
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 250
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
+ 220
+ 265
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):lnpSpeed.VAL
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ caLineEdit::Static
+
+
+ decimal
+
+
+
+
+
+ 220
+ 235
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):lnpSpeed_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Pressure (mBar)
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 295
+ 190
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 220
+ 295
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):pressure_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Vac Limit (mBar)
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 325
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 385
+ 325
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):vacuumLimit_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ decimal
+
+
+ caLineEdit::Static
+
+
+
+
+
+ 220
+ 325
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):vacuumLimit
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ caLineEdit::Static
+
+
+ decimal
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Vacuum
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 355
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
+ 220
+ 175
+ 162
+ 27
+
+
+
+
+
+ 0
+ 0
+ 75
+ 25
+
+
+
+ EPushButton::WidthAndHeight
+
+
+ $(P)$(T):heating
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+ 40
+ 147
+ 21
+
+
+
+ On
+
+
+ 1
+
+
+ caMessageButton::Static
+
+
+
+
+
+ 85
+ 0
+ 75
+ 25
+
+
+
+ EPushButton::WidthAndHeight
+
+
+ $(P)$(T):heating
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+ 190
+ 25
+ 11
+
+
+
+ Off
+
+
+ 0
+
+
+ caMessageButton::Static
+
+
+
+
+
+
+ 385
+ 205
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):lnpMode_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ string
+
+
+ caLineEdit::Static
+
+
+
+
+ caGraphics::Rectangle
+
+
+
+ 210
+ 55
+ 8
+ 25
+
+
+
+
+ 51
+ 153
+ 0
+
+
+
+ Filled
+
+
+
+ 51
+ 153
+ 0
+
+
+
+ Solid
+
+
+ caGraphics::IfNotZero
+
+
+ A
+
+
+ $(P)$(T):rampAtLimit_RBV
+
+
+
+
+
+ 385
+ 265
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):lnpStatus_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ string
+
+
+ caLineEdit::Static
+
+
+
+
+
+ 385
+ 355
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):vacuumStatus_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ string
+
+
+ caLineEdit::Static
+
+
+
+
+ caGraphics::Rectangle
+
+
+
+ 210
+ 295
+ 8
+ 25
+
+
+
+
+ 51
+ 153
+ 0
+
+
+
+ Filled
+
+
+
+ 51
+ 153
+ 0
+
+
+
+ Solid
+
+
+ caGraphics::IfNotZero
+
+
+ A
+
+
+ $(P)$(T):vacuumAtLimit_RBV
+
+
+
+
+ QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+ Controller Error
+
+
+ ESimpleLabel::WidthAndHeight
+
+
+
+ 15
+ 385
+ 200
+ 25
+
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 220
+ 385
+ 160
+ 25
+
+
+
+ caLineEdit::WidthAndHeight
+
+
+ $(P)$(T):statusError_RBV
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ 187
+ 187
+ 187
+
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ caLineEdit::Channel
+
+
+ 0.0
+
+
+ 1.0
+
+
+ Qt::AlignAbsolute|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ string
+
+
+ caLineEdit::Static
+
+
+ caLabel_0
+ caLabel_1
+ caLabel_2
+ caLabel_3
+ caLabel_4
+ caLabel_5
+ caLabel_6
+ caLabel_7
+ caLabel_8
+ caLabel_9
+ caLabel_10
+ caFrame_0
+ caRectangle_0
+ caRectangle_1
+ caLabel_11
+ caLineEdit_0
+ caLineEdit_1
+ caLineEdit_2
+ caTextEntry_0
+ caTextEntry_1
+ caMenu_0
+ caLineEdit_3
+ caMenu_1
+ caLineEdit_4
+ caRelatedDisplay_0
+ caMenu_2
+ caTextEntry_2
+ caLineEdit_5
+ caMenu_3
+ caLineEdit_6
+ caMenu_4
+ caLineEdit_7
+ caTextEntry_3
+ caMenu_5
+ caMessageButton_0
+ caMessageButton_1
+ caLineEdit_8
+ caLineEdit_9
+ caLineEdit_10
+ caLineEdit_11
+
+
+
\ No newline at end of file
diff --git a/LinkamApp/src/Linkam_T96.cpp b/LinkamApp/src/Linkam_T96.cpp
index 9fb44291a8361f90de9042a5e276533c82b840a7..e871e7b102c55e87c4da74ecd6caf06646acf1cf 100644
--- a/LinkamApp/src/Linkam_T96.cpp
+++ b/LinkamApp/src/Linkam_T96.cpp
@@ -1,6 +1,9 @@
#include
-#include "dllImports.h"
-
+//#ifdef WINDOWS
+#include "dllHeader.h"
+//#else
+// #include "dllImports.h"
+//#endif
#include
#include
#include
@@ -11,15 +14,27 @@
// Is this needed?
using namespace std;
-Linkam::Linkam(const char *portName, const char *serialPort) : asynPortDriver(portName, MAX_CONTROLLERS,
+// This needs to come before the Linkam constructor to avoid compiler errors
+static void pollerThreadC(void * pPvt)
+{
+ Linkam *pLinkam = (Linkam *)pPvt;
+ pLinkam->pollerThread();
+}
+
+Linkam::Linkam(const char *portName, const epicsUInt32 commType, const epicsUInt32 commPort) : asynPortDriver(portName, MAX_CONTROLLERS,
asynInt32Mask | asynFloat64Mask | asynDrvUserMask,
asynInt32Mask | asynFloat64Mask,
ASYN_MULTIDEVICE | ASYN_CANBLOCK, 1, /* ASYN_CANBLOCK=0, ASYN_MULTIDEVICE=1, autoConnect=1 */
- 0, 0) /* Default priority and stack size */
+ 0, 0), /* Default priority and stack size */
+ pollTime_(DEFAULT_POLL_TIME)
{
- serialPort_ = epicsStrDup(serialPort);
static const char *functionName = "Linkam";
+ // Add validation in the future
+ commType_ = commType;
+ commPort_ = commPort;
+
+ //
createParam(temperatureInValueString, asynParamFloat64, &temperatureInValue_);
createParam(rampLimitOutValueString, asynParamFloat64, &rampLimitOutValue_);
createParam(rampLimitInValueString, asynParamFloat64, &rampLimitInValue_);
@@ -27,10 +42,32 @@ Linkam::Linkam(const char *portName, const char *serialPort) : asynPortDriver(po
createParam(rampRateInValueString, asynParamFloat64, &rampRateInValue_);
createParam(heaterPowerInValueString, asynParamFloat64, &heaterPowerInValue_);
createParam(heatingOutValueString, asynParamInt32, &heatingOutValue_);
-
- // Must be in the directory with the DLL when this line is executed
- LoadMonoLibrary("LinkamCommsDll.dll");
-
+ //
+ createParam(lnpModeOutValueString, asynParamInt32, &lnpModeOutValue_);
+ createParam(lnpSpeedOutValueString, asynParamInt32, &lnpSpeedOutValue_);
+ createParam(lnpSpeedInValueString, asynParamFloat64, &lnpSpeedInValue_);
+ //
+ createParam(vacuumOutValueString, asynParamInt32, &vacuumOutValue_);
+ createParam(vacuumLimitOutValueString, asynParamFloat64, &vacuumLimitOutValue_);
+ createParam(vacuumLimitInValueString, asynParamFloat64, &vacuumLimitInValue_);
+ createParam(pressureInValueString, asynParamFloat64, &pressureInValue_);
+ //
+ createParam(controllerConfigInValueString, asynParamInt32, &controllerConfigInValue_);
+ createParam(controllerErrorInValueString, asynParamInt32, &controllerErrorInValue_);
+ createParam(controllerStatusInValueString, asynParamInt32, &controllerStatusInValue_);
+ createParam(stageConfigInValueString, asynParamInt32, &stageConfigInValue_);
+ //
+ createParam(statusControllerErrorString, asynParamInt32, &statusControllerError_);
+ createParam(statusRampSetpointString, asynParamInt32, &statusRampSetpoint_);
+ createParam(statusRampStartedString, asynParamInt32, &statusRampStarted_);
+ createParam(statusVacuumSetpointString, asynParamInt32, &statusVacuumSetpoint_);
+ createParam(statusVacuumStartedString, asynParamInt32, &statusVacuumStarted_);
+ createParam(statusLnpCoolingStartedString, asynParamInt32, &statusLnpCoolingStarted_);
+ createParam(statusLnpCoolingAutoString, asynParamInt32, &statusLnpCoolingAuto_);
+
+ // Must be in the directory with the DLL when this line is executed
+ //LoadMonoLibrary("LinkamCommsDll.dll");
+
// Call to internal library method, will return wrapper version.
wrapperVersion_ = GetWrapperVersion();
printf("Using Wrapper Version %s\n", wrapperVersion_);
@@ -38,12 +75,29 @@ Linkam::Linkam(const char *portName, const char *serialPort) : asynPortDriver(po
libraryVersion_ = GetDllVersion();
printf("Comms Library Version %s\n", libraryVersion_);
- // Start poller? For now just initialize the temperature
-
// Force the device to connect now
connect(this->pasynUserSelf);
- //epicsThreadSleep(5.0);
+ //
+ readControllerConfig();
+
+ //
+ readStageConfig();
+
+ /*
+ * Initialize parameters here that need to be set because init record order is
+ * not predictable or because the corresponding records are PINI=NO
+ */
+ //setIntegerParam(variable_, 1);
+
+ // Start the poller
+ epicsThreadCreate("LinkamPoller",
+ epicsThreadPriorityLow,
+ epicsThreadGetStackSize(epicsThreadStackMedium),
+ (EPICSTHREADFUNC)pollerThreadC,
+ this);
+
+ //epicsThreadSleep(5.0);
}
Linkam::~Linkam()
@@ -71,10 +125,16 @@ asynStatus Linkam::connect(asynUser *pasynUser)
* 1, UInt32 u32Commtype: Connection protocol (0: USB, 1: Serial)
* 3); UInt32 u32CommPort: Set to the COMM port that the controller is connected to. (e.g. COMM port 3)
*/
- // OpenComms only works for Windows-style numbering of COM ports
- //commStatus_ = OpenComms(true, 1, 0);
this->lock();
- commStatus_ = OpenCommsFromDevice(true, serialPort_);
+ // OpenComms only works for Windows-style numbering of COM ports
+ //commStatus_ = OpenComms(true, 1, 1);
+ // USB on windows
+ //commStatus_ = OpenComms(true, 0, 6);
+ // A different call would be needed for Linux
+ //commStatus_ = OpenCommsFromDevice(true, serialPort_);
+ //
+ commStatus_ = OpenComms(true, commType_, commPort_);
+
this->unlock();
/* We found the controller and everything is OK. Signal to asynManager that we are connected. */
@@ -97,10 +157,15 @@ asynStatus Linkam::disconnect(asynUser *pasynUser)
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: Disconnecting...\n", driverName, functionName);
- // OpenComms only works for Windows-style numbering of COM ports
- //commStatus_ = OpenComms(false, 1, 0);
this->lock();
- commStatus_ = OpenCommsFromDevice(false, serialPort_);
+ //commStatus_ = OpenCommsFromDevice(false, serialPort_);
+ // OpenComms only works for Windows-style numbering of COM ports
+ //commStatus_ = OpenComms(false, 1, 1);
+ // USB on Windows
+ //commStatus_ = OpenComms(false, 1, 6);
+ //
+ commStatus_ = OpenComms(false, commType_, commPort_);
+
this->unlock();
/* We found the controller and everything is OK. Signal to asynManager that we are connected. */
@@ -115,7 +180,79 @@ asynStatus Linkam::disconnect(asynUser *pasynUser)
return asynSuccess;
}
+/*
+ *
+ * poller
+ *
+ */
+void Linkam::pollerThread()
+{
+ /* This function runs in a separate thread. It waits for the poll time. */
+ static const char *functionName = "pollerThread";
+ // Other variable declarations
+ epicsInt32 ival;
+ epicsFloat64 fval;
+
+ while (1)
+ {
+ lock();
+
+ // Get the controller status
+ this->controllerStatus_ = GetStatus();
+
+ /*
+ * Parse the controller status
+ */
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64ControllerError) ) ? 1 : 0;
+ setIntegerParam(statusControllerError_, ival);
+
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64Heater1RampSetpoint) ) ? 1 : 0;
+ setIntegerParam(statusRampSetpoint_, ival);
+
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64Heater1Started) ) ? 1 : 0;
+ setIntegerParam(statusRampStarted_, ival);
+
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64VacuumSetPoint) ) ? 1 : 0;
+ setIntegerParam(statusVacuumSetpoint_, ival);
+
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64VacuumControlStarted) ) ? 1 : 0;
+ setIntegerParam(statusVacuumStarted_, ival);
+
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64LnpCoolingStarted) ) ? 1 : 0;
+ setIntegerParam(statusLnpCoolingStarted_, ival);
+
+ ival = ( controllerStatus_ & ((epicsUInt64)1 << (int)u64LnpCoolingAuto) ) ? 1 : 0;
+ setIntegerParam(statusLnpCoolingAuto_, ival);
+
+ // Get the temperature
+ fval = GetValue(u32Heater1TempR);
+ setDoubleParam(temperatureInValue_, fval);
+
+ // Get the heater power
+ fval = GetValue(u32Heater1PowerR);
+ setDoubleParam(heaterPowerInValue_, fval);
+
+ // Get the LN pump speed
+ fval = GetValue(u32Heater1LnpSpeedR);
+ setDoubleParam(lnpSpeedInValue_, fval);
+
+ // Get the pressure
+ fval = GetValue(u32VacuumR);
+ setDoubleParam(pressureInValue_, fval);
+
+ callParamCallbacks();
+
+ unlock();
+ epicsThreadSleep(pollTime_);
+ }
+}
+
+/*
+ *
+ * readFloat64
+ *
+ */
asynStatus Linkam::readFloat64(asynUser *pasynUser, epicsFloat64 *value)
{
int function = pasynUser->reason;
@@ -126,25 +263,20 @@ asynStatus Linkam::readFloat64(asynUser *pasynUser, epicsFloat64 *value)
"%s:%s, port %s, function = %d\n",
driverName, functionName, this->portName, function);
- if (function == temperatureInValue_) {
-
- // Read the temperature from the controller
- status = readTemperature(value);
-
- } else if (function == rampLimitInValue_) {
+ if (function == rampLimitInValue_) {
- // Read the ramp limit from the controller
+ // Read the ramp limit from the controller (Celsius)
status = readRampLimit(value);
} else if (function == rampRateInValue_) {
- // Read the ramp rate from the controller
+ // Read the ramp rate from the controller (C/min)
status = readRampRate(value);
- } else if (function == heaterPowerInValue_) {
+ } else if (function == vacuumLimitInValue_) {
- // Read the temperature from the controller
- status = readHeaterPower(value);
+ // Read the vacuum limit from the controller (mBar)
+ status = readVacuumLimit(value);
} else {
status = asynPortDriver::readFloat64(pasynUser,value);
@@ -158,24 +290,6 @@ asynStatus Linkam::readFloat64(asynUser *pasynUser, epicsFloat64 *value)
return (status==0) ? asynSuccess : asynError;
}
-asynStatus Linkam::readTemperature(epicsFloat64 *value)
-{
- static const char *functionName = "readTemperature";
-
- this->lock();
- *value = GetValue(u32Heater1TempR);
- this->unlock();
- // There probably isn't a good reason to retain the temperature in a private variable;
- // The value is already stored in the parameter library
- temperatureRbv_ = *value;
-
- asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
- "%s:%s, port %s, value = %lf\n",
- driverName, functionName, this->portName, *value);
-
- return asynSuccess;
-}
-
asynStatus Linkam::readRampLimit(epicsFloat64 *value)
{
static const char *functionName = "readRampLimit";
@@ -206,22 +320,27 @@ asynStatus Linkam::readRampRate(epicsFloat64 *value)
return asynSuccess;
}
-asynStatus Linkam::readHeaterPower(epicsFloat64 *value)
+asynStatus Linkam::readVacuumLimit(epicsFloat64 *value)
{
- static const char *functionName = "readHeaterPower";
+ static const char *functionName = "readVacuumLimit";
this->lock();
- *value = GetValue(u32Heater1PowerR);
+ *value = GetValue(u32VacuumLimitRW);
this->unlock();
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, value = %lf\n",
- driverName, functionName, this->portName, temperatureRbv_);
+ driverName, functionName, this->portName, *value);
return asynSuccess;
}
+/*
+ *
+ * writeFloat64
+ *
+ */
asynStatus Linkam::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
{
int function = pasynUser->reason;
@@ -237,14 +356,19 @@ asynStatus Linkam::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
if (function == rampLimitOutValue_) {
- // Read the temperature from the controller
+ // set the desired temperature
status = setRampLimit(value);
} else if (function == rampRateOutValue_) {
- // Read the temperature from the controller
+ // set the desired ramp rate
status = setRampRate(value);
+ } else if (function == vacuumLimitOutValue_) {
+
+ // set the desired pressure
+ status = setVacuumLimit(value);
+
} else {
status = asynPortDriver::writeFloat64(pasynUser,value);
}
@@ -276,8 +400,7 @@ asynStatus Linkam::setRampLimit(epicsFloat64 value)
* Returns true if set successfully, false otherwise.
*/
this->lock();
- //status = SetValue(u32Heater1LimitRW, (float) value);
- status = SetValue(2, (float) value);
+ status = SetValue(u32Heater1LimitRW, (float) value);
this->unlock();
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
@@ -293,8 +416,48 @@ asynStatus Linkam::setRampRate(epicsFloat64 value)
static const char *functionName = "setRampRate";
this->lock();
- //status = SetValue(u32Heater1RateRW, (float) value);
- status = SetValue(1, (float) value);
+ status = SetValue(u32Heater1RateRW, (float) value);
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, value = %lf\n",
+ driverName, functionName, this->portName, value);
+
+ return (status) ? asynSuccess : asynError;
+}
+
+asynStatus Linkam::setVacuumLimit(epicsFloat64 value)
+{
+ bool status;
+ static const char *functionName = "setVacuumLimit";
+
+ this->lock();
+
+ if (controllerVacuumReady_)
+ {
+ if (stageVacuum_)
+ {
+ // Vacuum control is supported and ready
+ status = SetValue(u32VacuumLimitRW, (float) value);
+ }
+ else
+ {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting vacuum limit: stageVacuum_ = %d\n",
+ driverName, functionName, this->portName, stageVacuum_);
+ }
+ }
+ else
+ {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting vacuum limit: controllerVacuumReady_ = %d\n",
+ driverName, functionName, this->portName, controllerVacuumReady_);
+ }
+
this->unlock();
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
@@ -305,6 +468,11 @@ asynStatus Linkam::setRampRate(epicsFloat64 value)
}
+/*
+ *
+ * writeInt32
+ *
+ */
asynStatus Linkam::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
int function = pasynUser->reason;
@@ -323,7 +491,23 @@ asynStatus Linkam::writeInt32(asynUser *pasynUser, epicsInt32 value)
// Enable/disable heating
status = setHeating(value);
- }
+ } else if (function == lnpModeOutValue_) {
+
+ // Set Manual/Auto LNP mode
+ status = setLnpMode(value);
+
+ } else if (function == lnpSpeedOutValue_) {
+
+ // Set LN pump speed (0-100%)
+ status = setLnpSpeed(value);
+
+ } else if (function == vacuumOutValue_) {
+
+ // Set vacuum on/off
+ status = setVacuum(value);
+
+ }
+
callParamCallbacks();
if (status == 0) {
@@ -355,32 +539,324 @@ asynStatus Linkam::setHeating(epicsInt32 value)
return (status) ? asynSuccess : asynError;
}
+asynStatus Linkam::setLnpMode(epicsInt32 value)
+{
+ bool status;
+ static const char *functionName = "setLnpMode";
+
+ this->lock();
+
+ if (controllerLnpReady_)
+ {
+ if (value == 1)
+ {
+ // User requested Auto mode
+ if (stageLnpAuto_ == 1)
+ {
+ status = SetLnpMode(true);
+ } else {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting LNP Mode: stageLnpAuto_ = %d\n",
+ driverName, functionName, this->portName, stageLnpAuto_);
+ }
+ } else {
+ // User requested Manual mode
+ if (stageLnpManual_ == 1)
+ {
+ status = SetLnpMode(false);
+ } else {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting LNP Mode: stageLnpManual_ = %d\n",
+ driverName, functionName, this->portName, stageLnpManual_);
+ }
+ }
+ } else {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting LNP Mode: controllerLnpReady_ = %d\n",
+ driverName, functionName, this->portName, controllerLnpReady_);
+ }
+
+ // Manual = 0 = false ; Auto = 1 = true
+ //status = SetLnpMode((value==1) ? true : false);
+
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, value = %d\n",
+ driverName, functionName, this->portName, value);
+
+ return (status) ? asynSuccess : asynError;
+}
+
+asynStatus Linkam::setLnpSpeed(epicsInt32 value)
+{
+ bool status;
+ static const char *functionName = "setLnpSpeed";
+
+ this->lock();
+
+ if (controllerLnpReady_)
+ {
+ // 0-100%
+ if (stageLnpManual_ == 1)
+ {
+ status = SetLnpSpeed(value);
+ } else {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting LNP Speed: stageLnpManual_ = %d\n",
+ driverName, functionName, this->portName, stageLnpManual_);
+ }
+ } else {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting LNP Speed: controllerLnpReady_ = %d\n",
+ driverName, functionName, this->portName, controllerLnpReady_);
+ }
+
+ // 0-100%
+ //status = SetLnpMode(value);
+
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, value = %d\n",
+ driverName, functionName, this->portName, value);
+
+ return (status) ? asynSuccess : asynError;
+}
+
+asynStatus Linkam::setVacuum(epicsInt32 value)
+{
+ bool status;
+ static const char *functionName = "setVacuum";
+
+ this->lock();
+
+ // Off = 0 = false ; On = 1 = true
+ if (controllerVacuumReady_)
+ {
+ if (stageVacuum_)
+ {
+ // Vacuum control is supported and ready
+ status = StartVacuum((value) ? true : false);
+ }
+ else
+ {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting vacuum: stageVacuum_ = %d\n",
+ driverName, functionName, this->portName, stageVacuum_);
+ }
+ }
+ else
+ {
+ status = false;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR setting vacuum: controllerVacuumReady_ = %d\n",
+ driverName, functionName, this->portName, controllerVacuumReady_);
+ }
+
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, value = %d\n",
+ driverName, functionName, this->portName, value);
+
+ return (status) ? asynSuccess : asynError;
+}
+
+
+/*
+ *
+ * readInt32
+ *
+ */
+asynStatus Linkam::readInt32(asynUser *pasynUser, epicsInt32 *value)
+{
+ int function = pasynUser->reason;
+ asynStatus status = asynSuccess;
+ static const char *functionName = "readInt32";
+
+ asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, function = %d\n",
+ driverName, functionName, this->portName, function);
+
+ // Get the current value; it can be reverted later if commands fail
+ getIntegerParam(function, value);
+
+ if (function == controllerConfigInValue_) {
+
+ status = readControllerConfig();
+
+ } else if (function == controllerErrorInValue_) {
+
+ status = readControllerError();
+
+ } else if (function == controllerStatusInValue_) {
+
+ status = readControllerStatus();
+
+ } else if (function == stageConfigInValue_) {
+
+ status = readStageConfig();
+
+ }
+
+ // Increment the value so we can see that records are processing
+ if (*value > 100000)
+ *value = 0;
+ else
+ *value += 1;
+
+ callParamCallbacks();
+ if (status == 0) {
+ asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, wrote %d\n",
+ driverName, functionName, this->portName, value);
+ } else {
+ asynPrint(pasynUser, ASYN_TRACE_ERROR,
+ "%s:%s, port %s, ERROR writing %d, status=%d\n",
+ driverName, functionName, this->portName, value, status);
+ }
+
+ return (status==0) ? asynSuccess : asynError;
+}
+
+asynStatus Linkam::readControllerConfig()
+{
+ static const char *functionName = "readControllerConfig";
+
+ this->lock();
+ this->controllerConfig_ = GetControllerConfig();
+
+ if (controllerConfig_ & ( (epicsUInt64)1 << (int)u64LnpReady ) )
+ controllerLnpReady_ = 1;
+ else
+ controllerLnpReady_ = 0;
+
+ if (controllerConfig_ & ( (epicsUInt64)1 << (int)u64VacuumReady ) )
+ controllerVacuumReady_ = 1;
+ else
+ controllerVacuumReady_ = 0;
+
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, controllerConfig_ = %llx; controllerLnpReady_ = %d\n",
+ driverName, functionName, this->portName, this->controllerConfig_, this->controllerLnpReady_);
+
+ return asynSuccess;
+}
+
+asynStatus Linkam::readControllerError()
+{
+ static const char *functionName = "readControllerError";
+
+ this->lock();
+ this->controllerError_ = GetControllerError();
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, controllerError_ = %lx\n",
+ driverName, functionName, this->portName, this->controllerError_);
+
+ return asynSuccess;
+}
+
+asynStatus Linkam::readControllerStatus()
+{
+ static const char *functionName = "readControllerStatus";
+
+ this->lock();
+ this->controllerStatus_ = GetStatus();
+ this->unlock();
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, controllerStatus_ = %llx\n",
+ driverName, functionName, this->portName, this->controllerStatus_);
+
+ return asynSuccess;
+}
+
+asynStatus Linkam::readStageConfig()
+{
+ static const char *functionName = "readStageConfig";
+
+ this->lock();
+ this->stageConfig_ = GetStageConfig();
+ this->unlock();
+
+ if (stageConfig_ & ( (epicsUInt64)1 << (int)u64SupportsLNPMan ) )
+ stageLnpManual_ = 1;
+ else
+ stageLnpManual_ = 0;
+
+ if (stageConfig_ & ( (epicsUInt64)1 << (int)u64SupportsLNPAuto ) )
+ stageLnpAuto_ = 1;
+ else
+ stageLnpAuto_ = 0;
+
+ if (stageConfig_ & ( (epicsUInt64)1 << (int)u64SupportsVacuum ) )
+ stageVacuum_ = 1;
+ else
+ stageVacuum_ = 0;
+
+ asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
+ "%s:%s, port %s, stageConfig_ = %llx, stageLnpManual_ = %d, stageLnpAuto_ = %d\n",
+ driverName, functionName, this->portName, this->stageConfig_, stageLnpManual_, stageLnpAuto_);
+
+ return asynSuccess;
+}
+
void Linkam::report(FILE *fp, int details)
{
asynPortDriver::report(fp, details);
- fprintf(fp, "* Port: %s, %s, commStatus=%d\n", this->portName, serialPort_, commStatus_);
+ fprintf(fp, "* Port: %s, commType=%d, commPort=%d, commStatus=%d\n", this->portName, commType_, commPort_, commStatus_);
if (details >= 1)
- fprintf(fp, " interesting value = ");
+ {
+ fprintf(fp, " controller config = %llx\n", controllerConfig_);
+ fprintf(fp, "\tLNP Ready = %d\n", controllerLnpReady_);
+ fprintf(fp, "\tVac Ready = %d\n", controllerVacuumReady_);
+ fprintf(fp, " controller error = %lx\n", controllerError_);
+ fprintf(fp, " controller status = %llx\n", controllerStatus_);
+ fprintf(fp, " stage config = %llx\n", stageConfig_);
+ fprintf(fp, "\tLNP Manual = %d\n", stageLnpManual_);
+ fprintf(fp, "\tLNP Auto = %d\n", stageLnpAuto_);
+ fprintf(fp, "\tVacuum = %d\n", stageVacuum_);
+ }
fprintf(fp, "\n");
}
-extern "C" int LinkamConfig(const char *portName, const char *serialPort)
+extern "C" int LinkamConfig(const char *portName, const epicsUInt32 commType, const epicsUInt32 commPort)
{
- Linkam *pLinkam = new Linkam(portName, serialPort);
+ Linkam *pLinkam = new Linkam(portName, commType, commPort);
pLinkam = NULL; /* This is just to avoid compiler warnings */
return(asynSuccess);
}
static const iocshArg linkamArg0 = { "Port name", iocshArgString};
-static const iocshArg linkamArg1 = { "Serial port", iocshArgString};
-static const iocshArg * const linkamArgs[2] = {&linkamArg0,
- &linkamArg1};
-static const iocshFuncDef linkamFuncDef = {"LinkamConfig", 2, linkamArgs};
+static const iocshArg linkamArg1 = { "Comm Type", iocshArgInt};
+static const iocshArg linkamArg2 = { "Comm port", iocshArgInt};
+static const iocshArg * const linkamArgs[3] = {&linkamArg0,
+ &linkamArg1,
+ &linkamArg2};
+static const iocshFuncDef linkamFuncDef = {"LinkamConfig", 3, linkamArgs};
static void linkamCallFunc(const iocshArgBuf *args)
{
- LinkamConfig(args[0].sval, args[1].sval);
+ LinkamConfig(args[0].sval, args[1].ival, args[2].ival);
}
void drvLinkamRegister(void)
diff --git a/LinkamApp/src/Linkam_T96.h b/LinkamApp/src/Linkam_T96.h
index 60e46bac07971c59b5b5adfe04f0cabca69db3a2..706f7d199fd573991040fddb4ef480e1db7369a7 100644
--- a/LinkamApp/src/Linkam_T96.h
+++ b/LinkamApp/src/Linkam_T96.h
@@ -9,13 +9,40 @@
static const char *driverName = "Linkam";
#define MAX_CONTROLLERS 1
+#define DEFAULT_POLL_TIME 0.05
// eVALUETYPE Enumeration
-#define u32Heater1TempR 0
-#define u32Heater1RateRW 1
-#define u32Heater1LimitRW 2
-#define u32Heater1PowerR 3
+#define u32Heater1TempR 0
+#define u32Heater1RateRW 1
+#define u32Heater1LimitRW 2
+#define u32Heater1PowerR 3
+#define u32Heater1LnpSpeedR 4
+#define u32VacuumR 12
+#define u32VacuumLimitRW 13
+// eSTAGECONFIG Enumeration
+#define u64StandardStage 0
+#define u64HighTempStage 1
+#define u64PeltierStage 2
+#define u64SupportsLNPMan 21
+#define u64SupportsLNPAuto 22
+#define u64SupportsHeater1Present 26
+#define u64Heater1SupportsTemperatureControl 27
+#define u64SupportsVacuum 48
+
+// eCONTROLLERCONFIG Enumeration
+#define u64SupportsHeater 0
+#define u64VacuumReady 10
+#define u64LnpReady 36
+
+// eSTATUS Enumeration
+#define u64ControllerError 0
+#define u64Heater1RampSetpoint 1
+#define u64Heater1Started 2
+#define u64VacuumSetPoint 5
+#define u64VacuumControlStarted 6
+#define u64LnpCoolingStarted 11
+#define u64LnpCoolingAuto 12
/* These are the drvInfo strings that are used to identify the parameters.
* They are used by asyn clients, including standard asyn device support */
@@ -26,21 +53,46 @@ static const char *driverName = "Linkam";
#define rampRateInValueString "RAMP_RATE_IN_VALUE" /* asynFloat64 r/o */
#define heaterPowerInValueString "HEATER_POWER_IN_VALUE" /* asynFloat64 r/o */
#define heatingOutValueString "HEATING_OUT_VALUE" /* asynInt32 r/w */
+//
+#define lnpModeOutValueString "LNP_MODE_OUT_VALUE" /* asynInt32 r/w */
+#define lnpSpeedOutValueString "LNP_SPEED_OUT_VALUE" /* asynInt32 r/w */
+#define lnpSpeedInValueString "LNP_SPEED_IN_VALUE" /* asynFloat64 r/o */
+//
+#define vacuumOutValueString "VACUUM_OUT_VALUE" /* asynInt32 r/w */
+#define vacuumLimitOutValueString "VACUUM_LIMIT_OUT_VALUE" /* asynFloat64 r/w */
+#define vacuumLimitInValueString "VACUUM_LIMIT_IN_VALUE" /* asynFloat64 r/o */
+#define pressureInValueString "PRESSURE_IN_VALUE" /* asynFloat64 r/o */
+//
+#define controllerConfigInValueString "CONTROLLER_CONFIG_IN_VALUE" /* asynInt32 r/o */
+#define controllerErrorInValueString "CONTROLLER_ERROR_IN_VALUE" /* asynInt32 r/o */
+#define controllerStatusInValueString "CONTROLLER_STATUS_IN_VALUE" /* asynInt32 r/o */
+#define stageConfigInValueString "STAGE_CONFIG_IN_VALUE" /* asynInt32 r/o */
+//
+#define statusControllerErrorString "STATUS_CONTROLLER_ERROR" /* asynInt32 r/o */
+#define statusRampSetpointString "STATUS_RAMP_SETPOINT" /* asynInt32 r/o */
+#define statusRampStartedString "STATUS_RAMP_STARTED" /* asynInt32 r/o */
+#define statusVacuumSetpointString "STATUS_VACUUM_SETPOINT" /* asynInt32 r/o */
+#define statusVacuumStartedString "STATUS_VACUUM_STARTED" /* asynInt32 r/o */
+#define statusLnpCoolingStartedString "STATUS_LNP_COOLING_STARTED" /* asynInt32 r/o */
+#define statusLnpCoolingAutoString "STATUS_LNP_COOLING_AUTO" /* asynInt32 r/o */
/*
* Class definition for the Linkam class
*/
class Linkam : public asynPortDriver {
public:
- Linkam(const char *portName, const char *serialPort);
+ Linkam(const char *portName, const epicsUInt32 commType, const epicsUInt32 commPort);
/* These are the methods that we override from asynPortDriver */
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
+ virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
virtual asynStatus disconnect(asynUser *pasynUser);
virtual asynStatus connect(asynUser *pasynUser);
virtual ~Linkam();
+ // These should be private but are called from C
+ virtual void pollerThread(void);
protected:
int temperatureInValue_;
@@ -50,24 +102,65 @@ protected:
int rampRateInValue_;
int heaterPowerInValue_;
int heatingOutValue_;
- #define FIRST_LINKAM_PARAM temperatureInValue_;
- #define LAST_LINKAM_PARAM heatingOutValue_;
+ int lnpModeOutValue_;
+ int lnpSpeedOutValue_;
+ int lnpSpeedInValue_;
+ int vacuumOutValue_;
+ int vacuumLimitOutValue_;
+ int vacuumLimitInValue_;
+ int pressureInValue_;
+ int controllerConfigInValue_;
+ int controllerErrorInValue_;
+ int controllerStatusInValue_;
+ int stageConfigInValue_;
+ int statusControllerError_;
+ int statusRampSetpoint_;
+ int statusRampStarted_;
+ int statusVacuumSetpoint_;
+ int statusVacuumStarted_;
+ int statusLnpCoolingStarted_;
+ int statusLnpCoolingAuto_;
+ #define FIRST_LINKAM_PARAM temperatureInValue_;
+ #define LAST_LINKAM_PARAM statusLnpCoolingAuto_;
private:
- asynStatus readTemperature(epicsFloat64 *value);
+ //
asynStatus readRampLimit(epicsFloat64 *value);
asynStatus readRampRate(epicsFloat64 *value);
asynStatus setRampLimit(epicsFloat64 value);
asynStatus setRampRate(epicsFloat64 value);
- asynStatus readHeaterPower(epicsFloat64 *value);
asynStatus setHeating(epicsInt32 value);
+ //
+ asynStatus setLnpMode(epicsInt32 value);
+ asynStatus setLnpSpeed(epicsInt32 value);
+ //
+ asynStatus setVacuum(epicsInt32 value);
+ asynStatus setVacuumLimit(epicsFloat64 value);
+ asynStatus readVacuumLimit(epicsFloat64 *value);
+ //
+ asynStatus readControllerConfig();
+ asynStatus readControllerError();
+ asynStatus readControllerStatus();
+ asynStatus readStageConfig();
void report(FILE *fp, int details);
- char* serialPort_;
+ double pollTime_;
+ epicsUInt32 commType_;
+ epicsUInt32 commPort_;
int commStatus_;
float temperatureRbv_;
char* wrapperVersion_;
char* libraryVersion_;
+ epicsUInt64 controllerConfig_;
+ epicsUInt32 controllerError_;
+ epicsUInt64 controllerStatus_;
+ epicsUInt64 stageConfig_;
+ short controllerLnpReady_;
+ short stageLnpAuto_;
+ short stageLnpManual_;
+ short controllerVacuumReady_;
+ short stageVacuum_;
+
};
#define NUM_PARAMS ((int)(&LAST_LINKAM_PARAM - &FIRST_LINKAM_PARAM + 1))
diff --git a/LinkamApp/src/Makefile b/LinkamApp/src/Makefile
index e61ad8d609cae7565f98e27bb6d69a53d00f11e3..81466eecd08f95d969db2e50dfbd57b124d67c45 100644
--- a/LinkamApp/src/Makefile
+++ b/LinkamApp/src/Makefile
@@ -5,12 +5,13 @@ include $(TOP)/configure/CONFIG
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
-USR_CXXFLAGS=-I/usr/include/mono-2.0
+#USR_CXXFLAGS=-I/usr/include/mono-2.0
+#USR_CXXFLAGS=-clr:safe
#==================================================
# build a support library
-LIBRARY_IOC_Linux += Linkam
+LIBRARY_IOC += Linkam
# xxxRecord.h will be created from xxxRecord.dbd
#DBDINC += xxxRecord
@@ -18,8 +19,11 @@ LIBRARY_IOC_Linux += Linkam
DBD += LinkamSupport.dbd
# specify all source files to be compiled and added to the library
-Linkam_SRCS_Linux += Linkam_T96.cpp
+Linkam_SRCS += Linkam_T96.cpp
Linkam_LIBS_Linux += Wrapper
+ifeq (win, $(findstring win, $(T_A)))
+Linkam_LIBS += CommsWrapper
+endif
Linkam_Libs += asyn
Linkam_LIBS += $(EPICS_BASE_IOC_LIBS)
diff --git a/LinkamSupport/Makefile b/LinkamSupport/Makefile
index 09c7a3d37f1b850b16b54c21d7cff6fad3c317ec..8b71693680271b93b7649f984037704cd5501163 100644
--- a/LinkamSupport/Makefile
+++ b/LinkamSupport/Makefile
@@ -7,6 +7,7 @@ include $(TOP)/configure/CONFIG
# Note, the following files were manually copied from the _____ directory.
INC += dllExports.h
INC += dllImports.h
+INC += dllHeader.h
ifeq (linux-x86_64, $(findstring linux-x86_64, $(T_A)))
LIB_INSTALLS += ../os/linux-x86_64/libWrapper.a
@@ -15,6 +16,22 @@ BIN_INSTALLS += ../os/linux-x86_64/libWrapper.so
BIN_INSTALLS += ../os/linux-x86_64/LinkamCommsDll.dll
endif
+ifeq (win32-x86, $(findstring win32-x86, $(T_A)))
+LIB_INSTALLS += ../os/win32-x86/CommsWrapper.lib
+LIB_INSTALLS += ../os/win32-x86/CommsWrapper.dll
+BIN_INSTALLS += ../os/win32-x86/CommsWrapper.dll
+BIN_INSTALLS += ../os/win32-x86/LinkamCommsLibrary.dll
+BIN_INSTALLS += ../os/win32-x86/Multimedia.dll
+endif
+
+ifeq (windows-x64, $(findstring windows-x64, $(T_A)))
+LIB_INSTALLS += ../os/windows-x64/CommsWrapper.lib
+LIB_INSTALLS += ../os/windows-x64/CommsWrapper.dll
+BIN_INSTALLS += ../os/windows-x64/CommsWrapper.dll
+BIN_INSTALLS += ../os/windows-x64/LinkamCommsLibrary.dll
+BIN_INSTALLS += ../os/windows-x64/Multimedia.dll
+endif
+
#=============================
include $(TOP)/configure/RULES
diff --git a/LinkamSupport/README.txt b/LinkamSupport/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..90d13802929b60daed45d41e56a84c59b5872ccd
--- /dev/null
+++ b/LinkamSupport/README.txt
@@ -0,0 +1,7 @@
+dllExports.h
+ used for building the C wrapper
+dllImports.h
+ used for building the EPICS support on Linux
+dllHeader.h
+ used for building the EPICS support on Windows
+
diff --git a/LinkamSupport/dllHeader.h b/LinkamSupport/dllHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8373ef748f98cb0c425113791fbf0eaebb37716
--- /dev/null
+++ b/LinkamSupport/dllHeader.h
@@ -0,0 +1,104 @@
+//Built on 11/04/2018 at 8:26:23.75 by UjasSidapara@LINKAM.LOCAL on SN1651-B
+// CommsWrapper.dll SHA:E23D139EA70508CD11041786C3751D213558DCA4A2FAFFC606B4B16438FEA539
+//-----------------------------------------------------------------------
+//
+// Copyright (c) Linkam Scientific Ltd. All rights reserved.
+//
+// 17-Jan-2018
+// US (support@linkam.co.uk)
+//-1.1.1
+//-----------------------------------------------------------------------
+/// This file contains the dllimports/ dllexports for the wrapper.
+
+// Dependencies:
+// - C runtime Library v120
+// -.net framework version 4.0 or newer
+// - LinkamCommsLibrary.dll (managed)
+#pragma once
+#ifndef dllHeader_h
+
+ #define dllHeader_h
+ // if DLLEXPORTS is defined, define as dllexports,
+ // otherwise declare dllimport prototypes.
+ #ifdef DLLEXPORTS
+ #define DLLAPI __declspec(dllexport)
+ #else
+ #define DLLAPI __declspec(dllimport)
+ #endif
+ #define DLLCALL __cdecl // Calling convention is __cdecl
+#endif
+// callbacks:
+// typedef return_type ( calling convention *func_pointer) (other parameters)
+typedef void(__stdcall *eventCallback)(void); // stdcall used for WINAPI compatibility.
+typedef void(__stdcall *eventNewValueCallback)(unsigned long long); //UInt64
+
+extern "C" // No name mangling
+{
+ // Open or close connection to controller
+ // (arg1: true=Connect, false=Disconnect arg2: 0=USB, 1=RS232, arg3: Comm port number)
+ DLLAPI unsigned int DLLCALL OpenComms(bool, unsigned int, unsigned int); // wraps Comms.OpenComms()
+ DLLAPI unsigned int DLLCALL OpenCommsFromDevice(bool bConnect, char* strSerialDevice);
+
+
+ // Methods in alphabetical order
+ DLLAPI bool DLLCALL ApplySampleCals(bool); // wraps Comms.ApplySampleCals()
+ // Toggle between uncalibrated and sample calibrated temperatures. Refer to example in html docs.
+ DLLAPI bool DLLCALL CalibrateTstDistance(void);
+
+ DLLAPI bool DLLCALL CssApplyValues(void);
+ DLLAPI unsigned char DLLCALL CssCheckValues(void);
+ DLLAPI bool DLLCALL CssGotoReference(void);
+ DLLAPI bool DLLCALL CssSensorCal(unsigned int);
+ DLLAPI bool DLLCALL CssStartJogGap(bool);
+ DLLAPI bool DLLCALL CssStartJogRot(bool);
+
+ DLLAPI int DLLCALL GetCommsPeriod();
+ DLLAPI unsigned long long DLLCALL GetControllerConfig(void); // Controller configuration: i.e. boards connected
+ DLLAPI unsigned int DLLCALL GetControllerError(void); // Controller error status
+ DLLAPI char* DLLCALL GetControllerName(void);
+ DLLAPI char* DLLCALL GetControllerSerial(void);
+ DLLAPI char* DLLCALL GetDllVersion(void); // Version number of ManagedDLL
+ DLLAPI char* DLLCALL GetWrapperVersion(void); // Version number of Wrapper
+
+ DLLAPI float DLLCALL GetMaxValue(unsigned int);
+ DLLAPI float DLLCALL GetMinValue(unsigned int);
+ DLLAPI float DLLCALL GetResolution(unsigned int);
+ DLLAPI unsigned long long DLLCALL GetStageConfig(void); // Unsigned 64-Bit Integer
+ DLLAPI char* DLLCALL GetStageName(void);
+ DLLAPI char* DLLCALL GetStageSerial(void);
+ DLLAPI unsigned long long DLLCALL GetStatus(void); // Unsigned 64-Bit Integer
+ DLLAPI float DLLCALL GetValue(unsigned int);
+
+ DLLAPI bool DLLCALL SaveSampleCals(void);
+
+ DLLAPI bool DLLCALL SetCommsPeriod(int);
+ DLLAPI bool DLLCALL SetLnpMode(bool);
+ DLLAPI bool DLLCALL SetLnpSpeed(unsigned int);
+ //DLLAPI bool DLLCALL SetSimulationMode(unsigned int); Deprecated as of v1.0.7/ SDK 2.3.4.1
+ DLLAPI bool DLLCALL SetValue(unsigned int, float);
+
+ DLLAPI bool DLLCALL StartHeating(bool);
+ DLLAPI bool DLLCALL StartMotors(bool, unsigned int);
+ DLLAPI bool DLLCALL StartVacuum(bool);
+ DLLAPI bool DLLCALL StartHumidity(bool);
+ DLLAPI bool DLLCALL StartHumidityDesiccantConditioning(bool);
+
+ DLLAPI bool DLLCALL SetTstMode(bool);
+ DLLAPI bool DLLCALL TstZeroForce(void);
+ DLLAPI bool DLLCALL TstZeroPosition(void);
+
+ // Comms Events
+ /*********************************************/
+ /* Event and callback methods */
+ /* See "helloLinkam" example in apiDocs */
+ /*********************************************/
+ // Start callbacks
+ DLLAPI void DLLCALL StartEvents();
+ // Stop callbacks
+ DLLAPI void DLLCALL StopEvents();
+
+ // Set or Register callbacks. See typedefs above for declaration of *eventCallback and *eventNewValueCallback.
+ DLLAPI void DLLCALL SetControllerConnectedCallback(eventCallback);
+ DLLAPI void DLLCALL SetNewValueCallback(eventNewValueCallback);
+ DLLAPI void DLLCALL SetControllerDisconnectedCallback(eventCallback);
+}
diff --git a/LinkamSupport/os/win32-x86/CommsWrapper.dll b/LinkamSupport/os/win32-x86/CommsWrapper.dll
new file mode 100644
index 0000000000000000000000000000000000000000..6289fd200b0b92c5147633762d2b89caa05d6e94
Binary files /dev/null and b/LinkamSupport/os/win32-x86/CommsWrapper.dll differ
diff --git a/LinkamSupport/os/win32-x86/CommsWrapper.lib b/LinkamSupport/os/win32-x86/CommsWrapper.lib
new file mode 100644
index 0000000000000000000000000000000000000000..fe9503b4538013b34023672de2f5cba13b5376b9
Binary files /dev/null and b/LinkamSupport/os/win32-x86/CommsWrapper.lib differ
diff --git a/LinkamSupport/os/win32-x86/LinkamCommsLibrary.dll b/LinkamSupport/os/win32-x86/LinkamCommsLibrary.dll
new file mode 100644
index 0000000000000000000000000000000000000000..ee517f8c9d679cbb0db25b4d98cba2c9329d70e9
Binary files /dev/null and b/LinkamSupport/os/win32-x86/LinkamCommsLibrary.dll differ
diff --git a/LinkamSupport/os/win32-x86/Multimedia.dll b/LinkamSupport/os/win32-x86/Multimedia.dll
new file mode 100644
index 0000000000000000000000000000000000000000..5c46298d36c592036b30a51154bd797c8a0c7e53
Binary files /dev/null and b/LinkamSupport/os/win32-x86/Multimedia.dll differ
diff --git a/LinkamSupport/os/windows-x64/CommsWrapper.dll b/LinkamSupport/os/windows-x64/CommsWrapper.dll
new file mode 100644
index 0000000000000000000000000000000000000000..0f52c753544072da25cafd4606d32b5431cbaa70
Binary files /dev/null and b/LinkamSupport/os/windows-x64/CommsWrapper.dll differ
diff --git a/LinkamSupport/os/windows-x64/CommsWrapper.lib b/LinkamSupport/os/windows-x64/CommsWrapper.lib
new file mode 100644
index 0000000000000000000000000000000000000000..a2bc47846d33e2ca841a9b24cb26ecb522476e2e
Binary files /dev/null and b/LinkamSupport/os/windows-x64/CommsWrapper.lib differ
diff --git a/LinkamSupport/os/windows-x64/LinkamCommsLibrary.dll b/LinkamSupport/os/windows-x64/LinkamCommsLibrary.dll
new file mode 100644
index 0000000000000000000000000000000000000000..074aac8148e3103711ba41cf4c9c64a34e596d5c
Binary files /dev/null and b/LinkamSupport/os/windows-x64/LinkamCommsLibrary.dll differ
diff --git a/LinkamSupport/os/windows-x64/Multimedia.dll b/LinkamSupport/os/windows-x64/Multimedia.dll
new file mode 100644
index 0000000000000000000000000000000000000000..4c330bb45727790837f2f6803fb2e9ffe7c7001d
Binary files /dev/null and b/LinkamSupport/os/windows-x64/Multimedia.dll differ
diff --git a/configure/RELEASE b/configure/RELEASE
index 3c9991a6ce90cfd98603668b75c3f5709253c4a8..1a37fd667ff0f810e5d5eac29cbee49b2cb7d5ed 100644
--- a/configure/RELEASE
+++ b/configure/RELEASE
@@ -24,10 +24,10 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
# If using the sequencer, point SNCSEQ at its top directory:
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
-ASYN=/home/KPETERSN/Current/9idc_Linkam/support/asyn
+ASYN=D:/epics/linkamDevel/support/asyn
# EPICS_BASE usually appears last so other apps can override stuff:
-EPICS_BASE=/APSshare/epics/base-3.14.12.5
+EPICS_BASE=D:/epics/base-3.15.5
# Set RULES here if you want to take build rules from somewhere
# other than EPICS_BASE:
diff --git a/iocs/linkamIOC/configure/RELEASE b/iocs/linkamIOC/configure/RELEASE
index 07c0921b335d4a9ad4f819a71a1dcc8022b65065..cbc6d5650c6e6608efd0d93d7a683bcab337c59b 100644
--- a/iocs/linkamIOC/configure/RELEASE
+++ b/iocs/linkamIOC/configure/RELEASE
@@ -25,11 +25,12 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
#
+#LINKAM=D:/epics/linkamDevel/support/Linkam
LINKAM=$(TOP)/../..
-include $(LINKAM)/configure/RELEASE
# EPICS_BASE usually appears last so other apps can override stuff:
-EPICS_BASE=/APSshare/epics/base-3.14.12.5
+#!EPICS_BASE=
# Set RULES here if you want to take build rules from somewhere
# other than EPICS_BASE:
diff --git a/iocs/linkamIOC/iocBoot/ioclinkam/Linkam_T96.cmd b/iocs/linkamIOC/iocBoot/ioclinkam/Linkam_T96.cmd
index c0b53f456ae17be14fcf01211ddd9f8cde04127a..5fa61ea96ed6a03cd4d4481b89622f193a5d4886 100644
--- a/iocs/linkamIOC/iocBoot/ioclinkam/Linkam_T96.cmd
+++ b/iocs/linkamIOC/iocBoot/ioclinkam/Linkam_T96.cmd
@@ -1,8 +1,15 @@
#
-dbLoadRecords("$(LINKAM)/db/Linkam_T96.db", "P=$(PREFIX),T=tc1,PORT=$(PORT),ADDR=0")
+dbLoadRecords("$(TOP)/db/Linkam_T96.db", "P=$(PREFIX),T=tc1,PORT=$(PORT),ADDR=0")
#
-dbLoadRecords("$(ASYN)/db/asynRecord.db", "P=$(PREFIX),R=asyn,PORT=$(PORT),ADDR=0,OMAX=255,IMAX=255")
+dbLoadRecords("$(TOP)/db/asynRecord.db", "P=$(PREFIX),R=tc1:asyn,PORT=$(PORT),ADDR=0,OMAX=255,IMAX=255")
## Run Linkam C# code
cd "${TOP}/bin/${ARCH}"
-LinkamConfig("$(PORT)", "/dev/ttyUSB0")
+# LinkamConfig(
+# portName Desired asyn port name (created by driver)
+# commType 0 = USB, 1 = RS232
+# commPort 0 = COM0, 1 = COM1, ...
+# RS232, COM1
+LinkamConfig("$(PORT)", 1, 1)
+# USB, device #6
+#!LinkamConfig("$(PORT)", 0, 6)
diff --git a/iocs/linkamIOC/iocBoot/ioclinkam/Makefile b/iocs/linkamIOC/iocBoot/ioclinkam/Makefile
index c68aac1039a6915a007cf76966f602890d3c49ec..338078324ae57b45c44338dd61e3219ee85f6f1e 100644
--- a/iocs/linkamIOC/iocBoot/ioclinkam/Makefile
+++ b/iocs/linkamIOC/iocBoot/ioclinkam/Makefile
@@ -1,6 +1,7 @@
TOP = ../..
include $(TOP)/configure/CONFIG
#!ARCH = linux-x86_64
-ARCH = linux-x86_64-debug
+#!ARCH = linux-x86_64-debug
+ARCH = windows-x64-static
TARGETS = envPaths
include $(TOP)/configure/RULES.ioc
diff --git a/iocs/linkamIOC/iocBoot/ioclinkam/st.cmd b/iocs/linkamIOC/iocBoot/ioclinkam/st.cmd
index 55aa255b03967fdb8b36b6ebeadce3f63f98008b..4bfaa4a01fa5555266e7309afc7a324adb07668d 100644
--- a/iocs/linkamIOC/iocBoot/ioclinkam/st.cmd
+++ b/iocs/linkamIOC/iocBoot/ioclinkam/st.cmd
@@ -5,7 +5,7 @@
< envPaths
-epicsEnvSet("PREFIX", "kmp:")
+epicsEnvSet("PREFIX", "ioc:")
epicsEnvSet("PORT", "linkam1")
## Register all support components
@@ -21,8 +21,15 @@ linkam_registerRecordDeviceDriver pdbbase
cd "${TOP}/iocBoot/${IOC}"
iocInit
-## Start any sequence programs
-#seq sncxxx,"user=kpetersnHost"
+# Turn off heating by default
+#!dbpf "$(PREFIX)tc1:heating" "0"
+# Turn off vacuum by default
+#!dbpf "$(PREFIX)tc1:vacuum" "0"
+# Make LNP Auto mode the default
+#!dbpf "$(PREFIX)tc1:lnpMode" "1"
# Ugly hack to allow disconnecting for manual control via the screen
-dbpf "$(PREFIX)asyn.AUCT" "noAutoConnect"
+#!dbpf "$(PREFIX)asyn.AUCT" "noAutoConnect"
+
+## Boot is complete
+date
diff --git a/iocs/linkamIOC/iocBoot/ioclinkam/start_ioc.bat b/iocs/linkamIOC/iocBoot/ioclinkam/start_ioc.bat
new file mode 100644
index 0000000000000000000000000000000000000000..96a1837ec59b329060d33590a21ac1afa47e56a4
--- /dev/null
+++ b/iocs/linkamIOC/iocBoot/ioclinkam/start_ioc.bat
@@ -0,0 +1,7 @@
+@echo off
+
+set EPICS_HOST_ARCH=windows-x64-static
+
+..\..\bin\%EPICS_HOST_ARCH%\linkam.exe st.cmd
+
+pause
diff --git a/iocs/linkamIOC/linkamApp/Db/Makefile b/iocs/linkamIOC/linkamApp/Db/Makefile
index 983981d401b27c05644f2f2cc19cbf888f053bf3..4b7505af536f7b3f3125e826146db867fdfad9eb 100644
--- a/iocs/linkamIOC/linkamApp/Db/Makefile
+++ b/iocs/linkamIOC/linkamApp/Db/Makefile
@@ -12,6 +12,9 @@ include $(TOP)/configure/CONFIG
# databases, templates, substitutions like this
#DB += xxx.db
+DB += $(LINKAM)/db/Linkam_T96.db
+DB += $(ASYN)/db/asynRecord.db
+
#----------------------------------------------------
# If .db template is not named *.template add
# _template =
diff --git a/iocs/linkamIOC/linkamApp/src/Makefile b/iocs/linkamIOC/linkamApp/src/Makefile
index b487bedda4e6afa62c72815a84f46b8a9e30e6d9..28cd247aa9c1235b00eb248e984d3e653173f5cb 100644
--- a/iocs/linkamIOC/linkamApp/src/Makefile
+++ b/iocs/linkamIOC/linkamApp/src/Makefile
@@ -8,13 +8,20 @@ include $(TOP)/configure/CONFIG
#=============================
# Build the IOC application
-PROD_IOC_Linux = linkam
+PROD_IOC = linkam
# linkam.dbd will be created and installed
DBD += linkam.dbd
#
+ifeq (linux-x86_64, $(findstring linux-x86_64, $(T_A)))
BIN_INSTALLS += ${LINKAM}/bin/${EPICS_HOST_ARCH}/LinkamCommsDll.dll
BIN_INSTALLS += ${LINKAM}/bin/${EPICS_HOST_ARCH}/libWrapper.so
+endif
+ifeq (win, $(findstring win, $(T_A)))
+BIN_INSTALLS += ${LINKAM}/bin/${EPICS_HOST_ARCH}/CommsWrapper.dll
+BIN_INSTALLS += ${LINKAM}/bin/${EPICS_HOST_ARCH}/LinkamCommsLibrary.dll
+BIN_INSTALLS += ${LINKAM}/bin/${EPICS_HOST_ARCH}/Multimedia.dll
+endif
# linkam.dbd will be made up from these files:
linkam_DBD += base.dbd
@@ -25,10 +32,13 @@ linkam_DBD += LinkamSupport.dbd
# Add all the support libraries needed by this IOC
PROD_SYS_LIBS_Linux += mono-2.0
-linkam_LIBS_Linux += Linkam
+linkam_LIBS += Linkam
# The following line isn't necessary, but it makes the depenency explicit
linkam_LIBS_Linux += Wrapper
-linkam_LIBS_Linux += asyn
+ifeq (win, $(findstring win, $(T_A)))
+linkam_LIBS += CommsWrapper
+endif
+linkam_LIBS += asyn
# linkam_registerRecordDeviceDriver.cpp derives from linkam.dbd
linkam_SRCS += linkam_registerRecordDeviceDriver.cpp