FUNCTION_BLOCK RA_PFx_ENET_PAR_WRITE
(*=====================================================================================================================================
	[UDFB Name]					:RA_PFx_ENET_PAR_WRITE (v6)     
	[Catagory]					:Communication
	[Description]				:Write a single PF4x or PF52x drive parameter over Ethernet using Explicit Messaging (v6)
	[Author]					:Rockwell Automation
	[Created using CCW version]	:6.01
	[FeedBack]					:RASampleCode@ra.rockwell.com
	[Revison History]			:2014-August - Original Release for Version 6
	[Notes]						:DO NOT USE THIS UDFB WITH MORE THAN 4 DRIVES IN A PROJECT - IF YOU DO, YOU WILL GET RANDOM MSG ERRORS!

 =====================================================================================================================================*)

FBENO := FBEN;
(*-------- Initialize --------*)
FBEN_RTRIG(FBEN);
IF (__SYSVA_FIRST_SCAN OR FBEN_RTRIG.Q) THEN
	MSGTimeOut_EN := TRUE;
	MSGParWrite_EN:= FALSE;
	TimeOutCtrlCfg.TriggerType		:= 1000; (*Triggers message every 1000 ms while MSGTimeOut_EN is true*)
	TimeOutTargetCfg.Path			:= '4,'+ IPAddress;
	TimeOutTargetCfg.CipConnMode	:= 0;    (*0-unconnected, 1-Class 3*)
	TimeOutTargetCfg.UcmmTimeout	:= 250;  (*Unconnected message time out, Set to 0 means 3000ms, range 250-10000*)
	TimeOutTargetCfg.ConnMsgTimeout	:= 800;  (*Class3 time out, Set to 0 means 3000ms, range 800-10000*)
	TimeOutTargetCfg.ConnClose		:= FALSE;(*Don't close the connection upon message completion*)
	TimeOutAppCfg.Service			:= 16; (*Service code 10h for Set Attribute Single*)
	TimeOutAppCfg.Class				:= 7;  (*Class code 7 for Register Object*)
	TimeOutAppCfg.Instance			:= 0;  (*Instance 0 for Class Attribute*)
	TimeOutAppCfg.Attribute			:= 100;(*Attribute 100 for Control Timeout*)
	
	IF EnetCtrlTO_sec <> 0 THEN 
   		TimeOutReqData[1]:= EnetCtrlTO_sec;	(*Set Ethernet Control Timeout value in seconds*)	
	ELSE	
		TimeOutReqData[1]:= 5; (*If 0 (invalid) set Ethernet Control Timeout to 5 seconds*)
	END_IF;	
		
	ParWriteCtrlCfg.TriggerType 	:= 0;
	ParWriteTargetCfg.Path			:= '4,'+ IPAddress;
	ParWriteTargetCfg.CipConnMode	:= 0;    (*0-unconnected, 1-Class 3*)
	ParWriteTargetCfg.UcmmTimeout	:= 250;  (*Unconnected message time out, Set to 0 means 3000ms, range 250-10000*)
	ParWriteTargetCfg.ConnMsgTimeout:= 800;  (*Class3 time out, Set to 0 means 3000ms, range 800-10000*)
	ParWriteTargetCfg.ConnClose		:= FALSE;(*Don't close the connection upon message completion*)
	ParWriteAppCfg.Service			:= 16;   (*Service code 10h for Set Attribute Single*)
	ParWriteAppCfg.Class			:= 15;   (*Class code 0Fh for Parameter Object*)
	ParWriteAppCfg.Instance			:= ANY_TO_UDINT(ParameterNumber);
	ParWriteAppCfg.Attribute		:= 1;    (*Attribute 1 for Parameter Value*)
	ParWriteReqData[1]				:= ANY_TO_USINT(AND_MASK(ANY_TO_DINT(ParameterValue), 2#0000_0000_1111_1111));
	ParWriteReqData[2]				:= ANY_TO_USINT(SHR(ANY_TO_DINT(ParameterValue), 8));
	CIPErrorStatus					:= NoErrorStatus;
END_IF;

(*-------- Main Routine --------*)
IF FBEN THEN
	MSGTimeOut_Q_RTRIG(MSGTimeOut.Q);
	MSGParWrite_Q_RTRIG(MSGParWrite.Q);
	
	IF MSGTimeOut_Q_RTRIG.Q THEN
		CIPErrorStatus	:= MSGTimeOut.Status;
		MSGTimeOut_EN	:= FALSE;
		MSGParWrite_EN	:= TRUE;
	END_IF;
	
	IF MSGParWrite_Q_RTRIG.Q THEN
		CIPErrorStatus	:= MSGParWrite.Status;
		MSGParWrite_EN	:= FALSE;
	END_IF;
	
	MSGTimeOut_Err_RTRIG(MSGTimeOut.Status.Error);
	MSGParWrite_Err_RTRIG(MSGParWrite.Status.Error);
	
	IF MSGTimeOut_Err_RTRIG.Q THEN
		CIPErrorStatus	:= MSGTimeOut.Status;
	END_IF;
	
	IF MSGParWrite_Err_RTRIG.Q THEN
		CIPErrorStatus	:= MSGParWrite.Status;
		MSGParWrite_EN	:= FALSE;
	END_IF;
	
ELSE
	MSGTimeOut_EN	:= FALSE;
	MSGParWrite_EN	:= FALSE;
	
END_IF;

MSGTimeOut(MSGTimeOut_EN, TimeOutCtrlCfg, TimeOutAppCfg, TimeOutTargetCfg, TimeOutReqData, 2,);
MSGParWrite(MSGParWrite_EN, ParWriteCtrlCfg, ParWriteAppCfg, ParWriteTargetCfg, ParWriteReqData, 2,);
END_FUNCTION_BLOCK