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 + + + + + + 385 + 55 + 160 + 25 + + + + $(P)$(T):temperature_RBV.SCAN + + + + 0 + 0 + 0 + + + + + 187 + 187 + 187 + + + + caMenu::Static + + + + + 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 + 145 + 160 + 25 + + + + $(P)$(T):heaterPower_RBV.SCAN + + + + 0 + 0 + 0 + + + + + 187 + 187 + 187 + + + + caMenu::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 + 205 + 160 + 25 + + + + $(P)$(T):lnpMode.VAL + + + + 0 + 0 + 0 + + + + + 187 + 187 + 187 + + + + caMenu::Static + + + + + + 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 + + + + + + 385 + 235 + 160 + 25 + + + + $(P)$(T):lnpSpeed_RBV.SCAN + + + + 0 + 0 + 0 + + + + + 187 + 187 + 187 + + + + caMenu::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 + + + + + + 385 + 295 + 160 + 25 + + + + $(P)$(T):pressure_RBV.SCAN + + + + 0 + 0 + 0 + + + + + 187 + 187 + 187 + + + + caMenu::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 + 355 + 160 + 25 + + + + $(P)$(T):vacuum.VAL + + + + 0 + 0 + 0 + + + + + 187 + 187 + 187 + + + + caMenu::Static + + + + + + 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