// FB10
// Block Type: FB
// Block Name (Original): FB HMI Interlock
// Block Number: 10
// Original Network Languages: SCL

FUNCTION_BLOCK "FB_HMI_Interlock"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1

VAR_STAT
  Status : STRUCT
    HMI_InUse : Bool;
    HMI_CanBeUsedBy : Int;
    HMI_Max_Count : Int;
    i_Request : Array[0..7] of Bool;
    o_HMI_CanBeUsedBy : Array[0..7] of Bool;
  END_STRUCT;

  AUX : STRUCT
    Cycle_Count : Int;
    Time_OUT : STRUCT
      PT : Time;
      ET : Time;
      IN : Bool;
      Q : Bool;
    END_STRUCT;

  END_STRUCT;

END_VAR

VAR_TEMP
  i : Int;
END_VAR

CONSTANT
  HMI_REQUEST_TRANSPORT : Int := 1;
  HMI_REQUEST_ELECTRIC_GUIDES : Int := 2;
END_CONSTANT

  #_5s : Bool; // Auto-generated temporary
  #AUX : Bool; // Auto-generated temporary
  #Status : Bool; // Auto-generated temporary
  #i : Bool; // Auto-generated temporary
BEGIN

  // Network 1: Number of logics that can use the HMI at the same time (Original Language: SCL)

  #Status.HMI_Max_Count := 2; // Only Transport & Electric Guides
  // Timeout after the HMI is not more requested by the area
  #AUX.Time_OUT(IN :=NOT (#Status.i_Request[#Status.HMI_CanBeUsedBy]), PT :=T#5s);
  IF #AUX.Time_OUT.Q THEN
    // Cancel the actual use after timeout
    #Status.HMI_InUse := FALSE;
    FOR #i:=0 TO 7 DO
      #Status.o_HMI_CanBeUsedBy[#i] := FALSE;
    END_FOR;
  END_IF;
  IF NOT #Status.HMI_InUse THEN
    #AUX.Cycle_Count := #AUX.Cycle_Count + "DINT_TO_INT"("DB ScanTime_OB1".SCAN_TIME_ms);
    IF #AUX.Cycle_Count> 1000 THEN
      #Status.HMI_CanBeUsedBy := (#Status.HMI_CanBeUsedBy MOD #Status.HMI_Max_Count) + 1;
      #AUX.Cycle_Count := #AUX.Cycle_Count - 1000;
    END_IF;
    IF #Status.HMI_CanBeUsedBy > 0 AND #Status.i_Request[#Status.HMI_CanBeUsedBy] THEN
      // Return that the actual request is active and can use the HMI
      #Status.o_HMI_CanBeUsedBy[#Status.HMI_CanBeUsedBy] :=  TRUE;
      #Status.HMI_InUse := TRUE;
    END_IF;
  END_IF;
  // Every cycle we reset all request. When some area need the HMI need to
  // request on every cycle until is granted.
  //
  FOR #i:=0 TO 7 DO
    #Status.i_Request[#i] := FALSE;
  END_FOR;
  #Status.o_HMI_CanBeUsedBy[0] := NOT #Status.HMI_InUse;

END_FUNCTION_BLOCK
