//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               = "MDD2000GeneralParaDS402"
	Revision           = "1.1"
	GUID               = "{A9122B28-0B68-4A50-8DBE-92FEA6B48BB1}"
	RealtimeTask       = "false"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	SharedCommandTable = "true"
	Objectsize         = "(544,120)">
	<Channels>
		<Server Name="State">
		</Server>
	</Channels>
	<Dependencies>
		<Files>
			<File Path=".\Class\MDD2000MngBase\MDD2000MngBase.h" Include="true"/>
		</Files>
	</Dependencies>
	<RevDoku>
		<Owner Company="Sigmatek" Author="LanSte"/>
		<Dokumentation Revision="1.1" Date="16.12.2024" Author="LanSte" Company="Sigmatek" Description="Added Server &quot;ParaNr&quot; to provide compatibility for old sigmatek drive Parameter format."/>
		<Dokumentation Revision="1.0" Date="28.08.2023" Author="LanSte" Company="Sigmatek" Description="First library version."/>
	</RevDoku>
	<Network Name="MDD2000GeneralParaDS402">
		<!-- List of Components in this network -->
		<Components>
			<Object
				Name       = "_base"
				GUID       = "{480D52C0-1030-420F-8223-24E147BED9F1}"
				Class      = "Drive_AsyncParaDS402"
				Position   = "(218,120)"
				Visualized = "true"
				Remotely   = "true">
				<Channels>
					<Server Name="ErrorQuit"/>
					<Server Name="ParaID"/>
					<Server Name="ParaNr"/>
					<Server Name="ParaRdWr"/>
					<Server Name="ParaSize"/>
					<Server Name="ParaSubID"/>
					<Server Name="ParaValue"/>
					<Server Name="State"/>
					<Client Name="DriveIF"/>
					<Client Name="ErrorCode"/>
				</Channels>
			</Object>
		</Components>
		<Comments>
		</Comments>
		<!-- List of Connections in this network -->
		<Connections>
			<Connection Source="this.State" Destination="_base.State" Vertices="(736,210),(564,210),"/>
			<Connection Source="this.ErrorQuit" Destination="_base.ErrorQuit" Vertices="(736,270),(564,270),"/>
			<Connection Source="this.ParaID" Destination="_base.ParaID" Vertices="(736,330),(564,330),"/>
			<Connection Source="this.ParaSubID" Destination="_base.ParaSubID" Vertices="(736,390),(564,390),"/>
			<Connection Source="this.ParaRdWr" Destination="_base.ParaRdWr" Vertices="(736,450),(564,450),"/>
			<Connection Source="this.ParaSize" Destination="_base.ParaSize" Vertices="(736,510),(564,510),"/>
			<Connection Source="this.ParaValue" Destination="_base.ParaValue" Vertices="(736,570),(564,570),"/>
			<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="this.ParaNr" Destination="_base.ParaNr" Vertices="(736,630),(564,690),"/>
		</Connections>
		<!-- Headerfiles -->
		<Options>
		</Options>
	</Network>
</Class>
*)
#pragma using Drive_AsyncParaDS402

MDD2000GeneralParaDS402 : CLASS
: Drive_AsyncParaDS402
  //Servers:
  //Clients:
  //Variables:
  //Functions:
	
	FUNCTION VIRTUAL GLOBAL RefreshPara
		VAR_INPUT
			hParaIndex 	: HINT;
			hsParaSubIndex 	: HSINT;
			bRW 	: DINT;
			bsDataInfo 	: BSINT;
			pValue 	: ^DINT;
		END_VAR;
	
	FUNCTION ConvertParaId
		VAR_INPUT
			ParaID 	: HINT;
			ParaSubID 	: HSINT;
			pNewParaId 	: ^HINT;
			pNewParaSubID 	: ^HSINT;
		END_VAR;
				//! <Function Name="State.NewInst" UseBaseCmd="true"/>
	FUNCTION VIRTUAL GLOBAL State::NewInst
		VAR_INPUT
			pPara 	: ^CmdStruct;
			pResult 	: ^results;
		END_VAR
		VAR_OUTPUT
			ret_code 	: iprStates;
		END_VAR;
  //Tables:
	FUNCTION @STD
		VAR_OUTPUT
			ret_code	: CONFSTATES;
		END_VAR;
	FUNCTION GLOBAL TAB @CT_;
END_CLASS;

//}}LSL_DECLARATION


FUNCTION GLOBAL TAB MDD2000GeneralParaDS402::@CT_
0$UINT,
2#0100000000000000$UINT, //TY_MDD2000GENERALPARADS402
1$UINT, 1$UINT, (SIZEOF(::MDD2000GeneralParaDS402))$UINT, 
0$UINT, 0$UINT, 0$UINT, 
TO_UDINT(927349505), "MDD2000GeneralParaDS402", //Class
TO_UDINT(3760282393), "Drive_AsyncParaDS402", 1$UINT, 1$UINT, //Baseclass
//Servers:
//Clients:
END_FUNCTION


#define USER_CNT_MDD2000GeneralParaDS402 19

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

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

	ret_code	:= Drive_AsyncParaDS402::@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_MDD2000GeneralParaDS402;
	vmt.CmdTable.NewInstr		:= #State::NewInst();
