DUTs ---- GVLs ---- Global_Version ^^^^^^^^^^^^^^ :: {attribute 'TcGenerated'} {attribute 'no-analysis'} {attribute 'linkalways'} // This function has been automatically generated from the project information. VAR_GLOBAL CONSTANT {attribute 'const_non_replaced'} stLibVersion_KFE_ARBITER : ST_LibVersion := (iMajor := 2, iMinor := 4, iBuild := 2, iRevision := 0, nFlags := 1, sVersion := '2.4.2'); END_VAR GVL ^^^ :: VAR_GLOBAL {attribute 'pytmc' := ' pv: @(PREFIX)Arbiter:01 '} g_fbArbiter1 : FB_Arbiter(25); ReqBP : ST_BeamParams; //Currently the placeholder for the fully arbitrated BP set //Example implementation of the FFO {attribute 'pytmc' := ' pv: @(PREFIX)FFO:01 '} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[FFO]^Channel 1^Output'} g_FastFaultOutput1 : FB_HardwareFFOutput := (bAutoReset:=TRUE); {attribute 'pytmc' := ' pv: @(PREFIX)FFO:02 '} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[FFO]^Channel 2^Output'} g_FastFaultOutput2 : FB_HardwareFFOutput := (bAutoReset:=TRUE); g_rTestingVelocity : LREAL := PMPS_GVL.VISIBLE_TEST_VELOCITY; AttemptReset : BOOL; // For testing END_VAR VAR_GLOBAL CONSTANT MAX_FAST_FAULTS : UINT := 100; //Judgement factor constants (administrative mode) nBeamIntensity : INT :=5;//mj MaxDuration : REAL :=12; END_VAR GVL_CheckBounds ^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL nTooLow : UDINT; nTooHigh : UDINT; nDivByZero : UDINT; END_VAR POUs ---- CheckBounds ^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckBounds : DINT VAR_INPUT index, lower, upper: DINT; END_VAR // User defined local variables VAR sMessageLow : STRING := 'CheckBounds: Index too low (%d)'; sMessageHigh : STRING := 'CheckBounds: Index too high (%d)'; END_VAR // Index too low IF index < lower THEN CheckBounds := lower; // Increase global counter GVL_CheckBounds.nTooLow := GVL_CheckBounds.nTooLow + 1; // Log message ADSLOGDINT(msgCtrlMask := ADSLOG_MSGTYPE_WARN, msgFmtStr := sMessageLow, dintArg := index); // Index too high ELSIF index > upper THEN CheckBounds := upper; // Increase global counter GVL_CheckBounds.nTooHigh := GVL_CheckBounds.nTooHigh + 1; // Log message ADSLOGDINT(msgCtrlMask := ADSLOG_MSGTYPE_WARN, msgFmtStr := sMessageHigh, dintArg := index); // Index OK ELSE CheckBounds := index; END_IF {flow} END_FUNCTION Related: * `GVL_CheckBounds`_ CheckRangeSigned ^^^^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckRangeSigned : DINT VAR_INPUT value, lower, upper: DINT; END_VAR // Implicitly generated code : Only an Implementation suggestion IF (value < lower) THEN CheckRangeSigned := lower; ELSIF(value > upper) THEN CheckRangeSigned := upper; ELSE CheckRangeSigned := value; END_IF {flow} END_FUNCTION CheckRangeUnsigned ^^^^^^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckRangeUnsigned : UDINT VAR_INPUT value, lower, upper: UDINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF (value < lower) THEN CheckRangeUnsigned := lower; ELSIF(value > upper) THEN CheckRangeUnsigned := upper; ELSE CheckRangeUnsigned := value; END_IF {flow} END_FUNCTION CurrentBPUpdate ^^^^^^^^^^^^^^^ :: PROGRAM CurrentBPUpdate VAR {attribute 'pytmc' := ' pv: @(PREFIX)K:Rate link: IOC:BSY0:MP01:BYKIKS_RATE field: EGU RateEnum '} fbBYKIK_Rate : FB_LREALFromEPICS := ( iMaximumValidSeverity := 2); {attribute 'pytmc' := ' pv: @(PREFIX) '} fbEPICS_KRate : FB_RateFromEPICS; {attribute 'pytmc' := ' pv: @(PREFIX)L:BC link: SIOC:SYS0:MP03:SC_SXR_BC field: EGU BCEnum '} fbMPS_BeamClass : FB_LREALFromEPICS := ( iMaximumValidSeverity := 2); {attribute 'pytmc' := ' pv: @(PREFIX) '} fbEPICSKBeamClass : FB_BeamClassFromEPICS; {attribute 'pytmc' := ' pv: @(PREFIX)K:Mode link: SIOC:FEES:MP01:FACMODE_RBV '} fbSXR_MachineMode : FB_LREALFromEPICS := ( iMaximumValidSeverity := 2); {attribute 'pytmc' := ' pv: @(PREFIX) '} fbEPICSLMachineMode : FB_MachineModeFromEPICS; {attribute 'pytmc' := ' pv: @(PREFIX)PE '} fbKPhotonEnergy : FB_KPhotonEnergy; // Photon energy for the masses {attribute 'TcLinkTo' := 'TIIB[plc-kfe-gatt]^IO Outputs^rPhotonEnergy'} {attribute 'TcLinkTo' := 'TIIB[plc-rix-mot]^IO Outputs^rPhotonEnergy'} {attribute 'TcLinkTo' := 'TIIB[plc-rix-optics]^IO Outputs^rPhotonEnergy'} q_rPhotonEnergy AT %Q* : REAL; // Stoppers {attribute 'TcLinkTo' := ' .i_StopperInLS:=TIIB[PPS Stoppers 1]^Channel 1^ST3K4 IN; .i_StopperOutLS:=TIIB[PPS Stoppers 1]^Channel 2^ST3K4 OUT; .q_StopperIN_Relay:=TIIB[PMPS_Premp]^Channel 12^ST3K4 RELAY IN; '} st3k4Watcher : FB_KStopper( PMPS.K_Stopper.ST3K4, 'ST3K4'); {attribute 'TcLinkTo' := ' .i_StopperInLS:=TIIB[PPS Stoppers 1]^Channel 3^ST1K2 IN; .i_StopperOutLS:=TIIB[PPS Stoppers 1]^Channel 4^ST1K2 OUT; .q_StopperIN_Relay:=TIIB[PMPS_Premp]^Channel 14^ST1K2 RELAY IN; '} st1k2Watcher : FB_KStopper( PMPS.K_Stopper.ST1K2, 'ST1K2'); {attribute 'TcLinkTo' := ' .i_StopperInLS:=TIIB[PPS Stoppers 1]^Channel 5^ST1K3 IN; .i_StopperOutLS:=TIIB[PPS Stoppers 1]^Channel 6^ST1K3 OUT; .q_StopperIN_Relay:=TIIB[PMPS_Premp]^Channel 7^ST1K3 RELAY IN; '} st1k3Watcher : FB_KStopper( PMPS.K_Stopper.ST1K3, 'ST1K3'); // MR1K1 Veto //////////////////////// {attribute 'TcLinkTo' := 'TIIB[plc-rix-optics]^IO Inputs^MR1K1_Y_ENC'} i_MR1K1_ENC AT %I* : UDINT; // MR1K1 encoder from the rix optics system cMR1K1_IN_UpperLimit : UDINT := 33411000; cMR1K1_IN_LowerLimit : UDINT := 31911000; cMR1K1_OUT_UpperLimit : UDINT := 14173400; {attribute 'TcLinkTo' := 'TIIB[PMPS_Premp]^Channel 13^MR1K1 IN'} q_MR1K1_VETO AT %Q* : BOOL; // Signal to accel. MPS that MR1K1 is in fbMR1K1VetoDevice : FB_KVetoDevice( eVetoDeviceIN := K_Stopper.MR1K1_IN, eVetoDeviceOUT := K_Stopper.MR1K1_OUT, sVetoDeviceName := 'MR1K1'); // ST4K4 Photon Terminator Veto {attribute 'TcLinkTo' := ' .i_StopperInLS:=TIIB[plc-tmo-mot]^IO Inputs^bST4K4_IN; .i_StopperOutLS:=TIIB[plc-tmo-mot]^IO Inputs^bST4K4_OUT; '} st4k4Watcher : FB_KStopper( PMPS.K_Stopper.ST4K4, 'ST4K4'); // MR1K3 Veto //////////////////////// {attribute 'TcLinkTo' := 'TIIB[plc-txi-optics]^IO Inputs^MR1K3_Y_ENC'} i_MR1K3_ENC AT %I* : ULINT; // MR1K3 encoder from the txi k optics optics system cMR1K3_IN_UpperLimit : UDINT := 108500000 + 5000000; cMR1K3_IN_LowerLimit : UDINT := 108500000 - 5000000 ; cMR1K3_OUT_UpperLimit : UDINT := 8900000; q_MR1K3_VETO AT %Q* : BOOL; // Signal to accel. MPS that MR1K3 is in fbMR1K3VetoDevice : FB_KVetoDevice( eVetoDeviceIN := K_Stopper.MR1K3_IN, eVetoDeviceOUT := K_Stopper.MR1K3_OUT, sVetoDeviceName := 'MR1K3'); // MR2K3 Veto //////////////////////// {attribute 'TcLinkTo' := 'TIIB[plc-txi-optics]^IO Inputs^MR2K3_Y_ENC'} i_MR2K3_ENC AT %I* : ULINT; // MR2K3 encoder from the txi k optics system cMR2K3_IN_UpperLimit : UDINT := 105650000 + 10000000; cMR2K3_IN_LowerLimit : UDINT := 105650000 - 10000000 ; cMR2K3_OUT_UpperLimit : UDINT := 10000000; q_MR2K3_VETO AT %Q* : BOOL; // Signal to accel. MPS that MR2K3 is in fbMR2K3VetoDevice : FB_KVetoDevice( eVetoDeviceIN := K_Stopper.MR2K3_IN, eVetoDeviceOUT := K_Stopper.MR2K3_OUT, sVetoDeviceName := 'MR2K3'); // ST1K4Veto // ST1K4 Test Photon stopper Veto in the FEE right before ST3K4 stopper st1k4Watcher : FB_KVetoDevice( eVetoDeviceIN := K_Stopper.ST1K4, eVetoDeviceOUT := K_Stopper.DEFAULT, // not used there is no ST1K4 OUT Just a place holder sVetoDeviceName := 'ST1K4'); //////////////////////// {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^IO Inputs^ST1K4_Y_ENC'} ST1K4_Y_ENC AT %I* : UDINT; // MR2K3 encoder from the system ST1K4_IN_UpperLimit : UDINT := 4293998998 + 10000; ST1K4_IN_LowerLimit : UDINT := 4293998000; ST1K4_OUT_UpperLimit : UDINT := 8900000; END_VAR // Acquiring K-line rate fbEPICS_KRate(BP:=PMPS_GVL.stCurrentBeamParameters, fbBYKIK_Rate:=fbBYKIK_Rate, FFO:=GVL.g_FastFaultOutput1); // Acquiring photon energy fbKPhotonEnergy(BP:=PMPS_GVL.stCurrentBeamParameters); q_rPhotonEnergy := LREAL_TO_REAL(fbKPhotonEnergy.fbSXU.fCurrentPhotonEnergy); //Update current photon energy PMPS_GVL.stCurrentBeamParameters.neV := LREAL_TO_REAL(fbKPhotonEnergy.fbSXU.fCurrentPhotonEnergy); // Acquiring K-line BeamClass fbEPICSKBeamClass(BP:=PMPS_GVL.stCurrentBeamParameters, fbMPS_BeamClass:=fbMPS_BeamClass, FFO:=GVL.g_FastFaultOutput1); // Acquiring K-line Machine Mode fbEPICSLMachineMode(BP:=PMPS_GVL.stCurrentBeamParameters, fbMPS_MachineMode:=fbSXR_MachineMode, FFO:=GVL.g_FastFaultOutput1); // Stopper readbacks st3k4Watcher(stCurrentBP:=PMPS_GVL.stCurrentBeamParameters); st1k2Watcher(stCurrentBP:=PMPS_GVL.stCurrentBeamParameters); st1k3Watcher(stCurrentBP:=PMPS_GVL.stCurrentBeamParameters); // ST4K4 Photon Terminator Veto st4k4Watcher(stCurrentBP:=PMPS_GVL.stCurrentBeamParameters); // MR1K1 Veto //////////////////////// fbMR1K1VetoDevice( i_bIn := cMR1K1_IN_LowerLimit < i_MR1K1_ENC AND i_MR1K1_ENC < cMR1K1_IN_UpperLimit, i_bOut := i_MR1K1_ENC < cMR1K1_OUT_UpperLimit, q_bIN => q_MR1K1_VETO, stCurrentBP:= PMPS_GVL.stCurrentBeamParameters); //////////////////////// fbMR1K3VetoDevice( i_bIn := cMR1K3_IN_LowerLimit < i_MR1K3_ENC AND i_MR1K3_ENC < cMR1K3_IN_UpperLimit, i_bOut := i_MR1K3_ENC < cMR1K3_OUT_UpperLimit, q_bIN => q_MR1K3_VETO, stCurrentBP:= PMPS_GVL.stCurrentBeamParameters); // MR2K3 Veto //////////////////////// fbMR2K3VetoDevice( i_bIn := cMR2K3_IN_LowerLimit < i_MR2K3_ENC AND i_MR2K3_ENC < cMR2K3_IN_UpperLimit, i_bOut := i_MR2K3_ENC < cMR2K3_OUT_UpperLimit, q_bIN => q_MR2K3_VETO, stCurrentBP:= PMPS_GVL.stCurrentBeamParameters); // ST1K4 Photon Test stopper Veto st1k4Watcher(i_bIn := ST1K4_IN_LowerLimit < ST1K4_Y_ENC AND ST1K4_Y_ENC < ST1K4_IN_UpperLimit, i_bOut := ST1K4_Y_ENC < ST1K4_OUT_UpperLimit, q_bIN => , stCurrentBP:= PMPS_GVL.stCurrentBeamParameters); END_PROGRAM Related: * `GVL`_ CXDisplay ^^^^^^^^^ :: PROGRAM CXDisplay VAR DisplayStats : FB_CXSetTextDisplayUSB := (nPort:=28928); fbFormat : FB_FormatString; bError : BOOL; nErrID : UDINT; sOut : T_MaxString; END_VAR (* DisplayStats.bExecute S= NOT DisplayStats.bBusy AND NOT DisplayStats.bError; DisplayStats.bExecute R= DisplayStats.bBusy OR DisplayStats.bError; DisplayStats.sLine1 := 'PMPS-ARBITER-K'; fbFormat(sFormat := 'Fast Faults: %d', arg1:=F_ULINT(PMPS_GVL.AccumulatedFF), sOut=>DisplayStats.sLine2, bError => bError, nErrID => nErrID ); DisplayStats(eMode:=E_CX2100_DisplayModesWr.eCX2100_WriteLines); *) END_PROGRAM Fast_Faults_Evaluate ^^^^^^^^^^^^^^^^^^^^ :: PROGRAM Fast_Faults_Evaluate VAR FFO : FB_FastFault :=( i_Desc := 'Fault occurs when the beamline valves on qrixs are not in open state', i_TypeCode := 16#1010); i_xFastFaultOut_qrix_vac AT %I*: BOOL; FFO2 : FB_FastFault :=( i_Desc := 'Forward Fault from TXI Vacuum.', i_TypeCode := 16#3010); {attribute 'TcLinkTo' := 'TIIB[plc-txi-vac]^IO Inputs^FFO'} i_xFastFaultOut_txi_vac AT %I*: BOOL; FFO3 : FB_FastFault :=( i_Desc := 'Forward Fault from TXI Motion.', i_TypeCode := 16#3013); {attribute 'TcLinkTo' := 'TIIB[plc-txi-mot]^IO Inputs^FFO'} i_xFastFaultOut_txi_mot AT %I*: BOOL; FFO4 : FB_FastFault :=( i_Desc := 'Forward Fault from TXI OPTICS.', i_TypeCode := 16#3013); {attribute 'TcLinkTo' := 'TIIB[plc-txi-optics]^IO Inputs^FFO'} i_xFastFaultOut_txi_optics AT %I*: BOOL; (*TXI OPTICS Protection Faults*) FFO_RIX_TXI_OPTICS : FB_FastFault :=( i_Desc := 'Fault when MR1K1 is IN while a TXI Optics is in (either MR1K3 and MR2K3)', i_TypeCode := 16#3103); FFO_TXI_OPTICS : FB_FastFault :=( i_Desc := 'Fault when MR1K3 is OUT and MR2K3 is IN', i_TypeCode := 16#3113); END_VAR FFO( io_fbFFHWO := g_FastFaultOutput2, i_xOK := i_xFastFaultOut_qrix_vac, i_xAutoReset := TRUE); FFO2( io_fbFFHWO := g_FastFaultOutput2, i_xOK := i_xFastFaultOut_txi_vac, i_xAutoReset := TRUE); FFO3( io_fbFFHWO := g_FastFaultOutput2, i_xOK := i_xFastFaultOut_txi_mot, i_xAutoReset := TRUE); FFO4( io_fbFFHWO := g_FastFaultOutput2, i_xOK := i_xFastFaultOut_txi_optics, i_xAutoReset := TRUE); (*TXI OPTICS Protection Faults*) (* MR1K1 | MR1K3 | MR2K3 | Fault *) (* IN | IN | OUT | TRUE *) (* IN | OUT | IN | TRUE *) (* IN | IN | IN | TRUE *) (* OUT | IN | OUT | TRUE *) (* OUT | OUT | IN | TRUE *) FFO_RIX_TXI_OPTICS( io_fbFFHWO := g_FastFaultOutput2, i_xOK := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]) AND ((PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K3_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K3_IN]) AND (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR2K3_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR2K3_IN])) OR (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN]) , i_xAutoReset := TRUE); FFO_TXI_OPTICS( io_fbFFHWO := g_FastFaultOutput2, i_xOK := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K3_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K3_IN] AND PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR2K3_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR2K3_IN]) OR (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K3_IN] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K3_OUT] AND PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR2K3_IN] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR2K3_OUT]) , i_xAutoReset := TRUE); g_FastFaultOutput2.EvaluateOutput(bAutoReset:=TRUE); END_PROGRAM FB_BeamClassOutputs ^^^^^^^^^^^^^^^^^^^ :: (* Sets the beam class assertion lines for a given beam class. *) FUNCTION_BLOCK FB_BeamClassOutputs VAR_INPUT BP : ST_BeamParams; END_VAR VAR_OUTPUT END_VAR VAR nBeamClass : BYTE; wBeamClass : BYTE; InitCounter: BYTE; counter : INT; // Beam class lines are restricted to 8 channels in the current design, since // there are no plans to use all 16. Channels 1-7 may be allocated to any other // beam classes so long as they are ordered least to greatest. // Channel 8 is reserved for full beam. {attribute 'pytmc' := 'pv: BeamClassChannel io: i field: DESC Hardwire channel state'} epicsBitmap : WORD; {attribute 'TcLinkTo' := '[1] := TIIB[PMPS_Premp]^Channel 1^Output; [2] := TIIB[PMPS_Premp]^Channel 2^Output; [3] := TIIB[PMPS_Premp]^Channel 3^Output; [4] := TIIB[PMPS_Premp]^Channel 4^Output; [5] := TIIB[PMPS_Premp]^Channel 5^Output; [6] := TIIB[PMPS_Premp]^Channel 6^Output; [7] := TIIB[PMPS_Premp]^Channel 7^Output; '} // 8 - Full beam q_BC_ASSERTION_LINES AT %Q* : ARRAY [1..MAX_BEAM_CLASS_LINES] OF BOOL; END_VAR VAR CONSTANT MAX_BEAM_CLASS_LINES : BYTE := 8; BC_1HZ : BYTE := 1; BC_10HZ : BYTE := 2; BC_FULL : BYTE := 16; END_VAR // Determine BC IF BP.nRate >= 120 THEN nBeamClass := BC_FULL; ELSIF BP.nRate >= 10 THEN nBeamClass := BC_10HZ; ELSIF BP.nRate >= 1 THEN nBeamClass := BC_1HZ; ELSE nBeamClass := 0; END_IF //Assert Beam Class //////////////////////////////////// //0x0 = 0000 0000 0000 0000 //0x1 = 0000 0000 0000 0001 //0xF = 1111 1111 1111 1111 //Initialize BC lines to zero on every pass FOR InitCounter := 1 TO MAX_BEAM_CLASS_LINES DO q_BC_ASSERTION_LINES[InitCounter] := FALSE; END_FOR //Set BC lines according to beam class //A BC of 0x0 would pass over this loop, setting none of the lines high // , as FOR loops check the initialized variable at the top to see if it's > // than the "TO" variable. FOR wBeamClass:=1 TO MIN(MAX_BEAM_CLASS_LINES-1, nBeamClass) DO q_BC_ASSERTION_LINES[wBeamClass] := TRUE; END_FOR q_BC_ASSERTION_LINES[8] := nBeamClass = 16; //Set channel 8 true if BC is 16 // Readbacks for EPICS epicsBitmap.0 := q_BC_ASSERTION_LINES[1]; epicsBitmap.1 := q_BC_ASSERTION_LINES[2]; epicsBitmap.2 := q_BC_ASSERTION_LINES[3]; epicsBitmap.3 := q_BC_ASSERTION_LINES[4]; epicsBitmap.4 := q_BC_ASSERTION_LINES[5]; epicsBitmap.5 := q_BC_ASSERTION_LINES[6]; epicsBitmap.6 := q_BC_ASSERTION_LINES[7]; epicsBitmap.7 := q_BC_ASSERTION_LINES[8]; END_FUNCTION_BLOCK MachineSimulation ^^^^^^^^^^^^^^^^^ :: PROGRAM MachineSimulation VAR fbMachine : FB_MachineSimulator; //Simulates attenuator as well fbeVSimulator : FB_eVSimulator := (NoiseLevel := 1); END_VAR // reV Simulator fbeVSimulator(); // Machine simulator fbMachine( i_stAssertedParams := PMPS_GVL.stRequestedBeamParameters, iq_stMachineParams := PMPS_GVL.stCurrentBeamParameters, i_xFault := NOT GVL.g_FastFaultOutput1.q_xFastFaultOut, xEnableAtt := false, xEnablePE := false ); //PMPS_GVL.stCurrentBeamParameters.neVRange := F_eVRangeCalculator(fbeVSimulator.eV, PMPS_GVL.stCurrentBeamParameters.neVRange); //PMPS_GVL.stCurrentBeamParameters.neVRange := 0; END_PROGRAM Related: * `GVL`_ MAIN ^^^^ :: PROGRAM MAIN VAR Initialize : BOOL := TRUE; fbLogHandler : FB_LogHandler; fbEcatDiag : FB_EcatDiagWrapper; {attribute 'pytmc' := ' pv: @(PREFIX)BeamParamCntl '} fbBPControl : FB_BPControlDevice(nID:=16#FFFF); PERanges : PE_Ranges; {attribute 'TcLinkTo' := 'TIIB[PMPS_Premp]^Channel 8^Output;'} bM1K1_OUT_Override AT %Q* : BOOL; // Using this book to completely overrule the last bit of the BC interface. //System Time {attribute 'pytmc' := ' pv: @(PREFIX)SystemDT io: i '} SystemTime:DINT; fbTime : FB_LocalSystemTime := ( bEnable := TRUE, dwCycle := 1 ); //Get current system time, used for override fbTime_to_UTC: FB_TzSpecificLocalTimeToSystemTime; fbGetTimeZone: FB_GetTimeZoneInformation; END_VAR //Arbiter PLC IF Initialize THEN Initialize := FALSE; END_IF // Ethercat Diagnostics fbEcatDiag(); // PMPS Functionality CurrentBPUpdate(); /////////////////////////////////////////////////// // This code should be disabled or removed in deployment // Might have a switch to change to simulation mode MachineSimulation(); //Testing(); /////////////////////////////////////////////////// // Dummy device for controling pmps beam parameters fbBPControl(Arbiter:=g_fbArbiter1); PMPS_Arbiter(); P_AT1K0_SL1K0(); P_SATT(); bM1K1_OUT_Override := PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]; fbLogHandler(); A_SystemTime(); Fast_Faults_Evaluate(); END_PROGRAM ACTION A_SystemTime: //Get local System Time fbTime(sNetID:=''); //Get Time Zone fbGetTimeZone(sNetID:='',bExecute:=TRUE,tTimeout:=T#10S); //change local time to UTC to be compatible with unix time epoch widget fbTime_to_UTC(in:= fbTime.systemTime , tzInfo:=fbGetTimeZone.tzInfo); SystemTime:= TO_DINT(TO_DT(SystemTime_TO_DT(fbTime_to_UTC.out))); END_ACTION ACTION Initialize: END_ACTION Related: * `CurrentBPUpdate`_ * `Fast_Faults_Evaluate`_ * `MachineSimulation`_ * `PMPS_Arbiter`_ * `P_AT1K0_SL1K0`_ * `P_SATT`_ * `Testing`_ P_AT1K0_SL1K0 ^^^^^^^^^^^^^ :: PROGRAM P_AT1K0_SL1K0 VAR // Transmisison request and status with plc-kfe-gatt {attribute 'TcLinkTo' := 'TIIB[plc-kfe-gatt]^IO Outputs^Requested Transmission'} q_nTranToAT1K0Req AT %Q* : ST_PMPS_Attenuator_IO; // Transmission request to AT1K0 {attribute 'TcLinkTo' := 'TIIB[plc-kfe-gatt]^IO Inputs^Current Transmission'} i_nTranToAT1K0Stat AT %I* : ST_PMPS_Attenuator_IO; // Transmission request to AT1K0 // plc-kfe-gatt interface diagnostics {attribute 'TcLinkTo' := 'TIIB[plc-kfe-gatt]^WcState^WcStateOut'} i_bWcStateOut_AT1K0 AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-gatt]^WcState^WcStateIn'} i_bWcStateIn_AT1K0 AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-gatt]^InfoData^State'} i_nState_AT1K0 AT %I* : UINT; // Apterure request and status to plc-kfe-motion {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^IO Outputs^AptArrayReq'} q_stAptArrayReq AT %Q* : ARRAY [1..4] OF ST_PMPS_Aperture_IO; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^IO Inputs^AptArrayStatus'} i_stAptArrayStat AT %I* : ARRAY [1..4] OF ST_PMPS_Aperture_IO; // plc-kfe-motion interface diagnostics {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^WcState^WcStateOut'} i_bWcStateOut_KFEMOT AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^WcState^WcStateIn'} i_bWcStateIn_KFEMOT AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^InfoData^State'} i_nState_KFEMOT AT %I* : UINT; idx : UINT; ffKFEMotConnection : FB_FastFault := ( i_DevName := 'PMPS Arbiter', i_Desc := 'EtherCAT interface watcher, for connection to KFE Motion systems for SL1K0 size requests. Very rare. Make a note, and if it can be reset, go ahead.', i_TypeCode := 16#5); ffKFEGattConnection : FB_FastFault := ( i_DevName := 'PMPS Arbiter', i_Desc := 'EtherCAT interface watcher, for connection to KFE Gas Att. systems for Transmission requests. Very rare. Make a note, and if it can be reset, go ahead.', i_TypeCode := 16#5); bSimApt: BOOL; // Administrative mode for beam intensity {attribute 'pytmc' := ' pv: @(PREFIX)IntensityJF '} nBeamIntensityJF: REAL :=GVL.nBeamIntensity; {attribute 'pytmc' := ' pv: @(PREFIX)ApplyJF '} bApplyJF: BOOL:=FALSE; {attribute 'pytmc' := ' pv: @(PREFIX)CancelJF '} bCancelJF: BOOL:=FALSE; {attribute 'pytmc' := ' pv: @(PREFIX)DurationJF '} rDurationJF: REAL:=GVL.MaxDuration;//hours {attribute 'pytmc' := ' pv: @(PREFIX)TimeRemainJF '} rTimeRemainJF: REAL:=GVL.MaxDuration;//hours tDuration:TIME; tonDuration:TON; END_VAR //Beam intensity factor implemenation // No diff by zero IF (nBeamIntensityJF =0) OR (nBeamIntensityJF > GVL.nBeamIntensity ) THEN nBeamIntensityJF:=GVL.nBeamIntensity; END_IF //Check it it has expired or is cancelled and reset to defaults IF(tonDuration.Q OR bCancelJF) THEN nBeamIntensityJF:=GVL.nBeamIntensity; bCancelJF := FALSE; bApplyJF := FALSE; END_IF // Maximum duration is 12 hours rDurationJF := LIMIT(0,rDurationJF,MaxDuration); //check if it is applied tDuration:= TO_TIME(rDurationJF*60*60*1000);//to msec tonDuration(IN:=bApplyJF,PT:=tDuration,ET=>); rTimeRemainJF:= rDurationJF - (TO_REAL(tonDuration.ET)/60/60/1000);//to hours // If interface with plc-kfe-gatt OK carry out exchange IF i_bWcStateOut_AT1K0 = 0 AND i_bWcStateIn_AT1K0 = 0 AND i_nState_AT1K0 = 8 THEN // Send request from this arbiter to the gas attenuator IF (bApplyJF) THEN q_nTranToAT1K0Req.nTran := LIMIT(0,(GVL.nBeamIntensity/nBeamIntensityJF)*PMPS_GVL.stRequestedBeamParameters.nTran*PMPS_GVL.TRANS_SCALING_FACTOR,1); ELSE q_nTranToAT1K0Req.nTran := PMPS_GVL.stRequestedBeamParameters.nTran*PMPS_GVL.TRANS_SCALING_FACTOR; END_IF q_nTranToAT1K0Req.xAttOK := 16#FF; //Update with judgement factor //Calculate the new requested transmission IF (bApplyJF) THEN PMPS_GVL.stCurrentBeamParameters.nTran := i_nTranToAT1K0Stat.nTran *(nBeamIntensityJF/GVL.nBeamIntensity);//REAL_TO_UINT(UINT_TO_REAL(i_nTranToAT1K0Stat.nTran)*0.01); ELSE PMPS_GVL.stCurrentBeamParameters.nTran := i_nTranToAT1K0Stat.nTran;//REAL_TO_UINT(UINT_TO_REAL(i_nTranToAT1K0Stat.nTran)*0.01); END_IF ffKFEGattConnection.i_xOK := TRUE; ELSE // Fast fault ffKFEGattConnection.i_xOK := FALSE; PMPS_GVL.stCurrentBeamParameters.nTran := PMPS_GVL.TRANS_SCALING_FACTOR;//100; END_IF ffKFEGattConnection(io_fbFFHWO := g_FastFaultOutput1); // If interface with plc-kfe-motion OK, carry out exchange IF i_bWcStateIn_KFEMOT = 0 AND i_bWcStateOut_KFEMOT = 0 AND i_nState_KFEMOT = 8 THEN // Send request from this arbiter to kfe-mot MEMCPY( ADR(q_stAptArrayReq) , ADR(PMPS_GVL.stRequestedBeamParameters.astApertures) , PMPS_GVL.MAX_APERTURES * SIZEOF(ST_PMPS_Aperture_IO) ); // Recieve current apreture state for broadcast MEMCPY( ADR(PMPS_GVL.stCurrentBeamParameters.astApertures) , ADR(i_stAptArrayStat) , PMPS_GVL.MAX_APERTURES * SIZEOF(ST_PMPS_Aperture_IO) ); ffKFEMotConnection.i_xOK := TRUE; ELSIF bSimApt THEN PMPS_GVL.stCurrentBeamParameters.astApertures := PMPS_GVL.stRequestedBeamParameters.astApertures; ELSE // Fast fault ffKFEMotConnection.i_xOK := FALSE; // Set broadcast apterture states to not OK FOR idx := 1 TO PMPS_GVL.MAX_APERTURES DO PMPS_GVL.stCurrentBeamParameters.astApertures[idx].xOK := FALSE; END_FOR END_IF ffKFEMotConnection(io_fbFFHWO := g_FastFaultOutput1); END_PROGRAM Related: * `GVL`_ P_SATT ^^^^^^ :: PROGRAM P_SATT VAR //All Sold attenuators requests are summerrized into this one output q_SattArrayReq AT %Q* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; // Transmission request to ALL PLCs //Per PLC current satt trans {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^IO Inputs^SattArrayStatus'} i_SattArrayStatus_KFE AT %I* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; // Transmission request to KFE MOT PLC {attribute 'TcLinkTo' := 'TIIB[plc-rix-mot]^IO Inputs^SattArrayStatus'} i_SattArrayStatus_RIX AT %I* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; // Transmission request to RIX MOT PLC // plc-tmo-mot interface diagnostics {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^WcState^WcStateOut'} i_bWcStateOut_kfe_mot AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^WcState^WcStateIn'} i_bWcStateIn_kfe_mot AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-kfe-motion]^InfoData^State'} i_nState_kfe_mot AT %I* : UINT; // plc-rix-mot interface diagnostics {attribute 'TcLinkTo' := 'TIIB[plc-rix-mot]^WcState^WcStateOut'} i_bWcStateOut_rix_mot AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-rix-mot]^WcState^WcStateIn'} i_bWcStateIn_rix_mot AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[plc-rix-mot]^InfoData^State'} i_nState_rix_mot AT %I* : UINT; //FFO Connection per PLC ffkfeConnection : FB_FastFault := ( i_DevName := 'PMPS Arbiter', i_Desc := 'EtherCAT interface watcher, for tmo-mot connection to systems for attenuation requests. Very rare. Make a note, and if it can be reset, go ahead.', i_TypeCode := 16#5); ffRixConnection : FB_FastFault := ( i_DevName := 'PMPS Arbiter', i_Desc := 'EtherCAT interface watcher, for rix-mot connection to systems for attenuation requests. Very rare. Make a note, and if it can be reset, go ahead.', i_TypeCode := 16#5); END_VAR // Send request from this arbiter to all satts MEMCPY( ADR(q_SattArrayReq) , ADR(PMPS_GVL.stRequestedBeamParameters.astAttenuators) , PMPS_GVL.AUX_ATTENUATORS * SIZEOF(ST_PMPS_Attenuator_IO) ); //TMO motion PLC SATT current trans update IF i_bWcStateIn_kfe_mot = 0 AND i_bWcStateOut_kfe_mot = 0 AND i_nState_kfe_mot = 8 THEN // Recieve current transmission of the satt //PMPS_GVL.stCurrentBeamParameters.astAttenuators[PMPS.K_Attenuators.AT1K4].nTran := i_SattArrayStatus_KFE[PMPS.K_Attenuators.AT1K4].nTran; //PMPS_GVL.stCurrentBeamParameters.astAttenuators[PMPS.K_Attenuators.AT1K4].xAttOK := i_SattArrayStatus_KFE[PMPS.K_Attenuators.AT1K4].xAttOK; ffkfeConnection.i_xOK := TRUE; ELSE // Fast fault ffkfeConnection.i_xOK := FALSE; END_IF ffkfeConnection(io_fbFFHWO := g_FastFaultOutput1); //RIX motion PLC SATT current trans update IF i_bWcStateIn_rix_mot = 0 AND i_bWcStateOut_rix_mot = 0 AND i_nState_rix_mot = 8 THEN // Recieve current transmission of the satt //PMPS_GVL.stCurrentBeamParameters.astAttenuators[PMPS.K_Attenuators.AT1K2].nTran := i_SattArrayStatus_RIX[PMPS.K_Attenuators.AT1K2].nTran; //PMPS_GVL.stCurrentBeamParameters.astAttenuators[PMPS.K_Attenuators.AT1K2].xAttOK := i_SattArrayStatus_RIX[PMPS.K_Attenuators.AT1K2].xAttOK; //PMPS_GVL.stCurrentBeamParameters.astAttenuators[PMPS.K_Attenuators.AT2K2].nTran := i_SattArrayStatus_RIX[PMPS.K_Attenuators.AT2K2].nTran; //PMPS_GVL.stCurrentBeamParameters.astAttenuators[PMPS.K_Attenuators.AT2K2].xAttOK := i_SattArrayStatus_RIX[PMPS.K_Attenuators.AT2K2].xAttOK; ffRixConnection.i_xOK := TRUE; ELSE // Fast fault ffRixConnection.i_xOK := FALSE; END_IF ffRixConnection(io_fbFFHWO := g_FastFaultOutput1); END_PROGRAM PMPS_Arbiter ^^^^^^^^^^^^ :: PROGRAM PMPS_Arbiter VAR fbSetPE : PE_Ranges; fbBPRequestor : FB_BPRequestor; // Updates global PMPS RequestedBeamParams {attribute 'pytmc' := ' pv: @(PREFIX)PhotonEnergyWatcher '} fbPhotonEnergyWatcher : FB_PhotonEnergyWatcher; {attribute 'pytmc' := ' pv: @(PREFIX)BeamClassWatcher '} fbBeamClassWatcher : FB_BeamClassWatcher; {attribute 'pytmc' := ' pv: @(PREFIX)BeamClassOutputs '} fbMPSInterface : FB_BeamClassOutputs_BCD; {attribute 'pytmc' := ' pv: @(PREFIX)CuRateOutputs '} fbCuInterface : FB_CTLS_Outputs; (* Subsystem requests use this FB and a pragma link to pass their requests to the arbiter. The fb is called on each cycle and updates the arbiter with the current BP set requested from the subsystem PLC.*) // make this so it does input and output to the IF (*{attribute 'pytmc' := ' pv: @(PREFIX):PLC1 '}*) {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-kfe-motion]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-kfe-motion]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-kfe-motion]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-kfe-motion]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-kfe-motion]^SYNC Inputs^TxPDO state; '} plc_kfe_motion_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#FF0F); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-kfe-vac]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-kfe-vac]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-kfe-vac]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-kfe-vac]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-kfe-vac]^SYNC Inputs^TxPDO state; '} plc_kfe_vac_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#FF11); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-kfe-gatt]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-kfe-gatt]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-kfe-gatt]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-kfe-gatt]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-kfe-gatt]^SYNC Inputs^TxPDO state; '} plc_kfe_gatt_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#FF12); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-kfe-gmd-vac-01]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-kfe-gmd-vac-01]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-kfe-gmd-vac-01]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-kfe-gmd-vac-01]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-kfe-gmd-vac-01]^SYNC Inputs^TxPDO state; '} plc_kfe_gmd_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#FF13); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-kfe-xgmd-vac-01]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-kfe-xgmd-vac-01]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-kfe-xgmd-vac-01]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-kfe-xgmd-vac-01]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-kfe-xgmd-vac-01]^SYNC Inputs^TxPDO state; '} plc_kfe_xgmd_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#FF14); ////////////////////////////////////////////// // TMO PLCs ///////////////////////////////////////////// {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-tmo-mot]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-tmo-mot]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-tmo-mot]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-tmo-mot]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-tmo-mot]^SYNC Inputs^TxPDO state; '} plc_tmo_motion_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F100); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-tmo-optics]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-tmo-optics]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-tmo-optics]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-tmo-optics]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-tmo-optics]^SYNC Inputs^TxPDO state; '} plc_tmo_optics_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F101); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-tmo-vac]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-tmo-vac]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-tmo-vac]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-tmo-vac]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-tmo-vac]^SYNC Inputs^TxPDO state; '} plc_tmo_vacuum_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F102); count : CTU; ////////////////////////////////////////////// // RIX PLCs ///////////////////////////////////////////// {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-rix-vac]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-rix-vac]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-rix-vac]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-rix-vac]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-rix-vac]^SYNC Inputs^TxPDO state; '} plc_rix_vac_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F200); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-rix-optics]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-rix-optics]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-rix-optics]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-rix-optics]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-rix-optics]^SYNC Inputs^TxPDO state; '} plc_rix_optics_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F201); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-rix-mot]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-rix-mot]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-rix-mot]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-rix-mot]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-rix-mot]^SYNC Inputs^TxPDO state; '} plc_rix_mot_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F202); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-crix-mot]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-crix-mot]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-crix-mot]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-crix-mot]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-crix-mot]^SYNC Inputs^TxPDO state; '} plc_crix_mot_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F203); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-crix-vac]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-crix-vac]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-crix-vac]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-crix-vac]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-crix-vac]^SYNC Inputs^TxPDO state; '} plc_crix_vac_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F205); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-qrix-mot]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-qrix-mot]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-qrix-mot]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-qrix-mot]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-qrix-mot]^SYNC Inputs^TxPDO state; '} plc_qrix_mot_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F206); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-qrix-vac]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-qrix-vac]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-qrix-vac]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-qrix-vac]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-qrix-vac]^SYNC Inputs^TxPDO state; '} plc_qrix_vac_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F204); ////////////////////////////////////////////// // TXI PLCs ///////////////////////////////////////////// {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-txi-mot]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-txi-mot]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-txi-mot]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-txi-mot]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-txi-mot]^SYNC Inputs^TxPDO state; '} plc_txi_motion_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F300); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-txi-optics]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-txi-optics]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-txi-optics]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-txi-optics]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-txi-optics]^SYNC Inputs^TxPDO state; '} plc_txi_optics_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F301); {attribute 'TcLinkTo' := '.i_RequestedBP:=TIIB[plc-txi-vac]^IO Inputs^RequestedBP; .o_CurrentBP:=TIIB[plc-txi-vac]^IO Outputs^CurrentBP; .i_Connected:=TIIB[plc-txi-vac]^SYNC Inputs^External device not connected; .i_WcState:=TIIB[plc-txi-vac]^WcState^WcStateIn; .i_TxPDOState:=TIIB[plc-txi-vac]^SYNC Inputs^TxPDO state; '} plc_txi_vacuum_PMPS_IO : FB_ArbiterToSubSys_IO := (RequestingSystemID := 16#F302); (*Remove*) ar1 : bool; ar2 : bool; nReqID:UDINT; nReqRM:UDINT; bRemove:bool; rtRemove: R_TRIG; END_VAR // Updating arbiter with subsystem requests. /////////////////////////// // KFE plc_kfe_motion_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'KFE MOTION'); plc_kfe_vac_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'KFE VACUUM'); plc_kfe_gatt_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'KFE GATT'); /////////////////////////// // TMO K4 plc_tmo_motion_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset , sName:= 'TMO MOTION'); plc_tmo_optics_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'TMO OPTICS'); plc_tmo_vacuum_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'TMO VACUUM'); ////////////////////////// // RIX plc_rix_mot_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'RIX MOTION'); plc_rix_vac_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'RIX VACUUM'); plc_rix_optics_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'RIX OPTICS'); plc_crix_mot_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'CRIX MOTION'); plc_crix_vac_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'CRIX VACUUM'); plc_qrix_vac_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'QRIX VACUUM'); /////////////////////////// /////////////////////////// // TXI K3 plc_txi_motion_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset , sName:= 'TXI MOTION'); plc_txi_optics_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'TXI OPTICS'); plc_txi_vacuum_PMPS_IO(Arbiter:=GVL.g_fbArbiter1, fbFFHWO:=GVL.g_FastFaultOutput1, Reset:=GVL.AttemptReset, sName:= 'TXI VACUUM'); ////////////////////////// //////////////////////////// // Beam parameter requestor fbBPRequestor(Arbiter:=GVL.g_fbArbiter1, q_ReqBP => PMPS_GVL.stRequestedBeamParameters); // Request beam class fbMPSInterface(BP := PMPS_GVL.stRequestedBeamParameters); // Request Cu beam rate fbCuInterface(BP := PMPS_GVL.stRequestedBeamParameters); // Keep an eye on the photon energy fbPhotonEnergyWatcher(i_stCurrentBeamParams := PMPS_GVL.stCurrentBeamParameters, i_stRequestedBeamParams := PMPS_GVL.stRequestedBeamParameters, io_fbFFHWO:= GVL.g_FastFaultOutput1, i_xReset := GVL.AttemptReset); // Keep an eye on the beam class fbBeamClassWatcher(i_stCurrentBeamParams := PMPS_GVL.stCurrentBeamParameters, i_stRequestedBeamParams := PMPS_GVL.stRequestedBeamParameters, io_fbFFHWO:= GVL.g_FastFaultOutput1, i_xAutoReset := TRUE); // Evaluate fast fault vetos g_FastFaultOutput1.Execute(); (*remove*) (*Debugging functions*) ar1:= GVL.g_fbArbiter1.CheckRequestInPool(nReqRM); rtRemove(CLK:= bRemove); if (rtRemove.Q) THEN GVL.g_fbArbiter1.RemoveRequest(nReqRM); END_IF END_PROGRAM Related: * `GVL`_ Testing ^^^^^^^ :: PROGRAM Testing VAR AttemptReset : TON := (PT:=T#1s); gAttemptReset : TON := (PT:=T#500ms); testFF : FB_FastFault; cycle : INT; END_VAR // Trip a fast fault periodically testFF(io_fbFFHWO:= g_FastFaultOutput1); //testFF.i_xOK := (cycle mod 1000) = 0; //cycle := cycle + 1; //Periodically try to reset the photon energy fault. AttemptReset(IN:=PMPS_Arbiter.fbPhotonEnergyWatcher.xPhotonEnergyWithinBounds, Q=>GVL.AttemptReset); gAttemptReset(IN:=GVL.g_FastFaultOutput1.xOK, Q=>GVL.g_FastFaultOutput1.i_xReset); END_PROGRAM Related: * `GVL`_ * `PMPS_Arbiter`_