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 := 1, iRevision := 0, nFlags := 1, sVersion := '2.4.1');
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:

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');

    // 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');

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);
// 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);
// ST4K4 Photon Terminator Veto
st4k4Watcher(stCurrentBP:=PMPS_GVL.stCurrentBeamParameters);

END_PROGRAM
Related:

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;
END_VAR
FFO(
    io_fbFFHWO := g_FastFaultOutput2,
    i_xOK := i_xFastFaultOut_qrix_vac,
    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:

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:

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:

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.*)
    //<TODO> 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);

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
    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');
///////////////////////////

////////////////////////////
// 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();

END_PROGRAM
Related:

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: