//This file was generated by the LASAL2 CodeGenerator  -- 
//Please, do not edit this file (it might be overwritten by the next generator run)
//{{LSL_DECLARATION
#include "..\..\Class\MDD2000MngBase\MDD2000MngBase.h"

(*!
<Class
	Name               = "MDD2000_AxisSafeInfo"
	Revision           = "1.0"
	GUID               = "{31A3F62D-E562-4761-990B-7EECE4E6E5E7}"
	RealtimeTask       = "false"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	IconPath           = ".\Class\MDD2000_Mng\MDD2000SafetyDrive.ico"
	SharedCommandTable = "true"
	Objectsize         = "(1080,1620)"
	Comment            = "Display safe information specific to the connected axis.&#13;&#10;The class can be used to perform absolute position referencing of the axis. &#13;&#10;The class details error of safety functions and provides interfaces to acknowledge these errors.">
	<Channels>
		<Server Name="AckZeroPosition" GUID="{92CC04DD-EE8C-4DF2-9136-6369C661CB0C}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="Must be executed when the zero position has been approached again in order to confirm and permanently store it, sequence is then completed&#13;&#10;0 .. Read ReferenceState from Drive&#13;&#10;-1 .. Abort a prevously set DRIVESAFETYIF_SETREFERENCEAXIS cmd&#13;&#10;1 .. Ack Zeropost and Read ReferenceState from Drive"/>
		<Server Name="ActiveSafeFunctions" GUID="{DDE1301A-0979-4BA5-8D3A-E24B9B4EE029}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Display a bitfield in which for each active safety function a bit is set.&#13;&#10;The active safety functions are extracted from the SafeControlWord and SafeStatusWord via the Safe configuration.&#13;&#10;The order of the bits is independent of the order in the SafeControlWord and SafeStateWord.&#13;&#10;&#13;&#10;"/>
		<Server Name="CmdZeroPositionRsp" GUID="{DB205D88-98CF-46B2-8027-8854D78809F3}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Shows the response state of the SetZeroPosition and AckZeroPosition commands."/>
		<Server Name="ErrorAcknowledge" GUID="{1C8705A4-DA85-4969-85CF-B05E45FDE906}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="Call the write method to acknowledge an error that occurred in safety function."/>
		<Server Name="ErrorAcknowledgeNeeded" GUID="{589EB67F-1D54-4997-A310-F6F6393466BE}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="If this server is set, a acknowledge of a safety function error is needed. "/>
		<Server Name="ErrorIDSafetyFunction" GUID="{821C832A-2F4E-4499-A6EB-C2BC84F2092C}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="ID of the Error of the safety function."/>
		<Server Name="PositionReferenceState" GUID="{52EE0763-FC50-4D69-8BB8-58B9394C0E6D}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Shows the position reference state of the drive."/>
		<Server Name="RestartAcknowledge" GUID="{30CD7FC2-960E-4E05-8122-27328206C451}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="Call the write method to restart acknowledge a safety function.&#13;&#10;Safety functions can be configured to require a restart acknowledge after the cause for the safety function has been resolved."/>
		<Server Name="RestartAcknowledgeNeeded" GUID="{4F9B99F2-5838-4406-AB8D-FE6DD8019B4C}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="If this server is set, a restart acknowledge of a safety function is needed. "/>
		<Server Name="SafeControlWord" GUID="{2DE3D954-5669-47D7-96F7-CF548C8A3C81}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Display the Safe Control Word. Each bit corresponds to a safe function.&#13;&#10;The configuration of the individual bits is defined by the safe configuration. &#13;&#10;"/>
		<Server Name="SafeErrorWord" GUID="{0E236799-8FA0-4FB1-8B67-43D4404DA992}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Display the Safe Error Word. Each bit corresponds to a safe function that is in error.&#13;&#10;The configuration of the individual bits is defined by the safe configuration. "/>
		<Server Name="SafeStateWord" GUID="{E6785CE5-80B4-485A-9E5A-89FC0182080E}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Display the Safe Status Word. Each bit corresponds to a safe function.&#13;&#10;The configuration of the individual bits is defined by the safe configuration. &#13;&#10;"/>
		<Server Name="SafetyFunctionErrorInfo1" GUID="{6C2D2DFC-5E60-4862-9487-7ECDB5F311A2}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Reason code 1 of safety function error."/>
		<Server Name="SafetyFunctionErrorInfo2" GUID="{02F6B389-F411-459D-AE32-65E0DD38168D}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Reason code 2 of safety function error."/>
		<Server Name="SafetyFunctionErrorInfo3" GUID="{2C3F2A5A-5916-40D8-8164-27DF9C35B512}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Reason code 3 of safety function error."/>
		<Server Name="SafetyFunctionErrReact" GUID="{69F036EC-75D0-46E7-A9A4-4AE375DF2055}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="ID of the safety function that was triggered due to the error."/>
		<Server Name="SafetyFunctionErrReactSubID" GUID="{23CE7213-EABE-48AC-8281-DA35EB9F6EF3}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Sub ID of the safety function that was triggered due to the error."/>
		<Server Name="SafetyFunctionInErr" GUID="{23B68AC6-DCC8-41FC-B7E4-C416ED254023}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="ID of the safety function that detected the error."/>
		<Server Name="SafetyFunctionInErrSubID" GUID="{A35807C0-3C83-4FF1-AC76-C153C625B3AF}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Sub ID of the safety function that detected the error."/>
		<Server Name="SetZeroPosition" GUID="{E9861195-B37E-4DFF-9FD6-3A4F963BAE4A}" Visualized="true" Initialize="false" WriteProtected="false" Retentive="false" Comment="Starts the procedure for absolute position referencing, current position is saved as zero position&#13;&#10;0 .. Read ReferenceState from Drive&#13;&#10;-1 .. Reset ReferenceState of this axis &#13;&#10;1 .. SetReference and Read ReferenceState from Drive"/>
		<Server Name="VerifiedState" GUID="{52CB5385-86B8-4D24-A087-1312CA217958}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false" Comment="Shows the verification state of the drive."/>
	</Channels>
	<Separators>
		<Servers>
			<SepChn Position="4"/>
			<SepChn Position="10"/>
			<SepChn Position="19"/>
		</Servers>
	</Separators>
	<Dependencies>
		<Files>
			<File Path=".\Class\MDD2000MngBase\MDD2000MngBase.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>
	<Network Name="MDD2000_AxisSafeInfo">
		<!-- List of Components in this network -->
		<Components>
			<Object
				Name       = "_base"
				GUID       = "{D4FAEDF6-D1C3-4390-9169-BF8C757056BA}"
				Class      = "_DriveSafetyIFParaBase"
				Position   = "(218,120)"
				Visualized = "true"
				Remotely   = "true">
				<Channels>
					<Server Name="ErrorQuit"/>
					<Server Name="State"/>
					<Client Name="DriveIF"/>
					<Client Name="ErrorCode"/>
					<Client Name="UpdateCyTime" Value="100"/>
				</Channels>
			</Object>
		</Components>
		<Comments>
		</Comments>
		<!-- List of Connections in this network -->
		<Connections>
			<Connection Source="this.State" Destination="_base.State" Vertices="(740,210),(568,210),"/>
			<Connection Source="this.ErrorQuit" Destination="_base.ErrorQuit" Vertices="(740,270),(568,270),"/>
			<Connection Source="_base.DriveIF" Destination="this.DriveIF" Vertices="(218,210),(38,210),"/>
			<Connection Source="_base.ErrorCode" Destination="this.ErrorCode" Vertices="(218,270),(38,270),"/>
			<Connection Source="_base.UpdateCyTime" Destination="this.UpdateCyTime" Vertices="(218,330),(38,330),"/>
		</Connections>
		<!-- Headerfiles -->
		<Options>
		</Options>
	</Network>
</Class>
*)
#pragma using _DriveSafetyIFParaBase

MDD2000_AxisSafeInfo : CLASS
: _DriveSafetyIFParaBase
	TYPE
	  ge_MDD2000SafeFkt_ERR_ID :  //! <Type Public="true" Name="ge_MDD2000SafeFkt_ERR_ID"/>
	  (
	    ERR_ID_NO_ERROR:=0,  //! <Type Comment="no error" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_NO_ERROR"/>
	    ERR_ID_SS1_VELOCITY_UP:=8,  //! <Type Comment="SS1 velocity zero window not reached after SS1 time to STO (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SS1_VELOCITY_UP"/>
	    ERR_ID_SS1_VELOCITY_LO:=9,  //! <Type Comment="SS1 velocity zero window not reached after SS1 time to STO (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SS1_VELOCITY_LO"/>
	    ERR_ID_SS1_DECELERATION_POS:=10,  //! <Type Comment="SS1 velocity decreased slower than the minimum deceleration ramp (positive direction)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SS1_DECELERATION_POS"/>
	    ERR_ID_SS1_DECELERATION_NEG:=11,  //! <Type Comment="SS1 velocity decreased slower than the minimum deceleration ramp (negative direction)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SS1_DECELERATION_NEG"/>
	    ERR_ID_SS2_DECELERATION_POS:=16,  //! <Type Comment="SS2 velocity decreased slower than the minimum deceleration ramp (positive direction)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SS2_DECELERATION_POS"/>
	    ERR_ID_SS2_DECELERATION_NEG:=17,  //! <Type Comment="SS2 velocity decreased slower than the minimum deceleration ramp (negative direction)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SS2_DECELERATION_NEG"/>
	    ERR_ID_SOS_POSITION_UP:=24,  //! <Type Comment="SOS position zero window violated (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SOS_POSITION_UP"/>
	    ERR_ID_SOS_POSITION_LO:=25,  //! <Type Comment="SOS position zero window violated (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SOS_POSITION_LO"/>
	    ERR_ID_SOS_VELOCITY_UP:=26,  //! <Type Comment="SOS velocity zero window violated (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SOS_VELOCITY_UP"/>
	    ERR_ID_SOS_VELOCITY_LO:=27,  //! <Type Comment="SOS velocity zero window violated (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SOS_VELOCITY_LO"/>
	    ERR_ID_SBT_RC:=39,  //! <Type Comment="RC detected an error in its SBT routine" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_RC"/>
	    ERR_ID_SBT_TIME_STARTUP:=40,  //! <Type Comment=" first SBT hasn&apos;t been executed within startup time" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_TIME_STARTUP"/>
	    ERR_ID_SBT_TIME_CYCLIC:=41,  //! <Type Comment="SBT hasn&apos;t been executed within cyclic interval" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_TIME_CYCLIC"/>
	    ERR_ID_SBT_POSITION_UP:=42,  //! <Type Comment="SBT position zero window violated (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_POSITION_UP"/>
	    ERR_ID_SBT_POSITION_LO:=43,  //! <Type Comment="SBT position zero window violated (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_POSITION_LO"/>
	    ERR_ID_SBT_BRAKE_CLOSED:=44,  //! <Type Comment="brake was closed during SBT static time" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_BRAKE_CLOSED"/>
	    ERR_ID_SBT_BRAKE_OPEN:=45,  //! <Type Comment="brake was open during SBT test duration time" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_BRAKE_OPEN"/>
	    ERR_ID_SBT_MIN_TORQUE:=46,  //! <Type Comment="SBT minimum torque wasn&apos;t reached during SBT test duration time" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_MIN_TORQUE"/>
	    ERR_ID_SBT_TORQUE_DIR:=47,  //! <Type Comment="torque applied in wrong direction during SBT" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SBT_TORQUE_DIR"/>
	    ERR_ID_SLS_VELOCITY_UP:=48,  //! <Type Comment="SLS velocity limit violated (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLS_VELOCITY_UP"/>
	    ERR_ID_SLS_VELOCITY_LO:=49,  //! <Type Comment="SLS velocity limit violated (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLS_VELOCITY_LO"/>
	    ERR_ID_SLS_DECELERATION_POS:=50,  //! <Type Comment="SLS deceleration limit violated (positive direction)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLS_DECELERATION_POS"/>
	    ERR_ID_SLS_DECELERATION_NEG:=51,  //! <Type Comment="SLS deceleration limit violated (negative direction)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLS_DECELERATION_NEG"/>
	    ERR_ID_SLP_POSITION_UP:=56,  //! <Type Comment="SLP position limit violated (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLP_POSITION_UP"/>
	    ERR_ID_SLP_POSITION_LO:=57,  //! <Type Comment="SLP position limit violated (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLP_POSITION_LO"/>
	    ERR_ID_SLP_POSITION_INSIDE:=58,  //! <Type Comment="SLP position limit violated (position in inside window)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLP_POSITION_INSIDE"/>
	    ERR_ID_SLA_POSDIR_ACCELERATION:=64,  //! <Type Comment="SLA maximum acceleration in positive direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLA_POSDIR_ACCELERATION"/>
	    ERR_ID_SLA_POSDIR_DECELERATION:=65,  //! <Type Comment="SLA maximum deceleration in positive direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLA_POSDIR_DECELERATION"/>
	    ERR_ID_SLA_NEGDIR_ACCELERATION:=66,  //! <Type Comment="SLA maximum acceleration in negative direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLA_NEGDIR_ACCELERATION"/>
	    ERR_ID_SLA_NEGDIR_DECELERATION:=67,  //! <Type Comment="SLA maximum deceleration in negative direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLA_NEGDIR_DECELERATION"/>
	    ERR_ID_SLI_POSITION_UP:=80,  //! <Type Comment="SLI position limit violated (upper limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLI_POSITION_UP"/>
	    ERR_ID_SLI_POSITION_LO:=81,  //! <Type Comment="SLI position limit violated (lower limit exceeded)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SLI_POSITION_LO"/>
	    ERR_ID_SDI_VELOCITY_POS:=88,  //! <Type Comment="SDI velocity for positive direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SDI_VELOCITY_POS"/>
	    ERR_ID_SDI_VELOCITY_NEG:=89,  //! <Type Comment="SDI velocity for negative direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SDI_VELOCITY_NEG"/>
	    ERR_ID_SDI_POSITION_POS:=90,  //! <Type Comment="SDI position for positive direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SDI_POSITION_POS"/>
	    ERR_ID_SDI_POSITION_NEG:=91,  //! <Type Comment="SDI position for negative direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SDI_POSITION_NEG"/>
	    ERR_ID_SMS_POS_VELOCITY:=96,  //! <Type Comment="SMS maximum positive velocity violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMS_POS_VELOCITY"/>
	    ERR_ID_SMS_NEG_VELOCITY:=97,  //! <Type Comment="SMS maximum negative velocity violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMS_NEG_VELOCITY"/>
	    ERR_ID_SMP_UPPER_POSITION:=104,  //! <Type Comment="SMP upper position violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMP_UPPER_POSITION"/>
	    ERR_ID_SMP_LOWER_POSITION:=105,  //! <Type Comment="SMP lower position violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMP_LOWER_POSITION"/>
	    ERR_ID_SMP_INSIDE_POSITION:=106,  //! <Type Comment="SMP window position violated (position in inside window)" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMP_INSIDE_POSITION"/>
	    ERR_ID_SMA_POSDIR_ACCELERATION:=112,  //! <Type Comment="SMA maximum acceleration in positive direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMA_POSDIR_ACCELERATION"/>
	    ERR_ID_SMA_POSDIR_DECELERATION:=113,  //! <Type Comment="SMA maximum deceleration in positive direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMA_POSDIR_DECELERATION"/>
	    ERR_ID_SMA_NEGDIR_ACCELERATION:=114,  //! <Type Comment="SMA maximum acceleration in negative direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMA_NEGDIR_ACCELERATION"/>
	    ERR_ID_SMA_NEGDIR_DECELERATION:=115  //! <Type Comment="SMA maximum deceleration in negative direction violated" Name="ge_MDD2000SafeFkt_ERR_ID.ERR_ID_SMA_NEGDIR_DECELERATION"/>
	  )$UDINT;
	  ge_MDD2000SafeFkt_ID :  //! <Type Public="true" Name="ge_MDD2000SafeFkt_ID"/>
	  (
	    None:=0,
	    STO:=26176,
	    SS1:=26192,
	    SS2:=26224,
	    SOS:=26216,
	    SBC:=26208,
	    SBT:=26400,
	    SLS:=26256,
	    SLP:=26272,
	    SLA:=26368,
	    SLT:=26288,
	    SLI:=26296,
	    SDI:=26320,
	    SMS:=26280,
	    SMP:=26416,
	    SMA:=26312,
	    SMT:=26424,
	    SSM:=26336,
	    SCA:=26344
	  )$UDINT;
	  pReqReferenceMDD2000_Axisbase : ^MDD2000_AxisBase;
	  t_MDD2000Mng_AsyncPara_Entry : STRUCT
	    pThisObj : ^void;
	    usEntry : USINT;
	    uiParaIndex : UINT;
	    usParaSubIndex : USINT;
	    usRDWR : USINT;
	    dValue : ARRAY [0..11] OF USINT;
	    bsDataInfo : BSINT
	    [
	    ];
	    udTimeStamp : UDINT;
	    udTimeoutCycles : UDINT;
	    dCallID : DINT;
	    bSent : BOOL;
	    bFinished : BOOL;
	  END_STRUCT;
	  t_MDD2000Mng_ParaObjectListEntry : STRUCT
	    pObject : ^VirtualBase;
	    udIndex : UDINT;
	  END_STRUCT;
#pragma pack(push, 1)
	  ts_BitMasksSafeFktCfg : STRUCT
	    STO : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SS1 : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SS2 : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SOS : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SBC : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SBT : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SLS : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SLP : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SLA : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SLT : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SLI : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SDI : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SMS : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SMP : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SMA : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SMT : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SSM : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	    SCA : BINT
	    [
	      1 Bit1,
	      2 Bit2,
	      3 Bit3,
	      4 Bit4,
	      5 Bit5,
	      6 Bit6,
	      7 Bit7,
	      8 Bit8,
	      9 Bit9,
	      10 Bit10,
	      11 Bit11,
	      12 Bit12,
	      13 Bit13,
	      14 Bit14,
	      15 Bit15,
	      16 Bit16,
	    ];
	  END_STRUCT;
#pragma pack(pop)
#pragma pack(push, 1)
	  ts_SafeFktUpdateElement : STRUCT
	    pBitMask : ^HINT;
	    SetBit : HDINT;
	  END_STRUCT;
#pragma pack(pop)
	END_TYPE
  //Servers:
	SafeControlWord 	: SvrCh_BDINT;
	SafeStateWord 	: SvrCh_BDINT;
	SafeErrorWord 	: SvrCh_BDINT;
	ActiveSafeFunctions 	: SvrCh_gb_MDD2000ActiveSafeFkt_PTofCls_MDD2000_AxisBase;
	VerifiedState 	: SvrCh_t_e_SafeVerifiedState_PTofCls_MDD2000_AxisBase;
	SetZeroPosition 	: SvrCh_DINT;
	AckZeroPosition 	: SvrCh_DINT;
	CmdZeroPositionRsp 	: SvrCh_t_e_SafeReferenceRsp_PTofCls_MDD2000_AxisBase;
	PositionReferenceState 	: SvrCh_t_e_SafeReferencedState_PTofCls_MDD2000_AxisBase;
	ErrorIDSafetyFunction 	: SvrCh_ge_MDD2000SafeFkt_ERR_ID_PTofCls_MDD2000_AxisSafeInfo;
	SafetyFunctionInErr 	: SvrCh_ge_MDD2000SafeFkt_ID_PTofCls_MDD2000_AxisSafeInfo;
	SafetyFunctionInErrSubID 	: SvrCh_DINT;
	SafetyFunctionErrReact 	: SvrCh_ge_MDD2000SafeFkt_ID_PTofCls_MDD2000_AxisSafeInfo;
	SafetyFunctionErrReactSubID 	: SvrCh_DINT;
	SafetyFunctionErrorInfo1 	: SvrCh_DINT;
	SafetyFunctionErrorInfo2 	: SvrCh_DINT;
	SafetyFunctionErrorInfo3 	: SvrCh_DINT;
	RestartAcknowledgeNeeded 	: SvrCh_DINT;
	RestartAcknowledge 	: SvrCh_DINT;
	ErrorAcknowledgeNeeded 	: SvrCh_DINT;
	ErrorAcknowledge 	: SvrCh_DINT;
  //Clients:
  //Variables:
		BitMasksSafeFktCfgCtrl 	: ts_BitMasksSafeFktCfg;
		BitMasksSafeFktCfgState 	: ts_BitMasksSafeFktCfg;
		aSafeFktUpdateListCtrl : ARRAY [0..MDD2000_AXISSAFE_MAX_IDX_SAFEFKT] OF ts_SafeFktUpdateElement;

		aSafeFktUpdateListState : ARRAY [0..MDD2000_AXISSAFE_MAX_IDX_SAFEFKT] OF ts_SafeFktUpdateElement;

		bSafeControlStateinPDO 	: BOOL;
		bSafetyRun : BDINT
		[
		  1 _TempOp,
		  2 _Op,
		];

		bGetPosRefState 	: BOOL;
		udTimeStampUpdateSafeControlState 	: UDINT;
  //Functions:
	
	FUNCTION VIRTUAL GLOBAL Init;
	
	FUNCTION VIRTUAL GLOBAL RefreshPara
		VAR_INPUT
			hParaIndex 	: HINT;
			hsParaSubIndex 	: HSINT;
			bRW 	: DINT;
			bsDataInfo 	: BSINT;
			pValue 	: ^DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL UpdateCy
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL SafetyChanged
		VAR_INPUT
			StateInfo 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL SetSafeCtrlWordBitmask
		VAR_INPUT
			SafeFktId 	: HDINT;
			BitIdx 	: DINT;
			bStateCfg 	: BOOL;
		END_VAR;
	
	FUNCTION VIRTUAL SetSafeFktUpdateList;
	
	FUNCTION VIRTUAL UpdateActiveSafeFunctions
		VAR_INPUT
			sControlWord 	: BDINT;
			sStateWord 	: BDINT;
		END_VAR;
	
	FUNCTION VIRTUAL UpdateSafeControlStateinPDO;
	
	FUNCTION VIRTUAL GLOBAL SafeControlWord::Read
		VAR_OUTPUT
			output (EAX) 	: BDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SafeStateWord::Read
		VAR_OUTPUT
			output (EAX) 	: BDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL ActiveSafeFunctions::Read
		VAR_OUTPUT
			output (EAX) 	: MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SetZeroPosition::Write
		VAR_INPUT
			input (EAX) 	: DINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL AckZeroPosition::Write
		VAR_INPUT
			input (EAX) 	: DINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL RestartAcknowledge::Write
		VAR_INPUT
			input (EAX) 	: DINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL ErrorAcknowledge::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 MDD2000_AxisSafeInfo::@CT_
0$UINT,
2#0100000000000000$UINT, //TY_MDD2000_AXISSAFEINFO
1$UINT, 0$UINT, (SIZEOF(::MDD2000_AxisSafeInfo))$UINT, 
21$UINT, 0$UINT, 0$UINT, 
TO_UDINT(540025696), "MDD2000_AxisSafeInfo", //Class
TO_UDINT(1914213293), "_DriveSafetyIFParaBase", 1$UINT, 0$UINT, //Baseclass
//Servers:
(::MDD2000_AxisSafeInfo.SafeControlWord.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3312034049), "SafeControlWord", 
(::MDD2000_AxisSafeInfo.SafeStateWord.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(4253015497), "SafeStateWord", 
(::MDD2000_AxisSafeInfo.SafeErrorWord.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(153997356), "SafeErrorWord", 
(::MDD2000_AxisSafeInfo.ActiveSafeFunctions.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(184883718), "ActiveSafeFunctions", 
(::MDD2000_AxisSafeInfo.VerifiedState.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3353571576), "VerifiedState", 
(::MDD2000_AxisSafeInfo.SetZeroPosition.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1824158564), "SetZeroPosition", 
(::MDD2000_AxisSafeInfo.AckZeroPosition.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3958072803), "AckZeroPosition", 
(::MDD2000_AxisSafeInfo.CmdZeroPositionRsp.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(610812544), "CmdZeroPositionRsp", 
(::MDD2000_AxisSafeInfo.PositionReferenceState.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(221551760), "PositionReferenceState", 
(::MDD2000_AxisSafeInfo.ErrorIDSafetyFunction.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(672299165), "ErrorIDSafetyFunction", 
(::MDD2000_AxisSafeInfo.SafetyFunctionInErr.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3536391674), "SafetyFunctionInErr", 
(::MDD2000_AxisSafeInfo.SafetyFunctionInErrSubID.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3150450574), "SafetyFunctionInErrSubID", 
(::MDD2000_AxisSafeInfo.SafetyFunctionErrReact.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(4072864691), "SafetyFunctionErrReact", 
(::MDD2000_AxisSafeInfo.SafetyFunctionErrReactSubID.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3573004174), "SafetyFunctionErrReactSubID", 
(::MDD2000_AxisSafeInfo.SafetyFunctionErrorInfo1.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1191398925), "SafetyFunctionErrorInfo1", 
(::MDD2000_AxisSafeInfo.SafetyFunctionErrorInfo2.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(3725205431), "SafetyFunctionErrorInfo2", 
(::MDD2000_AxisSafeInfo.SafetyFunctionErrorInfo3.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(2836213537), "SafetyFunctionErrorInfo3", 
(::MDD2000_AxisSafeInfo.RestartAcknowledgeNeeded.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(2925793295), "RestartAcknowledgeNeeded", 
(::MDD2000_AxisSafeInfo.RestartAcknowledge.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1860654871), "RestartAcknowledge", 
(::MDD2000_AxisSafeInfo.ErrorAcknowledgeNeeded.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(4087649383), "ErrorAcknowledgeNeeded", 
(::MDD2000_AxisSafeInfo.ErrorAcknowledge.pMeth)$UINT, _CH_SVR$UINT, 2#0000000000000000$UINT, TO_UDINT(1289544951), "ErrorAcknowledge", 
//Clients:
END_FUNCTION


#define USER_CNT_MDD2000_AxisSafeInfo 23

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

FUNCTION MDD2000_AxisSafeInfo::@STD
	VAR_OUTPUT
		ret_code	: CONFSTATES;
	END_VAR
	VAR
		vmt	: _LSL_STD_VMETH;
		nCmdSize	: UINT;
	END_VAR

	ret_code	:= _DriveSafetyIFParaBase::@STD();
	IF ret_code <> C_OK THEN
		RETURN;
	END_IF;
	nCmdSize		:= _DriveSafetyIFParaBase::State.pMeth^.nCmds$UINT*SIZEOF(pVoid) + CMDMETH.Init;

	_memcpy((#vmt.CmdTable)$^USINT, _DriveSafetyIFParaBase::State.pMeth, nCmdSize);
	vmt.CmdTable.nCmds		:= nSTDCMD + USER_CNT_MDD2000_AxisSafeInfo;
	vmt.CmdTable.Init		:= #Init();
#pragma warning (disable : 74)
	vmt.UserFcts[2]		:= #RefreshPara();

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

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

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

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

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

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

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

	IF _DriveSafetyIFParaBase::State.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	SafeControlWord.pMeth			:= StoreMethod( #SafeControlWord::Read(), #M_NO_F() );
	IF SafeControlWord.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	SafeStateWord.pMeth			:= StoreMethod( #SafeStateWord::Read(), #M_NO_F() );
	IF SafeStateWord.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ActiveSafeFunctions.pMeth			:= StoreMethod( #ActiveSafeFunctions::Read(), #M_NO_F() );
	IF ActiveSafeFunctions.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	SetZeroPosition.pMeth			:= StoreMethod( #M_RD_DIRECT(), #SetZeroPosition::Write() );
	IF SetZeroPosition.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	AckZeroPosition.pMeth			:= StoreMethod( #M_RD_DIRECT(), #AckZeroPosition::Write() );
	IF AckZeroPosition.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	RestartAcknowledge.pMeth			:= StoreMethod( #M_RD_DIRECT(), #RestartAcknowledge::Write() );
	IF RestartAcknowledge.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ErrorAcknowledge.pMeth			:= StoreMethod( #M_RD_DIRECT(), #ErrorAcknowledge::Write() );
	IF ErrorAcknowledge.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;

END_FUNCTION

#pragma usingLtd MDD2000_AxisBase

//{{LSL_IMPLEMENTATION
FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::Init

  // call base class
  _DriveSafetyIFParaBase::Init();

  if _firstscan then
    if (IsAxisConnected() = TRUE) then
      AddParaObjects(dIndex:=MDD2000MNG_PARAIDX_SAFEINFO, pThis:=this);// add the object in the list of the axis
    end_if;
  end_if;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::RefreshPara
	VAR_INPUT
		hParaIndex 	: HINT;
		hsParaSubIndex 	: HSINT;
		bRW 	: DINT;
		bsDataInfo 	: BSINT;
		pValue 	: ^DINT;
	END_VAR
  VAR
  	hTempVal : HDINT;
  END_VAR

  
  case hParaIndex of
  
    //*****************************************************************************
    MDD2000_PID_SAFETY_AXIS_INFO:
  
      // check the parameter number
      case hsParaSubIndex of
           
        MDD2000_SPID_SAFETY_AXIS_FEEDBACK_STATE:
          VerifiedState$DINT          := pValue^;
          
        MDD2000_SPID_SAFETY_AXIS_SETZEROPOS:
          CmdZeroPositionRsp$DINT     := pValue^;
          
        MDD2000_SPID_SAFETY_AXIS_POSSREFTATE:
          PositionReferenceState$DINT := pValue^;
      end_case;

    //*****************************************************************************
    MDD2000_PID_SAFETY_AXIS_FUNC_INFO:

      // check the parameter number
      case hsParaSubIndex of
      
        MDD2000_SPID_SAFETY_AXIS_RESTARTACK:
        
          if bRW = FALSE then
            RestartAcknowledgeNeeded := pValue^;
          else
            // Command sent succesfull
            RestartAcknowledge := 0;
          end_if;
        
        MDD2000_SPID_SAFETY_AXIS_ERRORACK:
        
          if bRW = FALSE then
            ErrorAcknowledgeNeeded  := pValue^;
          else
            // Command sent succesfull
            ErrorAcknowledge  := 0;
          end_if;
        
        MDD2000_SPID_SAFETY_AXIS_CONT_WORD:
          SafeControlWord := pValue^$BDINT;
          
        MDD2000_SPID_SAFETY_AXIS_STATE_WORD:
          SafeStateWord := pValue^$BDINT;
          UpdateActiveSafeFunctions(sControlWord:=SafeControlWord, sStateWord:=SafeStateWord);
                  
        MDD2000_SPID_SAFETY_AXIS_ERROR_WORD:
          SafeErrorWord := pValue^$BDINT;
        
        MDD2000_SPID_SAFETY_AXIS_ERR_ID:
        
          if ErrorIDSafetyFunction <> pValue^$ge_MDD2000SafeFkt_ERR_ID then
            ErrorIDSafetyFunction := pValue^$ge_MDD2000SafeFkt_ERR_ID;
            
            // ErrorID Changed, Update dependant parameters
            AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_ERR_SOURCE, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
            AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_ERR_REACT,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
            AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_ERR_INFO1,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
            AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_ERR_INFO2,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
            AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_ERR_INFO3,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
            
          end_if;          
        
        MDD2000_SPID_SAFETY_AXIS_ERR_SOURCE:
        
          hTempVal := to_UDINT(pValue^ AND 16#FFFF);
          while hTempVal > MDD2000_SFKTCFG_IDX_MAX do
            hTempVal -= MDD2000_SFKTCFG_IDXOFFSET;  // Eliminate axis dependant offset
          end_while;
          SafetyFunctionInErr         := hTempVal$ge_MDD2000SafeFkt_ID;
          SafetyFunctionInErrSubID    := ((pValue^ SHR 16) AND 16#FF);
        
        MDD2000_SPID_SAFETY_AXIS_ERR_REACT:
          
          hTempVal := to_UDINT(pValue^ AND 16#FFFF);
          while hTempVal > MDD2000_SFKTCFG_IDX_MAX do
            hTempVal -= MDD2000_SFKTCFG_IDXOFFSET;  // Eliminate axis dependant offset
          end_while;
          SafetyFunctionErrReact      := hTempVal$ge_MDD2000SafeFkt_ID;
          SafetyFunctionErrReactSubID := ((pValue^ SHR 16) AND 16#FF);
          
        MDD2000_SPID_SAFETY_AXIS_ERR_INFO1:
          SafetyFunctionErrorInfo1 := pValue^;
        
        MDD2000_SPID_SAFETY_AXIS_ERR_INFO2:
          SafetyFunctionErrorInfo2 := pValue^;
          
        MDD2000_SPID_SAFETY_AXIS_ERR_INFO3:
          SafetyFunctionErrorInfo3 := pValue^;
                  
      end_case;
      
    //*****************************************************************************
    MDD2000_PID_SFKTCFG_CTRLWORD_FKTMAPPING:
      SetSafeCtrlWordBitmask(SafeFktId:=pValue^$HDINT, BitIdx:=hsParaSubIndex, bStateCfg:=FALSE);
      
    MDD2000_PID_SFKTCFG_STATEWORD_FKTMAPPING:
      SetSafeCtrlWordBitmask(SafeFktId:=pValue^$HDINT, BitIdx:=hsParaSubIndex, bStateCfg:=TRUE);
      if hsParaSubIndex = MDD2000_SPIDMAX_SFKTCFG_CTRLSTATEWORD_FKTMAPPING then  // Last mapping info recieved
        SetSafeFktUpdateList();
      end_if;
      
  end_case;

END_FUNCTION

FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::UpdateCy
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
  VAR
  	MyCmdStruct : CmdStruct;
    MyResult : results;
    retcode : iprStates;
  END_VAR  
  
  if (bSafetyRun) & (UpdateCyTime > 0) then
  
    // We are waiting for no Parameters
    if (AnzASyncPara) = 0 then
      if (ops.tAbsolute - udTimeStampUpdateCy) > UpdateCyTime then 
       
        if bSafeControlStateinPDO = FALSE then  // Don't read asy if they are already read in iso PDO data
          AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_CONT_WORD,  ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
          AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_STATE_WORD, ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
        elsif (ops.tAbsolute - udTimeStampUpdateSafeControlState) > UpdateCyTime then
          // Update if configured in Rt incase the read methods of the Servers are not Called.
          UpdateSafeControlStateinPDO();
        end_if;
        
        AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_ERROR_WORD, ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
        AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_ERR_ID,     ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
        
        // Get State RestartAck and ErrorAck
        AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_RESTARTACK, ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
        AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_ERRORACK,   ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
        
        // VerifiedState and PositionReferenceState cannot change in _OP Mode
        if (bSafetyRun._TempOp) then
          // Read VerifiedState
          AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO,  ParaSubID:=MDD2000_SPID_SAFETY_AXIS_FEEDBACK_STATE, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
          // Read PositionReferenceState
          AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO,  ParaSubID:=MDD2000_SPID_SAFETY_AXIS_POSSREFTATE,    ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
        end_if;
        
        if bGetPosRefState = TRUE then
        
          // Get Refstate and Command response
          MyCmdStruct.uiCmd    := DRIVESAFETYIF_GETREFERENCESTATE;
          MyCmdStruct.aPara[0] := DRIVESAFETYIF_GETREFERENCESTATE_VER_1;
  
          retcode := DriveIF.NewInst(#MyCmdStruct, #MyResult);
          
          if retcode = READY then
          
            //  results
            //  uiLng               : 20 Byte
            //  aData[0]$DINT       : Command Version : max supported version
            //  aData[4]$iprStates  : REFERENCE CMDRSP Executionstate: READY .. Done, Busy, Error .. Asy Comm Failed 
            //  aData[8]$DINT       : REFERENCE CMDRSP, see below
            //  aData[12]$iprStates : REFERENCE STATE Executionstate: READY .. Done, Busy, Error .. Asy Comm Failed
            //  aData[16]$DINT      : REFERENCE STATE, see below
            if MyResult.uiLng >= 20 then              
              CmdZeroPositionRsp      := MyResult.aData[8]$MDD2000_AxisBase::t_e_SafeReferenceRsp;
              PositionReferenceState  := MyResult.aData[16]$MDD2000_AxisBase::t_e_SafeReferencedState;
              
              if (MyResult.aData[4]$iprStates <> BUSY) & (MyResult.aData[12]$iprStates <> BUSY) then                
                
                // Stop polling Referencestate and cmd when it no longer is beeing activly read
                bGetPosRefState := FALSE;
                
              end_if;

            end_if;
          
          elsif retcode <> BUSY then
            bGetPosRefState := FALSE;
          end_if;
        end_if;
        
      end_if;
    else
      udTimeStampUpdateCy := ops.tAbsolute;
    end_if;
    
  end_if;

END_FUNCTION


FUNCTION VIRTUAL MDD2000_AxisSafeInfo::SafetyChanged
	VAR_INPUT
		StateInfo 	: DINT;
	END_VAR
  VAR
  	idx : HSINT;
  END_VAR
  
  if ( (StateInfo$MDD2000MngBase::t_e_MDD2000SafetyRunState = _OP)      |  
       (StateInfo$MDD2000MngBase::t_e_MDD2000SafetyRunState = _TEMP_OP) ) then
       
    bSafeControlStateinPDO := TRUE;
  
    // Reset Bitmasks 
    _memset(dest:=#BitMasksSafeFktCfgCtrl, usByte:=0, cntr:=sizeof(BitMasksSafeFktCfgCtrl));
    // Read the mapping for the safety controlword, 1 Mapping for each of the 16 Bit
    for idx := 1 to MDD2000_SPIDMAX_SFKTCFG_CTRLSTATEWORD_FKTMAPPING do  // idx 0 is no of entries
      AddAsyncEntryDS402(ParaID:=MDD2000_PID_SFKTCFG_CTRLWORD_FKTMAPPING, ParaSubID:=idx, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);        
    end_for;
    // Read the mapping for the safety stateword, 1 Mapping for each of the 16 Bit
    for idx := 1 to MDD2000_SPIDMAX_SFKTCFG_CTRLSTATEWORD_FKTMAPPING do  // idx 0 is no of entries
      AddAsyncEntryDS402(ParaID:=MDD2000_PID_SFKTCFG_STATEWORD_FKTMAPPING, ParaSubID:=idx, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);        
    end_for;
    
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_CONT_WORD,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_STATE_WORD, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID:=MDD2000_SPID_SAFETY_AXIS_ERROR_WORD, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    
    // Get State RestartAck and ErrorAck
    AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_RESTARTACK, ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    AddAsyncEntryDS402(ParaID := MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_ERRORACK,   ParaRdWr :=0, ParaSize := MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);

    // Read VerifiedState
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO,  ParaSubID:=MDD2000_SPID_SAFETY_AXIS_FEEDBACK_STATE, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    // Read PositionReferenceState
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO,  ParaSubID:=MDD2000_SPID_SAFETY_AXIS_POSSREFTATE,    ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    // Read CmdZeroPositionRsp
    AddASyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO,  ParaSubID := MDD2000_SPID_SAFETY_AXIS_SETZEROPOS,   ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    
    if (StateInfo$MDD2000MngBase::t_e_MDD2000SafetyRunState = _OP) then
      bSafetyRun._Op      := TRUE;
    else
      bSafetyRun._TempOp  := TRUE;
    end_if;
    
  else
  
    bSafetyRun := 0;
    
  end_if;

END_FUNCTION


FUNCTION VIRTUAL MDD2000_AxisSafeInfo::SetSafeCtrlWordBitmask
	VAR_INPUT
		SafeFktId 	: HDINT;
		BitIdx 	: DINT;
    bStateCfg : BOOL;
	END_VAR
  VAR
  	SafeFktIndex    : HINT;
    SafeFktSubIndex : HSINT;
    SafeFktBitLen   : USINT;
    pBitMask        : ^BINT;
  END_VAR

  SafeFktBitLen   := (SafeFktId AND 0xFF)$USINT;
  SafeFktId       := SafeFktId shr 8;
  SafeFktSubIndex := (SafeFktId AND 0xFF)$USINT;
  SafeFktId       := SafeFktId shr 8;  
  SafeFktIndex    := (SafeFktId AND 0xFFFF)$UINT;
  
  pBitMask := NIL;
  
  if (BitIdx > 0) & (BitIdx <= MDD2000_SPIDMAX_SFKTCFG_CTRLSTATEWORD_FKTMAPPING) then
    
    while SafeFktIndex > MDD2000_SFKTCFG_IDX_MAX  do
      SafeFktIndex -= MDD2000_SFKTCFG_IDXOFFSET;  // Eliminate axis dependant offset
    end_while;
    
    if bStateCfg = FALSE then
    
      case SafeFktIndex of
      
        // Stop Functions
        MDD2000_PID_SFKTCFG_STO:
          pBitMask := (#BitMasksSafeFktCfgCtrl.STO)$^BINT;
        MDD2000_PID_SFKTCFG_SS1:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SS1)$^BINT;
        MDD2000_PID_SFKTCFG_SS2:
          pBitMask := (#BitMasksSafeFktCfgCtrl.ss2)$^BINT;
        MDD2000_PID_SFKTCFG_SOS:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SOS)$^BINT;
          
        // Break Functions
        MDD2000_PID_SFKTCFG_SBC:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SBC)$^BINT;
        MDD2000_PID_SFKTCFG_SBT:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SBT)$^BINT;
          
        // Limit Functions
        MDD2000_PID_SFKTCFG_SLS:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SLS)$^BINT;
        MDD2000_PID_SFKTCFG_SLP:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SLP)$^BINT;
        MDD2000_PID_SFKTCFG_SLA:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SLA)$^BINT;
        MDD2000_PID_SFKTCFG_SLT:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SLT)$^BINT;
        MDD2000_PID_SFKTCFG_SLI:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SLI)$^BINT;
        MDD2000_PID_SFKTCFG_SDI:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SDI)$^BINT;
          
        // Monitoring Functions
        MDD2000_PID_SFKTCFG_SMS:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SMS)$^BINT;
        MDD2000_PID_SFKTCFG_SMP:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SMP)$^BINT;
        MDD2000_PID_SFKTCFG_SMA:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SMA)$^BINT;
        MDD2000_PID_SFKTCFG_SMT:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SMT)$^BINT;
        MDD2000_PID_SFKTCFG_SSM:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SSM)$^BINT;
        MDD2000_PID_SFKTCFG_SCA:
          pBitMask := (#BitMasksSafeFktCfgCtrl.SCA)$^BINT;

      end_case;
      
    else
      
      case SafeFktIndex of
      
        // Stop Functions
        MDD2000_PID_SFKTCFG_STO:
          pBitMask := (#BitMasksSafeFktCfgState.STO)$^BINT;
        MDD2000_PID_SFKTCFG_SS1:
          pBitMask := (#BitMasksSafeFktCfgState.SS1)$^BINT;
        MDD2000_PID_SFKTCFG_SS2:
          pBitMask := (#BitMasksSafeFktCfgState.ss2)$^BINT;
        MDD2000_PID_SFKTCFG_SOS:
          pBitMask := (#BitMasksSafeFktCfgState.SOS)$^BINT;
          
        // Break Functions
        MDD2000_PID_SFKTCFG_SBC:
          pBitMask := (#BitMasksSafeFktCfgState.SBC)$^BINT;
        MDD2000_PID_SFKTCFG_SBT:
          pBitMask := (#BitMasksSafeFktCfgState.SBT)$^BINT;
          
        // Limit Functions
        MDD2000_PID_SFKTCFG_SLS:
          pBitMask := (#BitMasksSafeFktCfgState.SLS)$^BINT;
        MDD2000_PID_SFKTCFG_SLP:
          pBitMask := (#BitMasksSafeFktCfgState.SLP)$^BINT;
        MDD2000_PID_SFKTCFG_SLA:
          pBitMask := (#BitMasksSafeFktCfgState.SLA)$^BINT;
        MDD2000_PID_SFKTCFG_SLT:
          pBitMask := (#BitMasksSafeFktCfgState.SLT)$^BINT;
        MDD2000_PID_SFKTCFG_SLI:
          pBitMask := (#BitMasksSafeFktCfgState.SLI)$^BINT;
        MDD2000_PID_SFKTCFG_SDI:
          pBitMask := (#BitMasksSafeFktCfgState.SDI)$^BINT;
          
        // Monitoring Functions
        MDD2000_PID_SFKTCFG_SMS:
          pBitMask := (#BitMasksSafeFktCfgState.SMS)$^BINT;
        MDD2000_PID_SFKTCFG_SMP:
          pBitMask := (#BitMasksSafeFktCfgState.SMP)$^BINT;
        MDD2000_PID_SFKTCFG_SMA:
          pBitMask := (#BitMasksSafeFktCfgState.SMA)$^BINT;
        MDD2000_PID_SFKTCFG_SMT:
          pBitMask := (#BitMasksSafeFktCfgState.SMT)$^BINT;
        MDD2000_PID_SFKTCFG_SSM:
          pBitMask := (#BitMasksSafeFktCfgState.SSM)$^BINT;
        MDD2000_PID_SFKTCFG_SCA:
          pBitMask := (#BitMasksSafeFktCfgState.SCA)$^BINT;
          
      end_case;
      
    end_if;
    
    if pBitMask then
      BitIdx -= 1;
      pBitMask^ := pBitMask^ OR (1 shl BitIdx);
    end_if;

  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL MDD2000_AxisSafeInfo::SetSafeFktUpdateList
VAR
	idx : DINT;
END_VAR

  // Reset old List
  _memset(dest:=#aSafeFktUpdateListCtrl[0], usByte:=0, cntr:=sizeof(aSafeFktUpdateListCtrl) );
  _memset(dest:=#aSafeFktUpdateListState[0], usByte:=0, cntr:=sizeof(aSafeFktUpdateListState) );
  
  // Control Word Masks *****************************************************************
  idx := 0;
  
  if BitMasksSafeFktCfgCtrl.STO then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.STO)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.STO;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SS1 then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SS1)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SS1;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SS2 then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SS2)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SS2;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SOS then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SOS)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SOS;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SBC then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SBC)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SBC;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SBT then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SBT)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SBT;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SLS then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SLS)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLS;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SLP then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SLP)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLP;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SLA then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SLA)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLA;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SLT then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SLT)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLT;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SLI then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SLI)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLI;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SDI then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SDI)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SDI;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SMS then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SMS)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMS;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SMP then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SMP)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMP;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SMA then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SMA)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMA;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgCtrl.SMT then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SMT)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMT;
    idx += 1;
  end_if;

  if BitMasksSafeFktCfgCtrl.SSM then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SSM)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SSM;
    idx += 1;
  end_if;  
    
  if BitMasksSafeFktCfgCtrl.SCA then
    aSafeFktUpdateListCtrl[idx].pBitMask  := (#BitMasksSafeFktCfgCtrl.SCA)$^HINT;
    aSafeFktUpdateListCtrl[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SCA;
    idx += 1;
  end_if;
  
  // Status Word Masks *****************************************************************
  idx := 0;
  
  if BitMasksSafeFktCfgState.STO then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.STO)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.STO;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SS1 then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SS1)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SS1;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SS2 then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SS2)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SS2;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SOS then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SOS)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SOS;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SBC then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SBC)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SBC;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SBT then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SBT)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SBT;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SLS then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SLS)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLS;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SLP then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SLP)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLP;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SLA then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SLA)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLA;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SLT then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SLT)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLT;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SLI then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SLI)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SLI;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SDI then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SDI)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SDI;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SMS then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SMS)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMS;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SMP then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SMP)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMP;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SMA then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SMA)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMA;
    idx += 1;
  end_if;
  
  if BitMasksSafeFktCfgState.SMT then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SMT)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SMT;
    idx += 1;
  end_if;

  if BitMasksSafeFktCfgState.SSM then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SSM)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SSM;
    idx += 1;
  end_if;  
    
  if BitMasksSafeFktCfgState.SCA then
    aSafeFktUpdateListState[idx].pBitMask  := (#BitMasksSafeFktCfgState.SCA)$^HINT;
    aSafeFktUpdateListState[idx].SetBit    := MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt.SCA;
    idx += 1;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL MDD2000_AxisSafeInfo::UpdateActiveSafeFunctions
	VAR_INPUT
		sControlWord 	: BDINT;
		sStateWord    : BDINT;
	END_VAR
  VAR
  	NewActiveSafeFunctions : MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt;
    pSafeFktUpdateElement : ^ts_SafeFktUpdateElement;
  END_VAR
  
  NewActiveSafeFunctions := 0;
  // Check in Ctrl Word
  pSafeFktUpdateElement  := #aSafeFktUpdateListCtrl[0];
  while (pSafeFktUpdateElement <= #aSafeFktUpdateListCtrl[MDD2000_AXISSAFE_MAX_IDX_SAFEFKT]) &
        (pSafeFktUpdateElement^.pBitMask) do  // Stop when there are no more bitmasks in the list.
  
    if (sControlWord AND pSafeFktUpdateElement^.pBitMask^) then
      NewActiveSafeFunctions := NewActiveSafeFunctions OR pSafeFktUpdateElement^.SetBit;
    end_if;
    
    pSafeFktUpdateElement += sizeof(ts_SafeFktUpdateElement);

  end_while;
  
  // Check in State Word
  pSafeFktUpdateElement  := #aSafeFktUpdateListState[0];
  while (pSafeFktUpdateElement <= #aSafeFktUpdateListState[MDD2000_AXISSAFE_MAX_IDX_SAFEFKT]) &
        (pSafeFktUpdateElement^.pBitMask) do  // Stop when there are no more bitmasks in the list.
  
    if (sStateWord AND pSafeFktUpdateElement^.pBitMask^) then
      NewActiveSafeFunctions := NewActiveSafeFunctions OR pSafeFktUpdateElement^.SetBit;
    end_if;
    
    pSafeFktUpdateElement += sizeof(ts_SafeFktUpdateElement);

  end_while;

  ActiveSafeFunctions := NewActiveSafeFunctions;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::SetZeroPosition::Write
	VAR_INPUT
		input (EAX) 	: DINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: DINT;
	END_VAR
  VAR
  	MyCmdStruct : CmdStruct;
    MyResult : results;
    retcode : iprStates;
  END_VAR  

//#define DRIVESAFETYIF_SETREFERENCEAXIS                  0x8595
//#define DRIVESAFETYIF_SETREFERENCEAXIS_VER_1                 1                   //version 1
//#define DRIVESAFETYIF_SETREFERENCEAXIS_VER_MAX          DRIVESAFETYIF_SETREFERENCEAXIS_VER_1   //newest implemented version
//  Command Version 1 **  
//  CmdStruct
//  aPara[0]$DINT     : Command Version : 1
//  aPara[1]$DINT     : 0 .. Read ReferenceState from Drive, -1 .. Reset ReferenceState off this axis, else SetReference and Read ReferenceState from Drive

//  results
//  uiLng         : 4 Byte (sizeof(DINT))
//  aData[0]$DINT : Command Version : max supported version

//  retcode
//  READY
//  BUSY
//  ERROR

	SetZeroPosition := input;
  
  if SetZeroPosition <> 0 then
  
    MyCmdStruct.uiCmd    := DRIVESAFETYIF_SETREFERENCEAXIS;
    MyCmdStruct.aPara[0] := DRIVESAFETYIF_SETREFERENCEAXIS_VER_1;
    MyCmdStruct.aPara[1] := SetZeroPosition;
    
    retcode := DriveIF.NewInst(#MyCmdStruct, #MyResult);
    if retcode = ERROR then
      SetZeroPosition := -1;
    else
      bGetPosRefState := TRUE;
    end_if;
    
  else
    // Read PositionReferenceState
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_POSSREFTATE, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);    
    // Read CmdZeroPositionRsp
    AddASyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_SETZEROPOS,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
  end_if;
  
	result := SetZeroPosition;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::AckZeroPosition::Write
	VAR_INPUT
		input (EAX) 	: DINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: DINT;
	END_VAR
  VAR
  	MyCmdStruct : CmdStruct;
    MyResult : results;
    retcode : iprStates;
  END_VAR  
  
//#define DRIVESAFETYIF_SETACKZEROPOSITION                0x8597
//#define DRIVESAFETYIF_SETACKZEROPOSITION_VER_1               1                   //version 1
//#define DRIVESAFETYIF_SETACKZEROPOSITION_VER_MAX        DRIVESAFETYIF_SETACKZEROPOSITION_VER_1   //newest implemented version
//  Command Version 1 **  
//  CmdStruct
//  aPara[0]$DINT     : Command Version : 1

//  results
//  uiLng         : 4 Byte (sizeof(DINT))
//  aData[0]$DINT : Command Version : max supported version
//  aPara[1]$DINT     : 0 .. Read ReferenceState from Drive, -1 .. Abort a prevously set DRIVESAFETYIF_SETREFERENCEAXIS cmd, else Ack Zeropost and Read ReferenceState from Drive

//  retcode
//  READY
//  BUSY
//  ERROR

	AckZeroPosition := input;
  
  if AckZeroPosition <> 0 then
  
    MyCmdStruct.uiCmd    := DRIVESAFETYIF_SETACKZEROPOSITION;
    MyCmdStruct.aPara[0] := DRIVESAFETYIF_SETACKZEROPOSITION_VER_1;
    MyCmdStruct.aPara[1] := AckZeroPosition;
    
    retcode := DriveIF.NewInst(#MyCmdStruct, #MyResult);
    if retcode = ERROR then
      SetZeroPosition := -1;
    else
      bGetPosRefState := TRUE;
    end_if;
  
  else
    // Read PositionReferenceState
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_POSSREFTATE, ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
    // Read CmdZeroPositionRsp
    AddASyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_SETZEROPOS,  ParaRdWr:=0, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=NIL, pThis:=this);
  end_if;
  
	result := AckZeroPosition;

END_FUNCTION

FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::SafeControlWord::Read
	VAR_OUTPUT
		output (EAX) 	: BDINT;
	END_VAR
  
  if bSafeControlStateinPDO then
    UpdateSafeControlStateinPDO();
  end_if;

	output := SafeControlWord;

END_FUNCTION

FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::SafeStateWord::Read
	VAR_OUTPUT
		output (EAX) 	: BDINT;
	END_VAR
  
  if bSafeControlStateinPDO then
    UpdateSafeControlStateinPDO();
  end_if;

	output := SafeStateWord;

END_FUNCTION

FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::ActiveSafeFunctions::Read
	VAR_OUTPUT
		output (EAX) 	: MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt;
	END_VAR
  
  if bSafeControlStateinPDO then
    UpdateSafeControlStateinPDO();
  end_if;

	output := ActiveSafeFunctions;

END_FUNCTION

FUNCTION VIRTUAL MDD2000_AxisSafeInfo::UpdateSafeControlStateinPDO
  VAR
  	MyCmdStruct : CmdStruct;
    MyResult : results;
    retcode : iprStates;
  END_VAR
  
//#define DRIVESAFETYIF_GETSAFECONTROLSTATEWORD           0x859D
//#define DRIVESAFETYIF_GETSAFECONTROLSTATEWORD_VER_1          1                   //version 1
//#define DRIVESAFETYIF_GETSAFECONTROLSTATEWORD_VER_MAX DRIVESAFETYIF_GETSAFECONTROLSTATEWORD_VER_1   //newest implemented version
//  Command Version 1 **  
//  CmdStruct
//  aPara[0]$DINT     : Command Version : 1

//  results
//  uiLng         : 4, 12, 16 Byte
//  aData[0]$DINT : Command Version : max supported version            
//  aData[4]$DINT := SafeControlWord                         .. Only Valid if uiLng >= 12 and retcode = READY
//  aData[8]$DINT := SafeStateWord                           .. Only Valid if uiLng >= 12 and retcode = READY
//  aData[12]$MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt := ActiveSafeFunctions  
//                                                           .. Only Valid if uiLng = 16  and retcode = READY, 
//                                                           .. The mapping info for the Safe Function is read asynchrone, 
//                                                           .. therefore ActiveSafeFunctions is not immediately available even if SafeControlWord and SafeStateWord are valid
  
  if IsAxisConnected() = TRUE then
    
    MyCmdStruct.uiCmd    := DRIVESAFETYIF_GETSAFECONTROLSTATEWORD;
    MyCmdStruct.aPara[0] := DRIVESAFETYIF_GETSAFECONTROLSTATEWORD_VER_1;
    
    retcode := DriveIF.NewInst(#MyCmdStruct, #MyResult);
    
    if (retcode = READY) & 
       (MyResult.uiLng >= 12) then
       
      SafeControlWord := MyResult.aData[4]$BDINT;
      SafeStateWord   := MyResult.aData[8]$BDINT;
      
      if MyResult.uiLng = 16 then
        ActiveSafeFunctions := MyResult.aData[12]$MDD2000_AxisBase::gb_MDD2000ActiveSafeFkt;
      end_if;

    else
    
      // Stop trying to read as PDO Data
      bSafeControlStateinPDO := FALSE;
      
    end_if;
    
    udTimeStampUpdateSafeControlState := ops.tAbsolute;
  
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::RestartAcknowledge::Write
	VAR_INPUT
		input (EAX) 	: DINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: DINT;
	END_VAR  

	RestartAcknowledge := input;
  if RestartAcknowledge > 1 then
    RestartAcknowledge := 1;
  end_if;

  if RestartAcknowledge = 1 then
  
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_RESTARTACK, ParaRdWr:=1, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=#RestartAcknowledge.dData, pThis:=this);
    
  end_if;

	result := RestartAcknowledge;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL MDD2000_AxisSafeInfo::ErrorAcknowledge::Write
	VAR_INPUT
		input (EAX) 	: DINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: DINT;
	END_VAR

	ErrorAcknowledge := input;
  if ErrorAcknowledge > 1 then
    ErrorAcknowledge := 1;
  end_if;
  
  if ErrorAcknowledge = 1 then  
    
    AddAsyncEntryDS402(ParaID:=MDD2000_PID_SAFETY_AXIS_FUNC_INFO, ParaSubID := MDD2000_SPID_SAFETY_AXIS_ERRORACK, ParaRdWr:=1, ParaSize:=MDD2000MNG_DATASIZE_4BYTE, pParaValue:=#ErrorAcknowledge.dData, pThis:=this);
  
  end_if;

	result := ErrorAcknowledge;

END_FUNCTION