#pragma warning (disable : 74)
	vmt.UserFcts[2]		:= #RefreshPara();

#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;

END_FUNCTION

//{{LSL_IMPLEMENTATION
FUNCTION VIRTUAL GLOBAL MDD2000GeneralParaDS402::State::NewInst
	VAR_INPUT
		pPara 	: ^CmdStruct;
		pResult 	: ^Results;
	END_VAR
	VAR_OUTPUT
		ret_code 	: IprStates;
	END_VAR
  VAR
  	NewParaID : HINT;
    NewParaSubID : HSINT;
  END_VAR

  
  case pPara^.uiCmd of
  
    //*****************************************************************************
    DRIVESAFETYIF_GETGENERALPARA:
    
      ret_code := ERROR; //unsupported version
        
      pResult^.uiLng := 4;
      pResult^.aData[0]$DINT := DRIVESAFETYIF_GETGENERALPARA_VER_MAX;  //max supported version
      
      //Check version 1
      if pPara^.aPara[0] = DRIVESAFETYIF_GETGENERALPARA_VER_1 then
      
//  Command Version 1 **  
//  CmdStruct
//  aPara[0]$DINT  :  Command Version : 1
//  aPara[1]$DINT  :  <> 0 .. Set New Request, 0 .. Poll Response of last request    
//  aPara[2]$UINT  :  ParaID;
//  aPara[3]$USINT :  ParaSubID;
//  aPara[4]$USINT :  0 Read Parameter, 1 Write Parameter
//  aPara[5]$^void := Pointer to Read / Write Data, Read Data is returen with Poll response and retcode = READY
//  aPara[6]$DINT  := size of parameter, 0 .. 4 Byte, .. 1 8 Byte, 2 .. 12 Byte

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

//  retcode
//  READY
//  BUSY
//  ERROR
      
        if pPara^.aPara[1] <> 0 then // Set a new Parameter request

          if State = ERROR then
            ErrorQuit.Write(input:=1);
          end_if;

          if State = READY then
            ConvertParaId(ParaID        := pPara^.aPara[2]$UINT
                        , ParaSubID     := pPara^.aPara[3]$USINT
                        , pNewParaId    := #NewParaID
                        , pNewParaSubID := #NewParaSubID);          
          
            ParaSize.Write(pPara^.aPara[6]);
            ParaID.Write(NewParaID);
            ParaSubID.Write(NewParaSubID);
            
            if (pPara^.aPara[4] = 0) then // Read
              ParaRdWr.Write(pPara^.aPara[4]);
              ret_code := READY;
            elsif (pPara^.aPara[4] = 1) & // Write 
                  (pPara^.aPara[5]$^DINT) then  // Pointer Valid
              SetValue(pValue:=pPara^.aPara[5]$^DINT);
              ret_code := READY;
            end_if;
            
          elsif State = BUSY then
            ret_code := ERROR_BUSY; // Cannot add new asy command because last one is still running
          end_if;
  
        else  // Return previously read value
        
          ConvertParaId(ParaID        := pPara^.aPara[2]$UINT
                      , ParaSubID     := pPara^.aPara[3]$USINT
                      , pNewParaId    := #NewParaID
                      , pNewParaSubID := #NewParaSubID);
                      
          // Check if the ids are the same as before
          if (NewParaID       = ParaID.Read()) & 
             (NewParaSubID    = ParaSubID.Read()) then
            
            // Parameter is correct
            if State = READY then
            
              if (ParaRdWr = 0) &  // Read
                 (pPara^.aPara[4] >= ParaRdWr.Read()) & 
                 (pPara^.aPara[5]$^DINT) then  // Pointer Valid
                GetValue(pValue:=pPara^.aPara[5]$^DINT);
                ret_code := READY;
              else  // Write
                // Write succesfuly
                ret_code := READY;
              end_if;
            
            elsif State = BUSY then
              ret_code := BUSY;
            end_if;
          
          end_if;
        
        end_if;
        
      end_if;
  
  else
    ret_code := Drive_AsyncParaDS402::NewInst(pPara, pResult);
  end_case;

		
END_FUNCTION

FUNCTION MDD2000GeneralParaDS402::ConvertParaId
	VAR_INPUT
		ParaID 	: HINT;
		ParaSubID 	: HSINT;
		pNewParaId 	: ^HINT;
		pNewParaSubID 	: ^HSINT;
	END_VAR
  
  // TODO Implement lookuptable, for default convert 1:1
  
  pNewParaId^     := ParaID;
  pNewParaSubID^  := ParaSubID;

END_FUNCTION


FUNCTION VIRTUAL GLOBAL MDD2000GeneralParaDS402::RefreshPara
	VAR_INPUT
		hParaIndex 	: HINT;
		hsParaSubIndex 	: HSINT;
		bRW 	: DINT;
		bsDataInfo 	: BSINT;
		pValue 	: ^DINT;
	END_VAR
  
  if hParaIndex = ParaID & hsParaSubIndex = ParaSubID then
    ParaValue := pValue^;
    _memcpy(ptr1:=#aReadBuffer[0], ptr2:=pValue, cntr:=4*(ParaSize$USINT+1));
  end_if;

END_FUNCTION
