DUTs
ST_EpicsMotorMSTA
TYPE ST_EpicsMotorMSTA :
STRUCT
(* DIRECTION: last raw direction; (0:Negative, 1:Positive) *)
bPositiveDirection : BIT;
(* DONE: motion is complete. *)
bDone : BIT;
(* PLUS_LS: plus limit switch has been hit. *)
bPlusLimitSwitch : BIT;
(* HOMELS: state of the home limit switch. *)
bHomeLimitSwitch : BIT;
(* Unused *)
bUnused0 : BIT;
(* POSITION: closed-loop position control is enabled. *)
bClosedLoop : BIT;
(* SLIP_STALL: Slip/Stall detected (eg. fatal following error) *)
bSlipStall : BIT;
(* HOME: if at home position. *)
bHome : BIT;
(* PRESENT: encoder is present. *)
bEncoderPresent : BIT;
(* PROBLEM: driver stopped polling, or hardware problem *)
bHardwareProblem : BIT;
(* MOVING: non-zero velocity present. *)
bMoving : BIT;
(* GAIN_SUPPORT: motor supports closed-loop position control. *)
bGainSupport : BIT;
(* COMM_ERR: Controller communication error. *)
bCommError : BIT;
(* MINUS_LS: minus limit switch has been hit. *)
bMinusLimitSwitch : BIT;
(* HOMED: the motor has been homed. *)
bHomed : BIT;
END_STRUCT
END_TYPE
- Related:
ST_ShutterControl
TYPE ST_ShutterControl :
STRUCT
{attribute 'pytmc' := '
pv: REQ
io: io
field: DESC LSS Shutter Open Request
'}
bOpenRequest AT %Q* : BOOL;
{attribute 'pytmc' := '
pv: OPN
io: i
field: DESC LSS Shutter Open
'}
bOpenStatus AT %I* : BOOL;
{attribute 'pytmc' := '
pv: CLS
io: i
field: DESC LSS Shutter Closed
'}
bCloseStatus AT %I* : BOOL;
{attribute 'pytmc' := '
pv: LSS
io: i
field: DESC LSS Permission Status
'}
bLssStatus AT %I* : BOOL;
END_STRUCT
END_TYPE
ST_SourceDataStore
TYPE ST_SourceDataStore :
STRUCT
{attribute 'pytmc' := 'pv: Name; io: input'}
sName : STRING;
(* Do not pragma valve; Use original PVs to access valve state *)
fbSourceValve : REFERENCE TO FB_VGC;
{attribute 'pytmc' := '
pv: Valid
io: input
field: ZNAM Data Invalid
field: ONAM Data Valid
field: ZSV MAJOR
field: OSV NO_ALARM
'}
bDataValid : BOOL;
{attribute 'pytmc' := '
pv: EntryValveReady
io: input
field: ZNAM Not ready
field: ONAM Ready
field: ZSV MAJOR
field: OSV NO_ALARM
'}
bEntryValveReady : BOOL;
{attribute 'pytmc' := '
pv: ChecksOK
io: input
field: ZNAM Failed
field: ONAM Passed
field: ZSV MAJOR
field: OSV NO_ALARM
'}
bChecksOK : BOOL;
{attribute 'pytmc' := '
pv: InPosition
io: input
field: ZNAM FALSE
field: ONAM TRUE
field: DESC Linear stage in position for dest
'}
bInPosition : BOOL;
{attribute 'pytmc' := 'pv: Linear'}
fbLinear : FB_RangeComparison;
{attribute 'pytmc' := 'pv: Rotary'}
fbRotary : FB_RangeComparison;
{attribute 'pytmc' := 'pv: Goniometer'}
fbGoniometer : FB_RangeComparison;
{attribute 'pytmc' := 'pv: NFCenterX'}
fbNFCentroidX : FB_RangeComparison;
{attribute 'pytmc' := 'pv: NFCenterY'}
fbNFCentroidY : FB_RangeComparison;
{attribute 'pytmc' := 'pv: FFCenterX'}
fbFFCentroidX : FB_RangeComparison;
{attribute 'pytmc' := 'pv: FFCenterY'}
fbFFCentroidY : FB_RangeComparison;
END_STRUCT
END_TYPE
- Related:
GVLs
GVL_BTPS
{attribute 'qualified_only'}
VAR_GLOBAL
(*
Motor - Linear
LAS:BTS:MCS2:01:m1 (ioc-las-bts-mcs1, las_bts_mcs2_01_m1)
LAS:BTS:MCS2:01:m4 (ioc-las-bts-mcs1, las_bts_mcs2_01_m4)
LAS:BTS:MCS2:01:m7 (ioc-las-bts-mcs1, las_bts_mcs2_01_m7)
LAS:BTS:MCS2:01:m13
LAS:BTS:MCS2:01:m10
LAS:BTS:MCS2:01:m16
*)
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS1:Lin
link: @(SIM)LAS:BTS:MCS2:01:m1
'}
fbLS1Linear : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS5:Lin
link: @(SIM)LAS:BTS:MCS2:01:m4
'}
fbLS5Linear : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS8:Lin
link: @(SIM)LAS:BTS:MCS2:01:m7
'}
fbLS8Linear : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS3:Lin
link: @(SIM)LAS:BTS:MCS2:01:m13
'}
fbLS3Linear : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS4:Lin
link: @(SIM)LAS:BTS:MCS2:01:m10
'}
fbLS4Linear : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS6:Lin
link: @(SIM)LAS:BTS:MCS2:01:m16
'}
fbLS6Linear : FB_EpicsMotorMonitor;
(*
Motor - Rotary
LAS:BTS:MCS2:01:m2 (ioc-las-bts-mcs1, las_bts_mcs2_01_m2)
LAS:BTS:MCS2:01:m6 (ioc-las-bts-mcs1, las_bts_mcs2_01_m6)
LAS:BTS:MCS2:01:m8 (ioc-las-bts-mcs1, las_bts_mcs2_01_m8)
LAS:BTS:MCS2:01:m14
LAS:BTS:MCS2:01:m12
LAS:BTS:MCS2:01:m17
*)
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS1:Rot
link: @(SIM)LAS:BTS:MCS2:01:m2
'}
fbLS1Rotary : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS5:Rot
link: @(SIM)LAS:BTS:MCS2:01:m6
'}
fbLS5Rotary : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS8:Rot
link: @(SIM)LAS:BTS:MCS2:01:m8
'}
fbLS8Rotary : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS3:Rot
link: @(SIM)LAS:BTS:MCS2:01:m14
'}
fbLS3Rotary : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS4:Rot
link: @(SIM)LAS:BTS:MCS2:01:m12
'}
fbLS4Rotary : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS6:Rot
link: @(SIM)LAS:BTS:MCS2:01:m17
'}
fbLS6Rotary : FB_EpicsMotorMonitor;
(*
Motor - Goniometer
LAS:BTS:MCS2:01:m3 (ioc-las-bts-mcs1, las_bts_mcs2_01_m3)
LAS:BTS:MCS2:01:m5 (ioc-las-bts-mcs1, las_bts_mcs2_01_m5)
LAS:BTS:MCS2:01:m9 (ioc-las-bts-mcs1, las_bts_mcs2_01_m9)
*)
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS1:Gon
link: @(SIM)LAS:BTS:MCS2:01:m3
'}
fbLS1Goniometer : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS5:Gon
link: @(SIM)LAS:BTS:MCS2:01:m5
'}
fbLS5Goniometer : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS8:Gon
link: @(SIM)LAS:BTS:MCS2:01:m9
'}
fbLS8Goniometer : FB_EpicsMotorMonitor;
//1um / 800nm Lines
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS3:Gon
link: @(SIM)LAS:BTS:MCS2:01:m15
'}
fbLS3Goniometer : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS4:Gon
link: @(SIM)LAS:BTS:MCS2:01:m11
'}
fbLS4Goniometer : FB_EpicsMotorMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS6:Gon
link: @(SIM)LAS:BTS:MCS2:01:m18
'}
fbLS6Goniometer : FB_EpicsMotorMonitor;
(* Near field camera stats plugins, per bay *)
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS1:NF
link: @(SIM)LAS:LHN:BAY1:CAM:01:Stats2:
'}
fbLS1NearFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS5:NF
link: @(SIM)LAS:LHN:BAY3:CAM:01:Stats2:
'}
fbLS5NearFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS8:NF
link: @(SIM)LAS:LHN:BAY4:CAM:01:Stats2:
'}
fbLS8NearFieldCamStats : FB_EpicsStatsMonitor;
// 1um/ 800 nm line
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS3:NF
link: @(SIM)LAS:LHN:BAY2:CAM:01:Stats2:
'}
fbLS3NearFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS4:NF
link: @(SIM)LAS:LHN:BAY2:CAM:01:Stats2:
'}
fbLS4NearFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS6:NF
link: @(SIM)LAS:LHN:BAY3:CAM:01:Stats2:
'}
fbLS6NearFieldCamStats : FB_EpicsStatsMonitor;
(* Far-field camera stats plugins, per bay *)
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS1:FF
link: @(SIM)LAS:LHN:BAY1:CAM:02:Stats2:
'}
fbLS1FarFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS5:FF
link: @(SIM)LAS:LHN:BAY3:CAM:02:Stats2:
'}
fbLS5FarFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS8:FF
link: @(SIM)LAS:LHN:BAY4:CAM:02:Stats2:
'}
fbLS8FarFieldCamStats : FB_EpicsStatsMonitor;
//1um and 800nm Lines
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS3:FF
link: @(SIM)LAS:LHN:BAY2:CAM:02:Stats2:
'}
fbLS3FarFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS4:FF
link: @(SIM)LAS:LHN:BAY2:CAM:02:Stats2:
'}
fbLS4FarFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Chk:LS6:FF
link: @(SIM)LAS:LHN:BAY3:CAM:02:Stats2:
'}
fbLS6FarFieldCamStats : FB_EpicsStatsMonitor;
{attribute 'pytmc' := 'pv: LTLHN:LS1:BTPS'}
fbSafetyLS1 : FB_ShutterSafety;
{attribute 'pytmc' := 'pv: LTLHN:LS5:BTPS'}
fbSafetyLS5 : FB_ShutterSafety;
{attribute 'pytmc' := 'pv: LTLHN:LS8:BTPS'}
fbSafetyLS8 : FB_ShutterSafety;
{attribute 'pytmc' := 'pv: LTLHN:LS3:BTPS'}
fbSafetyLS3 : FB_ShutterSafety;
{attribute 'pytmc' := 'pv: LTLHN:LS4:BTPS'}
fbSafetyLS4 : FB_ShutterSafety;
{attribute 'pytmc' := 'pv: LTLHN:LS6:BTPS'}
fbSafetyLS6 : FB_ShutterSafety;
{attribute 'pytmc' := '
pv: LTLHN:LD
expand: %d
'}
fbDestinations : ARRAY [1..GVL_BTPS_Constants.nDestinations] OF FB_DestinationDataStore;
END_VAR
GVL_BTPS_Constants
{attribute 'qualified_only'}
VAR_GLOBAL CONSTANT
nSources : UINT := 8;
(* Destinations
LTLHN:LD2:VGC:01 (ioc-las-bts) - TMO - IP3
LTLHN:LD4:VGC:01 (ioc-las-bts) - RIX - ChemRIXS
LTLHN:LD6:VGC:01 (ioc-las-bts) - RIX - qRIXS
LTLHN:LD8:VGC:01 (ioc-las-bts) - TMO - IP1
LTLHN:LD9:VGC:01 (ioc-las-bts) - Laser Lab
LTLHN:LD10:VGC:01 (ioc-las-bts) - TMO - IP2
LTLHN:LD14:VGC:01 (ioc-las-bts) - XPP
*)
nDestinations: UINT := 14;
END_VAR
GVL_BTPS_Retain
{attribute 'qualified_only'}
VAR_GLOBAL PERSISTENT
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Config:MaxFrameTime
field: DESC Maximum delay from frame to frame
field: EGU sec
io: io
'}
fMaximumFrameTime : LREAL := 5.0;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Config:MinPixelChange
field: DESC Minimum px change to be considered valid
field: EGU px
io: io
'}
fMinPixelChange : LREAL := 0.05;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Config:SystemOverride
field: DESC Full system-level override
io: io
'}
bSystemOverride : BOOL;
{attribute 'pytmc' := '
pv: LTLHN:BTPS:Config:Maintenance
io: io
field: DESC System undergoing maintenance
field: ZNAM Normal operation
field: ONAM Maintenance
field: ZSV NO_ALARM
field: OSV MAJOR
'}
bMaintenanceMode : BOOL;
END_VAR
GVL_BTS_VAC
//{attribute 'qualified_only'}
VAR_GLOBAL
(* Valves *)
g_FFOut : FB_HardwareFFOutput;
{attribute 'pytmc' := ' pv: LXLHN:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_12]^Channel 2^Input;
.i_xClsLS := TIIB[EL1004_02_12]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_14]^Channel 2^Output'}
fb_PP_VGC : FB_VGC; // Gate valve, vacuum switchbox
{attribute 'pytmc' := ' pv: LXLHN:VVC:01 '}
{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[EL2004_02_05]^Channel 3^Output'}
fb_PP_VVC : FB_VVC; // Turbo N2 purge
{attribute 'pytmc' := ' pv: LXLHN:VRC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1002_02_01]^Channel 2^Input;
.i_xClsLS := TIIB[EL1002_02_01]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_04]^Channel 1^Output'}
fb_PP_VRC_1 : FB_VRC; // O-ring diff pump valve
{attribute 'pytmc' := ' pv: LXLHN:VRC:02 '}
{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[EL2004_02_04]^Channel 3^Output'}
(*'.i_xOpnLS := TIIB[EL1002_02_02]^Channel 2^Input;
.i_xClsLS := TIIB[EL1002_02_02]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_04]^Channel 3^Output'} *)
fb_PP_VRC_2 : FB_VVC; // Foreline valve //valve has bad readouts so using VVC
{attribute 'pytmc' := ' pv: LXLHN:VRC:03 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1002_02_03]^Channel 2^Input;
.i_xClsLS := TIIB[EL1002_02_03]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_04]^Channel 4^Output'}
fb_PP_VRC_3 : FB_VRC; // Slow pump valve
st_VP_VVC_1 : ST_VVC;
{attribute 'pytmc' := ' pv: LXLHN:VVC:02 '}
{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[EL2004_02_05]^Channel 1^Output'}
fb_VP_VVC_1 : FB_VVC; // Vent valve, Switchbox
st_VP_VVC_2 : ST_VVC;
{attribute 'pytmc' := ' pv: LXLHN:VVC:03 '}
{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[EL2004_02_05]^Channel 2^Output'}
fb_VP_VVC_2 : FB_VVC; // Vent valve, Slow, Switchbox
// Vent Valve addition
st_VP_VVC_4 : ST_VVC;
{attribute 'pytmc' := ' pv: LXLHN:VVC:04 '}
{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[EL2004_02_15]^Channel 1^Output'}
fb_VP_VVC_4 : FB_VVC;
{attribute 'pytmc' := ' pv: LXLHN:VRC:04 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_03_17]^Channel 1^Input;
.i_xClsLS := TIIB[EL1004_03_17]^Channel 2^Input'}
fb_PP_VRC_4 : FB_VRC; // Turbo Isolation Valve
(* Pumps *)
{attribute 'pytmc' := '
pv: LXLHN:PTM:01
io: io
'}
{attribute 'TcLinkTo' := '.i_xAtSpd := TIIB[EL1004_00_03]^Channel 3^Input;
.i_xRemote := TIIB[EL1004_00_03]^Channel 2^Input;
.i_xFaultNC := TIIB[EL1004_00_03]^Channel 1^Input;
.q_RunDO := TIIB[EL2004_00_04]^Channel 1^Output;
.q_xRemote := TIIB[EL2004_00_04]^Channel 2^Output;
.q_PumpingStation := TIIB[EL2004_00_04]^Channel 3^Output'}
fb_PP_PTM : FB_PTM_Pfeiffer; // Turbo pump
// Serial port
st_Pfeiffer_CTRL_PTM : ARRAY[1..20] OF ST_PfeifferControl;
st_Pfeiffer_RBK_PTM : ARRAY[1..20] OF ST_PfeifferStatus;
PTM_COM : FB_PFEIFFER_COM;
{attribute 'pytmc' := '
pv: LXLHN:PMF:01
io: io
'}
{attribute 'TcLinkTo' := '.i_xWarning := TIIB[EL1004_00_01]^Channel 4^Input;
.i_xAlarm := TIIB[EL1004_00_01]^Channel 3^Input;
.i_xRemote := TIIB[EL1004_00_01]^Channel 2^Input;
.i_xIsRun := TIIB[EL1004_00_01]^Channel 1^Input;
.q_xRunDO := TIIB[EL2794_00_02]^Channel 1^Output;
.q_xLspdDO := TIIB[EL2794_00_02]^Channel 2^Output;
.q_xResetDo := TIIB[EL2794_00_02]^Channel 3^Output'}
fb_PP_PMF : FB_KashiyamaPump; // Roughing Pump
{attribute 'pytmc' := ' pv: LXLHN:PIP:01'}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_08]^AI Standard Channel 3^Value;
.i_xSP_DI := TIIB[EL1004_00_07]^Channel 3^Input;
.q_xHVEna_DO := TIIB[EL2794_00_06]^Channel 3^Output'}
fb_PP_PIP : FB_PIP_Gamma; // Ion Pump, SW
(* Gauges *)
{attribute 'pytmc' := ' pv: LXLHN:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_10]^AI Standard Channel 3^Value '}
fb_PP_GPI_1 : FB_MKS275; // Switchbox pumpline ATM gauge
{attribute 'pytmc' := ' pv: LXLHN:GPI:02 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_11]^AI Standard Channel 1^Value '}
fb_PP_GPI_2 : FB_MKS275; // Foreline gauge
{attribute 'pytmc' := ' pv: LXLHN:GPI:03 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_10]^AI Standard Channel 2^Value '}
fb_DP_GPI : FB_MKS275; // Switchbox gauge
{attribute 'pytmc' := ' pv: LXLHN:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_09]^AI Standard Channel 2^Value;
.i_xHV_ON := TIIB[EL1124_01_06]^Channel 1^Input;
.i_xDisc_Active := TIIB[EL1124_01_06]^Channel 2^Input;
.q_xHV_DIS := TIIB[EL2624_01_02]^Channel 2^Output '}
fb_PP_GCC : FB_MKS500; // Switchbox pumpline Cold Cathode gauge
{attribute 'pytmc' := ' pv: LXLHN:GCC:02 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_09]^AI Standard Channel 4^Value;
.i_xHV_ON := TIIB[EL1124_01_07]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_01_07]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_01_02]^Channel 4^Output '}
fb_DP_GCC : FB_MKS500; // Switchbox Cold Cathode gauge
(* Transport Tubes *)
// LS1
{attribute 'pytmc' := ' pv: LTLHN:LS1:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_06]^Channel 2^Input;
.i_xClsLS := TIIB[EL1004_02_06]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_08]^Channel 1^Output'}
fb_LS1_VGC : FB_VGC; // Gate valve, Input LS1 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LS1:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_08]^AI Standard Channel 2^Value;
.i_xSP_DI := TIIB[EL1004_00_07]^Channel 2^Input;
.q_xHVEna_DO := TIIB[EL2794_00_06]^Channel 2^Output'}
fb_LS1_PIP : FB_PIP_Gamma; // Ion Pump, input tube LS1
{attribute 'pytmc' := ' pv: LTLHN:LS1:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_10]^AI Standard Channel 4^Value '}
fb_LS1_GPI : FB_MKS275; // Input tube LS1 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LS1:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_10]^AI Standard Channel 4^Value;
.i_xHV_ON := TIIB[EL1124_03_06]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_03_06]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_03_01]^Channel 4^Output '}
fb_LS1_GCC : FB_MKS500; // Input tube LS1, Cold Cathode gauge
// LS5
{attribute 'pytmc' := ' pv: LTLHN:LS5:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_09]^Channel 4^Input;
.i_xClsLS := TIIB[EL1004_02_09]^Channel 3^Input;
.q_xOPN_DO := TIIB[EL2004_02_11]^Channel 2^Output'}
fb_LS5_VGC : FB_VGC; // Gate valve, Input LS5 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LS5:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_11]^AI Standard Channel 4^Value;
.i_xSP_DI := TIIB[EL1004_00_10]^Channel 4^Input;
.q_xHVEna_DO := TIIB[EL2794_00_09]^Channel 4^Output'}
fb_LS5_PIP : FB_PIP_Gamma; // Ion Pump, input tube LS5
{attribute 'pytmc' := ' pv: LTLHN:LS5:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_13]^AI Standard Channel 1^Value '}
fb_LS5_GPI : FB_MKS275; // Input tube LS5 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LS5:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_11]^AI Standard Channel 1^Value;
.i_xHV_ON := TIIB[EL1124_03_08]^Channel 1^Input;
.i_xDisc_Active := TIIB[EL1124_03_08]^Channel 2^Input;
.q_xHV_DIS := TIIB[EL2624_03_02]^Channel 1^Output '}
fb_LS5_GCC : FB_MKS500; // Input tube LS5, Cold Cathode gauge
// LS8
{attribute 'pytmc' := ' pv: LTLHN:LS8:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_09]^Channel 2^Input;
.i_xClsLS := TIIB[EL1004_02_09]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_11]^Channel 3^Output'}
fb_LS8_VGC : FB_VGC; // Gate valve, Input LS8 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LS8:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_11]^AI Standard Channel 3^Value;
.i_xSP_DI := TIIB[EL1004_00_10]^Channel 3^Input;
.q_xHVEna_DO := TIIB[EL2794_00_09]^Channel 3^Output'}
fb_LS8_PIP : FB_PIP_Gamma; // Ion Pump, input tube LS8
{attribute 'pytmc' := ' pv: LTLHN:LS8:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_13]^AI Standard Channel 2^Value '}
fb_LS8_GPI : FB_MKS275; // Input tube LS8 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LS8:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_11]^AI Standard Channel 2^Value;
.i_xHV_ON := TIIB[EL1124_03_08]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_03_08]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_03_02]^Channel 2^Output '}
fb_LS8_GCC : FB_MKS500; // Input tube LS8, Cold Cathode gauge
// LD2
{attribute 'pytmc' := ' pv: LTLHN:LD2:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_12]^Channel 4^Input;
.i_xClsLS := TIIB[EL1004_02_12]^Channel 3^Input;
.q_xOPN_DO := TIIB[EL2004_02_14]^Channel 3^Output'}
fb_LD2_VGC : FB_VGC; // Gate valve, Output tube LD2 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD2:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_08]^AI Standard Channel 1^Value;
.i_xSP_DI := TIIB[EL1004_00_07]^Channel 1^Input;
.q_xHVEna_DO := TIIB[EL2794_00_06]^Channel 1^Output'}
fb_LD2_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD2
{attribute 'pytmc' := ' pv: LTLHN:LD2:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_10]^AI Standard Channel 1^Value '}
fb_LD2_GPI : FB_MKS275; // Output tube LD2 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD2:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_09]^AI Standard Channel 1^Value;
.i_xHV_ON := TIIB[EL1124_01_07]^Channel 1^Input;
.i_xDisc_Active := TIIB[EL1124_01_07]^Channel 2^Input;
.q_xHV_DIS := TIIB[EL2624_01_02]^Channel 1^Output '}
fb_LD2_GCC : FB_MKS500; // Output tube LD2, Cold Cathode gauge
// LD4
{attribute 'pytmc' := ' pv: LTLHN:LD4:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_10]^Channel 2^Input;
.i_xClsLS := TIIB[EL1004_02_10]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_11]^Channel 1^Output'}
fb_LD4_VGC : FB_VGC; // Gate valve, Output tube LD4 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD4:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_11]^AI Standard Channel 1^Value;
.i_xSP_DI := TIIB[EL1004_00_10]^Channel 1^Input;
.q_xHVEna_DO := TIIB[EL2794_00_09]^Channel 1^Output'}
fb_LD4_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD4
{attribute 'pytmc' := ' pv: LTLHN:LD4:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_13]^AI Standard Channel 4^Value '}
fb_LD4_GPI : FB_MKS275; // Output tube LD4 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD4:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_11]^AI Standard Channel 4^Value;
.i_xHV_ON := TIIB[EL1124_03_09]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_03_09]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_03_02]^Channel 4^Output '}
fb_LD4_GCC : FB_MKS500; // Output tube LD4, Cold Cathode gauge
// LD6
{attribute 'pytmc' := ' pv: LTLHN:LD6:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_13]^Channel 4^Input;
.i_xClsLS := TIIB[EL1004_02_13]^Channel 3^Input;
.q_xOPN_DO := TIIB[EL2004_02_14]^Channel 4^Output'}
fb_LD6_VGC : FB_VGC; // Gate valve, Output tube LD6 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD6:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_11]^AI Standard Channel 2^Value;
.i_xSP_DI := TIIB[EL1004_00_10]^Channel 2^Input;
.q_xHVEna_DO := TIIB[EL2794_00_09]^Channel 2^Output'}
fb_LD6_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD6
{attribute 'pytmc' := ' pv: LTLHN:LD6:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_13]^AI Standard Channel 3^Value '}
fb_LD6_GPI : FB_MKS275; // Output tube LD6 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD6:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3064_02_16]^AI Standard Channel 2^Value;
.q_xHV_DIS := TIIB[EL2794_02_17]^Channel 2^Input'}
fb_LD6_GCC : FB_MKS422; // Output tube LD6, Cold Cathode gauge
// LD8
{attribute 'pytmc' := ' pv: LTLHN:LD8:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_07]^Channel 4^Input;
.i_xClsLS := TIIB[EL1004_02_07]^Channel 3^Input;
.q_xOPN_DO := TIIB[EL2004_02_08]^Channel 4^Output'}
fb_LD8_VGC : FB_VGC; // Gate valve, Output tube LD8 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD8:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_08]^AI Standard Channel 4^Value;
.i_xSP_DI := TIIB[EL1004_00_07]^Channel 4^Input;
.q_xHVEna_DO := TIIB[EL2794_00_06]^Channel 4^Output'}
fb_LD8_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD8
{attribute 'pytmc' := ' pv: LTLHN:LD8:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_11]^AI Standard Channel 2^Value '}
fb_LD8_GPI : FB_MKS275; // Output tube LD8 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD8:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_11]^AI Standard Channel 3^Value;
.i_xHV_ON := TIIB[EL1124_01_08]^Channel 1^Input;
.i_xDisc_Active := TIIB[EL1124_01_08]^Channel 2^Input;
.q_xHV_DIS := TIIB[EL2624_01_01]^Channel 1^Output '}
fb_LD8_GCC : FB_MKS500; // Output tube LD8, Cold Cathode gauge
// LD9
{attribute 'pytmc' := ' pv: LTLHN:LD9:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_06]^Channel 4^Input;
.i_xClsLS := TIIB[EL1004_02_06]^Channel 3^Input;
.q_xOPN_DO := TIIB[EL2004_02_08]^Channel 2^Output'}
fb_LD9_VGC : FB_VGC; // Gate valve, Output tube LD9 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD9:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_14]^AI Standard Channel 2^Value;
.i_xSP_DI := TIIB[EL1004_00_13]^Channel 2^Input;
.q_xHVEna_DO := TIIB[EL2794_00_12]^Channel 2^Output'}
fb_LD9_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD9
{attribute 'pytmc' := ' pv: LTLHN:LD9:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_12]^AI Standard Channel 1^Value '}
fb_LD9_GPI : FB_MKS275; // Output tube LD9 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD9:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_10]^AI Standard Channel 1^Value;
.i_xHV_ON := TIIB[EL1124_03_06]^Channel 1^Input;
.i_xDisc_Active := TIIB[EL1124_03_06]^Channel 2^Input;
.q_xHV_DIS := TIIB[EL2624_03_01]^Channel 1^Output '}
fb_LD9_GCC : FB_MKS500; // Output tube LD9, Cold Cathode gauge
// LD10
{attribute 'pytmc' := ' pv: LTLHN:LD10:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_07]^Channel 2^Input;
.i_xClsLS := TIIB[EL1004_02_07]^Channel 1^Input;
.q_xOPN_DO := TIIB[EL2004_02_08]^Channel 3^Output'}
fb_LD10_VGC : FB_VGC; // Gate valve, Output tube LD10 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD10:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_14]^AI Standard Channel 1^Value;
.i_xSP_DI := TIIB[EL1004_00_13]^Channel 1^Input;
.q_xHVEna_DO := TIIB[EL2794_00_12]^Channel 1^Output'}
fb_LD10_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD10
{attribute 'pytmc' := ' pv: LTLHN:LD10:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_12]^AI Standard Channel 2^Value '}
fb_LD10_GPI : FB_MKS275; // Output tube LD10 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD10:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_10]^AI Standard Channel 2^Value;
.i_xHV_ON := TIIB[EL1124_03_07]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_03_07]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_03_01]^Channel 2^Output '}
fb_LD10_GCC : FB_MKS500; // Output tube LD10, Cold Cathode gauge
// LD14
{attribute 'pytmc' := ' pv: LTLHN:LD14:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_10]^Channel 4^Input;
.i_xClsLS := TIIB[EL1004_02_10]^Channel 3^Input;
.q_xOPN_DO := TIIB[EL2004_02_11]^Channel 4^Output'}
fb_LD14_VGC : FB_VGC; // Gate valve, Output tube LD14 laser Table
{attribute 'pytmc' := ' pv: LTLHN:LD14:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_00_14]^AI Standard Channel 3^Value;
.i_xSP_DI := TIIB[EL1004_00_13]^Channel 3^Input;
.q_xHVEna_DO := TIIB[EL2794_00_12]^Channel 3^Output'}
fb_LD14_PIP : FB_PIP_Gamma; // Ion Pump, output tube LD14
{attribute 'pytmc' := ' pv: LTLHN:LD14:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_12]^AI Standard Channel 3^Value '}
fb_LD14_GPI : FB_MKS275; // Output tube LD14 ATM gauge
{attribute 'pytmc' := ' pv: LTLHN:LD14:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_03_10]^AI Standard Channel 3^Value;
.i_xHV_ON := TIIB[EL1124_03_07]^Channel 1^Input;
.i_xDisc_Active := TIIB[EL1124_03_07]^Channel 2^Input;
.q_xHV_DIS := TIIB[EL2624_03_01]^Channel 3^Output '}
fb_LD14_GCC : FB_MKS500; // Output tube LD14, Cold Cathode gauge
////Bay 2 - Line Upgrade
// LS3
{attribute 'pytmc' := ' pv: LTLHN:LS3:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_8A]^AI Standard Channel 2^Value;
.i_xHV_ON := TIIB[EL1124_01_06]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_01_06]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_01_01]^Channel 3^Output'}
fb_LS3_GCC : FB_MKS500; // LS3, Cold Cathode gauge
{attribute 'pytmc' := ' pv: LTLHN:LS3:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_11]^AI Standard Channel 4^Value '}
fb_LS3_GPI : FB_MKS275; // LS3 Pirani gauge
{attribute 'pytmc' := ' pv: LTLHN:LS3:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_00_16]^Channel 1^Input;
.i_xClsLS := TIIB[EL1004_00_16]^Channel 2^Input;
.q_xOPN_DO := TIIB[EL2004_00_17]^Channel 1^Output'}
fb_LS3_VGC : FB_VGC; // Gate valve
{attribute 'pytmc' := ' pv: LTLHN:LS3:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_01_15]^AI Standard Channel 1^Value;
.i_xSP_DI := TIIB[EL1004_01_16]^Channel 1^Input;
.q_xHVEna_DO := TIIB[EL2794_01_17]^Channel 1^Output'}
fb_LS3_PIP : FB_PIP_Gamma; // Ion Pump
//LS4
{attribute 'pytmc' := ' pv: LTLHN:LS4:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_8A]^AI Standard Channel 3^Value;
.i_xHV_ON := TIIB[EL1124_01_08]^Channel 3^Input;
.i_xDisc_Active := TIIB[EL1124_01_08]^Channel 4^Input;
.q_xHV_DIS := TIIB[EL2624_01_01]^Channel 4^Output '}
fb_LS4_GCC : FB_MKS500; // LS4, Cold Cathode gauge
{attribute 'pytmc' := ' pv: LTLHN:LS4:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_09]^AI Standard Channel 3^Value '}
fb_LS4_GPI : FB_MKS275; // LS4 Pirani gauge
{attribute 'pytmc' := ' pv: LTLHN:LS4:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_00_16]^Channel 3^Input;
.i_xClsLS := TIIB[EL1004_00_16]^Channel 4^Input;
.q_xOPN_DO := TIIB[EL2004_00_17]^Channel 2^Output'}
fb_LS4_VGC : FB_VGC; // Gate valve
{attribute 'pytmc' := ' pv: LTLHN:LS4:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_01_15]^AI Standard Channel 2^Value;
.i_xSP_DI := TIIB[EL1004_01_16]^Channel 2^Input;
.q_xHVEna_DO := TIIB[EL2794_01_17]^Channel 2^Output'}
fb_LS4_PIP : FB_PIP_Gamma; // Ion Pump
//LS6
{attribute 'pytmc' := ' pv: LTLHN:LS6:GCC:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3064_02_16]^AI Standard Channel 1^Value;
.q_xHV_DIS := TIIB[EL2794_02_17]^Channel 1^Input'}
fb_LS6_GCC : FB_MKS422; // LS6, Cold Cathode gauge
{attribute 'pytmc' := ' pv: LTLHN:LS6:GPI:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[EL3174_01_09]^AI Standard Channel 3^Value '}
fb_LS6_GPI : FB_MKS275; // LS6 Pirani gauge
{attribute 'pytmc' := ' pv: LTLHN:LS6:VGC:01 '}
{attribute 'TcLinkTo' := '.i_xOpnLS := TIIB[EL1004_02_13]^Channel 1^Input;
.i_xClsLS := TIIB[EL1004_02_13]^Channel 2^Input;
.q_xOPN_DO := TIIB[EL2004_02_14]^Channel 1^Output'}
fb_LS6_VGC : FB_VGC; // Gate valve
{attribute 'pytmc' := ' pv: LTLHN:LS6:PIP:01 '}
{attribute 'TcLinkTo' := '.i_iPRESS := TIIB[EL3064_01_15]^AI Standard Channel 3^Value;
.i_xSP_DI := TIIB[EL1004_01_16]^Channel 3^Input;
.q_xHVEna_DO := TIIB[EL2794_01_17]^Channel 3^Output'}
fb_LS6_PIP : FB_PIP_Gamma; // Ion Pump
//Preemptive Arbiter Content
g_fbArbiter : FB_Arbiter(1);
END_VAR
GVL_COM
//{attribute 'qualified_only'}
VAR_GLOBAL
// Define COM Ports/Buffers incl. library Tc2_SerialCom
//LXLHN_PTM_01
PTM_SerialRXBuffer : ComBuffer;
PTM_SerialTXBuffer : ComBuffer;
// Serial Terminal
PTM_fbSerialLineControl: SerialLineControl;
//SERIAL IO //EL6021_00_05
{attribute 'TcLinkTo' := '.Status:=TIIB[EL6021_00_05)]^COM TxPDO-Map Inputs^Status;
.D[0]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 0;
.D[1]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 1;
.D[2]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 2;
.D[3]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 3;
.D[4]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 4;
.D[5]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 5;
.D[6]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 6;
.D[7]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 7;
.D[8]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 8;
.D[9]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 9;
.D[10]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 10;
.D[11]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 11;
.D[12]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 12;
.D[13]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 13;
.D[14]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 14;
.D[15]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 15;
.D[16]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 16;
.D[17]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 17;
.D[18]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 18;
.D[19]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 19;
.D[20]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 20;
.D[21]:=TIIB[EL6021_00_05]^COM TxPDO-Map Inputs^Data In 21;
'}
PTM_stComIn AT %I* : EL6inData22B;
{attribute 'TcLinkTo' := '.Ctrl:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Ctrl;
.D[0]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 0;
.D[1]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 1;
.D[2]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 2;
.D[3]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 3;
.D[4]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 4;
.D[5]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 5;
.D[6]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 6;
.D[7]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 7;
.D[8]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 8;
.D[9]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 9;
.D[10]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 10;
.D[11]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 11;
.D[12]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 12;
.D[13]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 13;
.D[14]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 14;
.D[15]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 15;
.D[16]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 16;
.D[17]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 17;
.D[18]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 18;
.D[19]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 19;
.D[20]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 20;
.D[21]:=TIIB[EL6021_00_05]^COM RxPDO-Map Outputs^Data Out 21;
'}
PTM_stComOut AT %Q* : EL6outData22B;
END_VAR
GVL_Constants
VAR_GLOBAL CONSTANT
ATM_PRESS : INT := 760; // Atmospheric pressure in Torr
ATM_PRESS_ERR_RNG : INT := 10; // Error range that is still considered atmospheric pressure
EPICS_STRING_SIZE : INT := 40;
PTM_INTERLOCK_SP : REAL := 1E-2;
END_VAR
GVL_Shutters
{attribute 'qualified_only'}
VAR_GLOBAL
{attribute 'TcLinkTo' := '
.bOpenRequest := TIID^EtherCAT1^EK1100_04_00^EL2624_04_01^Channel 1^Output;
.bOpenStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_02^Channel 1^Input;
.bCloseStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_02^Channel 2^Input;
.bLssStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_04^Channel 1^Input;
'}
{attribute 'pytmc' := 'pv: LTLHN:LS1:LST'}
fbLS1 : ST_ShutterControl;
{attribute 'TcLinkTo' := '
.bOpenRequest := TIID^EtherCAT1^EK1100_04_00^EL2624_04_01^Channel 3^Output;
.bOpenStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_03^Channel 1^Input;
.bCloseStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_03^Channel 2^Input;
.bLssStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_04^Channel 3^Input;
'}
{attribute 'pytmc' := 'pv: LTLHN:LS5:LST'}
fbLS5 : ST_ShutterControl;
{attribute 'TcLinkTo' := '
.bOpenRequest := TIID^EtherCAT1^EK1100_04_00^EL2624_04_01^Channel 4^Output;
.bOpenStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_03^Channel 3^Input;
.bCloseStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_03^Channel 4^Input;
.bLssStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_04^Channel 4^Input;
'}
{attribute 'pytmc' := 'pv: LTLHN:LS8:LST'}
fbLS8 : ST_ShutterControl;
// Shutter controls for 1um Line
{attribute 'TcLinkTo' := '
.bOpenRequest := TIID^EtherCAT1^EK1100_04_00^EL2624_04_05^Channel 1^Output;
.bOpenStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_06^Channel 1^Input;
.bCloseStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_06^Channel 2^Input;
.bLssStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_07^Channel 1^Input;
'}
{attribute 'pytmc' := 'pv: LTLHN:LS3:LST'}
fbLS3 : ST_ShutterControl;
// Shutter controls for 800nm Line
{attribute 'TcLinkTo' := '
.bOpenRequest := TIID^EtherCAT1^EK1100_04_00^EL2624_04_01^Channel 2^Output;
.bOpenStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_02^Channel 3^Input;
.bCloseStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_02^Channel 4^Input;
.bLssStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_04^Channel 2^Input
'}
{attribute 'pytmc' := 'pv: LTLHN:LS4:LST'}
fbLS4 : ST_ShutterControl;
{attribute 'TcLinkTo' := '
.bOpenRequest := TIID^EtherCAT1^EK1100_04_00^EL2624_04_05^Channel 3^Output;
.bOpenStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_06^Channel 3^Input;
.bCloseStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_06^Channel 4^Input;
.bLssStatus := TIID^EtherCAT1^EK1100_04_00^EL1004_04_07^Channel 2^Input;
'}
{attribute 'pytmc' := 'pv: LTLHN:LS6:LST'}
fbLS6 : ST_ShutterControl;
END_VAR
- Related:
GVL_Variables
//{attribute 'qualified_only'}
VAR_GLOBAL
{attribute 'pytmc' := '
pv: LXLHN:VAC:OVRD_ON
field: ZNAM Override Off ;
field: ONAM Override On ;
'}
xSystemOverrideMode_BTS : BOOL := FALSE; (* Global system override for the BTS Vacuum System *)
{attribute 'pytmc' := 'pv: LXLHN:VAC:GCC:ENABLE'}
xGCC_Enable_SW: BOOL := FALSE; (* Global enable for all GCCs *)
END_VAR
POUs
DIAGNOSTICS
PROGRAM DIAGNOSTICS
VAR
//Change the PLC String Name to the actual PLC NAME
sPLCName :STRING := 'PLC-LAS-BTS';
//Link the sAMSNetID to the Etherat Master netID
i_sAMSNetID AT %I*: AMSNETID;
// DO NOT CHANGE
sAMSNetID : STRING; //used for EPICS PV
sLibVersion_LCLS_General : STRING;(* := stLibVersion_LCLS_General.sVersion*) ;
fbEcatDiag:FB_EcatDiag;
{attribute 'pytmc' := ' pv:PLC:LAS:BTS:AllSlaveStateGood '}
bAllSlaveStateGood : BOOL;
{attribute 'pytmc' := ' pv:PLC:LAS:BTS:MasterStateGood '}
bMasterStateGood :BOOL;
iMasterState: WORD;
sMasterState:STRING;
nSlaveNumber : UINT;
aiSlaveStates: ARRAY[1..256] OF BYTE;
aEcSlaveInfo : ARRAY[1..256] OF ST_EcDevice;
END_VAR
// Instaniating a call to the fbEcatDiag
fbEcatDiag(
I_AMSNetId:=i_sAMSNetID,
i_xFirstPass:= _TaskInfo[1].FirstCycle,
q_xAllSlaveStatesGood=> bAllSlaveStateGood,
q_anTermStates=> aiSlaveStates,
q_xMasterStateGood=>bMasterStateGood,
q_nMasterState=> iMasterState,
q_sMasterState=> sMasterState,
q_astEcConfSlaveInfo=> aEcSlaveInfo,
q_nSlaves=> nSlaveNumber);
END_PROGRAM
F_IsValveReady
FUNCTION F_IsValveReady : BOOL
VAR_IN_OUT
fbValve : FB_VGC;
END_VAR
VAR
END_VAR
F_IsValveReady := (
fbValve.iq_stValve.eState = E_ValvePositionState.OPEN AND
TRUE (*
* Placeholder for something else?
* TODO: Do we check eVGC_State for errors?
* TODO: Do we care if the laser is used at atmosphere?
*)
);
END_FUNCTION
FB_DestinationDataStore
FUNCTION_BLOCK FB_DestinationDataStore
VAR_INPUT
{attribute 'pytmc' := '
pv: BTPS:Name; io: input
'}
sName : STRING;
(* Do not pragma valve; Use original PVs to access valve state *)
fbDestinationValve : REFERENCE TO FB_VGC;
{attribute 'pytmc' := '
pv: BTPS:ExitValveReady
io: input
field: ZNAM Not ready
field: ONAM Ready
field: ZSV MAJOR
field: OSV NO_ALARM
'}
bExitValveReady : BOOL;
{attribute 'pytmc' := '
pv: BTPS:YieldsControl
io: output
field: DESC Destination yields control to others
field: ZNAM Using beam
field: ONAM Yielding
field: ZSV MINOR
field: OSV NO_ALARM
'}
bYieldsControl : BOOL;
{attribute 'pytmc' := '
pv: LS
expand: %s:BTPS
'}
stSourceDataStore : ARRAY [1..GVL_BTPS_Constants.nSources] OF ST_SourceDataStore;
END_VAR
VAR_OUTPUT
//
bDataValid : BOOL;
END_VAR
VAR
nIndex : UINT;
stSource: REFERENCE TO ST_SourceDataStore;
bInit : BOOL := FALSE;
END_VAR
IF NOT bInit THEN
bYieldsControl := TRUE;
bInit := TRUE;
END_IF
bExitValveReady := F_IsValveReady(fbDestinationValve);
Update(
stDataSource:=stSourceDataStore[1],
sName:='LS1 (From laser bay 1)',
fbSourceValve:=GVL_BTS_VAC.fb_LS1_VGC,
fbLinear:=GVL_BTPS.fbLS1Linear,
fbRotary:=GVL_BTPS.fbLS1Rotary,
fbGoniometer:=GVL_BTPS.fbLS1Goniometer,
fbNearField:=GVL_BTPS.fbLS1NearFieldCamStats,
fbFarField:=GVL_BTPS.fbLS1FarFieldCamStats
);
Update(
stDataSource:=stSourceDataStore[5],
sName:='LS5 (From laser bay 3)',
fbSourceValve:=GVL_BTS_VAC.fb_LS5_VGC,
fbLinear:=GVL_BTPS.fbLS5Linear,
fbRotary:=GVL_BTPS.fbLS5Rotary,
fbGoniometer:=GVL_BTPS.fbLS5Goniometer,
fbNearField:=GVL_BTPS.fbLS5NearFieldCamStats,
fbFarField:=GVL_BTPS.fbLS5FarFieldCamStats
);
Update(
stDataSource:=stSourceDataStore[8],
sName:='LS8 (From laser bay 4)',
fbSourceValve:=GVL_BTS_VAC.fb_LS8_VGC,
fbLinear:=GVL_BTPS.fbLS8Linear,
fbRotary:=GVL_BTPS.fbLS8Rotary,
fbGoniometer:=GVL_BTPS.fbLS8Goniometer,
fbNearField:=GVL_BTPS.fbLS8NearFieldCamStats,
fbFarField:=GVL_BTPS.fbLS8FarFieldCamStats
);
Update(
stDataSource:=stSourceDataStore[3],
sName:='LS3 (From laser bay 2)',
fbSourceValve:=GVL_BTS_VAC.fb_LS3_VGC,
fbLinear:=GVL_BTPS.fbLS3Linear,
fbRotary:=GVL_BTPS.fbLS3Rotary,
fbGoniometer:=GVL_BTPS.fbLS3Goniometer,
fbNearField:=GVL_BTPS.fbLS3NearFieldCamStats,
fbFarField:=GVL_BTPS.fbLS3FarFieldCamStats
);
Update(
stDataSource:=stSourceDataStore[4],
sName:='LS4 (From laser bay 2)',
fbSourceValve:=GVL_BTS_VAC.fb_LS4_VGC,
fbLinear:=GVL_BTPS.fbLS4Linear,
fbRotary:=GVL_BTPS.fbLS4Rotary,
fbGoniometer:=GVL_BTPS.fbLS4Goniometer,
fbNearField:=GVL_BTPS.fbLS4NearFieldCamStats,
fbFarField:=GVL_BTPS.fbLS4FarFieldCamStats
);
Update(
stDataSource:=stSourceDataStore[6],
sName:='LS6 (From laser bay 3)',
fbSourceValve:=GVL_BTS_VAC.fb_LS6_VGC,
fbLinear:=GVL_BTPS.fbLS6Linear,
fbRotary:=GVL_BTPS.fbLS6Rotary,
fbGoniometer:=GVL_BTPS.fbLS6Goniometer,
fbNearField:=GVL_BTPS.fbLS6NearFieldCamStats,
fbFarField:=GVL_BTPS.fbLS6FarFieldCamStats
);
END_FUNCTION_BLOCK
METHOD Update : BOOL
VAR_INPUT
sName : STRING;
END_VAR
VAR_IN_OUT
// The data source to update
stDataSource : ST_SourceDataStore;
// The source information
fbSourceValve : FB_VGC;
fbNearField : FB_EpicsStatsMonitor;
fbFarField : FB_EpicsStatsMonitor;
fbLinear : FB_EpicsMotorMonitor;
fbRotary : FB_EpicsMotorMonitor;
fbGoniometer : FB_EpicsMotorMonitor;
END_VAR
stDataSource.sName := sName;
stDataSource.fbSourceValve REF= fbSourceValve;
stDataSource.bEntryValveReady := F_IsValveReady(fbSourceValve);
(* Update range comparisons with their source values *)
(* Cameras *)
stDataSource.fbNFCentroidX.fValue := fbNearField.fCentroidX;
stDataSource.fbNFCentroidX.bInputValid := fbNearField.bValid AND fbNearField.bIsUpdating;
stDataSource.fbNFCentroidY.fValue := fbNearField.fCentroidY;
stDataSource.fbNFCentroidY.bInputValid := fbNearField.bValid AND fbNearField.bIsUpdating;
stDataSource.fbFFCentroidX.fValue := fbFarField.fCentroidX;
stDataSource.fbFFCentroidX.bInputValid := fbFarField.bValid AND fbFarField.bIsUpdating;
stDataSource.fbFFCentroidY.fValue := fbFarField.fCentroidY;
stDataSource.fbFFCentroidY.bInputValid := fbFarField.bValid AND fbFarField.bIsUpdating;
(* Motors *)
stDataSource.fbLinear.fValue := fbLinear.fPosition;
stDataSource.fbLinear.bInputValid := fbLinear.bValid AND fbLinear.stMSTA.bHomed (* AND fbLinear.stMSTA.bClosedLoop *);
stDataSource.fbRotary.fValue := fbRotary.fPosition;
stDataSource.fbRotary.bInputValid := fbRotary.bValid AND fbRotary.stMSTA.bHomed (* AND fbRotary.stMSTA.bClosedLoop *);
stDataSource.fbGoniometer.fValue := fbGoniometer.fPosition;
stDataSource.fbGoniometer.bInputValid := fbGoniometer.bValid AND fbGoniometer.stMSTA.bHomed (* AND fbGoniometer.stMSTA.bClosedLoop *);
(* Run the range comparisons *)
stDataSource.fbNFCentroidX();
stDataSource.fbNFCentroidY();
stDataSource.fbFFCentroidX();
stDataSource.fbFFCentroidY();
stDataSource.fbLinear();
stDataSource.fbRotary();
stDataSource.fbGoniometer();
(* Data is valid overall if *all* range comparisons say so *)
stDataSource.bDataValid := (
stDataSource.fbNFCentroidX.bInputValid AND
stDataSource.fbNFCentroidY.bInputValid AND
stDataSource.fbFFCentroidX.bInputValid AND
stDataSource.fbFFCentroidY.bInputValid AND
stDataSource.fbLinear.bInputValid AND
stDataSource.fbRotary.bInputValid AND
stDataSource.fbGoniometer.bInputValid AND
TRUE
);
(* Checks only pass if data is valid and all comparisons are true *)
stDataSource.bChecksOK := (
stDataSource.bDataValid AND
stDataSource.fbNFCentroidX.bInRange AND
stDataSource.fbNFCentroidY.bInRange AND
stDataSource.fbFFCentroidX.bInRange AND
stDataSource.fbFFCentroidY.bInRange AND
stDataSource.fbLinear.bInRange AND
stDataSource.fbRotary.bInRange AND
stDataSource.fbGoniometer.bInRange AND
stDataSource.bEntryValveReady AND
bExitValveReady AND
TRUE
);
stDataSource.bInPosition := stDataSource.fbLinear.bInputValid AND stDataSource.fbLinear.bInRange;
END_METHOD
FB_EpicsMotorMonitor
(*
EPICS Motor Record Monitoring tool
Requires a "link" pragma to specify the motor record prefix.
*)
FUNCTION_BLOCK FB_EpicsMotorMonitor
VAR_INPUT
bEnable : BOOL := TRUE;
END_VAR
VAR_OUTPUT
bIsMoving : BOOL;
fPosition : LREAL;
nMSTA_Raw : UINT;
stMSTA : ST_EpicsMotorMSTA;
bValid : BOOL;
END_VAR
VAR
{attribute 'pytmc' := '
pv: RBV_
link: .RBV
'}
fbRBVCheck : FB_LREALFromEPICS;
{attribute 'pytmc' := '
pv: Dmov_
link: .DMOV
'}
fbMovingCheck : FB_LREALFromEPICS;
{attribute 'pytmc' := '
pv: Msta_
link: .MSTA
'}
fbMotorStatusCheck : FB_LREALFromEPICS;
END_VAR
IF NOT bEnable THEN
bValid := FALSE;
RETURN;
END_IF
fbRBVCheck();
fbMovingCheck();
fbMotorStatusCheck();
bValid := (
fbRBVCheck.bValid AND
fbMovingCheck.bValid AND
fbMotorStatusCheck.bValid
);
(* Moving status is DMOV; this comes in as a floating point value
DMOV = 0 -> moving
DMOV = 1 -> done moving, or not moving
*)
bIsMoving := ABS(fbMovingCheck.fValue) < 1e-5;
fPosition := fbRBVCheck.fValue;
nMSTA_Raw := LREAL_TO_UINT(fbMotorStatusCheck.fValue);
stMSTA.bPositiveDirection := nMSTA_Raw.0;
stMSTA.bDone := nMSTA_Raw.1;
stMSTA.bPlusLimitSwitch := nMSTA_Raw.2;
stMSTA.bHomeLimitSwitch := nMSTA_Raw.3;
stMSTA.bUnused0 := nMSTA_Raw.4;
stMSTA.bClosedLoop := nMSTA_Raw.5;
stMSTA.bSlipStall := nMSTA_Raw.6;
stMSTA.bHome := nMSTA_Raw.7;
stMSTA.bEncoderPresent := nMSTA_Raw.8;
stMSTA.bHardwareProblem := nMSTA_Raw.9;
stMSTA.bMoving := nMSTA_Raw.10;
stMSTA.bGainSupport := nMSTA_Raw.11;
stMSTA.bCommError := nMSTA_Raw.12;
stMSTA.bMinusLimitSwitch := nMSTA_Raw.13;
stMSTA.bHomed := nMSTA_Raw.14;
END_FUNCTION_BLOCK
- Related:
FB_EpicsStatsMonitor
(*
EPICS AreaDetector Stats Plugin Monitor
Requires a "link" pragma to specify the full plugin prefix.
*)
FUNCTION_BLOCK FB_EpicsStatsMonitor
VAR_INPUT
fMaximumFrameTime : LREAL := 0.2;
(* Minimum change in pixels to be considered a new frame, using pixel sum (total) as a metric *)
fMinPixelSumChange : LREAL := 1E-6;
bEnable : BOOL := TRUE;
END_VAR
VAR_OUTPUT
{attribute 'pytmc' := '
pv: IsUpdating
io: input
'}
bIsUpdating : BOOL;
{attribute 'pytmc' := '
pv: CentroidX
io: input
'}
fCentroidX : LREAL;
{attribute 'pytmc' := '
pv: CentroidY
io: input
'}
fCentroidY : LREAL;
{attribute 'pytmc' := '
pv: Total
io: input
field: DESC Sum of all elements in the image
'}
fTotal : LREAL;
{attribute 'pytmc' := '
pv: ArrayCount
io: input
'}
nArrayCount : UDINT;
bValid : BOOL;
{attribute 'pytmc' := '
pv: FrameTime
io: input
field: DESC Avg time between frame updates
field: EGU sec
'}
fFrameTime : LREAL;
END_VAR
VAR
(* The previous frame times, used for averaging *)
fFrameTimes : ARRAY [1..nFrameArraySize] OF LREAL;
bFrameTimeValid : ARRAY [1..nFrameArraySize] OF BOOL;
nFrameIndex : UINT;
{attribute 'pytmc' := '
pv: CX_
link: CentroidX_RBV
'}
fbCentroidX : FB_LREALFromEPICS;
{attribute 'pytmc' := '
pv: CY_
link: CentroidY_RBV
'}
fbCentroidY : FB_LREALFromEPICS;
{attribute 'pytmc' := '
pv: Total_
link: Total_RBV
'}
fbTotal : FB_LREALFromEPICS;
fLastCentroidX : LREAL;
fLastCentroidY : LREAL;
{attribute 'pytmc' := '
pv: Cnt_
link: ArrayCounter_RBV
'}
fbArrayCounter : FB_LREALFromEPICS;
// Last array count value
nLastArrayCount : UDINT;
fLastTotal : LREAL;
fInternalMaximumFrameTime : LREAL;
nIdx : UINT;
// Time of the last frame update
tLastUpdate: TIME;
tSinceLastFrame : TIME;
tMaximumFrameTime : TIME;
tonLastGoodFrame : TON;
bInit : BOOL;
// Did we see a frame update yet? (FALSE at startup; TRUE after first frame.)
bSawFrame : BOOL;
// Do we have a new frame? Has the array count updated, and position change above fNewFrameMinimumChange?
{attribute 'pytmc' := 'pv: HaveNewFrame; io: i'}
bHaveNewFrame : BOOL;
// For this new frame, is it above the threshold fNewFrameMinimumChange?
{attribute 'pytmc' := 'pv: AboveThreshold; io: i'}
bAboveThreshold : BOOL;
tCheckFrame : TON;
END_VAR
VAR CONSTANT
nFrameArraySize : UINT := 10;
fInvalidFrameTime : LREAL := 0.0;
END_VAR
IF NOT bEnable THEN
bValid := FALSE;
RETURN;
END_IF
IF NOT bInit THEN
bInit := TRUE;
fLastTotal := 0;
bSawFrame := FALSE;
tLastUpdate := TIME();
END_IF
fbCentroidX();
fbCentroidY();
fbTotal();
fbArrayCounter();
bValid := (
fbTotal.bValid AND
fbCentroidX.bValid AND
fbCentroidY.bValid AND
fbArrayCounter.bValid
);
fCentroidX := fbCentroidX.fValue;
fCentroidY := fbCentroidY.fValue;
fTotal := fbTotal.fValue;
nArrayCount := LREAL_TO_UDINT(fbArrayCounter.fValue);
tonLastGoodFrame.PT := T#60S;
tonLastGoodFrame(IN:=TRUE);
IF ABS(fTotal - fLastTotal) >= fMinPixelSumChange AND fMinPixelSumChange > 0.0 THEN
fFrameTime := TIME_TO_LREAL(tonLastGoodFrame.ET) * 0.001; // ms to seconds
tonLastGoodFrame(IN:=FALSE);
tonLastGoodFrame(IN:=TRUE);
bSawFrame := TRUE;
fLastTotal := fTotal;
fLastCentroidX := fCentroidX;
fLastCentroidY := fCentroidY;
nLastArrayCount := nArrayCount;
ELSIF TIME_TO_LREAL(tonLastGoodFrame.ET) * 0.001 > fMaximumFrameTime THEN
fFrameTime := TIME_TO_LREAL(tonLastGoodFrame.ET) * 0.001; // ms to seconds
END_IF
bIsUpdating := bSawFrame AND (fFrameTime < fMaximumFrameTime);
END_FUNCTION_BLOCK
FB_RangeComparison
FUNCTION_BLOCK FB_RangeComparison
VAR_INPUT PERSISTENT
(* The low part of the range. *)
{attribute 'pytmc' := 'pv: Low'}
fLow : LREAL;
(* The high part of the range. *)
{attribute 'pytmc' := 'pv: High'}
fHigh : LREAL;
(* Nominal value for this. User-facing value. *)
{attribute 'pytmc' := '
pv: Nominal
io: io
field: DESC Nominal value for setting
'}
fNominal : LREAL;
(* Are the limits inclusive? *)
{attribute 'pytmc' := '
pv: Inclusive
field: ZNAM Exclusive
field: ONAM Inclusive
'}
bInclusive : BOOL := TRUE;
END_VAR
VAR_INPUT
(* The input value for comparison *)
{attribute 'pytmc' := 'pv: Value; io: input'}
fValue : LREAL;
(* Should the input value be trusted? *)
{attribute 'pytmc' := '
pv: Valid
io: input
field: ZNAM Data Invalid
field: ONAM Data Valid
field: ZSV MAJOR
field: OSV NO_ALARM
'}
bInputValid : BOOL := FALSE;
END_VAR
VAR_OUTPUT
{attribute 'pytmc' := '
pv: InRange
io: input
field: ZNAM Out of range
field: ONAM In range
field: ZSV MAJOR
field: OSV NO_ALARM
'}
bInRange : BOOL;
END_VAR
IF NOT bInputValid OR fHigh < fLow THEN
bInRange := FALSE;
ELSIF bInclusive THEN
bInRange := (fValue >= fLow) AND (fValue <= fHigh);
ELSE
bInRange := (fValue > fLow) AND (fValue < fHigh);
END_IF
END_FUNCTION_BLOCK
FB_ShutterSafety
FUNCTION_BLOCK FB_ShutterSafety
VAR_INPUT
{attribute 'pytmc' := '
pv: LSSPermission
io: i
field: ZNAM FALSE
field: ONAM TRUE
'}
bLSSPermission : BOOL;
{attribute 'pytmc' := '
pv: Acknowledge
io: io
field: ZNAM FALSE
field: ONAM TRUE
'}
bAcknowledge : BOOL;
{attribute 'pytmc' := '
pv: UserOpen
io: io
field: ZNAM Close
field: ONAM Open
'}
bUserOpenRequest : BOOL;
{attribute 'pytmc' := '
pv: Override
io: io
field: ZNAM Normal mode
field: ONAM Override mode
'}
bOverride : BOOL;
nSourceIndex : UINT;
Shutter_Enable : BOOL;
END_VAR
VAR_IN_OUT
(* VAR_IN_OUT -> reference to fbDestinations *)
fbDestinations : ARRAY [1..GVL_BTPS_Constants.nDestinations] OF FB_DestinationDataStore;
END_VAR
VAR_OUTPUT
{attribute 'pytmc' := '
pv: Safe
io: input
field: ZNAM Unsafe
field: ONAM Safe
'}
bSafeToOpen : BOOL;
{attribute 'pytmc' := '
pv: Error
io: input
field: ZNAM No error
field: ONAM Error
field: ZSV NO_ALARM
field: OSV MAJOR
'}
bLatchedError : BOOL;
{attribute 'pytmc' := '
pv: LSS:OpenRequest
io: input
field: ZNAM Request close
field: ONAM Request open
'}
bOpenSignal : BOOL;
{attribute 'pytmc' := '
pv: CurrentLD
io: input
field: DESC Current laser destination (LD)
field: LOW 0
field: HIGH 15
field: LSV MAJOR
field: HSV MAJOR
'}
nCurrentLD : INT;
(* Rising trigger indicator of a new error condition. *)
rtError : R_TRIG;
(* Rising trigger indicator of user requesting override. *)
rtOverrideSet : R_TRIG;
(* Falling trigger for a 'close shutter' request. *)
ftCloseRequest : F_TRIG;
END_VAR
VAR
nDestIndex : UINT;
bBtpsPermission : BOOL;
END_VAR
bLatchedError R= bAcknowledge;
bAcknowledge := FALSE;
// Figure out the current destination below
nCurrentLD := 0;
IF nSourceIndex >= 1 AND nSourceIndex <= GVL_BTPS_Constants.nSources THEN
bBtpsPermission := FALSE;
FOR nDestIndex := 1 TO GVL_BTPS_Constants.nDestinations DO
bBtpsPermission := (
bBtpsPermission OR
fbDestinations[nDestIndex].stSourceDataStore[nSourceIndex].bChecksOK
);
IF fbDestinations[nDestIndex].stSourceDataStore[nSourceIndex].bInPosition THEN
IF nCurrentLD = 0 THEN
(* First "valid" destination we've seen *)
nCurrentLD := UINT_TO_INT(nDestIndex);
ELSE
(* Multiple "valid" destinations? This means none are valid *)
nCurrentLD := -1;
END_IF
END_IF
END_FOR
ELSE
bBtpsPermission := FALSE;
bLatchedError := TRUE;
END_IF
(* Latch an error if we have no permission. *)
bLatchedError S= NOT bBtpsPermission;
rtError(CLK:=bLatchedError);
(* Reset the user open request on a new error (if not in override mode) *)
bUserOpenRequest R= rtError.Q AND NOT bOverride;
(* If the user requesets a shutter close, clear override mode. *)
ftCloseRequest(CLK:=bUserOpenRequest);
bOverride R= ftCloseRequest.Q;
(* Don't open immediately when in override mode. Make the user request it. *)
rtOverrideSet(CLK:=bOverride);
bUserOpenRequest R= rtOverrideSet.Q AND NOT bBtpsPermission;
(* LSS permission goes low -> stop override and reset user open
NOTE: We do not have these connected yet, so we can't test this.
TODO: connect bLssPermission
TODO: Double-check logic
bOverride R= NOT bLssPermission;
bUserOpenRequest R= NOT bLssPermission;
*)
(* Lose permission on a latched error. *)
bBtpsPermission R= bLatchedError;
(* It's safe to open IF in override mode (user says so!) or we determined it. *)
bSafeToOpen := bOverride OR bBtpsPermission;
(* Only open the shutter if requested and it's safe. *)
bOpenSignal := bSafeToOpen AND bUserOpenRequest;
END_FUNCTION_BLOCK
FB_Test_EpicsCentroidMonitor
{attribute 'call_after_init'}
FUNCTION_BLOCK FB_Test_EpicsCentroidMonitor EXTENDS TcUnit.FB_TestSuite
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR
TestBasics();
END_FUNCTION_BLOCK
METHOD TestBasics
VAR_INPUT
END_VAR
VAR_INST
fbMonitor : FB_EpicsStatsMonitor;
nCount : INT := 0;
END_VAR
TEST('Updating_OK');
fbMonitor.nMaxDroppedFrames := 2;
fbMonitor.fMaximumFrameTime := 10.0;
fbMonitor.fMinPixelSumChange := 0.5;
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#0S, fX:=0.0, fY:=0.0, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#1S, fX:=0.1, fY:=0.1, fTotal:=1.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#2S, fX:=0.1, fY:=0.1, fTotal:=2.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
AssertTrue(fbMonitor.bIsUpdating, Message:='Centroid not reporting updating');
AssertEquals_LREAL(fbMonitor.fFrameTime, 1.5, 1E-6, Message:='Update time inaccurate');
AssertEquals_LREAL(fbMonitor.fFrameTimes[1], 1.0, 1E-6, Message:='Update time inaccurate');
AssertEquals_LREAL(fbMonitor.fFrameTimes[2], 2.0, 1E-6, Message:='Update time inaccurate');
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#2S, fX:=0.1, fY:=0.1, fTotal:=3.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
AssertEquals_LREAL(fbMonitor.fFrameTimes[1], 2.0, 1E-6, Message:='Update time inaccurate');
AssertEquals_LREAL(fbMonitor.fFrameTimes[2], 2.0, 1E-6, Message:='Update time inaccurate');
TEST_FINISHED();
(*
TEST('Updating_Not_OK');
fbMonitor.Initialize();
fbMonitor.nMaxDroppedFrames := 2;
fbMonitor.fMaximumFrameTime := 10.0;
fbMonitor.fMinPixelSumChange := 0.5;
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#0S, fX:=0.0, fY:=0.0, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#11S, fX:=0.1, fY:=0.1, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
WriteCentroidValue(fbMonitor:=fbMonitor, tLastUpdate:=T#11S, fX:=0.1, fY:=0.1, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0);
fbMonitor();
AssertFalse(fbMonitor.bIsUpdating, Message:='Centroid not updating');
AssertEquals_LREAL(fbMonitor.fFrameTime, fbMonitor.fMaximumFrameTime, 1E-6, Message:='Update time inaccurate');
AssertEquals_LREAL(fbMonitor.fFrameTimes[1], fbMonitor.fMaximumFrameTime, 1E-6, Message:='Update time inaccurate');
AssertEquals_LREAL(fbMonitor.fFrameTimes[2], fbMonitor.fMaximumFrameTime, 1E-6, Message:='Update time inaccurate');
TEST_FINISHED();
// TODO: how to make that timer trigger?
*)
TEST('Severity invalidation');
WriteCentroidValue(fbMonitor:=fbMonitor, fX:=0.0, fY:=0.0, fTotal:=0.0, nCount:=nCount, nX_Severity:=2, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0, tLastUpdate:=T#0.2S);
fbMonitor(fMinPixelSumChange:=0.0);
AssertFalse(fbMonitor.bValid, Message:='Invalid data - x severity');
WriteCentroidValue(fbMonitor:=fbMonitor, fX:=0.1, fY:=0.1, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=2, nCount_Severity:=0, nTotal_Severity:=0, tLastUpdate:=T#0.2S);
fbMonitor(fMinPixelSumChange:=0.0);
AssertFalse(fbMonitor.bValid, Message:='Invalid data - y severity');
WriteCentroidValue(fbMonitor:=fbMonitor, fX:=0.2, fY:=0.2, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=2, nTotal_Severity:=0, tLastUpdate:=T#0.2S);
fbMonitor(fMinPixelSumChange:=0.0);
AssertFalse(fbMonitor.bValid, Message:='Invalid data - count severity');
WriteCentroidValue(fbMonitor:=fbMonitor, fX:=0.2, fY:=0.2, fTotal:=0.0, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=2, tLastUpdate:=T#0.2S);
fbMonitor(fMinPixelSumChange:=0.0);
AssertFalse(fbMonitor.bValid, Message:='Invalid data - total severity');
WriteCentroidValue(fbMonitor:=fbMonitor, fX:=0.0, fY:=0.0, fTotal:=fbMonitor.fMinPixelSumChange, nCount:=nCount, nX_Severity:=0, nY_Severity:=0, nCount_Severity:=0, nTotal_Severity:=0, tLastUpdate:=T#0.1S);
fbMonitor(fMinPixelSumChange:=0.0);
AssertTrue(fbMonitor.bValid, Message:='Data valid');
AssertTrue(fbMonitor.bIsUpdating, Message:='Data valid and updating');
TEST_FINISHED();
END_METHOD
METHOD WriteCentroidValue
VAR_IN_OUT
fbMonitor : FB_EpicsStatsMonitor;
END_VAR
VAR_INPUT
fX : LREAL;
fY : LREAL;
fTotal : LREAL;
nCount : INT;
nX_Severity : INT := 0;
nY_Severity : INT := 0;
nCount_Severity : INT := 0;
nTotal_Severity : INT := 0;
tLastUpdate : TIME;
END_VAR
WRITE_PROTECTED_INT(ADR(fbMonitor.fbCentroidX.iPLCInternalSeverity), nX_Severity);
WRITE_PROTECTED_INT(ADR(fbMonitor.fbCentroidY.iPLCInternalSeverity), nY_Severity);
WRITE_PROTECTED_INT(ADR(fbMonitor.fbArrayCounter.iPLCInternalSeverity), nCount_Severity);
WRITE_PROTECTED_INT(ADR(fbMonitor.fbTotal.iPLCInternalSeverity), nTotal_Severity);
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbCentroidX.fPLCInternalValue), fX);
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbCentroidY.fPLCInternalValue), fY);
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbTotal.fPLCInternalValue), fTotal);
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbArrayCounter.fPLCInternalValue), INT_TO_LREAL(nCount));
WRITE_PROTECTED_TIME(ADR(fbMonitor.tLastUpdate), TIME() - tLastUpdate);
END_METHOD
- Related:
FB_Test_EpicsMotorMonitor
{attribute 'call_after_init'}
FUNCTION_BLOCK FB_Test_EpicsMotorMonitor EXTENDS TcUnit.FB_TestSuite
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR
TestBasics();
END_FUNCTION_BLOCK
METHOD TestBasics
VAR_INPUT
END_VAR
VAR_INST
fbMonitor : FB_EpicsMotorMonitor;
END_VAR
TEST('Basic');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertTrue(fbMonitor.bValid, Message:='Data valid');
TEST_FINISHED();
TEST('Severities');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=0, nRBV_Severity:=2, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertFalse(fbMonitor.bValid, Message:='Invalid RBV');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=2, nMoving_Severity:=0);
fbMonitor();
AssertFalse(fbMonitor.bValid, Message:='Invalid status');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=2);
fbMonitor();
AssertFalse(fbMonitor.bValid, Message:='Invalid moving');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertTrue(fbMonitor.bValid, Message:='All valid');
TEST_FINISHED();
TEST('Moving');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0 (* DMOV *), nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertTrue(fbMonitor.bIsMoving, Message:='Moving');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=1 (* DMOV *), nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertFalse(fbMonitor.bIsMoving, Message:='Not moving');
TEST_FINISHED();
TEST('Position');
WriteData(fbMonitor:=fbMonitor, fRBV:=10.0, nMoving:=0, nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertEquals_LREAL(Actual:=fbMonitor.fPosition, Expected:=10.0, Delta:=0.1, Message:='Position 1 OK');
WriteData(fbMonitor:=fbMonitor, fRBV:=20.0, nMoving:=0, nStatus:=0, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertEquals_LREAL(Actual:=fbMonitor.fPosition, Expected:=20.0, Delta:=0.1, Message:='Position 2 OK');
TEST_FINISHED();
TEST('MSTA set');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=16#0FFFF, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertTrue(fbMonitor.stMSTA.bPositiveDirection, Message:='bPositiveDirection True');
AssertTrue(fbMonitor.stMSTA.bDone, Message:='bDone True');
AssertTrue(fbMonitor.stMSTA.bPlusLimitSwitch, Message:='bPlusLimitSwitch True');
AssertTrue(fbMonitor.stMSTA.bHomeLimitSwitch, Message:='bHomeLimitSwitch True');
AssertTrue(fbMonitor.stMSTA.bUnused0, Message:='bUnused0 True');
AssertTrue(fbMonitor.stMSTA.bClosedLoop, Message:='bClosedLoop True');
AssertTrue(fbMonitor.stMSTA.bSlipStall, Message:='bSlipStall True');
AssertTrue(fbMonitor.stMSTA.bHome, Message:='bHome True');
AssertTrue(fbMonitor.stMSTA.bEncoderPresent, Message:='bEncoderPresent True');
AssertTrue(fbMonitor.stMSTA.bHardwareProblem, Message:='bHardwareProblem True');
AssertTrue(fbMonitor.stMSTA.bMoving, Message:='bMoving True');
AssertTrue(fbMonitor.stMSTA.bGainSupport, Message:='bGainSupport True');
AssertTrue(fbMonitor.stMSTA.bCommError, Message:='bCommError True');
AssertTrue(fbMonitor.stMSTA.bMinusLimitSwitch, Message:='bMinusLimitSwitch True');
AssertTrue(fbMonitor.stMSTA.bHomed, Message:='bHomed True');
TEST_FINISHED();
TEST('MSTA zero');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=16#0000, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertFalse(fbMonitor.stMSTA.bPositiveDirection, Message:='bPositiveDirection False');
AssertFalse(fbMonitor.stMSTA.bDone, Message:='bDone False');
AssertFalse(fbMonitor.stMSTA.bPlusLimitSwitch, Message:='bPlusLimitSwitch False');
AssertFalse(fbMonitor.stMSTA.bHomeLimitSwitch, Message:='bHomeLimitSwitch False');
AssertFalse(fbMonitor.stMSTA.bUnused0, Message:='bUnused0 False');
AssertFalse(fbMonitor.stMSTA.bClosedLoop, Message:='bClosedLoop False');
AssertFalse(fbMonitor.stMSTA.bSlipStall, Message:='bSlipStall False');
AssertFalse(fbMonitor.stMSTA.bHome, Message:='bHome False');
AssertFalse(fbMonitor.stMSTA.bEncoderPresent, Message:='bEncoderPresent False');
AssertFalse(fbMonitor.stMSTA.bHardwareProblem, Message:='bHardwareProblem False');
AssertFalse(fbMonitor.stMSTA.bMoving, Message:='bMoving False');
AssertFalse(fbMonitor.stMSTA.bGainSupport, Message:='bGainSupport False');
AssertFalse(fbMonitor.stMSTA.bCommError, Message:='bCommError False');
AssertFalse(fbMonitor.stMSTA.bMinusLimitSwitch, Message:='bMinusLimitSwitch False');
AssertFalse(fbMonitor.stMSTA.bHomed, Message:='bHomed False');
TEST_FINISHED();
TEST('MSTA something');
WriteData(fbMonitor:=fbMonitor, fRBV:=0.0, nMoving:=0, nStatus:=2#0100_0011_0000_0110, nRBV_Severity:=0, nStatus_Severity:=0, nMoving_Severity:=0);
fbMonitor();
AssertFalse(fbMonitor.stMSTA.bPositiveDirection, Message:='bPositiveDirection');
AssertTrue(fbMonitor.stMSTA.bDone, Message:='bDone');
AssertTrue(fbMonitor.stMSTA.bPlusLimitSwitch, Message:='bPlusLimitSwitch');
AssertFalse(fbMonitor.stMSTA.bHomeLimitSwitch, Message:='bHomeLimitSwitch');
AssertFalse(fbMonitor.stMSTA.bUnused0, Message:='bUnused0');
AssertFalse(fbMonitor.stMSTA.bClosedLoop, Message:='bClosedLoop');
AssertFalse(fbMonitor.stMSTA.bSlipStall, Message:='bSlipStall');
AssertFalse(fbMonitor.stMSTA.bHome, Message:='bHome');
AssertTrue(fbMonitor.stMSTA.bEncoderPresent, Message:='bEncoderPresent');
AssertTrue(fbMonitor.stMSTA.bHardwareProblem, Message:='bHardwareProblem');
AssertFalse(fbMonitor.stMSTA.bMoving, Message:='bMoving');
AssertFalse(fbMonitor.stMSTA.bGainSupport, Message:='bGainSupport');
AssertFalse(fbMonitor.stMSTA.bCommError, Message:='bCommError');
AssertFalse(fbMonitor.stMSTA.bMinusLimitSwitch, Message:='bMinusLimitSwitch');
AssertTrue(fbMonitor.stMSTA.bHomed, Message:='bHomed');
TEST_FINISHED();
END_METHOD
METHOD WriteData
VAR_IN_OUT
fbMonitor : FB_EpicsMotorMonitor;
END_VAR
VAR_INPUT
fRBV : LREAL;
nMoving : INT;
nStatus : UINT;
nRBV_Severity : INT := 0;
nStatus_Severity : INT := 0;
nMoving_Severity : INT := 0;
END_VAR
WRITE_PROTECTED_INT(ADR(fbMonitor.fbRBVCheck.iPLCInternalSeverity), nRBV_Severity);
WRITE_PROTECTED_INT(ADR(fbMonitor.fbMotorStatusCheck.iPLCInternalSeverity), nStatus_Severity);
WRITE_PROTECTED_INT(ADR(fbMonitor.fbMovingCheck.iPLCInternalSeverity), nMoving_Severity);
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbRBVCheck.fPLCInternalValue), fRBV);
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbMotorStatusCheck.fPLCInternalValue), UINT_TO_LREAL(nStatus));
WRITE_PROTECTED_LREAL(ADR(fbMonitor.fbMovingCheck.fPLCInternalValue), INT_TO_LREAL(nMoving));
END_METHOD
- Related:
FB_TestRangeComparison
{attribute 'call_after_init'}
FUNCTION_BLOCK FB_TestRangeComparison EXTENDS TcUnit.FB_TestSuite
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
fbRange : FB_RangeComparison;
END_VAR
TEST('Inclusive valid data');
fbRange.fLow := 0.0;
fbRange.fHigh := 10.0;
fbRange.fNominal := 0.0;
fbRange.bInclusive := TRUE;
fbRange.bInputValid := TRUE;
fbRange(fValue:=0.0);
AssertTrue(fbRange.bInRange, Message:='lower bound');
fbRange(fValue:=10.0);
AssertTrue(fbRange.bInRange, Message:='upper bound');
fbRange(fValue:=5.0);
AssertTrue(fbRange.bInRange, Message:='mid range');
fbRange(fValue:=-1.0);
AssertFalse(fbRange.bInRange, Message:='below range');
fbRange(fValue:=11.0);
AssertFalse(fbRange.bInRange, Message:='above range');
TEST_FINISHED();
TEST('Exclusive valid data');
fbRange.fLow := 0.0;
fbRange.fHigh := 10.0;
fbRange.fNominal := 0.0;
fbRange.bInclusive := FALSE;
fbRange.bInputValid := TRUE;
fbRange(fValue:=0.0);
AssertFalse(fbRange.bInRange, Message:='lower bound');
fbRange(fValue:=10.0);
AssertFalse(fbRange.bInRange, Message:='upper bound');
fbRange(fValue:=5.0);
AssertTrue(fbRange.bInRange, Message:='mid range');
fbRange(fValue:=-1.0);
AssertFalse(fbRange.bInRange, Message:='below range');
fbRange(fValue:=11.0);
AssertFalse(fbRange.bInRange, Message:='above range');
TEST_FINISHED();
TEST('Invalid data');
fbRange.fLow := 0.0;
fbRange.fHigh := 10.0;
fbRange.fNominal := 0.0;
fbRange.bInclusive := TRUE;
fbRange.bInputValid := FALSE;
fbRange(fValue:=0.0);
AssertFalse(fbRange.bInRange, Message:='lower bound');
fbRange(fValue:=10.0);
AssertFalse(fbRange.bInRange, Message:='upper bound');
fbRange(fValue:=5.0);
AssertFalse(fbRange.bInRange, Message:='mid range');
fbRange(fValue:=-1.0);
AssertFalse(fbRange.bInRange, Message:='below range');
fbRange(fValue:=11.0);
AssertFalse(fbRange.bInRange, Message:='above range');
TEST_FINISHED();
TEST('Bad range');
fbRange.fLow := 0.0;
fbRange.fHigh := 0.0;
fbRange.fNominal := 0.0;
fbRange.bInclusive := TRUE;
fbRange.bInputValid := FALSE;
fbRange(fValue:=0.0);
AssertFalse(fbRange.bInRange, Message:='lower bound');
fbRange(fValue:=10.0);
AssertFalse(fbRange.bInRange, Message:='upper bound');
fbRange(fValue:=5.0);
AssertFalse(fbRange.bInRange, Message:='mid range');
fbRange(fValue:=-1.0);
AssertFalse(fbRange.bInRange, Message:='below range');
fbRange(fValue:=11.0);
AssertFalse(fbRange.bInRange, Message:='above range');
TEST_FINISHED();
END_FUNCTION_BLOCK
- Related:
FB_TestShutterSafety
FUNCTION_BLOCK FB_TestShutterSafety EXTENDS TcUnit.FB_TestSuite
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
fbShutter : FB_ShutterSafety;
fbDestinations : ARRAY [1..GVL_BTPS_Constants.nDestinations] OF FB_DestinationDataStore;
nDest : UINT;
nSource : UINT;
END_VAR
TEST('Bad source index');
Reset();
fbShutter.bAcknowledge := FALSE;
fbShutter.bUserOpenRequest := FALSE;
fbShutter.bOverride := FALSE;
fbShutter.nSourceIndex := 0;
fbShutter(fbDestinations:=fbDestinations);
AssertFalse(fbShutter.bSafeToOpen, Message:='Bad source index');
TEST_FINISHED();
TEST('Safe to open');
Reset();
fbDestinations[1].stSourceDataStore[1].bChecksOK := TRUE;
fbShutter.bAcknowledge := FALSE;
fbShutter.bOverride := FALSE;
fbShutter(nSourceIndex:=1, bUserOpenRequest:=FALSE, fbDestinations:=fbDestinations);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 1');
AssertFalse(fbShutter.bOpenSignal, Message:='Safe for source 1; close');
fbShutter(nSourceIndex:=1, bUserOpenRequest:=TRUE, fbDestinations:=fbDestinations);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 1');
AssertTrue(fbShutter.bOpenSignal, Message:='Safe for source 1; open');
fbShutter(nSourceIndex:=2, bUserOpenRequest:=TRUE, fbDestinations:=fbDestinations);
AssertFalse(fbShutter.bSafeToOpen, Message:='Not safe for source 2');
AssertFalse(fbShutter.bOpenSignal, Message:='Not safe for source 2; close');
TEST_FINISHED();
TEST('Acknowledge error');
Reset();
fbDestinations[1].stSourceDataStore[1].bChecksOK := FALSE;
fbShutter(nSourceIndex:=1, bUserOpenRequest:=TRUE, fbDestinations:=fbDestinations, bAcknowledge:=False);
AssertFalse(fbShutter.bSafeToOpen, Message:='Not safe yet');
AssertFalse(fbShutter.bOpenSignal, Message:='Not safe yet; close');
AssertFalse(fbShutter.bUserOpenRequest, Message:='Reset open request on fail');
AssertTrue(fbShutter.bLatchedError, Message:='Latched error');
fbDestinations[1].stSourceDataStore[1].bChecksOK := TRUE;
fbShutter(nSourceIndex:=1, fbDestinations:=fbDestinations, bAcknowledge:=TRUE);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 2');
AssertFalse(fbShutter.bOpenSignal, Message:='Open not yet requested');
AssertFalse(fbShutter.bLatchedError, Message:='Latched error cleared');
fbShutter(nSourceIndex:=1, bUserOpenRequest:=TRUE, fbDestinations:=fbDestinations, bAcknowledge:=FALSE);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 2');
AssertTrue(fbShutter.bOpenSignal, Message:='Safe for source 2; open');
AssertFalse(fbShutter.bLatchedError, Message:='Latched error cleared');
TEST_FINISHED();
TEST('Override error');
Reset();
fbDestinations[1].stSourceDataStore[1].bChecksOK := FALSE;
fbShutter(nSourceIndex:=1, bUserOpenRequest:=TRUE, fbDestinations:=fbDestinations, bAcknowledge:=False);
AssertFalse(fbShutter.bSafeToOpen, Message:='Not safe yet');
AssertFalse(fbShutter.bOpenSignal, Message:='Not safe yet; close');
AssertFalse(fbShutter.bUserOpenRequest, Message:='Reset open request on fail');
AssertTrue(fbShutter.bLatchedError, Message:='Latched error');
fbShutter.bOverride := TRUE;
fbShutter(nSourceIndex:=1, fbDestinations:=fbDestinations);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 2');
AssertFalse(fbShutter.bOpenSignal, Message:='Open not yet requested');
AssertTrue(fbShutter.bLatchedError, Message:='Latched error overridden not cleared');
fbShutter(nSourceIndex:=1, bUserOpenRequest:=TRUE, fbDestinations:=fbDestinations);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 2');
AssertTrue(fbShutter.bOpenSignal, Message:='Safe for source 2; open');
AssertFalse(fbShutter.bLatchedError, Message:='Latched error still there');
fbShutter(nSourceIndex:=1, bUserOpenRequest:=FALSE, fbDestinations:=fbDestinations);
AssertTrue(fbShutter.bSafeToOpen, Message:='Safe for source 2');
AssertTrue(fbShutter.bOpenSignal, Message:='Safe for source 2; open');
AssertFalse(fbShutter.bLatchedError, Message:='Latched error still there');
AssertFalse(fbShutter.bOverride, Message:='Override set after shutter closure');
TEST_FINISHED();
END_FUNCTION_BLOCK
ACTION Reset:
fbShutter.bAcknowledge := TRUE;
fbShutter.bUserOpenRequest := FALSE;
fbShutter.bOverride := TRUE;
fbShutter.nSourceIndex := 1;
fbShutter(fbDestinations:=fbDestinations);
fbShutter.bAcknowledge := FALSE;
fbShutter.bUserOpenRequest := FALSE;
fbShutter.bOverride := FALSE;
fbShutter.nSourceIndex := 1;
fbShutter(fbDestinations:=fbDestinations);
FOR nDest := 1 TO GVL_BTPS_Constants.nDestinations DO
fbDestinations[nDest].stSourceDataStore[nSource].bChecksOK := FALSE;
END_FOR
WRITE_PROTECTED_BOOL(ADR(fbShutter.bLatchedError), FALSE);
WRITE_PROTECTED_BOOL(ADR(fbShutter.bOpenSignal), FALSE);
WRITE_PROTECTED_BOOL(ADR(fbShutter.bSafeToOpen), FALSE);
END_ACTION
MAIN
PROGRAM MAIN
VAR
fbLogHandler : FB_LogHandler;
END_VAR
fbLogHandler();
// Run the Diagnostics PRG
DIAGNOSTICS();
// Run the Gauges PRG
PRG_GAUGES();
// Run the Valves PRG
PRG_VALVES();
// Run the Pumps PRG
PRG_PUMPS();
// Run the beam transport protection system code (BTPS)
PRG_BTPS();
// Run Evaluation of Shutter Request
PRG_ShutterRequest();
// Uncomment me to run tests
(* PRG_RunTests(); *)
END_PROGRAM
PRG_BTPS
PROGRAM PRG_BTPS
VAR
END_VAR
GVL_BTPS.fbLS1Linear(bEnable:=TRUE);
GVL_BTPS.fbLS5Linear(bEnable:=TRUE);
GVL_BTPS.fbLS8Linear(bEnable:=TRUE);
GVL_BTPS.fbLS3Linear(bEnable:=TRUE);
GVL_BTPS.fbLS4Linear(bEnable:=TRUE);
GVL_BTPS.fbLS6Linear(bEnable:=TRUE);
GVL_BTPS.fbLS1Rotary(bEnable:=TRUE);
GVL_BTPS.fbLS5Rotary(bEnable:=TRUE);
GVL_BTPS.fbLS8Rotary(bEnable:=TRUE);
GVL_BTPS.fbLS3Rotary(bEnable:=TRUE);
GVL_BTPS.fbLS4Rotary(bEnable:=TRUE);
GVL_BTPS.fbLS6Rotary(bEnable:=TRUE);
GVL_BTPS.fbLS1Goniometer(bEnable:=TRUE);
GVL_BTPS.fbLS5Goniometer(bEnable:=TRUE);
GVL_BTPS.fbLS8Goniometer(bEnable:=TRUE);
GVL_BTPS.fbLS3Goniometer(bEnable:=TRUE);
GVL_BTPS.fbLS4Goniometer(bEnable:=TRUE);
GVL_BTPS.fbLS6Goniometer(bEnable:=TRUE);
GVL_BTPS.fbLS1NearFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS5NearFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS8NearFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS3NearFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS4NearFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS6NearFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS1FarFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS5FarFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS8FarFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS3FarFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS4FarFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbLS6FarFieldCamStats(bEnable:=TRUE, fMaximumFrameTime:=GVL_BTPS_Retain.fMaximumFrameTime, fMinPixelSumChange:=GVL_BTPS_Retain.fMinPixelChange);
GVL_BTPS.fbDestinations[2](sName:='RIX IP3', fbDestinationValve:=GVL_BTS_VAC.fb_LD2_VGC);
GVL_BTPS.fbDestinations[4](sName:='RIX ChemRIXS', fbDestinationValve:=GVL_BTS_VAC.fb_LD4_VGC);
GVL_BTPS.fbDestinations[6](sName:='RIX qRIXS', fbDestinationValve:=GVL_BTS_VAC.fb_LD6_VGC);
GVL_BTPS.fbDestinations[8](sName:='TMO IP1', fbDestinationValve:=GVL_BTS_VAC.fb_LD8_VGC);
GVL_BTPS.fbDestinations[9](sName:='Laser Lab', fbDestinationValve:=GVL_BTS_VAC.fb_LD9_VGC);
GVL_BTPS.fbDestinations[10](sName:='TMO IP2', fbDestinationValve:=GVL_BTS_VAC.fb_LD10_VGC);
GVL_BTPS.fbDestinations[14](sName:='XPP', fbDestinationValve:=GVL_BTS_VAC.fb_LD14_VGC);
(* Shutter safety evaluation should always come at the end. *)
GVL_BTPS.fbSafetyLS1(nSourceIndex:=1, fbDestinations:=GVL_BTPS.fbDestinations);
GVL_BTPS.fbSafetyLS5(nSourceIndex:=5, fbDestinations:=GVL_BTPS.fbDestinations);
GVL_BTPS.fbSafetyLS8(nSourceIndex:=8, fbDestinations:=GVL_BTPS.fbDestinations);
GVL_BTPS.fbSafetyLS3(nSourceIndex:=3, fbDestinations:=GVL_BTPS.fbDestinations);
GVL_BTPS.fbSafetyLS4(nSourceIndex:=4, fbDestinations:=GVL_BTPS.fbDestinations);
GVL_BTPS.fbSafetyLS6(nSourceIndex:=6, fbDestinations:=GVL_BTPS.fbDestinations);
(* Based on the shutter safety result; send open or close request to shutters *)
IF NOT GVL_BTPS_Retain.bSystemOverride THEN
GVL_Shutters.fbLS1.bOpenRequest := GVL_BTPS.fbSafetyLS1.bOpenSignal;
GVL_Shutters.fbLS5.bOpenRequest := GVL_BTPS.fbSafetyLS5.bOpenSignal;
GVL_Shutters.fbLS8.bOpenRequest := GVL_BTPS.fbSafetyLS8.bOpenSignal;
GVL_Shutters.fbLS3.bOpenRequest := GVL_BTPS.fbSafetyLS3.bOpenSignal;
GVL_Shutters.fbLS4.bOpenRequest := GVL_BTPS.fbSafetyLS4.bOpenSignal;
GVL_Shutters.fbLS6.bOpenRequest := GVL_BTPS.fbSafetyLS6.bOpenSignal;
END_IF
(* Periodically save persistent variables with source/destination store information *)
PRG_SavePeristentVariables();
END_PROGRAM
PRG_COM
PROGRAM PRG_COM
VAR
END_VAR
//needs to run on a seperate task
(*Instanitate Serial port com function *)
//LXLHN_PTM_01
PTM_fbSerialLineControl(
Mode:= SERIALLINEMODE_EL6_22B,
pComIn:= ADR(PTM_stComIn),
pComOut:=ADR(PTM_stComOut),
SizeComIn:= SIZEOF(PTM_stComOut),
TxBuffer:= PTM_SerialTXBuffer,
RxBuffer:= PTM_SerialRXBuffer,
Error=> ,
ErrorID=> );
END_PROGRAM
PRG_GAUGES
PROGRAM PRG_GAUGES
VAR
END_VAR
(* Switchbox Gauges *)
fb_PP_GPI_1.M_SetBits(30518);
fb_PP_GPI_1();
fb_PP_GPI_2.M_SetBits(30518);
fb_PP_GPI_2();
fb_DP_GPI.M_SetBits(30518);
fb_DP_GPI();
fb_PP_GCC.M_SetBits(30518);
fb_PP_GCC(PG := GVL_BTS_VAC.fb_PP_GPI_1.PG , IG=> );
fb_DP_GCC.M_SetBits(30518);
fb_DP_GCC(PG := GVL_BTS_VAC.fb_PP_GPI_1.PG , IG=> );
(* Transport Tube Gauges *)
// LS1
fb_LS1_GPI.M_SetBits(30518);
fb_LS1_GPI();
fb_LS1_GCC.M_SetBits(30518);
fb_LS1_GCC(PG := GVL_BTS_VAC.fb_LS1_GPI.PG , IG=> );
// LS5
fb_LS5_GPI.M_SetBits(30518);
fb_LS5_GPI();
fb_LS5_GCC.M_SetBits(30518);
fb_LS5_GCC(PG := GVL_BTS_VAC.fb_LS5_GPI.PG , IG=> );
// LS8
fb_LS8_GPI.M_SetBits(30518);
fb_LS8_GPI();
fb_LS8_GCC.M_SetBits(30518);
fb_LS8_GCC(PG := GVL_BTS_VAC.fb_LS8_GPI.PG , IG=> );
// LD2
fb_LD2_GPI.M_SetBits(30518);
fb_LD2_GPI();
fb_LD2_GCC.M_SetBits(30518);
fb_LD2_GCC(PG := GVL_BTS_VAC.fb_LD2_GPI.PG , IG=> );
// LD4
fb_LD4_GPI.M_SetBits(30518);
fb_LD4_GPI();
fb_LD4_GCC.M_SetBits(30518);
fb_LD4_GCC(PG := GVL_BTS_VAC.fb_LD4_GPI.PG , IG=> );
// LD6
fb_LD6_GPI.M_SetBits(30518);
fb_LD6_GPI();
fb_LD6_GCC(PG := GVL_BTS_VAC.fb_LD6_GPI.PG , IG=> );
// LD8
fb_LD8_GPI.M_SetBits(30518);
fb_LD8_GPI();
fb_LD8_GCC.M_SetBits(30518);
fb_LD8_GCC(PG := GVL_BTS_VAC.fb_LD8_GPI.PG , IG=> );
// LD9
fb_LD9_GPI.M_SetBits(30518);
fb_LD9_GPI();
fb_LD9_GCC.M_SetBits(30518);
fb_LD9_GCC(PG := GVL_BTS_VAC.fb_LD9_GPI.PG , IG=> );
// LD10
fb_LD10_GPI.M_SetBits(30518);
fb_LD10_GPI();
fb_LD10_GCC.M_SetBits(30518);
fb_LD10_GCC(PG := GVL_BTS_VAC.fb_LD10_GPI.PG , IG=> );
// LD14
fb_LD14_GPI.M_SetBits(30518);
fb_LD14_GPI();
fb_LD14_GCC.M_SetBits(30518);
fb_LD14_GCC(PG := GVL_BTS_VAC.fb_LD14_GPI.PG , IG=> );
//1um upgrade lines
// LS3
fb_LS3_GPI.M_SetBits(30518);
fb_LS3_GPI();
fb_LS3_GCC.M_SetBits(30518);
fb_LS3_GCC(PG := GVL_BTS_VAC.fb_LS3_GPI.PG , IG=> );
//LS4
fb_LS4_GPI.M_SetBits(30518);
fb_LS4_GPI();
fb_LS4_GCC.M_SetBits(30518);
fb_LS4_GCC(PG := GVL_BTS_VAC.fb_LS4_GPI.PG , IG=> );
//LS6
fb_LS6_GPI.M_SetBits(30518);
fb_LS6_GPI();
fb_LS6_GCC(PG := GVL_BTS_VAC.fb_LS6_GPI.PG , IG=> );
(* Auto switch on cold cathode gauges if interlock permits *)
If xGCC_Enable_SW THEN
fb_PP_GCC.M_HVE(TRUE);
fb_DP_GCC.M_HVE(TRUE);
fb_LS1_GCC.M_HVE(TRUE);
fb_LS5_GCC.M_HVE(TRUE);
fb_LS8_GCC.M_HVE(TRUE);
fb_LD2_GCC.M_HVE(TRUE);
fb_LD4_GCC.M_HVE(TRUE);
fb_LD6_GCC.M_HVE(TRUE);
fb_LD8_GCC.M_HVE(TRUE);
fb_LD9_GCC.M_HVE(TRUE);
fb_LD10_GCC.M_HVE(TRUE);
fb_LD14_GCC.M_HVE(TRUE);
fb_LS3_GCC.M_HVE(TRUE);
fb_LS4_GCC.M_HVE(TRUE);
fb_LS6_GCC.M_HVE(TRUE);
xGCC_Enable_SW := False;
END_IF
END_PROGRAM
- Related:
PRG_PUMPS
PROGRAM PRG_PUMPS
VAR
END_VAR
(* Switchbox pumps *)
fb_PP_PMF();
//fb_PP_PTM(i_xExtIlkOK := fb_PP_VVC.M_IsClosed());
//F_TurboExtILKLogic_2(Turbo:=fb_PP_PTM.iq_stPTM,
//BackingGauge:= , InletGauge:=, ScrollPump:=fb_PP_PMF.q_stPump));
//GVL_BTS_VAC.fb_PP_PTM(i_xExtIlkOK := F_PumpStationTurboPumpInterlock());
fb_PP_PTM(i_xExtIlkOK := F_TurboExtILKLogic(Turbo:=fb_PP_PTM.iq_stPTM, BackingGauge:=fb_PP_GPI_2.PG,
InletGauge:=fb_PP_GPI_1.PG, VentValve:=fb_PP_VVC.iq_stValve,
ScrollPump:=fb_PP_PMF.q_stPump));
fb_PP_PIP(i_stGauge := fb_DP_GCC.IG);
(* Transport Tube pumps *)
// LS1
fb_LS1_PIP(i_stGauge := fb_LS1_GCC.IG, stPump=>);
// LS5
fb_LS5_PIP(i_stGauge := fb_LS5_GCC.IG, stPump=>);
// LS8
fb_LS8_PIP(i_stGauge := fb_LS8_GCC.IG, stPump=>);
// LD2
fb_LD2_PIP(i_stGauge := fb_LD2_GCC.IG, stPump=>);
// LD4
fb_LD4_PIP(i_stGauge := fb_LD4_GCC.IG, stPump=>);
// LD6
fb_LD6_PIP(i_stGauge := fb_LD6_GCC.IG, stPump=>);
// LD8
fb_LD8_PIP(i_stGauge := fb_LD8_GCC.IG, stPump=>);
// LD9
fb_LD9_PIP(i_stGauge := fb_LD9_GCC.IG, stPump=>);
// LD10
fb_LD10_PIP(i_stGauge := fb_LD10_GCC.IG, stPump=>);
// LD14
fb_LD14_PIP(i_stGauge := fb_LD14_GCC.IG, stPump=>);
//LS3
fb_LS3_PIP(i_stGauge := fb_LS3_GCC.IG, stPump=>);
//LS4
fb_LS4_PIP(i_stGauge := fb_LS4_GCC.IG, stPump=>);
//LS6
fb_LS6_PIP(i_stGauge := fb_LS6_GCC.IG, stPump=>);
(*Serial Interface*)
(*Assign adresses to the pfeiffer controller connected to this serial terminal*)
st_Pfeiffer_CTRL_PTM[1].iSerialAddress :=1; //LXLHN_PTM_01
st_Pfeiffer_CTRL_PTM[1].xEnableComm := TRUE;
(* Instanitate the Function block for serial communication with Pfeiffer*)
PTM_COM(astPfeifferControl := st_Pfeiffer_CTRL_PTM,
astPfeifferStatus:= st_Pfeiffer_RBK_PTM,
SerialRXBuffer:= PTM_SerialRXBuffer,
SerialTXBuffer:= PTM_SerialTXBuffer);
(* Copy Status Pv's into the PTM structure*)
fb_PP_PTM.M_Serial_IO(st_Pfeiffer_CTRL:=st_Pfeiffer_CTRL_PTM[1],st_Pfeiffer_RBK:=st_Pfeiffer_RBK_PTM[1]);
END_PROGRAM
- Related:
PRG_RunTests
PROGRAM PRG_RunTests
VAR
fbRangeComparison : FB_TestRangeComparison;
fbShutterSafety : FB_TestShutterSafety;
fbCentroidTest : FB_Test_EpicsCentroidMonitor;
fbMotorTest : FB_Test_EpicsMotorMonitor;
END_VAR
TcUnit.RUN();
END_PROGRAM
PRG_SavePeristentVariables
PROGRAM PRG_SavePeristentVariables
VAR
fbWritePersistentData: FB_WritePersistentData;
tonStart : TON;
tonInterval : TON;
END_VAR
tonInterval(
IN:=TRUE,
PT:=T#1ms (* Write 1ms after startup of the PLC *)
);
tonStart(
IN:=tonStart.Q AND NOT fbWritePersistentData.BUSY,
PT:=T#1m (* Write every minute *)
);
fbWritePersistentData(
NETID:='', (* This PLC *)
PORT:=851, (* Application port! *)
TMOUT:=T#10s, (* Maximum time before considering this a failure *)
START:=tonStart.Q OR tonInterval.Q (* Start with tonStart goes high or periodically *)
);
END_PROGRAM
PRG_ShutterRequest
PROGRAM PRG_ShutterRequest
VAR
END_VAR
/////Shutter Request Program evaluates the LSS Permission state from the DI and acts on the Open Request state
//// 1um Lines
//LS3
IF (NOT GVL_Shutters.fbLS3.bLssStatus) THEN
GVL_Shutters.fbLS3.bOpenRequest := FALSE;
END_IF
//LS6
IF (NOT GVL_Shutters.fbLS6.bLssStatus) THEN
GVL_Shutters.fbLS6.bOpenRequest := FALSE;
END_IF
/////800 nm
//LS1
IF (NOT GVL_Shutters.fbLS1.bLssStatus) THEN
GVL_Shutters.fbLS1.bOpenRequest := FALSE;
END_IF
//LS4
IF (NOT GVL_Shutters.fbLS4.bLssStatus) THEN
GVL_Shutters.fbLS4.bOpenRequest := FALSE;
END_IF
//LS5
IF (NOT GVL_Shutters.fbLS5.bLssStatus) THEN
GVL_Shutters.fbLS5.bOpenRequest := FALSE;
END_IF
//LS8
IF (NOT GVL_Shutters.fbLS8.bLssStatus) THEN
GVL_Shutters.fbLS8.bOpenRequest := FALSE;
END_IF
END_PROGRAM
- Related:
PRG_VALVES
PROGRAM PRG_VALVES
VAR
Valve_opn_ok : BOOL;
END_VAR
(* Switchbox valves *)
fb_PP_VGC(
i_stUSG := fb_PP_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
fb_PP_VVC(
i_xExtILK_OK := fb_PP_VGC.M_IsClosed(),
i_xOverrideMode := xSystemOverrideMode_BTS
);
GVL_BTS_VAC.fb_PP_VRC_1(
i_xExtILK_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS
);
GVL_BTS_VAC.fb_PP_VRC_2(
i_xExtILK_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS
);
fb_VP_VVC_1(
i_xExtILK_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS
);
fb_VP_VVC_2(
i_xExtILK_OK := TRUE
);
// Vent manifold valve - interlock logic with slow or fast vent
IF (fb_PP_PMF.q_stPump.eState <> E_PumpState.pumpSTOPPED) THEN // Condition to evaluate if Roughing Pump is ON
fb_VP_VVC_4.i_xExtILK_OK := FALSE;
fb_VP_VVC_2.i_xExtILK_OK := FALSE;
fb_VP_VVC_1.i_xExtILK_OK := FALSE;
ELSE
fb_VP_VVC_4.i_xExtILK_OK := TRUE;
fb_VP_VVC_2.i_xExtILK_OK := TRUE;
fb_VP_VVC_1.i_xExtILK_OK := TRUE;
IF (fb_VP_VVC_2.iq_stValve.q_xOPN_DO OR fb_VP_VVC_1.iq_stValve.q_xOPN_DO) THEN
fb_VP_VVC_4.M_Set_OPN_SW(TRUE);
ELSE
fb_VP_VVC_4.M_Set_OPN_SW(FALSE);
END_IF
END_IF
fb_VP_VVC_4(
i_xOverrideMode := xSystemOverrideMode_BTS
);
// Turbo Isolation valve - Interlocked with turbo pump operation
fb_PP_VRC_4(
i_xExtILK_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS
);
(* Transport Tube vavles *)
// LS1
fb_LS1_VGC(
i_stUSG := fb_LS1_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter,
);
// LS5
fb_LS5_VGC(
i_stUSG := fb_LS5_GPI.PG,
i_stDSG := fb_DP_GPI.PG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LS8
fb_LS8_VGC(
i_stUSG := fb_LS8_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD2
fb_LD2_VGC(
i_stUSG := fb_LD2_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD4
fb_LD4_VGC(
i_stUSG := fb_LD4_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD6
fb_LD6_VGC(
i_stUSG := fb_LD6_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD8
fb_LD8_VGC(
i_stUSG := fb_LD8_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD9
fb_LD9_VGC(
i_stUSG := fb_LD9_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD10
fb_LD10_VGC(
i_stUSG := fb_LD10_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LD14
fb_LD14_VGC(
i_stUSG := fb_LD14_GCC.IG,
i_stDSG := fb_DP_GCC.IG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
//// LS3
fb_LS3_VGC(
i_stUSG := fb_LS3_GPI.PG,
i_stDSG := fb_DP_GPI.PG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LS4
fb_LS4_VGC(
i_stUSG := fb_LS4_GPI.PG,
i_stDSG := fb_DP_GPI.PG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
// LS6
fb_LS6_VGC(
i_stUSG := fb_LS6_GPI.PG,
i_stDSG := fb_DP_GPI.PG,
i_xDis_DPIlk := FALSE,
i_xEPS_OK := TRUE,
i_xPMPS_OK := TRUE,
i_xExt_OK := TRUE,
i_xOverrideMode := xSystemOverrideMode_BTS,
io_fbFFHWO := g_FFOut,
fbArbiter := g_fbArbiter
);
END_PROGRAM
- Related: