//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
// Defines for Mutex Generation
#define CDIAS_STR_MUTEX_NAME_SEPERATOR ".."
#define CDIAS_MUTEX_NAME_END_LENGTH 5
#define CDIAS_MUTEX_NAME_MAX_LENGTH 32

#define CDIAS_OFFSET_FPGA_VERSION     16#FB // Not EEPROM

#define CDIAS_EEPROM_OFFSET_HWVERSION 16#05
#define CDIAS_EEPROM_OFFSET_VARIANTE  16#03

#define CDIAS_EEPROM_OFFSET_FPGA      16#08
//}}LSL_DEFINES

//{{LSL_DECLARATION
#include "..\..\Class\HwControl\HwControl.h"

(*!
<Class
	Name               = "HwBaseCDIAS"
	Revision           = "2.56"
	GUID               = "{97D4E012-1873-4474-A4CD-0D0F0E4B798B}"
	RealtimeTask       = "false"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	IconPath           = ".\Class\Tool.ico"
	SharedCommandTable = "true"
	Objectsize         = "(284,120)"
	Comment            = "The Base hardware class for CDIAS">
	<Channels>
		<Server Name="SerialNo" GUID="{3F8692D6-0411-4033-B6EC-EF3D2CE66576}" Class="String" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Server Name="State" GUID="{00F2C12B-2999-4F47-8730-E501D1A5C3A7}" Visualized="true" Initialize="false" WriteProtected="true" Retentive="false"/>
		<Client Name="MasterConnect" Required="true" Internal="false" Comment="Connect to CICXXX_IM, CIVXXX or DiasMasterC (depending on hardware)"/>
		<Client Name="Place" Required="true" Internal="false" Comment="Rackplace of CDIAS Modul [0..7]"/>
		<Client Name="Required" Required="false" Internal="false" DefValue="1" Comment="0 = module is not required&#13;&#10;1 = module is required (CPU will crash if module is missing)"/>
		<Client Name="SerialNoStr" Required="true" Internal="true"/>
		<Client Name="TimeBase" Required="false" Internal="false" DefValue="0"/>
		<Client Name="TimeBaseOffset" Required="false" Internal="false" DefValue="0"/>
		<Client Name="To_StdLib" Required="false" Internal="false"/>
	</Channels>
	<Dependencies>
		<Files>
			<File Path=".\Source\interfaces\lsl_st_varan.h" Include="false"/>
			<File Path=".\Class\DiasMaster\DIASMaster.h" Include="false"/>
			<File Path=".\Class\VaranManager_Base\VaranManager_Base.h" Include="false"/>
			<File Path=".\Class\HwControl\HwControl.h" Include="true"/>
		</Files>
	</Dependencies>
	<RevDoku>
		<Owner Company="Sigmatek" Author="SilBer"/>
		<Dokumentation Revision="2.56" Date="18.12.2020" Author="RamAnd" Company="Sigmatek" Description="Removed CLI/STI occurances in internal time measurements"/>
		<Dokumentation Revision="2.55" Date="06.03.2018" Author="EisMic" Company="Sigmatek" Description="Attached header files no longer point to the installation directory of LASAL but instead now point to the the source/interfaces folder."/>
		<Dokumentation Revision="2.54" Date="23.01.2018" Author="RamAnd" Company="Sigmatek" Description="Log messages have been standardized for easier maintenance, easier use in any class and to allow spam filtering. Code for the logging functions is now only located in HwControl."/>
		<Dokumentation Revision="2.53" Date="23.05.2017" Author="RamAnd" Company="Sigmatek" Description="A pointer for dynamic parameters has been added to the hardware diagnosis. Added initialisation of the pointer with NIL."/>
		<Dokumentation Revision="2.52" Date="10.05.2016" Author="RamAnd" Company="Sigmatek" Description="Suppressed warning that would occur with target ARM on compiler version 30 or higher."/>
		<Dokumentation Revision="2.51" Date="24.06.2014" Author="LanSte" Company="Sigmatek" Description="Added support for reading hardware diagnosis."/>
		<Dokumentation Revision="2.50" Date="06.12.2013" Author="RamAnd&#13;&#10;LanSte" Company="Sigmatek" Description="Corrected define names for mutex creation (could have lead to redefinition warnings).&#13;&#10;Added Payload Support"/>
		<Dokumentation Revision="2.40" Date="30.08.2013" Author="EisMic" Company="Sigmatek" Description="Added serial number display"/>
		<Dokumentation Revision="2.30" Date="18.07.2013" Author="LanSte&#13;&#10;ZoePat" Company="Sigmatek" Description="Added functions for mutex handling"/>
		<Dokumentation Revision="2.20" Date="07.03.2013" Author="BeiWol&#13;&#10;RamAnd" Company="Sigmatek" Description="Added functionality to use module optional via define DEACTIVATED_LSL as Place value.&#13;&#10;New methods Checksum_8 and Checksum_16 to calculate EEPROM checksums and validate EEPROM content."/>
		<Dokumentation Revision="2.14" Date="18.07.2012" Author="ObeChr" Company="Sigmatek" Description="Implemented time measurement for internal tests in methods UpdateRt, UpdateRtPostScan and UpdateCy"/>
		<Dokumentation Revision="2.13" Date="19.01.2012" Author="ZoePat" Company="Sigmatek" Description="Corrected handling of RequiredError (In some cases it could have happened, that an error has been generated even if the module has been connected)"/>
		<Dokumentation Revision="2.12" Date="13.04.2011" Author="BleErn" Company="Sigmatek" Description="Set Server State to visualized"/>
		<Dokumentation Revision="2.11" Date="02.09.2010" Author="BleErn" Company="Sigmatek" Description="improved comment of client MasterConnect"/>
		<Dokumentation Revision="2.10" Date="22.07.2010" Author="WocPet" Company="Sigmatek" Description="new client &quot;Required&quot; and functionality for required error handling added"/>
		<Dokumentation Revision="2.9" Date="04.03.2010" Author="BleErn" Company="Sigmatek" Description="Changed order of methods"/>
		<Dokumentation Revision="2.8" Date="08.02.2010" Author="BleErn" Company="Sigmatek" Description="New virtual method UpdateRtPostScan&#13;&#10;New method SetUpdateRtPostScan"/>
		<Dokumentation Revision="2.7" Date="15.07.2009" Author="RamAnd" Company="Sigmatek" Description="Added functions for safety and hardwaretree."/>
	</RevDoku>
	<Network Name="HwBaseCDIAS">
		<!-- List of Components in this network -->
		<Components>
			<Object
				Name       = "SerialNoStr"
				GUID       = "{C06D79E3-5127-40D0-B7BE-203D8E66B1AD}"
				Class      = "String"
				Position   = "(300,480)"
				Visualized = "true">
				<Channels>
					<Server Name="Data"/>
					<Client Name="SingleRealloc" Value="1"/>
				</Channels>
			</Object>
		</Components>
		<Comments>
		</Comments>
		<!-- List of Connections in this network -->
		<Connections>
			<Connection Source="this.SerialNoStr" Destination="SerialNoStr.Data"/>
			<Connection Source="this.SerialNo" Destination="SerialNoStr.Data" Vertices="(788,270),(616,570),"/>
		</Connections>
		<!-- Headerfiles -->
		<Options>
		</Options>
	</Network>
</Class>
*)
HwBaseCDIAS : CLASS
  //Servers:
	State 	: SvrChCmd_IO_State;
	SerialNo 	: SvrChCmd_UDINT;
  //Clients:
	MasterConnect 	: CltChCmd_DiasMaster;
	Place 	: CltCh_UDINT;
	Required 	: CltCh_DINT;
	To_StdLib 	: CltChCmd__StdLib;
	TimeBase 	: CltCh_UDINT;
	TimeBaseOffset 	: CltCh_UDINT;
	SerialNoStr 	: CltChCmd_String;
  //Variables:
		Kennung 	: UDINT;			//! <Variable Comment="Modulgroup of modul" Name="Kennung"/>
		Connection 	: DINT;			//! <Variable Comment="0=connected direct on CDIAS&#13;&#10;1=connected via a CIC on DIASBus" Name="Connection"/>
		MasterType 	: UDINT;			//! <Variable Comment="MasterType&#13;&#10;&#13;&#10;0=no DiasMaster&#13;&#10;1=normal Master &#13;&#10;2=intelligent Master (is set after calling the Init() )" Name="MasterType"/>
		IOSegmentByte 	: ^USINT;			//! <Variable Comment="Bytepointer on Modul =&gt; only normal Master (is set after calling the Init() )" Name="IOSegmentByte"/>
		b_VaranAvailable 	: BOOL;
		b_PayloadSupport 	: BOOL;			//! <Variable Comment="TRUE When Payload DOs are supporded by the OS Interface." Name="b_PayloadSupport"/>
		b_DMAactive 	: BOOL;			//! <Variable Comment="TRUE When Payload DOs are supporded by the OS Interface and the FPGA has an DMA Controller." Name="b_DMAactive"/>
		pMultiVaran 	: ^LSL_MULTI_VARAN;
		IOSegmentWord 	: ^UINT;			//! <Variable Comment="Wordpointer on Modul =&gt; only normal Master (is set after calling the Init() )" Name="IOSegmentWord"/>
		p_ObjectPath 	: ^USINT;
		b_initialized 	: BOOL;
		us_EEOk 	: USINT;
		ProfilerCy 	: s_PROFILER_Time;
		ProfilerRt 	: s_PROFILER_Time;
		ProfilerRtPostScan 	: s_PROFILER_Time;
		mt_api 	: ^LSL_MT_TYPE;
		aEEPROMData : ARRAY [0..255] OF USINT;

		b_GotEEPROMValues 	: BOOL;
  //Functions:
	
	FUNCTION HwBaseCDIAS
		VAR_OUTPUT
			ret_code 	: ConfStates;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL Init;
	
	FUNCTION VIRTUAL GLOBAL UpDataCY
		VAR_INPUT
			Handle 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL UpDateRT
		VAR_INPUT
			Handle 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL UpDateRTPostScan
		VAR_INPUT
			Handle 	: UDINT := 0;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL CheckSync
		VAR_OUTPUT
			Sync (AL) 	: USINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetEEState
		VAR_OUTPUT
			State 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetEEData
		VAR_INPUT
			Offset 	: UINT;
		END_VAR
		VAR_OUTPUT
			Data 	: UINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL AddOneChannel
		VAR_INPUT
			thisp 	: ^void;
			RTCY 	: DINT;
			channel 	: DINT;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetCallHandle
		VAR_INPUT
			channel 	: DINT;
		END_VAR
		VAR_OUTPUT
			Handle 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetPlace
		VAR_OUTPUT
			PlaceR 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetConnection
		VAR_OUTPUT
			Connect 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetMasterType
		VAR_OUTPUT
			MasType 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetIOsByte
		VAR_OUTPUT
			IOsByte 	: ^USINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL GetIOsWord
		VAR_OUTPUT
			IOsWord 	: ^UINT;
		END_VAR;
				//! <Function Comment="find path of object in network" Name="GetOwnObjectPath"/>
	FUNCTION GetOwnObjectPath;
				//! <Function Comment="saves this-pointer of object" Name="SetObjectThisp"/>
	FUNCTION SetObjectThisp
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
				//! <Function Comment="returns type of module" Name="GetModuleType"/>
	FUNCTION VIRTUAL GLOBAL GetModuleType
		VAR_OUTPUT
			ui_ModuleType 	: UINT;
		END_VAR;
				//! <Function Comment="Function to intialize TimeMeassurement" Name="InitTimeMeasurement"/>
	FUNCTION InitTimeMeasurement
		VAR_INPUT
			usMode (EAX) 	: DINT;			//! <Variable Comment="Indicates the type of the Profiler:&#13;&#10;&#13;&#10;DMTIME_RT (0) .......... Profiler for UpdateRt-Task&#13;&#10;DMTIME_CY (1) .......... Profiler for UpdateCy-Task&#13;&#10;DMTIME_RTPOSTSCAN (2) .. Profiler for UpdateRtPostScan-Task" Name="InitTimeMeasurement.usMode"/>
		END_VAR;
				//! <Function Comment="Function to start TimeMeassurement" Name="StartTimeMeasurement"/>
	FUNCTION StartTimeMeasurement
		VAR_INPUT
			usMode (EAX) 	: DINT;			//! <Variable Comment="Indicates the type of the Profiler:&#13;&#10;&#13;&#10;DMTIME_RT (0) .......... Profiler for UpdateRt-Task&#13;&#10;DMTIME_CY (1) .......... Profiler for UpdateCy-Task&#13;&#10;DMTIME_RTPOSTSCAN (2) .. Profiler for UpdateRtPostScan-Task" Name="StartTimeMeasurement.usMode"/>
		END_VAR;
				//! <Function Comment="Function to stop TimeMeassurement" Name="StopTimeMeasurement"/>
	FUNCTION StopTimeMeasurement
		VAR_INPUT
			usMode (EAX) 	: DINT;			//! <Variable Comment="Indicates the type of the Profiler:&#13;&#10;&#13;&#10;DMTIME_RT (0) .......... Profiler for UpdateRt-Task&#13;&#10;DMTIME_CY (1) .......... Profiler for UpdateCy-Task&#13;&#10;DMTIME_RTPOSTSCAN (2) .. Profiler for UpdateRtPostScan-Task" Name="StopTimeMeasurement.usMode"/>
		END_VAR;
	
	FUNCTION Checksum_8
		VAR_INPUT
			iptr 	: pVoid;
		END_VAR
		VAR_OUTPUT
			checksum 	: HSINT;
		END_VAR;
	
	FUNCTION Checksum_16
		VAR_INPUT
			iptr 	: pVoid;
		END_VAR
		VAR_OUTPUT
			checksum 	: HINT;
		END_VAR;
				//! <Function Comment="Method to add a read payload data object to varan manager.&#13;&#10;The parameters are passed on to the varan manager via a new inst call.&#13;&#10;" Name="AddRdPayloadDO"/>
	FUNCTION VIRTUAL GLOBAL AddRdPayloadDO
		VAR_INPUT
			ud_dol_type 	: UDINT;			//! <Variable Comment="DOL into witch the DO is to be inserted. &#13;&#10;VARAN_DOL_ASY or VARAN_DOL_ISO" Name="AddRdPayloadDO.ud_dol_type"/>
			p_ud_handle 	: ^UDINT;			//! <Variable Comment="Pointer to variable to set the DO handle.&#13;&#10;Value does not represent a valid address." Name="AddRdPayloadDO.p_ud_handle"/>
			ud_offset_read 	: UDINT;			//! <Variable Comment="Offset of read data within the module. &#13;&#10;(DeviceAddress is not included in this value.)" Name="AddRdPayloadDO.ud_offset_read"/>
			ud_length_read 	: UDINT;			//! <Variable Comment="Length of read data object." Name="AddRdPayloadDO.ud_length_read"/>
			p_ud_data_read 	: ^UDINT;			//! <Variable Comment="The pointer to the read data is written to this address." Name="AddRdPayloadDO.p_ud_data_read"/>
			ud_type 	: UDINT;			//! <Variable Comment="0=control area, 1=memory area" Name="AddRdPayloadDO.ud_type"/>
			ud_priority 	: UDINT := VM_PRIORITY_INVALID;			//! <Variable Comment="Priority of the DO within the DOL. &#13;&#10;1000 highest priority&#13;&#10;9000 lowest priority&#13;&#10;Priority not dividable by 1000 cannot be used outside of the init phase.&#13;&#10;Optional." Name="AddRdPayloadDO.ud_priority"/>
			pp_Enable 	: ^pVoid := nil;			//! <Variable Comment="The address of the enable byte is stored back here. Only used in combination with the varan datamover.&#13;&#10;" Name="AddRdPayloadDO.pp_Enable"/>
			p_ud_DataAddr_read 	: ^HDINT := nil;			//! <Variable Comment="here the used DPRam address of the read data is given back" Name="AddRdPayloadDO.p_ud_DataAddr_read"/>
			ud_WritePayloadType 	: UDINT := 0;			//! <Variable Comment="Changeable DO.&#13;&#10;Set this parameter if the DO length and or offset needs to be changed after creation.&#13;&#10;Optional." Name="AddRdPayloadDO.ud_WritePayloadType"/>
			p_UserDOHandle 	: ^UDINT := NIL;			//! <Variable Comment="Optional Parameter&#13;&#10;Once the VaranDOs are created the DO Handle is saved to the passed address.&#13;&#10;Parameter added to get the Handle for the Payload Move DOs.&#13;&#10;Only used with Varan Datamover." Name="AddRdPayloadDO.p_UserDOHandle"/>
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;			//! <Variable Comment="Value &lt;&gt; 0 equal an error.&#13;&#10;See &#13;&#10;lsl_st_varan.h   // Ergebniscodes&#13;&#10;VaranManager_Base.h // Return Codes of the Control NewInst method&#13;&#10;for errorcodes." Name="AddRdPayloadDO.sd_retval"/>
		END_VAR;
				//! <Function Comment="Method to add a write payload data object to varan manager.&#13;&#10;The parameters are passed on to the varan manager via a new inst call.&#13;&#10;" Name="AddWrPayloadDO"/>
	FUNCTION VIRTUAL GLOBAL AddWrPayloadDO
		VAR_INPUT
			ud_dol_type 	: UDINT;			//! <Variable Comment="DOL into witch the DO is to be inserted. &#13;&#10;VARAN_DOL_ASY or VARAN_DOL_ISO" Name="AddWrPayloadDO.ud_dol_type"/>
			p_ud_handle 	: ^UDINT;			//! <Variable Comment="Pointer to variable to set the DO handle.&#13;&#10;Value does not represent a valid address." Name="AddWrPayloadDO.p_ud_handle"/>
			ud_offset_write 	: UDINT;			//! <Variable Comment="Offset of write data within the module. &#13;&#10;(DeviceAddress is not included in this value.)" Name="AddWrPayloadDO.ud_offset_write"/>
			ud_length_write 	: UDINT;			//! <Variable Comment="Length of write data object." Name="AddWrPayloadDO.ud_length_write"/>
			p_ud_data_write 	: ^UDINT;			//! <Variable Comment="The pointer to the read data is written to this address." Name="AddWrPayloadDO.p_ud_data_write"/>
			ud_type 	: UDINT;			//! <Variable Comment="0=control area, 1=memory area" Name="AddWrPayloadDO.ud_type"/>
			ud_priority 	: UDINT := VM_PRIORITY_INVALID;			//! <Variable Comment="Priority of the DO within the DOL. &#13;&#10;1000 highest priority&#13;&#10;9000 lowest priority&#13;&#10;Priority not dividable by 1000 cannot be used outside of the init phase.&#13;&#10;Optional." Name="AddWrPayloadDO.ud_priority"/>
			pp_Enable 	: ^pVoid := nil;			//! <Variable Comment="The address of the enable byte is stored back here. Only used in combination with the varan datamover." Name="AddWrPayloadDO.pp_Enable"/>
			p_ud_DataAddr_write 	: ^HDINT := nil;			//! <Variable Comment="here the used DPRam address of the write data is given back" Name="AddWrPayloadDO.p_ud_DataAddr_write"/>
			ud_WritePayloadType 	: UDINT := 0;			//! <Variable Comment="Changeable DO.&#13;&#10;Set this parameter if the DO length and or offset needs to be changed after creation.&#13;&#10;Optional." Name="AddWrPayloadDO.ud_WritePayloadType"/>
			p_UserDOHandle 	: ^UDINT := NIL;			//! <Variable Comment="Optional Parameter&#13;&#10;Once the VaranDOs are created the DO Handle is saved to the passed address.&#13;&#10;Parameter added to get the Handle for the Payload Move DOs.&#13;&#10;Only used with Varan Datamover." Name="AddWrPayloadDO.p_UserDOHandle"/>
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;			//! <Variable Comment="Value &lt;&gt; 0 equal an error.&#13;&#10;See &#13;&#10;lsl_st_varan.h   // Ergebniscodes&#13;&#10;VaranManager_Base.h // Return Codes of the Control NewInst method&#13;&#10;for errorcodes." Name="AddWrPayloadDO.sd_retval"/>
		END_VAR;
				//! <Function Comment="Method to add a read/write payload data object to varan manager.&#13;&#10;The parameters are passed on to the varan manager via a new inst call.&#13;&#10;" Name="AddRdWrPayloadDO"/>
	FUNCTION VIRTUAL GLOBAL AddRdWrPayloadDO
		VAR_INPUT
			ud_dol_type 	: UDINT;			//! <Variable Comment="DOL into witch the DO is to be inserted. &#13;&#10;VARAN_DOL_ASY or VARAN_DOL_ISO" Name="AddRdWrPayloadDO.ud_dol_type"/>
			p_ud_handle 	: ^UDINT;			//! <Variable Comment="Pointer to variable to set the DO handle.&#13;&#10;Value does not represent a valid address." Name="AddRdWrPayloadDO.p_ud_handle"/>
			ud_offset_read 	: UDINT;			//! <Variable Comment="Offset of read data within the module. &#13;&#10;(DeviceAddress is not included in this value.)" Name="AddRdWrPayloadDO.ud_offset_read"/>
			ud_length_read 	: UDINT;			//! <Variable Comment="Length of read data object." Name="AddRdWrPayloadDO.ud_length_read"/>
			p_ud_data_read 	: ^UDINT;			//! <Variable Comment="The pointer to the read data is written to this address." Name="AddRdWrPayloadDO.p_ud_data_read"/>
			ud_offset_write 	: UDINT;			//! <Variable Comment="Offset of write data within the module. &#13;&#10;(DeviceAddress is not included in this value.)" Name="AddRdWrPayloadDO.ud_offset_write"/>
			ud_length_write 	: UDINT;			//! <Variable Comment="Length of write data object." Name="AddRdWrPayloadDO.ud_length_write"/>
			p_ud_data_write 	: ^UDINT;			//! <Variable Comment="The pointer to the read data is written to this address." Name="AddRdWrPayloadDO.p_ud_data_write"/>
			ud_type 	: UDINT;			//! <Variable Comment="0=control area, 1=memory area" Name="AddRdWrPayloadDO.ud_type"/>
			ud_priority 	: UDINT := VM_PRIORITY_INVALID;			//! <Variable Comment="Priority of the DO within the DOL. &#13;&#10;1000 highest priority&#13;&#10;9000 lowest priority&#13;&#10;Priority not dividable by 1000 cannot be used outside of the init phase.&#13;&#10;Optional." Name="AddRdWrPayloadDO.ud_priority"/>
			pp_Enable 	: ^pVoid := nil;			//! <Variable Comment="The address of the enable byte is stored back here. Only used in combination with the varan datamover." Name="AddRdWrPayloadDO.pp_Enable"/>
			p_ud_DataAddr_read 	: ^HDINT := nil;			//! <Variable Comment="here the used DPRam address of the read data is given back" Name="AddRdWrPayloadDO.p_ud_DataAddr_read"/>
			p_ud_DataAddr_write 	: ^HDINT := nil;			//! <Variable Comment="here the used DPRam address of the write data is given back" Name="AddRdWrPayloadDO.p_ud_DataAddr_write"/>
			ud_WritePayloadType 	: UDINT := 0;			//! <Variable Comment="Changeable DO.&#13;&#10;Set this parameter if the DO length and or offset needs to be changed after creation.&#13;&#10;Optional." Name="AddRdWrPayloadDO.ud_WritePayloadType"/>
			p_UserDOHandle 	: ^UDINT := NIL;			//! <Variable Comment="Optional Parameter&#13;&#10;Once the VaranDOs are created the DO Handle is saved to the passed address.&#13;&#10;Parameter added to get the Handle for the Payload Move DOs.&#13;&#10;Only used with Varan Datamover." Name="AddRdWrPayloadDO.p_UserDOHandle"/>
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;			//! <Variable Comment="Value &lt;&gt; 0 equal an error.&#13;&#10;See &#13;&#10;lsl_st_varan.h   // Ergebniscodes&#13;&#10;VaranManager_Base.h // Return Codes of the Control NewInst method&#13;&#10;for errorcodes." Name="AddRdWrPayloadDO.sd_retval"/>
		END_VAR;
				//! <Function Comment="Method to Enable/Start a DO&#13;&#10;Can only be used with Varan without Mover." Name="EnableDO"/>
	FUNCTION VIRTUAL GLOBAL EnableDO
		VAR_INPUT
			ud_DOHandle 	: UDINT;
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
				//! <Function Comment="Method to Disable/Stop a DO&#13;&#10;Can only be used with Varan without Mover." Name="DisableDO"/>
	FUNCTION VIRTUAL GLOBAL DisableDO
		VAR_INPUT
			ud_DOHandle 	: UDINT;
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
	
	FUNCTION CreateMutex
		VAR_INPUT
			MutexName 	: ^CHAR;
			pThis 	: ^VirtualBase := nil;
		END_VAR
		VAR_OUTPUT
			pv_RetMutex 	: pVoid;
		END_VAR;
				//! <Function Comment="Method to add a move payload data object to varan manager.&#13;&#10;The parameters are passed on to the varan manager via a new inst call.&#13;&#10;" Name="AddMovePayloadDO"/>
	FUNCTION VIRTUAL GLOBAL AddMovePayloadDO
		VAR_INPUT
			ud_dol_type 	: UDINT;			//! <Variable Comment="DOL into witch the DO is to be inserted. &#13;&#10;VARAN_DOL_ASY or VARAN_DOL_ISO" Name="AddMovePayloadDO.ud_dol_type"/>
			p_ud_handle 	: ^UDINT;			//! <Variable Comment="Pointer to variable to set the DO handle.&#13;&#10;Value does not represent a valid address." Name="AddMovePayloadDO.p_ud_handle"/>
			ud_SourceReadDOHandle 	: UDINT;			//! <Variable Comment="Handle of the source DO.&#13;&#10;" Name="AddMovePayloadDO.ud_SourceReadDOHandle"/>
			ud_SourceReadOffset 	: UDINT;			//! <Variable Comment="Offset within the source DO from where to copy the data.&#13;&#10;This offset + the number of bytes to be copied must not exceed the size of the source DO." Name="AddMovePayloadDO.ud_SourceReadOffset"/>
			ud_DestinationWriteDOHandle 	: UDINT;			//! <Variable Comment="Handle of the destination DO.&#13;&#10;" Name="AddMovePayloadDO.ud_DestinationWriteDOHandle"/>
			ud_DestinationWriteOffset 	: UDINT;			//! <Variable Comment="Offset within the destination DO from where to copy the data.&#13;&#10;This offset + the number of bytes to be copied must not exceed the size of the source DO." Name="AddMovePayloadDO.ud_DestinationWriteOffset"/>
			ud_LengthMove 	: UDINT;			//! <Variable Comment="Number of bytes to be copied." Name="AddMovePayloadDO.ud_LengthMove"/>
			ud_Priority 	: UDINT;			//! <Variable Comment="Priority of the DO within the DOL. &#13;&#10;1000 highest priority&#13;&#10;9000 lowest priority&#13;&#10;Priority not dividable by 1000 cannot be used outside of the init phase.&#13;&#10;This value must be set in correct relation with the source and destination DO." Name="AddMovePayloadDO.ud_Priority"/>
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;			//! <Variable Comment="Value &lt;&gt; 0 equal an error.&#13;&#10;See &#13;&#10;lsl_st_varan.h   // Ergebniscodes&#13;&#10;VaranManager_Base.h // Return Codes of the Control NewInst method&#13;&#10;for errorcodes." Name="AddMovePayloadDO.sd_retval"/>
		END_VAR;
				//! <Function Comment="Method to Change the offset and lengths of a  DO&#13;&#10;Can only be used with Varan without Mover.&#13;&#10;Only Supported with Payload OS" Name="ChangeDOLengthOffset"/>
	FUNCTION VIRTUAL GLOBAL ChangeDOLengthOffset
		VAR_INPUT
			ud_DOHandle 	: UDINT;			//! <Variable Comment="Handle of the DO" Name="ChangeDOLengthOffset.ud_DOHandle"/>
			ud_offset_read 	: UDINT := VM_DO_PROPERTY_INVALID;			//! <Variable Comment="New read offset" Name="ChangeDOLengthOffset.ud_offset_read"/>
			ud_length_read 	: UDINT := VM_DO_PROPERTY_INVALID;			//! <Variable Comment="New read length" Name="ChangeDOLengthOffset.ud_length_read"/>
			ud_offset_write 	: UDINT := VM_DO_PROPERTY_INVALID;			//! <Variable Comment="New write offset" Name="ChangeDOLengthOffset.ud_offset_write"/>
			ud_length_write 	: UDINT := VM_DO_PROPERTY_INVALID;			//! <Variable Comment="New write length" Name="ChangeDOLengthOffset.ud_length_write"/>
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
				//! <Function Comment="Method to Change the offset and lengths of a Move DO&#13;&#10;Only Supported with Payload OS" Name="ChangeMovDOLengthOffset"/>
	FUNCTION VIRTUAL GLOBAL ChangeMovDOLengthOffset
		VAR_INPUT
			ud_MovDOHandle 	: UDINT;
			ud_SourceReadDOHandle 	: UDINT := VM_DO_PROPERTY_INVALID;
			ud_SourceReadOffset 	: UDINT := VM_DO_PROPERTY_INVALID;
			ud_DestinationWriteDOHandle 	: UDINT := VM_DO_PROPERTY_INVALID;
			ud_DestinationWriteOffset 	: UDINT := VM_DO_PROPERTY_INVALID;
			ud_LengthMove 	: UDINT := VM_DO_PROPERTY_INVALID;
		END_VAR
		VAR_OUTPUT
			sd_retval 	: DINT;
		END_VAR;
	
	FUNCTION MutexStart
		VAR_INPUT
			pMutex 	: pVoid;
		END_VAR;
	
	FUNCTION MutexStop
		VAR_INPUT
			pMutex 	: pVoid;
		END_VAR;
				//! <Function Comment="This method returns the device id of the module.&#13;&#10;Has to be overwritten in every module." Name="GetVarianteValue"/>
	FUNCTION VIRTUAL GetVarianteValue
		VAR_OUTPUT
			output 	: UDINT;
		END_VAR;
				//! <Function Comment="This method returns the variante/kennung of the module.&#13;&#10;Has to be overwritten in every module." Name="GetKennung"/>
	FUNCTION VIRTUAL GetKennung
		VAR_OUTPUT
			output 	: UDINT;
		END_VAR;
				//! <Function Comment="Method simulates a SingleRun DO by En/Disabling the DO depending on p_b_DOIsRunning.&#13;&#10;To use this method t_SingleRunState^.StartRequest must be set where the singlerun is required&#13;&#10;and the Method must be called at the end of the task where the DO is used. (UpdatyCy, UpdateRt...)&#13;&#10;Only works with Varan DO (No with Mover)&#13;&#10;Method was made for Payload DO. Should work with standard DO&apos;s as well.&#13;&#10;(EnableDO, DisableDO does not equal ResetDO!)" Name="SingleRunSM"/>
	FUNCTION VIRTUAL GLOBAL SingleRunSM
		VAR_INPUT
			p_DOhandle 	: ^UDINT;
			p_b_DOIsRunning 	: ^t_SingleRunState;
		END_VAR;
	
	FUNCTION VIRTUAL GetSerialNo;
				//! <Function Comment="This method returns the firmware version of the module.&#13;&#10;Has to be overwritten in every module which has a FW." Name="GetFWVersion"/>
	FUNCTION VIRTUAL GetFWVersion
		VAR_INPUT
			pData 	: ^CHAR;
			length 	: DINT;
		END_VAR;
	
	FUNCTION VIRTUAL LogError
		VAR_INPUT
			e_msg 	: ^CHAR;
		END_VAR;
	
	FUNCTION VIRTUAL LogValue
		VAR_INPUT
			pString 	: ^CHAR;
			Value 	: UDINT;
			Value2 	: UDINT := 16#FFFFFFFF;
			Value3 	: UDINT := 16#FFFFFFFF;
		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 SerialNo::Read
		VAR_OUTPUT
			output (EAX) 	: UDINT;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL SerialNo::Write
		VAR_INPUT
			input (EAX) 	: UDINT;
		END_VAR
		VAR_OUTPUT
			result (EAX) 	: UDINT;
		END_VAR;
  //Tables:
	FUNCTION @STD
		VAR_OUTPUT
			ret_code	: CONFSTATES;
		END_VAR;
	FUNCTION GLOBAL TAB @CT_;
END_CLASS;

#pragma using String
#pragma usingLtd _StdLib
#pragma usingLtd DiasMaster


//}}LSL_DECLARATION


FUNCTION GLOBAL TAB HwBaseCDIAS::@CT_
0$UINT,
2#0100000000000000$UINT, //TY_HWBASECDIAS
2$UINT, 56$UINT, (SIZEOF(::HwBaseCDIAS))$UINT, 
2$UINT, 7$UINT, 0$UINT, 
TO_UDINT(1800499398), "HwBaseCDIAS", //Class
TO_UDINT(0), 0, 0$UINT, 0$UINT, //Baseclass
//Servers:
(::HwBaseCDIAS.State.pMeth)$UINT, _CH_CMD$UINT, 2#0000000000000000$UINT, TO_UDINT(1422331979), "State", 
(::HwBaseCDIAS.SerialNo.pMeth)$UINT, _CH_SVR_OBJ$UINT, 2#0000000001000000$UINT, TO_UDINT(1856804640), "SerialNo", 
//Clients:
(::HwBaseCDIAS.MasterConnect.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000010$UINT, TO_UDINT(1515240279), "MasterConnect", TO_UDINT(2647887450), "DiasMaster", 2$UINT, 33$UINT, 
(::HwBaseCDIAS.Place.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000010$UINT, TO_UDINT(2202636669), "Place", 
(::HwBaseCDIAS.Required.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(648558917), "Required", 
(::HwBaseCDIAS.To_StdLib.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000000$UINT, TO_UDINT(2139173287), "To_StdLib", TO_UDINT(3689364044), "_StdLib", 2$UINT, 0$UINT, 
(::HwBaseCDIAS.TimeBase.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(2439844029), "TimeBase", 
(::HwBaseCDIAS.TimeBaseOffset.pCh)$UINT, _CH_CLT_DATA$UINT, 2#0000000000000000$UINT, TO_UDINT(1524328294), "TimeBaseOffset", 
(::HwBaseCDIAS.SerialNoStr.pCh)$UINT, _CH_CLT_OBJ$UINT, 2#0000000000000010$UINT, TO_UDINT(321148131), "SerialNoStr", TO_UDINT(1850111279), "String", 1$UINT, 11$UINT, 
END_FUNCTION


#define USER_CNT_HwBaseCDIAS 29

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#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;
	_memcpy((#vmt.CmdTable)$^USINT, SerialNo.pMeth, SIZEOF(CMDMETH));
	vmt.CmdTable.nCmds		:= nSTDCMD;
	vmt.CmdTable.Read		:= #SerialNo::Read();
	vmt.CmdTable.Write		:= #SerialNo::Write();
	SerialNo.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF SerialNo.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ret_code	:= HwBaseCDIAS();

END_FUNCTION

//{{LSL_IMPLEMENTATION
(*******************************************************************************
*
*	Baseclass for CDias - Moduls
*	Created: Sigmatek / 2003
*	Changes:
*
*
*   FOR NEWER CHANGES SEE REVISION DOCUMENTATION IN CLASS PROPERTIES
*
*
*		2.5 => 2.6	/	20.04.2007	/	Mark:	//#SR000
*			- [DB 563]: bug in Function AddOneChannel with varan in lasal 2
*		1.4 => 2.5	/	16.03.2007	/	no Mark
*			- [DB 421]: now class is ready for plug & play over CIV
*		1.3 => 1.4 / 04.11.2005 / Mark: //ws001 
*			object names of trace messages are now ascertained by the loader
*		0.3 => 1.3 / 23.12.2004 / no Mark / ws
*			compatibility with Lasal Class 2
*			removed visible flags from internal servers
*		0.2 => 0.3 / 01.06.2004 / Mark: // #BS001
*			Added Function CheckSync()
*		0.1 => 0.2 / 29.01.2004 / Mark: // #BS000
*			Changed function from GetDiasIosegment() to GetCDiasPlaceIoSegment()
*			If you get a compilererror here you have to update the DiasMasterC and CIC class
*
*******************************************************************************)

VAR_PRIVATE
	
  // For Typelabel
  a_SerialNo			: ARRAY[0..31] OF CHAR;
  a_HWTEntryStr   : ARRAY[0.. VARAN_MAX_DEPTH+1] OF CHAR;  // VaranMaxDepth +1 because length is 2 byte long
  a_FWVersion     : ARRAY[0..43] OF CHAR;
END_VAR
    
  
#PRAGMA warning (disable:73)
FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::Init
  VAR 
      KennEE 			      : USINT;
    //pObj			: ^OBJ;	//ws001
    sz_name	            : array[ 0..255 ] of char;	//ws001
    
    //LanSte 12.04.2013 13:35
    // For NewInst command 
    _Para 	            : CmdStruct;
    _Result 	          : Results;

  END_VAR

  Place := Place.Read();

  // we must know if we are connected with a CIC(DIAS) or if we are on the C-DIAS Bus(parallel)
  IF Connection <> -1 THEN
    Connection := MasterConnect.GetConnection();
  END_IF;
  MasterType := MasterConnect.GetMasterType();	

  b_VaranAvailable := MasterConnect.IsVaranAvailable() <> 0;		//#SR000

  //only in our first init
  if b_initialized = false then
    Required := Required.Read();
    if Required then
      Required := 1;
      MasterConnect.AddRequiredObject(thisp:=this);
    end_if;  
    
    //LanSte 12.04.2013 13:33 Check for Varan Payload Support
    if b_VaranAvailable then      
      
      // Check if Payload is supported by the VM
      _Para.uiCmd := VM_CMD_IS_PAYLOAD_SUPPORTED;
      _Result.aData[0]$BOOL := 0;   // Set to 0 in case the NewInst Method is not Implemented
      
      if MasterConnect.NewInst(#_Para, #_Result) = READY then
        b_PayloadSupport := _Result.aData[0]$BOOL;
      end_if;

      // Check if the FPGA has (and uses) an DMA Controller
      if b_PayloadSupport then    
        _Para.uiCmd := VM_CMD_IS_DMA_ACTIVE;
        _Result.aData[0]$BOOL := 0;   // Set to 0 in case the NewInst Method is not Implemented
        
        if MasterConnect.NewInst(#_Para, #_Result) = READY then
          b_DMAactive := _Result.aData[0]$BOOL;   
        end_if;
      end_if;
      
      if b_PayloadSupport then
        // Get the pointer for the Payload inteface
        // Needed to Enable/Disable the DOs
        if ( OS_CILGet( INTERFACE_MULTIVARANMANAGER, #pMultiVaran ) <> SYS_ERR_NONE) then
          // Should be impossible b_PayloadSupport is only set when this interface was already called succesfully
          TRACE( "HwBaseCDIAS::Init No Multi_Varan Interface found" );        
#ifdef HWK_SHOW_PRAGMA_MESSAGES             
          #pragma message("LanSte 14.05.2013 17:58 \ Error Code?")
#endif
          
          // State := _NoVaranInterface;
          return;          
        end_if;
      end_if;
    end_if;

  end_if;

  b_initialized := true;  

// make the right pointer into the hardware
// 1. Can be direct on the C-DIAS Bus
// 2. or with a CIC connected to us
// this 2 things gives 2 complete different pointers 
#IFNDEF CICXXX_Compress // #BS000
  if Connection = 1 then
    // If you get a compilererror here you have to update the DiasMasterC and CICXXX_IM class
    IOSegmentByte := MasterConnect.GetCDiasPlaceIoSegment(Place);			// #BS000	 
    IOSegmentWord := MasterConnect.GetCDiasPlaceIoSegment(Place)+16#4000;	// #BS000	 
  else
    IOSegmentByte := MasterConnect.GetCDiasPlaceIoSegment(Place);			// #BS000	 
    IOSegmentWord := (MasterConnect.GetCDiasPlaceIoSegment(Place))$^UINT;		// #BS000	
  end_if;	
#ELSE
  if Connection = 1 then
    IOSegmentByte := MasterConnect.GetDiasIosegment()+(Place*16#100);		 
    IOSegmentWord := MasterConnect.GetDiasIosegment()+16#4000+(Place*16#100);		 
  else
    IOSegmentByte := MasterConnect.GetCDiasIosegment()+(Place*16#100);
    IOSegmentWord := MasterConnect.GetCDiasIosegment()+(Place*16#100);
  end_if;	
#ENDIF

  // read from EE_PROM (so interface must be ready !!)
  if MasterConnect.GetEEState() then
    if Place <= 7 then 

      if Connection = 1 then
        Kennung := MasterConnect.GetKennung(Place);
      else
        if MasterConnect.I2CReadOneByte(AdressCDIAS:=(Place*16#100)$UINT+2, pData:=#KennEE) then
          Kennung := 16#FF;
        else
          Kennung := KennEE;
        end_if;		
      end_if; 
    else
      IF Connection <> -1 THEN
        Connection := -1;
        TRACE("On CDIAS-Moduls only racknumbers have to be set to client place (0..7) !!! Error in object :");
        //ws001
        _GetObjName( this, #sz_name[ 0 ] );
        trace( #sz_name[ 0 ] );
        //pObj := LSL_GetHdr(this);
        //TRACE( (#pObj^.pObjDsc^.SymName)$^CHAR ); // => give out the objectname
        // /ws001

        Kennung :=16#FF;
      END_IF;
    end_if;
  else 
    Kennung := 16#ff;
  end_if;	   

  // Only Read Serial No if Kennung was successfully read. Otherwise we get an EPROM Error at the CIV even if the module is not required
  if Kennung & Kennung <> 16#ff then
    GetSerialNo();
  end_if;

  //get position in object network
  GetOwnObjectPath(); 

  //save this-pointer of object in reference to the object path
  SetObjectThisp();
  
END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::Init


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::UpDataCY
  VAR_INPUT
    Handle		: UDINT;
  END_VAR


END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::UpDataCY


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetEEState
  VAR_OUTPUT
    State		: DINT;
  END_VAR

	state := 1;  // no EEprom in BASE

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetEEState


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::AddOneChannel
  VAR_INPUT
    thisp		: ^void;
    RTCY		: DINT;
    channel		: DINT;
  END_VAR
  VAR_OUTPUT
    Handle		: DINT;
  END_VAR

	handle :=-1;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::AddOneChannel


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetCallHandle
  VAR_INPUT
    channel		: DINT;
  END_VAR
  VAR_OUTPUT
    Handle		: DINT;
  END_VAR

	Handle := -1;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetCallHandle


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::UpDateRT
VAR_INPUT
	Handle		: UDINT;
END_VAR

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::UpDateRT


FUNCTION  HwBaseCDIAS::HwBaseCDIAS
  VAR_OUTPUT
    ret_code		: CONFSTATES;
  END_VAR

#ifdef HWC_LogInit
  HWC_LogInit();
#endif

	state.uiIO_Flags :=16#ffff;
  Kennung := 16#ff;					//#SR000
	ret_code	:= C_OK;
  
END_FUNCTION //  HwBaseCDIAS::HwBaseCDIAS


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetEEData
  VAR_INPUT
    Offset		: UINT;
  END_VAR
  VAR_OUTPUT
    Data		: UINT;
  END_VAR

  Data :=16#FFFF;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetEEData


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetPlace
  VAR_OUTPUT
    PlaceR		: UDINT;
  END_VAR

	PlaceR :=Place.read();

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetPlace


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetMasterType
  VAR_OUTPUT
    MasType		: DINT;
  END_VAR

	MasType:=MasterType$DINT;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetMasterType


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetIOsByte
  VAR_OUTPUT
    IOsByte		: ^USINT;
  END_VAR

	IOsByte :=IOSegmentByte;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetIOsByte


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetIOsWord
  VAR_OUTPUT
    IOsWord		: ^UINT;
  END_VAR

	IOsWord := IOSegmentWord;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetIOsWord


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetConnection
  VAR_OUTPUT
    Connect		: DINT;
  END_VAR
  
  Connect := Connection;
    
END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::GetConnection


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::CheckSync // #BS001
  VAR_OUTPUT
    Sync(AL)		: USINT;
  END_VAR

	Sync := 0;

END_FUNCTION //VIRTUAL GLOBAL HwBaseCDIAS::CheckSync
#PRAGMA warning (default:73)


FUNCTION HwBaseCDIAS::GetOwnObjectPath
  VAR
    sd_retval : DINT;
  END_VAR

  //get position of connected class
  if ( p_ObjectPath = NIL ) then

    //alloc memory to get position
    p_ObjectPath := ( To_StdLib.Malloc( size := VARAN_MAX_DEPTH + 1 ) )$^USINT;

    //look if an error occurs
    if ( p_ObjectPath = NIL ) then
      return;
    end_if;

    //set length to 0
    p_ObjectPath^ := 0;		

    //get position
    sd_retval     := MasterConnect.GetObjectPath( p_us_ObjectPath := p_ObjectPath );
	
    //look if an error occurs and check length
    if ( ( sd_retval <> 0 ) | ( p_ObjectPath^ >= VARAN_MAX_DEPTH ) ) then
      p_ObjectPath :=	( To_StdLib.ReAlloc	( mptr		:= p_ObjectPath
                                          , newsize	:= 1
                                          ) 
                      )$^USINT;
      return;
    end_if;

    //class is connected to DiasMasterC
    if ( p_ObjectPath^ = 1 ) then
      p_ObjectPath^ := 2;
      ( p_ObjectPath + 2 )^ := HWT_ESCAPE_CDIAS;
    end_if;
    
    //alloc memory for position pointer and add one byte for place
    p_ObjectPath :=	( To_StdLib.ReAlloc	( mptr		:= p_ObjectPath
                                        , newsize	:= p_ObjectPath^ + 2
                                        ) 
                    )$^USINT;

    //look if an error occurs
    if ( p_ObjectPath = NIL ) then
      return;
    end_if;

    //increase length
    p_ObjectPath^ += 1;
    
    //add place
    ( p_ObjectPath + p_ObjectPath^ )^ := TO_USINT( Place );
    
  end_if;

END_FUNCTION


FUNCTION HwBaseCDIAS::SetObjectThisp
	VAR_OUTPUT
		sd_retval 	: DINT;
	END_VAR

  sd_retval := MasterConnect.SetObjectThisp( p_us_ObjectPath := p_ObjectPath
                                           , ud_thisp        := this$UDINT
                                           );

END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::GetModuleType
	VAR_OUTPUT
		ui_ModuleType 	: UINT;
	END_VAR

  ui_ModuleType := 0;
  
END_FUNCTION

//BLEERN001 start
#pragma warning(disable: 73 )
FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::UpDateRTPostScan
	VAR_INPUT
		Handle 	: UDINT;
	END_VAR

END_FUNCTION
#pragma warning(default: 73 )
//BLEERN001 end


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::State::NewInst
	VAR_INPUT
		pPara 	    : ^CmdStruct;
		pResult 	  : ^Results;
	END_VAR
	VAR_OUTPUT
		ret_code 	  : IprStates;
	END_VAR
  VAR
  	ptmpStr     : ^CHAR;
    ud_StrSize  : UDINT;
    us_temp     : USINT;    
  END_VAR
  
  ptmpStr     := NIL;
  ud_StrSize  := 0;
  us_temp     := 0;  


  ret_code := ERROR;

  CASE pPara^.uiCmd OF
//*****************************************************************************************************************************      
    DM_CHECK_REQUIRED_ERROR :
    
      ret_code := READY;
      
      // if it's not optional (mandatory) and the module could not be found and the eeprom data are invalid (module is actually not connected if used via VARAN; always zero if used on CDIAS)
      if (Place <> DEACTIVATED_LSL) & ((State$BINT and 2#1100000000000011) <> 0) & (us_EEOk = 0) then
        ret_code := ERROR;
        if pResult <> NIL then
          pResult^.aData[0] := Place$USINT;
          pResult^.aData[1] := CDIAS_MODULE;
        end_if;
      end_if;
//*****************************************************************************************************************************      
    CMD_GET_HARDWARE_TREE_ENTRY :
      
      //Set Errors
      ret_code := ERROR;
      pResult^.aData$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_ERROR;
      pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry := NIL;
      
      // Don't check for State = _ClassOk, method will be used to compare Real HWT with placed classes        
        
      if p_ObjectPath then
        //Copy Length of p_objectpath (is on 1st byte) on first byte of our array, length is 2 byte so set the 2nd byte manual
        a_HWTEntryStr[0] := p_ObjectPath^$USINT;
        a_HWTEntryStr[1] := 0;
        
        //a_HWTEntryStr + 2 because first 2 bytes are lenght, ObjectPath 1st byte is length, copy as long as the object path is
        _memcpy(ptr1:=#a_HWTEntryStr+2, ptr2:=p_ObjectPath+1, cntr:=a_HWTEntryStr[0]);   
        
        //Return Hardware Tree Entry and set return codes
        pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry := #a_HWTEntryStr[0];
        ret_code := READY;
        pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.retcode := _HWC_RETVAL_OK_HWTSTR_RETURNED;
      
        // Compare Module string with passed string
        if pPara^.aPara[0]$t_HWCGetHardwareDiagnosisIn.pStr_HardewareTreeEntry then 
        
          if pPara^.aPara[0]$t_HWCGetHardwareDiagnosisIn.pStr_HardewareTreeEntry$^USINT^ =
             pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry$^USINT^ then // Compare Length
             
            if _memcmp( ptr1:= pPara^.aPara[0]$t_HWCGetHardwareDiagnosisIn.pStr_HardewareTreeEntry // Compare Data 
                      , ptr2:= pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry
                      , cntr:= pResult^.aData[0]$t_HWCGetHardwareTreeEntryOut.pStr_NextHardewareTreeEntry$^USINT^ + 2) = 0 then  // + 2 for 2 Byte Length
                      
              pResult^.aData$t_HWCGetHardwareTreeEntryOut.retcode :=  _HWC_RETVAL_OK_MODULE_FOUND; 
            end_if;
          end_if;
        end_if;
        
      end_if;      
      
//*****************************************************************************************************************************      
    CMD_GET_HARDWARE_DIAGNOSIS :
      //Set Errors
      ret_code := ERROR;
      pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.retcode           := _HWC_RETVAL_ERROR_CLASS_NOT_ONLINE;
      
      //Return State and Device ID and Kennung of placed module --------------------------------
      if State.uiIO_Flags.WrongHW = 1 then
        pResult^.aData$t_HWCGetHardwareDiagnosisOut.ClassState := _WrongHardware;
        pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.retcode := _HWC_RETVAL_ERROR_WRONG_HARDWARE;
      elsif State.uiIO_Flags.NoHW = 1 then
        pResult^.aData$t_HWCGetHardwareDiagnosisOut.ClassState := _NoHardware;
        pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.retcode := _HWC_RETVAL_ERROR_NO_HARDWARE;
      elsif State.uiIO_Flags.NoCalibration = 1 then
        pResult^.aData$t_HWCGetHardwareDiagnosisOut.ClassState := _NoCalibDataFound;
        pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.retcode := _HWC_RETVAL_ERROR_NO_CALIB_DATA_FOUND;        
      end_if;

      pResult^.aData$t_HWCGetHardwareDiagnosisOut.ud_DeviceID := GetKennung();
      pResult^.aData$t_HWCGetHardwareDiagnosisOut.ud_Variante := GetVarianteValue();
      //-----------------------------------------------------------------------------------------
      
      // Only respond if the class is online
      if State.uiIO_Flags = 0 then    
        pResult^.aData$t_HWCGetHardwareDiagnosisOut.ClassState := _ClassOk;
        ptmpStr := pPara^.aPara[0]$t_HWCGetHardwareDiagnosisIn.pStr_HardewareTreeEntry;
        
        // Check if position pointers strings are valid
        if ptmpStr & p_ObjectPath then
          
          // Length is 2 byte for ptmpStr and 1 byte for p_ObjectPath
          if (ptmpStr)$^UINT^ > 0 & (ptmpStr)$^UINT^ = (p_ObjectPath)$^USINT^ then // Check if length if positionstring is valid and equal
          
            if _memcmp(ptr1:=ptmpStr+2, ptr2:=p_ObjectPath+1, cntr:= (ptmpStr)$^UINT^) = 0 then  // Compare strings , 2 bytes length for ptmpStr, 1 byte length for p_ObjectPath
              
              
              ret_code := READY;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.retcode           := _HWC_RETVAL_OK;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pStr_DeviceName   := NIL;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_DeviceID       := Kennung;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pStr_VendorName   := NIL;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_VendorID       := 0;
              
              // Get Serialno -----------------------------------------------------------------------------------------
              ud_StrSize := SerialNoStr.GetLength() ;              
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pStr_SerialNo     := NIL;
              
              if ud_StrSize then

                if (ud_StrSize < sizeof(a_SerialNo)) then // < to account for 0 termination
                  // Copy complete string
                  SerialNoStr.GetDataAt(pData:=#a_SerialNo[0], udSize:=ud_StrSize, udAt:=0);
                  a_SerialNo[ud_StrSize] := 0; // 0 termination
                else
                  // Copy part string
                  SerialNoStr.GetDataAt(pData:=#a_SerialNo[0], udSize:=sizeof(a_SerialNo)-1, udAt:=0);
                  a_SerialNo[sizeof(a_SerialNo)-1] := 0; // 0 termination                
                end_if; 
                pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pStr_SerialNo     := #a_SerialNo[0];                
              end_if;   
              // ----------------------------------------------------------------------------------------------------------

              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pStr_OrderingNo   := NIL;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_LicenseNo      := 0;
              
              // Get Hardwareversion --------------------------------------------------------------------------------------
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.hd_HWVersion := 0; 
              if MasterConnect.I2CReadOneByte(AdressCDIAS:=(Place*16#100)$UINT+CDIAS_EEPROM_OFFSET_HWVERSION, pData:=#us_temp) = 0 then
                pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.hd_HWVersion := us_temp;                
              end_if;             
              
              // Get Variante --------------------------------------------------------------------------------------
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_Variante := 0; 
              if MasterConnect.I2CReadOneByte(AdressCDIAS:=(Place*16#100)$UINT+CDIAS_EEPROM_OFFSET_VARIANTE, pData:=#us_temp) = 0 then
                pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_Variante := us_temp;                
              end_if;      
              
              
              // Get FPGA Version -----------------------------------------------------------------------------------------
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.hd_FPGAVersion := 0;
              
              // Check EEPROM if module has an FPGA
              if MasterConnect.I2CReadOneByte(AdressCDIAS:=(Place*16#100)$UINT+CDIAS_EEPROM_OFFSET_FPGA, pData:=#us_temp) = 0 then 
                
                if us_temp <> 0 & us_temp <> 16#ff then
                  // Module has FPGA
                  
                  if MasterConnect.RdDO( ud_address := (Place*16#100) + CDIAS_OFFSET_FPGA_VERSION
                                       , ud_length  := sizeof(us_temp)
                                       , p_ud_data  := #us_temp$^UDINT
                                       , ud_type    := 1) = 0 then
                    
                    pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.hd_FPGAVersion := us_temp;
                  end_if;
                
                end_if;

              end_if;
  
              // FW Version --------------------------------------------------------------------------------------------        
              GetFWVersion(pData:=#a_FWVersion[0],sizeof(a_FWVersion));
              pResult^.aData$t_HWCGetHardwareDiagnosisOut.pStr_FWVersion := #a_FWVersion[0];
              
              // -----------------------------------------------------------------------------------------------------------
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_Place          := Place;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_reserved_size  := 0;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pud_reserved      := NIL;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.ud_user_size      := 0;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.pud_user          := NIL;
              pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.p_DynExtList      := NIL;
                    
            end_if;

          end_if;

        end_if; 
//      else
//        pResult^.aData[0]$t_HWCGetHardwareDiagnosisOut.retcode           := _HWC_RETVAL_ERROR_CLASS_NOT_ONLINE;
      end_if;
//*****************************************************************************************************************************      
	END_CASE;

END_FUNCTION

#pragma warning(disable:74)
#pragma warning(disable:73)
FUNCTION HwBaseCDIAS::InitTimeMeasurement
	VAR_INPUT
		usMode (EAX) 	: DINT;
	END_VAR
  
#ifdef DM_Profiler
  VAR
  	tmpProfiler : ^s_PROFILER_Time;
  END_VAR

  case usMode of
 
    //-----------------------------------------------------------
    
    DMTIME_RT:
      tmpProfiler := #ProfilerRt;
      
    //-----------------------------------------------------------
    
    DMTIME_CY:
      tmpProfiler := #ProfilerCy;
      
    //-----------------------------------------------------------
    
    DMTIME_RTPOSTSCAN:
      tmpProfiler := #ProfilerRtPostScan;
      
    //-----------------------------------------------------------
    
  end_case;

  tmpProfiler^.sum 	:= 0;
  tmpProfiler^.run 	:= 0;
  tmpProfiler^._max := 0;
  tmpProfiler^._min := 16#ffffffff;
  tmpProfiler^.init := OS_readmicrosec();
  
#endif

END_FUNCTION


FUNCTION HwBaseCDIAS::StartTimeMeasurement
	VAR_INPUT
		usMode (EAX) 	: DINT;
	END_VAR
  
#ifdef DM_Profiler
  VAR
  	tmpProfiler : ^s_PROFILER_Time;
  END_VAR

  case usMode of
 
    //-----------------------------------------------------------
    
    DMTIME_RT:
      tmpProfiler := #ProfilerRt;
      
    //-----------------------------------------------------------
    
    DMTIME_CY:
      tmpProfiler := #ProfilerCy;
      
    //-----------------------------------------------------------
    
    DMTIME_RTPOSTSCAN:
      tmpProfiler := #ProfilerRtPostScan;
      
    //-----------------------------------------------------------
    
  end_case;
  
  tmpProfiler^.start := OS_ReadMicroSec();
  if ( ( tmpProfiler^.start - tmpProfiler^.init ) > DM_ProfilerDelay ) then
    tmpProfiler^.initfl := 0;
  else
    tmpProfiler^.initfl := 1;
  end_if;
#endif

END_FUNCTION


FUNCTION HwBaseCDIAS::StopTimeMeasurement
	VAR_INPUT
		usMode (EAX) 	: DINT;
	END_VAR
  
#ifdef DM_Profiler
  VAR
  	tmpProfiler : ^s_PROFILER_Time;
  END_VAR

  case usMode of
 
    //-----------------------------------------------------------
    
    DMTIME_RT:
      tmpProfiler := #ProfilerRt;
      
    //-----------------------------------------------------------
    
    DMTIME_CY:
      tmpProfiler := #ProfilerCy;
      
    //-----------------------------------------------------------
    
    DMTIME_RTPOSTSCAN:
      tmpProfiler := #ProfilerRtPostScan;
      
    //-----------------------------------------------------------
    
  end_case;

  if ( tmpProfiler^.initfl = 0 ) then

    tmpProfiler^.stop := OS_ReadMicroSec();
    tmpProfiler^.diff := tmpProfiler^.stop - tmpProfiler^.start - DM_CPUconstant;
    tmpProfiler^.sum += tmpProfiler^.diff;
    tmpProfiler^.run += 1;

    if ( tmpProfiler^.diff < tmpProfiler^._min ) then
      tmpProfiler^._min := tmpProfiler^.diff;
    end_if;

    if ( tmpProfiler^.diff > tmpProfiler^._max ) then
      tmpProfiler^._max := tmpProfiler^.diff;
    end_if;

    tmpProfiler^.avg := tmpProfiler^.sum * 100 / tmpProfiler^.run;

  end_if;
#endif

END_FUNCTION
#pragma warning(default:74)
#pragma warning(default:73)


FUNCTION HwBaseCDIAS::Checksum_8
	VAR_INPUT
		iptr 	    : pVoid;
	END_VAR
	VAR_OUTPUT
		checksum 	: HSINT;
	END_VAR
  VAR
    iI		    : USINT;
    chk		    : UINT;
  END_VAR
  
  chk	:= 16#FF;
  for iI:=1 to 5 do
    chk *= 2;
    if chk > 16#FF then
      chk += 2;
    end_if;
    chk := ((chk + (iptr+iI)^$USINT) and 16#FF)$USINT; 
  end_for;
  checksum	:= chk$USINT;
  
END_FUNCTION


FUNCTION HwBaseCDIAS::Checksum_16
	VAR_INPUT
		iptr 	      : pVoid;
	END_VAR
	VAR_OUTPUT
		checksum 	  : HINT;
	END_VAR
  VAR
    iI		      : USINT;
    chk		      : UDINT;
  END_VAR
	
  chk	:= 16#FFFF;
  
  // Safety check if the datalength to be checked is smaller than the Maximum EEProm size (16#FF byte)
  if ((iptr+4)^$UINT + 2) > 16#7F then
    checksum := 16#FFFF;
    return;
  end_if;
  
  for iI:=1 to (iptr+4)^$UINT + 2 do
    chk *= 2;
    if chk > 16#FFFF then
      chk += 2;
    end_if;
    chk := ((chk + (iptr+iI*2)^$UINT) and 16#FFFF)$UINT;
  end_for;
  checksum	:= chk$UINT;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::AddRdPayloadDO
	VAR_INPUT
		ud_dol_type 	          : UDINT;
		p_ud_handle 	          : ^UDINT;
		ud_offset_read 	        : UDINT;
		ud_length_read 	        : UDINT;
		p_ud_data_read 	        : ^UDINT;
		ud_type 	              : UDINT;
		ud_priority 	          : UDINT;
		pp_Enable 	            : ^pVoid;
		p_ud_DataAddr_read 	    : ^HDINT;
    ud_WritePayloadType     : UDINT;
     p_UserDOHandle 	      : ^UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	            : DINT;
	END_VAR
  VAR
      // For NewInst command 
    _Para 	                : CmdStruct;  
    _Result 	              : Results;    
    paraAddDO               : t_DM_CMD_AddDO;    
    dummy                   : UDINT;
  END_VAR
  
  // Add DO Command ------------------------------------------------------------------------------------------
  _Para.uiCmd                               := DM_ADD_PAYLOAD_DO;
  
  paraAddDO.ud_ModuleHandle                 := 0; // Module Handle will be set by the Civ  

  paraAddDO.p_ud_DoHandle                   := p_ud_handle;
  paraAddDO.ud_b_DoRequired                 := Required$UDINT;
  paraAddDO.ud_DolType                      := ud_dol_type;
  paraAddDO.ud_OffsetRead                   := ud_offset_read;
  paraAddDO.ud_LengthRead                   := ud_length_read;
  paraAddDO.ud_OffsetWrite                  := 0;
  paraAddDO.ud_LengthWrite                  := 0;
  
  if TimeBase > 0 then
    paraAddDO.ud_PreScalerCounterThreshold  := TimeBase - 1;
  else
    paraAddDO.ud_PreScalerCounterThreshold  := 0;
  end_if;
#ifdef HWK_SHOW_PRAGMA_MESSAGES     
  #pragma message("LanSte 11.04.2013 10:13 \ TODO Implement once we implement Timeslices")
#endif
  
  paraAddDO.ud_PreScalerCounterStartValue  := 0;
  
  if ud_priority = DM_PRIORITY_INVALID then
    // paraAddDO.ud_Priority := DM_PRIORITY_READ_DO; // Only with Timesplit
    paraAddDO.ud_Priority         := DM_PRIORITY_DEFAULT;
  else
    paraAddDO.ud_Priority         := ud_priority;
  end_if;
  
  if ud_WritePayloadType then
    paraAddDO.ud_WritePayloadType := WR_PLD_TYPE_RD_ACCESS_CONFIGURABLE;
  else
    paraAddDO.ud_WritePayloadType := WR_PLD_TYPE_STANDARD;
  end_if;
  
  if ud_type = DM_CONTROL_ACCESS then
    paraAddDO.ud_Command          := DM_CMD_CONTROL_READ;
  else
    paraAddDO.ud_Command          := DM_CMD_MEMORY_READ;
  end_if;
  
  paraAddDO.p_ud_ReadData         := p_ud_data_read;
  paraAddDO.p_ud_WriteData        := #dummy;  

  paraAddDO.pp_Enable             := pp_Enable;
  
  paraAddDO.p_UserDOHandle        := p_UserDOHandle;
  
  // pp_Enable needs to be a valid address so that the DO is registered as EnableAble Mover DI
  if (p_UserDOHandle) &  (pp_Enable = NIL) then
    paraAddDO.pp_Enable := (#dummy)$^pVoid;
  end_if;
  
  paraAddDO.p_ud_DataAddr_read  := p_ud_DataAddr_read;
  paraAddDO.p_ud_DataAddr_write := nil;
  
  _Para.aPara[0]  := (#paraAddDO)$DINT;
  
  _result.aData[0]$DINT := VM_CMD_OK;
  
  // Add DO via NewInst 
  if MasterConnect.NewInst(#_Para, #_Result) <> READY & 
     _result.aData[0]$DINT = VM_CMD_OK then
    // If NewInst failed but retcode is still OK
    sd_retval := VM_CMD_ERROR_NEW_INST;
  else    
    sd_retval := _result.aData[0]$DINT;
  end_if;
  
  if (p_UserDOHandle) &  (pp_Enable = NIL) then
    // Set Enable as caller does not want to swich on/off manually
    (dummy$^USINT)^ := VARAN_MOVER_DO_CONT_RUN;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::AddWrPayloadDO
	VAR_INPUT
		ud_dol_type 	        : UDINT;
		p_ud_handle 	        : ^UDINT;
		ud_offset_write 	    : UDINT;
		ud_length_write 	    : UDINT;
		p_ud_data_write 	    : ^UDINT;
		ud_type 	            : UDINT;
		ud_priority 	        : UDINT;
		pp_Enable 	          : ^pVoid;
		p_ud_DataAddr_write 	: ^HDINT;
    ud_WritePayloadType   : UDINT;   
     p_UserDOHandle 	    : ^UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	          : DINT;
	END_VAR
  VAR
      // For NewInst command 
    _Para 	              : CmdStruct;  
    _Result 	            : Results;    
    paraAddDO             : t_DM_CMD_AddDO;    
    dummy                 : UDINT;
  END_VAR
  
  // Add DO Command ------------------------------------------------------------------------------------------
  _Para.uiCmd := DM_ADD_PAYLOAD_DO;
  
  paraAddDO.ud_ModuleHandle := 0; // Module Handle will be set by the Civ  

  paraAddDO.p_ud_DoHandle   := p_ud_handle;
  paraAddDO.ud_b_DoRequired := Required$UDINT;
  paraAddDO.ud_DolType      := ud_dol_type;
  paraAddDO.ud_OffsetRead   := 0;
  paraAddDO.ud_LengthRead   := 0;
  paraAddDO.ud_OffsetWrite  := ud_offset_write;
  paraAddDO.ud_LengthWrite  := ud_length_write;
  
  if TimeBase > 0 then
    paraAddDO.ud_PreScalerCounterThreshold   := TimeBase - 1;
  else
    paraAddDO.ud_PreScalerCounterThreshold   := 0;
  end_if;
  
#ifdef HWK_SHOW_PRAGMA_MESSAGES     
  #pragma message("LanSte 11.04.2013 10:13 \ TODO Implement once we implement Timeslices")
#endif
  
  paraAddDO.ud_PreScalerCounterStartValue  := 0;
  
  if ud_priority = DM_PRIORITY_INVALID then
    // paraAddDO.ud_Priority := DM_PRIORITY_WRITE_DO;  // Only with Timesplit
    paraAddDO.ud_Priority         := DM_PRIORITY_DEFAULT;
  else    
    paraAddDO.ud_Priority         := ud_priority;
  end_if;
  
  if ud_WritePayloadType then
    paraAddDO.ud_WritePayloadType := WR_PLD_TYPE_WR_ACCESS_CONFIGURABLE;
  else
    paraAddDO.ud_WritePayloadType := WR_PLD_TYPE_STANDARD;
  end_if;  
  
  if ud_type = DM_CONTROL_ACCESS then
    paraAddDO.ud_Command          := DM_CMD_CONTROL_WRITE;
  else
    paraAddDO.ud_Command          := DM_CMD_MEMORY_WRITE;
  end_if;  
    
  paraAddDO.p_ud_ReadData         := #dummy;
  paraAddDO.p_ud_WriteData        := p_ud_data_write;  
  
  paraAddDO.pp_Enable             := pp_Enable;
  
  paraAddDO.p_UserDOHandle        := p_UserDOHandle;
  
  // pp_Enable needs to be a valid address so that the DO is registered as EnableAble Mover DI
  if (p_UserDOHandle) &  (pp_Enable = NIL) then
    paraAddDO.pp_Enable := (#dummy)$^pVoid;
  end_if;
  
  paraAddDO.p_ud_DataAddr_read  := nil;
  paraAddDO.p_ud_DataAddr_write := p_ud_DataAddr_write;
  
  _Para.aPara[0]  := (#paraAddDO)$DINT;
  
  _result.aData[0]$DINT := VM_CMD_OK;
  
  // Add DO via NewInst 
  if MasterConnect.NewInst(#_Para, #_Result) <> READY & 
     _result.aData[0]$DINT = VM_CMD_OK then
    // If NewInst failed but retcode is still OK
    sd_retval := VM_CMD_ERROR_NEW_INST;
  else    
    sd_retval := _result.aData[0]$DINT;
  end_if;
  
  if (p_UserDOHandle) &  (pp_Enable = NIL) then
    // Set Enable as caller does not want to swich on/off manually
    (dummy$^USINT)^ := VARAN_MOVER_DO_CONT_RUN;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::AddRdWrPayloadDO
	VAR_INPUT
		ud_dol_type 	        : UDINT;
		p_ud_handle 	        : ^UDINT;
		ud_offset_read 	      : UDINT;
		ud_length_read 	      : UDINT;
		p_ud_data_read 	      : ^UDINT;
		ud_offset_write 	    : UDINT;
		ud_length_write 	    : UDINT;
		p_ud_data_write 	    : ^UDINT;
		ud_type 	            : UDINT;
		ud_priority 	        : UDINT;
		pp_Enable 	          : ^pVoid;
		p_ud_DataAddr_read 	  : ^HDINT;
		p_ud_DataAddr_write 	: ^HDINT;
    ud_WritePayloadType   : UDINT;
    p_UserDOHandle 	      : ^UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	          : DINT;
	END_VAR
  VAR
      // For NewInst command 
    _Para 	              : CmdStruct;  
    _Result 	            : Results;    
    paraAddDO             : t_DM_CMD_AddDO;
    dummy                 : UDINT;
  END_VAR
  
  // Add DO Command ------------------------------------------------------------------------------------------
  _Para.uiCmd := DM_ADD_PAYLOAD_DO;
  
  paraAddDO.ud_ModuleHandle := 0; // Module Handle will be set by the Civ  

  paraAddDO.p_ud_DoHandle   := p_ud_handle;
  paraAddDO.ud_b_DoRequired := Required$UDINT;
  paraAddDO.ud_DolType      := ud_dol_type;
  paraAddDO.ud_OffsetRead   := ud_offset_read;
  paraAddDO.ud_LengthRead   := ud_length_read;
  paraAddDO.ud_OffsetWrite  := ud_offset_write;
  paraAddDO.ud_LengthWrite  := ud_length_write;
  
  if TimeBase > 0 then
    paraAddDO.ud_PreScalerCounterThreshold   := TimeBase - 1;
  else
    paraAddDO.ud_PreScalerCounterThreshold   := 0;
  end_if;
#ifdef HWK_SHOW_PRAGMA_MESSAGES     
  #pragma message("LanSte 11.04.2013 10:13 \ TODO Implement once we implement Timeslices")
#endif
  
  paraAddDO.ud_PreScalerCounterStartValue  := 0;
  
  if ud_priority = DM_PRIORITY_INVALID then
    // paraAddDO.ud_Priority := DM_PRIORITY_READ_DO; // Only with Timesplit
    paraAddDO.ud_Priority := DM_PRIORITY_DEFAULT;
  else    
    paraAddDO.ud_Priority := ud_priority;
  end_if;
  
  if ud_WritePayloadType then
    // Check if only the read or write part of the Payload DO needs to be changed
    if (ud_WritePayloadType = WR_PLD_TYPE_RD_ACCESS_CONFIGURABLE$UDINT) |
       (ud_WritePayloadType = WR_PLD_TYPE_WR_ACCESS_CONFIGURABLE$UDINT) then
      paraAddDO.ud_WritePayloadType := ud_WritePayloadType;
    else
      paraAddDO.ud_WritePayloadType := WR_PLD_TYPE_RW_ACCESS_CONFIGURABLE;
    end_if;
  else
    paraAddDO.ud_WritePayloadType   := WR_PLD_TYPE_STANDARD;
  end_if;
  
  if ud_type = DM_CONTROL_ACCESS then
    paraAddDO.ud_Command        := DM_CMD_CONTROL_READ_WRITE;
  else
    paraAddDO.ud_Command        := DM_CMD_MEMORY_READ_WRITE;
  end_if;

  paraAddDO.p_ud_ReadData       := p_ud_data_read;
  paraAddDO.p_ud_WriteData      := p_ud_data_write;
  
  paraAddDO.pp_Enable           := pp_Enable;
  
  paraAddDO.p_UserDOHandle      := p_UserDOHandle;
  
  // pp_Enable needs to be a valid address so that the DO is registered as EnableAble Mover DI
  if (p_UserDOHandle) &  (pp_Enable = NIL) then
    paraAddDO.pp_Enable         := (#dummy)$^pVoid;
  end_if;
  
  paraAddDO.p_ud_DataAddr_read  := p_ud_DataAddr_read;
  paraAddDO.p_ud_DataAddr_write := p_ud_DataAddr_write;
  
  _Para.aPara[0]  := (#paraAddDO)$DINT;
  
  _result.aData[0]$DINT := VM_CMD_OK;
  
  // Add DO via NewInst 
  if MasterConnect.NewInst(#_Para, #_Result) <> READY & 
     _result.aData[0]$DINT = VM_CMD_OK then
    // If NewInst failed but retcode is still OK
    sd_retval := VM_CMD_ERROR_NEW_INST;
  else    
    sd_retval := _result.aData[0]$DINT;
  end_if;
  
  if (p_UserDOHandle) &  (pp_Enable = NIL) then
    // Set Enable as caller does not want to swich on/off manually
    (dummy$^USINT)^ := VARAN_MOVER_DO_CONT_RUN;
  end_if;
  
END_FUNCTION

FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::AddMovePayloadDO
	VAR_INPUT
		ud_dol_type                   : UDINT;
		p_ud_handle                   : ^UDINT;
		ud_SourceReadDOHandle 	      : UDINT;
		ud_SourceReadOffset 	        : UDINT;
		ud_DestinationWriteDOHandle 	: UDINT;
		ud_DestinationWriteOffset 	  : UDINT;
		ud_LengthMove 	              : UDINT;
		ud_Priority 	                : UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	                  : DINT;
	END_VAR
  VAR
      // For NewInst command 
    _Para 	                      : CmdStruct;  
    _Result 	                    : Results;    
    paraMovDO                     : t_DM_CMD_AddMovDo;    
  END_VAR
  
   // Add Move DO Command ------------------------------------------------------------------------------------------
  _Para.uiCmd := DM_ADD_PAYLOAD_MOVE_DO; 
  
  paraMovDO.p_ud_DoHandle               := p_ud_handle;
  paraMovDO.ud_b_DoRequired             := Required$UDINT;
  paraMovDO.ud_DolType                  := ud_dol_type;
  paraMovDO.ud_SourceReadDoHandle       := ud_SourceReadDOHandle;
  paraMovDO.ud_SourceReadOffset         := ud_SourceReadOffset;
  paraMovDO.ud_DestinationWriteDoHandle := ud_DestinationWriteDOHandle;
  paraMovDO.ud_DestinationWriteOffset   := ud_DestinationWriteOffset;
  paraMovDO.ud_LengthMove               := ud_LengthMove;
  
  if TimeBase > 0 then
    paraMovDO.ud_PreScalerCounterThreshold   := TimeBase - 1;
  else
    paraMovDO.ud_PreScalerCounterThreshold   := 0;
  end_if;
#ifdef HWK_SHOW_PRAGMA_MESSAGES     
  #pragma message("LanSte 11.04.2013 10:13 \ TODO Implement once we implement Timeslices")
#endif
  
  paraMovDO.ud_PreScalerCounterStartValue  := 0;  

  paraMovDO.ud_Priority := ud_Priority;
  
  
  _Para.aPara[0]  := (#paraMovDO)$DINT;
  
  _result.aData[0]$DINT := VM_CMD_OK;
  
  // Add DO via NewInst 
  if MasterConnect.NewInst(#_Para, #_Result) <> READY & 
     _result.aData[0]$DINT = VM_CMD_OK then
    // If NewInst failed but retcode is still OK
    sd_retval := VM_CMD_ERROR_NEW_INST;
  else    
    sd_retval := _result.aData[0]$DINT;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::EnableDO
	VAR_INPUT
		ud_DOHandle 	: UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	  : DINT;
	END_VAR   
  
  // This Method those not work with Varan Mover
  // LanSte 12.04.2013 09:11 Use IMULTIVARANMANAGER,
  if b_PayloadSupport then  
    
    sd_retval := MULTI_VARAN_iEnableDo(ud_DOHandle);
    
  else
    if ud_DOHandle then
      if Required then
        ud_DOHandle$PLSL_VARANFRAME^.ucCtrlStat :=  VARAN_DO_CONT_RUN or VARAN_DO_REQUIRED;
      else
        ud_DOHandle$PLSL_VARANFRAME^.ucCtrlStat :=  VARAN_DO_CONT_RUN;
      end_if;
      
      sd_retval := VARANMANAGER_OK;
    else
      sd_retval := VARANMANAGER_DO_HANDLE_INVALID;
    end_if;    
  end_if;  
  
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::DisableDO
	VAR_INPUT
		ud_DOHandle 	: UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	  : DINT;
	END_VAR
  
  // This Method those not work with Varan Mover
  // LanSte 12.04.2013 09:11 Use IMULTIVARANMANAGER,
  if b_PayloadSupport then  
    
    sd_retval := MULTI_VARAN_iDisableDo(ud_DOHandle);
    
  else
    if ud_DOHandle then    
      ud_DOHandle$PLSL_VARANFRAME^.ucCtrlStat := VARAN_DO_NO_RUN;        
      sd_retval := VARANMANAGER_OK;
    else
      sd_retval := VARANMANAGER_DO_HANDLE_INVALID;
    end_if;
  end_if; 
  
END_FUNCTION


FUNCTION HwBaseCDIAS::CreateMutex
	VAR_INPUT
		MutexName 	      : ^CHAR;
    pThis 	          : ^VirtualBase;
	END_VAR
	VAR_OUTPUT
		pv_RetMutex 	    : pVoid;
	END_VAR
  VAR
    str_ObjName       : array[0..255] of char;
    str_ObjNamePart1  : array[0..CDIAS_MUTEX_NAME_MAX_LENGTH-1] of char;
    str_ObjNamePart2  : array[0..CDIAS_MUTEX_NAME_END_LENGTH] of char; // +1 for 0 Termination
    str_CombinedName  : array[0..CDIAS_MUTEX_NAME_MAX_LENGTH-1] of char; 
    str_this          : array[0..11] of char; // 2 byty %m, 8 byte Address, 1 byte for 0 Termination
  	
    ud_LenObjName     : UDINT;    
    ud_LenStr         : UDINT;    
    ud_SepLenStr      : UDINT;
    ud_LenCombObjName : UDINT;  
    ud_LenThis        : UDINT;

  END_VAR
  
  pv_RetMutex := Nil; // Error OS_CILGetv failed
  
  if pThis = nil then
    pthis := this;
  end_if;  
  
  if (mt_api = nil) then
    if(OS_CILGet("LSL_MULTITASK", #mt_api$void)) THEN
      mt_api := NIL;
    end_if;
  end_if;
  
  if mt_api then
  
    _memset(dest:=#str_ObjName[0], usByte:=0, cntr:=sizeof(str_ObjName) );
    _memset(dest:=#str_ObjNamePart1[0], usByte:=0, cntr:=sizeof(str_ObjNamePart1) );
    _memset(dest:=#str_ObjNamePart2[0], usByte:=0, cntr:=sizeof(str_ObjNamePart2) );
    _memset(dest:=#str_CombinedName[0], usByte:=0, cntr:=sizeof(str_CombinedName) );
    _memset(dest:=#str_this[0], usByte:=0, cntr:=sizeof(str_this) );
    
  
    ud_LenStr := _strlen(MutexName);    

    ud_SepLenStr := _strlen(CDIAS_STR_MUTEX_NAME_SEPERATOR);
    ud_LenObjName := _GetObjName(pThis:=pthis, pName:=#str_ObjName[0]);
  
    if (ud_LenStr < CDIAS_MUTEX_NAME_MAX_LENGTH) then
      _strcpy(dest:=#str_CombinedName[0], src:=MutexName);
    else
      _strncpy(dest:=#str_CombinedName[0], src:=MutexName, max:=CDIAS_MUTEX_NAME_MAX_LENGTH-1);
    end_if;
    
    if (ud_LenObjName + ud_LenStr) < CDIAS_MUTEX_NAME_MAX_LENGTH then      
      _strcat(dest:=#str_CombinedName[0], src:=#str_ObjName[0]); 
    else
      _strncpy(dest:=#str_ObjNamePart1[0], src:= #str_ObjName[0], max:= CDIAS_MUTEX_NAME_MAX_LENGTH - ud_LenStr - ud_SepLenStr - CDIAS_MUTEX_NAME_END_LENGTH - 1);    // Copy Beginning of str_ObjName
      _strncpy(dest:=#str_ObjNamePart2[0], src:= #str_ObjName[ud_LenObjName-CDIAS_MUTEX_NAME_END_LENGTH-1], max:=CDIAS_MUTEX_NAME_END_LENGTH);  // Copy Last MUTEX_NAME_END_LENGTH Char of str_ObjName
      
      // Put the Mutex String together
      _strcat(dest:=#str_CombinedName[0], src:= #str_ObjNamePart1[0]);
      _strcat(dest:=#str_CombinedName[0], src:= CDIAS_STR_MUTEX_NAME_SEPERATOR);
      _strcat(dest:=#str_CombinedName[0], src:= #str_ObjNamePart2[0]);      
    end_if;

    pv_RetMutex := OS_MT_CreateSemaphore(MTSEMATYPE_MUTEX, 1, 0, #str_CombinedName[0]);   
    
    if pv_RetMutex = nil then
    
      // If Create Mutex failed: Insert the this pointer into the string
      ud_LenCombObjName := _strlen(#str_CombinedName[0]);
      
      str_this[0] := '%';
      str_this[1] := 'm';
      _itoa(udNumber:=pthis$UDINT, pString:=#str_this[2]);
      ud_LenThis  := _strlen(src:=#str_this[0]);
      
      _strcpy(dest:=#str_CombinedName[ud_LenCombObjName-ud_LenThis], src:=#str_this[0]);      
      
      pv_RetMutex := OS_MT_CreateSemaphore(MTSEMATYPE_MUTEX, 1, 0, #str_CombinedName[0]); 
    
    end_if;

  end_if;    
  
END_FUNCTION


FUNCTION HwBaseCDIAS::MutexStart
  VAR_INPUT
    pMutex  : pVoid;
  END_VAR

  if(pMutex <> NIL) then
    OS_MT_WAIT(pMutex); 
  end_if;

END_FUNCTION


FUNCTION HwBaseCDIAS::MutexStop
  VAR_INPUT
    pMutex  : pVoid;
  END_VAR

  if(pMutex <> NIL) then
    OS_MT_SIGNAL(pMutex); 
  end_if;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::ChangeDOLengthOffset
	VAR_INPUT
		ud_DOHandle         : UDINT;
		ud_offset_read 	    : UDINT;
		ud_length_read 	    : UDINT;
		ud_offset_write 	  : UDINT;
		ud_length_write 	  : UDINT;
	END_VAR
	VAR_OUTPUT
		sd_retval 	        : DINT;
	END_VAR
  VAR  	    
    ud_PropertyCount    : UDINT;
    s_PropertyValuePair : ARRAY [0..4] of LSL_PROPERTY_VALUE_PAIR;
    ud_bytecnt  : UDINT;
    
    // For NewInst command 
    _Para 	            : CmdStruct;  
    _Result 	          : Results; 
  END_VAR
  
  // This Method those not work with Varan Mover
  if b_PayloadSupport = false then
    sd_retval := VM_CMD_WRONG_OS;
    return;    
  end_if;
  
  ud_bytecnt := 0;
  
  ud_PropertyCount := 0;
  
  if (ud_offset_read <> VM_DO_PROPERTY_INVALID) then    
    
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_READ_OFFSET;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_offset_read;
    
    ud_PropertyCount += 1;
  end_if;
  
  if ud_length_read <> VM_DO_PROPERTY_INVALID then
  
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_READ_LENGTH;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_length_read;
    
    ud_PropertyCount += 1;
    
    ud_bytecnt += ud_length_read;    
  end_if;  
  
  if ud_offset_write <> VM_DO_PROPERTY_INVALID then
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_WRITE_OFFSET;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_offset_write;
    
    ud_PropertyCount += 1;
  end_if;
  
  if ud_length_write <> VM_DO_PROPERTY_INVALID then
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_WRITE_LENGTH;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_length_write;
    
    ud_PropertyCount += 1;    
    
    ud_bytecnt += ud_length_write;
  end_if;
  
  if ud_PropertyCount then
    sd_retval := MULTI_VARAN_iSetDoProperties(ud_DOHandle, ud_PropertyCount, #s_PropertyValuePair[0] );
  else
    // Data undefined
    sd_retval := VM_CMD_ERROR_NO_PROPERTY;
  end_if;
  
  if sd_retval then
    return;
  end_if;

  if ud_bytecnt then
    // Calculate the Retrycounter and set it in the DO 
    _Para.uiCmd := DM_GET_PAYLOAD_RETRY_TIMEOUT;
    _Para.aPara[0]$UDINT    := ud_bytecnt;
    _Result.aData[0]$UDINT  := 0;
    
    MasterConnect.NewInst(#_Para, #_Result);
    
    s_PropertyValuePair[0].udPropertyId     := DO_PROP_RETRY_TIMEOUT;
    s_PropertyValuePair[0].udPropertyValue  := _result.aData[0]$UDINT;
    
    // Check retry timeout value
    if s_PropertyValuePair[0].udPropertyValue = 0 then
      sd_retval := VM_CMD_ERROR_INVALID_TIMEOUT;
      return;
    end_if;
      
    sd_retval := MULTI_VARAN_iSetDoProperties(ud_DOHandle, 1, #s_PropertyValuePair[0]);
    
    if sd_retval then
      return;
    end_if;
    
  end_if;  
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::ChangeMovDOLengthOffset
  VAR_INPUT
		ud_MovDOHandle              : UDINT;
		ud_SourceReadDOHandle       : UDINT;
		ud_SourceReadOffset         : UDINT;
		ud_DestinationWriteDOHandle : UDINT;
		ud_DestinationWriteOffset   : UDINT;
		ud_LengthMove               : UDINT;
	END_VAR
  VAR_OUTPUT
		sd_retval                   : DINT;
	END_VAR  
  VAR  	    
    ud_PropertyCount            : UDINT;
    s_PropertyValuePair         : ARRAY [0..5] of LSL_PROPERTY_VALUE_PAIR;  
  END_VAR
  
  ud_PropertyCount := 0;
  
  if (ud_sourceReadDOHandle <> VM_DO_PROPERTY_INVALID) then 
    
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_SOURCE_READ_DO;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_SourceReadDOHandle;
    
    ud_PropertyCount += 1;
  end_if;
  
  if (ud_SourceReadOffset <> VM_DO_PROPERTY_INVALID) then 
    
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_READ_OFFSET;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_SourceReadOffset;
    
    ud_PropertyCount += 1;
  end_if;
  
  if (ud_destinationWriteDOHandle <> VM_DO_PROPERTY_INVALID) then 
    
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_DESTINATION_WRITE_DO;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_DestinationWriteDOHandle;
    
    ud_PropertyCount += 1;
  end_if;
  
  if (ud_DestinationWriteOffset <> VM_DO_PROPERTY_INVALID) then 
    
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_WRITE_OFFSET;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_DestinationWriteOffset;
    
    ud_PropertyCount += 1;
  end_if;
  
  if (ud_lengthmove <> VM_DO_PROPERTY_INVALID) then 
    
    s_PropertyValuePair[ud_PropertyCount].udPropertyId    := DO_PROP_MOVE_DATA_LENGTH;
    s_PropertyValuePair[ud_PropertyCount].udPropertyValue := ud_LengthMove;
    
    ud_PropertyCount += 1;
  end_if;
  
  if ud_PropertyCount then
    sd_retval := MULTI_VARAN_iSetDoProperties(ud_MovDOHandle, ud_PropertyCount, #s_PropertyValuePair[0] );
  else
    // Data undefined
    sd_retval := VM_CMD_ERROR_NO_PROPERTY;
  end_if;
  
END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::SingleRunSM
	VAR_INPUT
		p_DOhandle 	: ^UDINT;
		p_b_DOIsRunning 	: ^t_SingleRunState;
	END_VAR
  
  // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  case p_b_DOIsRunning^ of
  
    SR_STATE_ENABLE_ME :  // DO is not running and start request is set ----------------------------------------
      EnableDO(ud_DOHandle := p_DOhandle^);        
      p_b_DOIsRunning^ := SR_STATE_DISABLE_ME;
      
    SR_STATE_DISABLE_ME : // DO is running and start request is not set ----------------------------------------
      DisableDO(ud_DOHandle:= p_DOhandle^);
      p_b_DOIsRunning^ := SR_STATE_NOTHING;
      
    SR_STATE_LEAVE_ME_ENABLED : // DO is running and another start request is set ------------------------------
      p_b_DOIsRunning^ := SR_STATE_DISABLE_ME;
      
  end_case;
  
END_FUNCTION


FUNCTION VIRTUAL HwBaseCDIAS::GetSerialNo
  VAR 
    szSerNoStr : ARRAY [0..10] OF CHAR;
    i : UINT;
  END_VAR

    if MasterConnect.I2CReadOneByte(AdressCDIAS:=(Place*16#100)$UINT+6, pData:=#aEEPROMData[6]) = 0 then
      if (aEEPROMData[6] <> 0) & (aEEPROMData[6] <> 16#FF) then
        _memset(dest:=#szSerNoStr[0], usByte:=0, cntr:=sizeof(szSerNoStr));
        
        for i := 0 to 9 do
          MasterConnect.I2CReadOneByte(AdressCDIAS:=(Place*16#100)$UINT+aEEPROMData[6]+i, pData:=#aEEPROMData[aEEPROMData[6]+i]);
        end_for;
        
        // if the first 2 characters are zero, show only the last 8 (like on the label of the module), otherwise all 10
        if (aEEPROMData[aEEPROMData[6]] = '0') & (aEEPROMData[aEEPROMData[6]+1] = '0') then
          _memcpy(ptr1:=#szSerNoStr[0], ptr2:=#aEEPROMData[aEEPROMData[6]+2], cntr:=8);
        else
          _memcpy(ptr1:=#szSerNoStr[0], ptr2:=#aEEPROMData[aEEPROMData[6]], cntr:=10);
        end_if;
        SerialNoStr.WriteDataOff(udLen:=_StrLen(#szSerNoStr[0]), udOff:=0, pData:=#szSerNoStr[0]);
      end_if;
    end_if;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::SerialNo::Read
	VAR_OUTPUT
		output (EAX) 	: UDINT;
	END_VAR

	SerialNo := SerialNoStr.Data.Read();
	output := SerialNo;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL HwBaseCDIAS::SerialNo::Write
	VAR_INPUT
		input (EAX) 	: UDINT;
	END_VAR
	VAR_OUTPUT
		result (EAX) 	: UDINT;
	END_VAR

	SerialNo := input;
	result := (SerialNoStr.Data.Write(SerialNo))$UDINT;

END_FUNCTION


FUNCTION VIRTUAL HwBaseCDIAS::GetVarianteValue
	VAR_OUTPUT
		output 	: UDINT;
	END_VAR
  
  //Overwrite this method in derived class
  output := HWC_INVALID_DEVICE_ID;

END_FUNCTION


FUNCTION VIRTUAL HwBaseCDIAS::GetKennung
	VAR_OUTPUT
		output 	: UDINT;
	END_VAR
  
  //Overwrite this method in derived class
  output := HWC_INVALID_DEVICE_ID;
  
END_FUNCTION


FUNCTION VIRTUAL HwBaseCDIAS::GetFWVersion
	VAR_INPUT
		pData 	: ^CHAR;
		length 	: DINT;
	END_VAR

  //Overwrite in derived Classes
  if pData then
    if Length >= 1 then
      pData^ := 0;    // Set first byte  to 0 termination = invalid string
    end_if;
  end_if;
  
END_FUNCTION

#pragma warning(disable: 73);
FUNCTION VIRTUAL HwBaseCDIAS::LogError
	VAR_INPUT
		e_msg 	: ^CHAR;
	END_VAR
  
#ifdef HWC_LogError
  HWC_LogError(this, e_msg);
#endif

END_FUNCTION


FUNCTION VIRTUAL HwBaseCDIAS::LogValue
	VAR_INPUT
		pString 	: ^CHAR;
		Value 	: UDINT;
		Value2 	: UDINT;(* := 16#FFFFFFFF *)
		Value3 	: UDINT;(* := 16#FFFFFFFF *)
	END_VAR
  
#ifdef HWC_LogValue3
  HWC_LogValue3(this, pString, Value, Value2, Value3);
#endif

END_FUNCTION
#pragma warning(default: 73);
