//This file was generated by the LASAL2 CodeGenerator  -- 
//Please, do not edit this file (it might be overwritten by the next generator run)

//{{LSL_DEFINES
#define MDD2000_DRIVE_PARA_BASE_NUMBER_APPLI_PARA       31
#define MDD2000_DRIVE_PARA_BASE_NUMBER_CURRENT_PARA     10
#define MDD2000_DRIVE_PARA_BASE_NUMBER_DEVICE_PARA      16
#define MDD2000_DRIVE_PARA_BASE_NUMBER_FEEDBACK_PARA    5
#define MDD2000_DRIVE_PARA_BASE_NUMBER_MOTOR_PARA       30
#define MDD2000_DRIVE_PARA_BASE_NUMBER_POSITION_PARA    7
#define MDD2000_DRIVE_PARA_BASE_NUMBER_VELOCITY_PARA    9
#define MDD2000_DRIVE_PARA_BASE_NUMBER_OPTIONAL_PARA    8
#define MDD2000_DRIVE_PARA_BASE_NUMBER_ERRORHANDLING    4
//}}LSL_DEFINES

//{{LSL_DECLARATION
#include "..\..\Source\DriveSafetyIF.h"

(*!
<Class
	Name               = "_DriveSafetyIFParaBase"
	Revision           = "1.0"
	GUID               = "{49AB1964-ADE0-4A35-8220-4D06A2AB6E9C}"
	RealtimeTask       = "false"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	IconPath           = ".\Class\_DriveMngBase\Drive.ico"
	SharedCommandTable = "true"
	Objectsize         = "(334,120)"
	Comment            = "Base class for the connected Drive parameter classes">
	<Channels>
		<Server Name="ErrorQuit" GUID="{92C7537D-F2BF-4520-9752-4C88F7F21F0A}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="This server is used to quit an error if the asynchron parameter handling failed."/>
		<Server Name="State" GUID="{03F860D9-10B8-46A8-9C7B-B03564D3847B}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Actual state of the parameter class&#13;&#10;Following states are possible :&#13;&#10;READY&#13;&#10;BUSY&#13;&#10;ERROR"/>
		<Client Name="DriveIF" Required="false" Internal="false" Comment="command channel to drive axis or manager class"/>
		<Client Name="ErrorCode" Required="false" Internal="false" Comment="Following error codes are possible :&#13;&#10;ErrorCode &#13;&#10;   2 =    SDO timeout&#13;&#10;   3 =    object change only in disabled state&#13;&#10;   4 =    object value greater than the max value or smaller than the min value&#13;&#10;   5 =    object write not possible&#13;&#10;   6 =    object cannot be changed in this mode&#13;&#10;   7 =    object not available&#13;&#10;   8 =    object read not possible&#13;&#10;   9 =    initialisation processed successfully&#13;&#10;  10 =    communication not initialised&#13;&#10;  11 =    axis number not available"/>
		<Client Name="UpdateCyTime" Required="true" Internal="false" Comment="Configures the cyclic refresh time for the asynchrone parameters.&#13;&#10;0 &gt; Update time in ms&#13;&#10;else deactiveted. "/>
	</Channels>
	<Dependencies>
		<Files>
			<File Path=".\Source\DriveSafetyIF.h" Include="true"/>
		</Files>
	</Dependencies>
	<RevDoku>
		<Owner Company="Sigmatek" Author="LanSte"/>
		<Dokumentation Revision="1.0" Date="28.08.2023" Author="LanSte" Company="Sigmatek" Description="First library version."/>
	</RevDoku>
</Class>
*)
_DriveSafetyIFParaBase : CLASS
	TYPE
	  MDD2000_ISTATE : BDINT  //! <Type Public="true" Name="MDD2000_ISTATE"/>
	  [
	    1 Free1,
	    2 MainsFault,
	    3 Overcurrent,
	    4 OverVoltageDCLink,
	    5 UnderVoltageDCLink,
	    6 MalfunctionMotorPhase,
	    7 HoldingBrakeError,
	    8 FirmwareException,
	    9 SystemError,
	    10 MotorThermostat,
	    11 TemperatureError,
	    12 Free12,
	    13 FeedbackError,
	    14 CommutationError,
	    15 OverSpeed,
	    16 ContouringError,
	    17 TrajectoryError,
	    18 HostCommunicationError,
	    19 DualUseError,
	    20 Free20,
	    21 Free21,
	    22 LowVoltageError,
	    23 RegenResistorError,
	    24 Free24,
	    25 SafetyError,
	    26 I2TError,
	    27 Free27,
	    28 MotorParameterError,
	    29 MultiturnPositionError,
	    30 GroundFault,
	    31 OptionalencoderError,
	    32 FanError,
	  ];
	  t_requiredrefsigclib : ^SigCLib;
	END_TYPE
  //Servers:
	State 	: SvrChCmd_iprStates;
	ErrorQuit 	: SvrCh_DINT;
  //Clients:
	DriveIF 	: CltChCmd_iprStates;
	ErrorCode 	: CltCh_DINT;
	UpdateCyTime 	: CltCh_UDINT;
  //Variables:
		dParaValue 	: DINT;
		hErrorParaIndex 	: HINT;
		hsErrorParaSubIndex 	: HSINT;
		dErrorParaVal 	: DINT;
		AnzASyncPara 	: DINT;
		bNoASync 	: BOOL;
		bCheckedClientConnected 	: BOOL;
		bAxisConnected 	: BOOL;
		aWriteBuffer : ARRAY [0..11] OF USINT;

		udTimeStampUpdateCy 	: UDINT;
  //Functions:
	
	FUNCTION VIRTUAL GLOBAL Init;
	
	FUNCTION VIRTUAL GLOBAL GetErrorInfo
		VAR_INPUT
			phParaIndex 	: ^HINT;
			phsParaSubIndex 	: ^HSINT;
			pValue 	: ^DINT;
		END_VAR
		VAR_OUTPUT
			dErrorCode 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL AddAsyncEntryDS402
		VAR_INPUT
			ParaID 	: HINT;
			ParaSubID 	: HSINT;
			ParaRdWr 	: USINT;
			ParaSize 	: DINT;
			pParaValue 	: ^void;
			pThis 	: ^void;
			usEntry 	: USINT := 0;
			udTimeout 	: DINT := 0;
			dCallID 	: DINT := 0;
		END_VAR
		VAR_OUTPUT
			result 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL RefreshPara
		VAR_INPUT
			hParaIndex 	: HINT;
			hsParaSubIndex 	: HSINT;
			bRW 	: DINT;
			bsDataInfo 	: BSINT;
			pValue 	: ^DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL RefreshAllPara;
	
	FUNCTION VIRTUAL GLOBAL AddParaObjects
		VAR_INPUT
			dIndex 	: DINT;
			pThis 	: ^void;
		END_VAR
		VAR_OUTPUT
			retcode 	: BOOL;
		END_VAR;
	
	FUNCTION VIRTUAL IsAxisConnected
		VAR_OUTPUT
			IsConnected 	: BOOL;
		END_VAR;
	
	FUNCTION VIRTUAL IsAxisOnline
		VAR_OUTPUT
			bIsOnline 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL IsAxisReady4AsyncParaAccess
		VAR_OUTPUT
			bIsReady 	: BOOL;
		END_VAR;
	
	FUNCTION VIRTUAL GetAxisClassState
		VAR_OUTPUT
			ClassState 	: iprStates;
		END_VAR;
	
	FUNCTION VIRTUAL GetAxisHardwareAvailable
		VAR_OUTPUT
			bHwAvailable 	: BOOL;
		END_VAR;
	
	FUNCTION VIRTUAL GeneralBusy;
	
	FUNCTION VIRTUAL GeneralError;
	
	FUNCTION VIRTUAL GeneralReady;
	
	FUNCTION VIRTUAL GLOBAL UpdateParaClassState
		VAR_INPUT
			NewState 	: DINT;
			StateInfo 	: DINT;
		END_VAR
		VAR_OUTPUT
			ret_code 	: iprStates;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL UpdateCy
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL SafetyReady
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL SafetyError
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL SafetyChanged
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL SafetySetServiceMode
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL State::NewInst
		VAR_INPUT
			pPara 	: ^CmdStruct;
			pResult 	: ^results;
		END_VAR
		VAR_OUTPUT
			ret_code 	: iprStates;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL ErrorQuit::Write
		VAR_INPUT
			input (EAX) 	: DINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: DINT;
		END_VAR;
  //Tables:
	FUNCTION @STD
		VAR_OUTPUT
			ret_code	: CONFSTATES;
		END_VAR;
	FUNCTION GLOBAL TAB @CT_;
END_CLASS;

//}}LSL_DECLARATION


FUNCTION GLOBAL TAB _DriveSafetyIFParaBase::@CT_
0$UINT,
2#0100000000000000$UINT, //TY__DRIVESAFETYIFPARABASE
1$UINT, 0$UINT, (SIZEOF(::_DriveSafetyIFParaBase))$UINT, 
2$UINT, 3$UINT, 0$UINT, 
TO_UDINT(1914213293), "_DriveSafetyIFParaBase", //Class
TO_UDINT(0), 0, 0$UINT, 0$UINT, //Baseclass
//Servers:
(::_DriveSafetyIFParaBase.State.pMeth)$UINT, _CH_CMD$UINT, 2#0000000000000000$UINT, TO_UDINT(1422331979), "State", 
(::_DriveSafetyIFParaBase.ErrorQuit.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(971218924), "ErrorQuit", 
//Clients:
(::_DriveSafetyIFParaBase.DriveIF.pCh)$UINT, _CH_CLT_CMD$UINT, 2#0000000000000000$UINT, TO_UDINT(532550252), "DriveIF", 
(::_DriveSafetyIFParaBase.ErrorCode.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(224164065), "ErrorCode", 
(::_DriveSafetyIFParaBase.UpdateCyTime.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(4208877246), "UpdateCyTime", 
END_FUNCTION


#define USER_CNT__DriveSafetyIFParaBase 19

TYPE
	_LSL_STD_VMETH	: STRUCT
			CmdTable	: CMDMETH;
			UserFcts	: ARRAY[0..USER_CNT__DriveSafetyIFParaBase] OF ^Void;
	END_STRUCT;
END_TYPE

FUNCTION _DriveSafetyIFParaBase::@STD
	VAR_OUTPUT
		ret_code	: CONFSTATES;
	END_VAR
	VAR
		vmt	: _LSL_STD_VMETH;
	END_VAR

	//Command Methods
	InitCmdTable (nCmd := nSTDCMD + USER_CNT__DriveSafetyIFParaBase, pCmd := #vmt.CmdTable);
	vmt.CmdTable.NewInstr		:= #NewInst();
	vmt.CmdTable.Init		:= #Init();
#pragma warning (disable : 74)
	vmt.UserFcts[0]		:= #GetErrorInfo();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[1]		:= #AddAsyncEntryDS402();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[2]		:= #RefreshPara();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[3]		:= #RefreshAllPara();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[4]		:= #AddParaObjects();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[5]		:= #IsAxisConnected();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[6]		:= #IsAxisOnline();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[7]		:= #IsAxisReady4AsyncParaAccess();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[8]		:= #GetAxisClassState();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[9]		:= #GetAxisHardwareAvailable();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[10]		:= #GeneralBusy();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[11]		:= #GeneralError();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[12]		:= #GeneralReady();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[13]		:= #UpdateParaClassState();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[14]		:= #UpdateCy();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[15]		:= #SafetyReady();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[16]		:= #SafetyError();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[17]		:= #SafetyChanged();

#pragma warning (default : 74)
#pragma warning (disable : 74)
	vmt.UserFcts[18]		:= #SafetySetServiceMode();

#pragma warning (default : 74)
	State.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF State.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ErrorQuit.pMeth			:= StoreMethod( #M_RD_DIRECT(), #ErrorQuit::Write() );
	IF ErrorQuit.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;

END_FUNCTION

#pragma usingLtd SigCLib

//{{LSL_IMPLEMENTATION
FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::Init
  
  if _FirstScan then
    UpdateCyTime := UpdateCyTime.Read();
    State := READY; 
  end_if;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::GetErrorInfo
	VAR_INPUT
		phParaIndex 	: ^HINT;
		phsParaSubIndex 	: ^HSINT;
		pValue 	: ^DINT;
	END_VAR
	VAR_OUTPUT
		dErrorCode 	: DINT;
	END_VAR
  
  if phParaIndex <> NIL then
    phParaIndex^ := hErrorParaIndex;
  end_if;

  if phsParaSubIndex <> NIL then
    phsParaSubIndex^ := hsErrorParaSubIndex;
  end_if;
  
  if pValue <> NIL then
    pValue^ := dErrorParaVal;
  end_if;
  
  dErrorCode := ErrorCode;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::State::NewInst
	VAR_INPUT
		pPara 	: ^CmdStruct;
		pResult 	: ^results;
	END_VAR
	VAR_OUTPUT
		ret_code 	: iprStates;
	END_VAR
  VAR
    hIndex        : HINT;
    hsSubIndex    : HSINT;
    bRW           : BOOL;
    bsDataInfo    : BSINT;
    pParaValue    : ^DINT;
  END_VAR

	ret_code:= ERROR;

	case pPara^.uiCmd of
//*****************************************************************************
	  DRIVESAFETYIF_ASYNC_READY:
    
      ret_code := ERROR; //unsupported version
      
      pResult^.uiLng := 4;
      pResult^.aData[0]$DINT := DRIVESAFETYIF_ASYNC_READY_VER_MAX;  //max supported version
      
      //Check version 1
      if pPara^.aPara[0] = DRIVESAFETYIF_ASYNC_READY_VER_1 then

        ret_code := READY;     
                
        hIndex      := pPara^.aPara[1]$HINT;
        hsSubIndex  := pPara^.aPara[2]$HSINT;
        bRW         := pPara^.aPara[3]$BOOL;
        bsDataInfo  := pPara^.aPara[5]$BSINT;
        pParaValue  := pPara^.aPara[6]$^DINT;
        dParaValue  := pParaValue^;

        RefreshPara(hParaIndex:=hindex, hsParaSubIndex:=hsSubIndex, bRW:=bRW, bsDataInfo:=bsDataInfo, pValue:=pParaValue);
        
        AnzASyncPara -= 1;
        if (AnzASyncPara = 0) then
          if State <> ERROR then
            State := READY;
          end_if;
          bNoASync := FALSE;
        end_if;
      end_if;
    
//*****************************************************************************
    DRIVESAFETYIF_ASYNC_ERROR:
      
      ret_code := ERROR; //unsupported version
      
      pResult^.uiLng := 4;
      pResult^.aData[0]$DINT := DRIVESAFETYIF_ASYNC_ERROR_VER_MAX;  //max supported version
      
      //Check version 1
      if pPara^.aPara[0] = DRIVESAFETYIF_ASYNC_ERROR_VER_1 then
        
        ret_code := READY;
        
        hErrorParaIndex     := pPara^.aPara[1]$HINT;
        hsErrorParaSubIndex := pPara^.aPara[2]$HSINT;
        dErrorParaVal       := pPara^.aPara[6]$^DINT^;
        ErrorCode           := pPara^.aPara[8];
        ErrorCode.write(ErrorCode);
        
        AnzASyncPara -= 1;
        if (AnzASyncPara = 0) then
          bNoASync := FALSE;
        end_if;
        
        State := ERROR;

      end_if;
    
//*****************************************************************************
    DRIVESAFETYIF_REFRESH_PARA_OBJECTS:
    
      ret_code := ERROR; //unsupported version
      
      pResult^.uiLng := 4;
      pResult^.aData[0]$DINT :=  DRIVESAFETYIF_REFRESH_PARA_OBJECTS_VER_MAX;  //max supported version
      
      //Check version 1
      if pPara^.aPara[0] =  DRIVESAFETYIF_REFRESH_PARA_OBJECTS_VER_1 then
        
        ret_code := READY;
        
        hIndex      := pPara^.aPara[1]$HINT;
        hsSubIndex  := pPara^.aPara[2]$HSINT;
        bRW         := pPara^.aPara[3]$BOOL;
        bsDataInfo  := pPara^.aPara[5]$BSINT;
        pParaValue  := pPara^.aPara[6]$^DINT;
        dParaValue  := pParaValue^;

        RefreshPara(hParaIndex:=hindex, hsParaSubIndex:=hsSubIndex, bRW:=bRW, bsDataInfo:=bsDataInfo, pValue:=pParaValue);
                
      end_if;

//*****************************************************************************
   DRIVESAFETYIF_UPDATEPARACLASS_STATE:
    
      ret_code := ERROR; //unsupported version
      
      pResult^.uiLng := 4;
      pResult^.aData[0]$DINT := DRIVESAFETYIF_UPDATEPARACLASS_STATE_VER_MAX;  //max supported version
      
      //Check version 1
      if pPara^.aPara[0] = DRIVESAFETYIF_UPDATEPARACLASS_STATE_VER_1 then
        
        ret_code := UpdateParaClassState(pPara^.aPara[1], pPara^.aPara[2]);
        
      end_if;
        
	end_case;

END_FUNCTION

#pragma warning(disable:0073)
FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::RefreshPara
	VAR_INPUT
		hParaIndex 	: HINT;
		hsParaSubIndex 	: HSINT;
		bRW 	: DINT;
		bsDataInfo 	: BSINT;
		pValue 	: ^DINT;
	END_VAR
#pragma warning(default:0073)
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::AddAsyncEntryDS402
	VAR_INPUT
		ParaID 	: HINT;
		ParaSubID 	: HSINT;
		ParaRdWr 	: USINT;
		ParaSize 	: DINT;
		pParaValue 	: ^void;
		pThis 	: ^void;
		usEntry 	: USINT;(* := 0 *)
		udTimeout 	: DINT;(* := 0 *)
		dCallID 	: DINT;(* := 0 *)
	END_VAR
	VAR_OUTPUT
		result 	: DINT;
	END_VAR
  VAR
  	tmpPara : CmdStruct;
    tmpResult : results;  	
  END_VAR
  
  result := ACCESS_DENIED;

  //Check if axis is connected and ready for parameter accesses
  if IsAxisConnected() = TRUE & IsAxisReady4AsyncParaAccess() = TRUE & pThis then
  
    if ParaRdWr & pParaValue then
      //Copy value into write buffer
      _memcpy(ptr1:=#aWriteBuffer[0], ptr2:=pParaValue, cntr:=4*(1+ParaSize$USINT));
    end_if;
    
    tmpPara.uiCmd    := DRIVESAFETYIF_ADD_ASYNC_ENTRY_DS402;
    tmpPara.aPara[0] := DRIVESAFETYIF_ADD_ASYNC_ENTRY_DS402_VER_1;
    tmpPara.aPara[1] := 0;  //axis no, will be set by axis 
    tmpPara.aPara[2] := ParaID;
    tmpPara.aPara[3] := ParaSubID;
    tmpPara.aPara[4] := ParaRdWr;
    tmpPara.aPara[5] := ((#aWriteBuffer[0])$^USINT)$DINT;
    tmpPara.aPara[6] := ParaSize;
    tmpPara.aPara[7] := pThis$DINT;
    tmpPara.aPara[8] := 0;  //usEntry
    tmpPara.aPara[9] := 0;  //udTimeout
    tmpPara.aPara[10]:= 0;  //CallID
        
		// Add the async entry to the buffer
    if DriveIF.NewInst(#tmpPara, #tmpResult) = READY then
      result := tmpResult.aData[4]$DINT;
      if result = 0 then
        State := BUSY;
        AnzASyncPara += 1;
      end_if;
    else
      result := -1;
    end_if;

  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::RefreshAllPara

  // Reset default sates from GeneralBusy if this method is not overloaded
  State := READY;
  bNoASync := FALSE;
  
END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::IsAxisConnected
	VAR_OUTPUT
		IsConnected 	: BOOL;
	END_VAR

  if bCheckedClientConnected then
    IsConnected := bAxisConnected;
  else
    IsConnected := bAxisConnected := IsClientConnected(#DriveIF)$BOOL;
    bCheckedClientConnected := TRUE;
  end_if;

END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::IsAxisReady4AsyncParaAccess
	VAR_OUTPUT
		bIsReady 	: BOOL;
	END_VAR
  VAR
  	tmpPara : CmdStruct;
    tmpResult : results;
  END_VAR
    
  tmpPara.uiCmd     := DRIVESAFETYIF_IS_AXIS_READY_4_ASYPARA;
  tmpPara.aPara[0]  := DRIVESAFETYIF_IS_AXIS_READY_4_ASYPARA_VER_1;
  
  if DriveIF.NewInst(pPara:=#tmpPara, pResult:=#tmpResult) = READY then
    bIsReady := tmpResult.aData[4]$BOOL;
  else
    bIsReady := FALSE;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::AddParaObjects
	VAR_INPUT
		dIndex 	: DINT;
		pThis 	: ^void;
	END_VAR
	VAR_OUTPUT
		retcode 	: BOOL;
	END_VAR
  VAR
  	tmpPara : CmdStruct;
    tmpResult : results;
  END_VAR
  
  tmpPara.uiCmd     := DRIVESAFETYIF_ADD_PARA_OBJECT;
  tmpPara.aPara[0]  := DRIVESAFETYIF_ADD_PARA_OBJECT_VER_1;
  tmpPara.aPara[1]  := dIndex;
  tmpPara.aPara[2]  := pThis$DINT;
  
  if DriveIF.NewInst(pPara:=#tmpPara, pResult:=#tmpResult) = READY then
    retcode := tmpResult.aData[4]$BOOL;  
  else
    HWC_LogPrintf(pThis:=this, format:="@08D0 (_DriveSafetyIFParaBase::Init) Failed to login axis object at drive manager.");      
    retcode := FALSE;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::IsAxisOnline
	VAR_OUTPUT
		bIsOnline 	: DINT;
	END_VAR
  VAR
  	tmpPara : CmdStruct;
    tmpResult : results;
  END_VAR

  //Get online state from axis
  tmpPara.uiCmd := DRIVESAFETYIF_IS_ONLINE;
  tmpPara.aPara[0] := DRIVESAFETYIF_IS_ONLINE_VER_1;
  DriveIF.NewInst(pPara:=#tmpPara, pResult:=#tmpResult);
  bIsOnline := tmpResult.aData[4]$BOOL;

END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::GetAxisClassState
	VAR_OUTPUT
		ClassState 	: iprStates;
	END_VAR
  VAR
  	tmpPara : CmdStruct;
    tmpResult : results;
  END_VAR

  //Get classstate from axis class (used to check if axis is ready for DS402 communication)
  tmpPara.uiCmd := DRIVESAFETYIF_GET_CLASS_STATE;
  tmpPara.aPara[0] := DRIVESAFETYIF_GET_CLASS_STATE_VER_1;
  DriveIF.NewInst(pPara:=#tmpPara, pResult:=#tmpResult);
  ClassState := tmpResult.aData[4]$iprStates;
  
END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::GetAxisHardwareAvailable
	VAR_OUTPUT
		bHwAvailable 	: BOOL;
	END_VAR
  VAR
  	tmpPara : CmdStruct;
    tmpResult : results;
  END_VAR

  tmpPara.uiCmd := DRIVESAFETYIF_IS_HARDWARE_AVAILABLE;
  tmpPara.aPara[0] := DRIVESAFETYIF_IS_HARDWARE_AVAILABLE_VER_1;
  DriveIF.NewInst(pPara:=#tmpPara, pResult:=#tmpResult);
  bHwAvailable := tmpResult.aData[4]$BOOL;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::ErrorQuit::Write
	VAR_INPUT
		input (EAX) 	: DINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: DINT;
	END_VAR
  VAR
    bError      : BOOL;
    IntState    : iprStates;
  END_VAR

  bError := TRUE;
  // quit an error
  if input = 1 then
  
    if State = ERROR then
      case ErrorCode of
      
      11 : //axis is not available
        IntState := GetAxisClassState();
        if IntState = ERROR then
          
          //Check if hardware is available now -> quit error is possible
          if GetAxisHardwareAvailable() = 1 then
            bError := FALSE;
          end_if;
        end_if;  
      else
        bError := FALSE;
      end_case;
    end_if;
  end_if;
	
  if bError = FALSE then
    State := DriveIF := READY;
    ErrorCode := 0;
    ErrorCode.write(ErrorCode);
  end_if;
  
  ErrorQuit := 0;
 	result := ErrorQuit;

END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::GeneralBusy

  State := BUSY;
  bNoASync := TRUE;
  RefreshAllPara();

END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::GeneralError

  State       := ERROR;
  DriveIF     := ERROR;
  AnzASyncPara:= 0;
  bNoASync    := TRUE;

END_FUNCTION


FUNCTION VIRTUAL _DriveSafetyIFParaBase::GeneralReady

  State       := READY;
  DriveIF     := READY;
  AnzASyncPara:= 0; // Rest AnzASyncPara as there is a new connect
  bNoASync    := FALSE;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::UpdateParaClassState
	VAR_INPUT
		NewState 	: DINT;
		StateInfo 	: DINT;
	END_VAR
	VAR_OUTPUT
		ret_code 	: iprStates;
	END_VAR

  ret_code := ERROR;
  
  case NewState of
  
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_GENERAL_ERROR:
      GeneralError();
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_ASYNC_BUSY:
      GeneralBusy();
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_GENERAL_READY: 
      GeneralReady();
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_UPDATE_CY:
      UpdateCy(StateInfo:=StateInfo);
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_SAFETY_READY:
      SafetyReady(StateInfo:=StateInfo);
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_SAFETY_ERROR:
      SafetyError(StateInfo:=StateInfo);
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_SAFETY_CHANGED:
      SafetyChanged(StateInfo:=StateInfo);
      ret_code := READY;
    DRIVESAFETYIF_UPDATEPARACLASS_STATE_SAFETY_SETSERVICEMODE_PENDING:
      SafetySetServiceMode(StateInfo:=StateInfo);
      ret_code := READY;
  end_case;
  
END_FUNCTION

#pragma warning(disable:0073)
FUNCTION VIRTUAL _DriveSafetyIFParaBase::SafetyReady
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
#pragma warning(default:0073)

END_FUNCTION

#pragma warning(disable:0073)
FUNCTION VIRTUAL _DriveSafetyIFParaBase::SafetyError
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
#pragma warning(default:0073)

END_FUNCTION

#pragma warning(disable:0073)
FUNCTION VIRTUAL _DriveSafetyIFParaBase::SafetyChanged
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
#pragma warning(default:0073)

END_FUNCTION

#pragma warning(disable:0073)
FUNCTION VIRTUAL _DriveSafetyIFParaBase::SafetySetServiceMode
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
#pragma warning(default:0073)

END_FUNCTION

#pragma warning(disable:0073)
FUNCTION VIRTUAL GLOBAL _DriveSafetyIFParaBase::UpdateCy
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
#pragma warning(default:0073)

END_FUNCTION
