[D
	/RebootWithoutStart [P
		[A counts ]
		1 RebootDevice
		%8000 wait
		/Stopped #0 def
		counts [B 
			150 wait
			PIVar:TalkIntf.StopProgram
			PIVar:TalkIntf.GetResult 0 eq PIVar:TalkIntf.GetResult $DA eq or [B 
				/Stopped #1 def
				ExitLoop 
			] if
		] repeat 
		Stopped not [B
			'StopProgram' '' PIVar:TalkIntf.GetResult PackInst:_RaiseTalkError           
		] if
		[A ]   
	]
	
	/StartROS [P
		[A numOfTries waitAfterReset repeatReboot]
		1 RebootDevice
		/ROSrunning FALSE def
		/ROSVersionCurrent 0 def
		/ROSSubVersionCurrent 0 def
		'Starting the ROS...' log
		
		% store the current talk message timeout
		/MsgTimeout PIVar:TalkIntf.GetTimeout def
		
		% set the talk message timeout to 80 ms to catch the ROS
		80 PIVar:TalkIntf.SetTimeout
		
		waitAfterReset wait
		
		numOfTries [B
			% inhibits the startup of the OS and remains in the ROS

			$A0 chr $01 chr add PIVar:TalkIntf.GenericCmd
			/TalkResponse PIVar:TalkIntf.GetResult def
			TalkResponse 0 eq [B
				
				% prepare ROS version number
				/ROSVersionStr PIVar:TalkIntf.GetDataStr def
				/ROSSubVersionCurrent ROSSubVersionCurrent ROSVersionStr 0 1 getsubstr ord add def
				/ROSSubVersionCurrent ROSSubVersionCurrent ROSVersionStr 1 1 getsubstr ord 8 shl add def
				/ROSVersionCurrent ROSVersionCurrent ROSVersionStr 2 1 getsubstr ord add def
				/ROSVersionCurrent ROSVersionCurrent ROSVersionStr 3 1 getsubstr ord 8 shl add def
				
				% ROS started
				/ROSrunning TRUE def
				'ROS running' log
				'ROS version: V0x' ROSVersionCurrent 16 cvrs add ' S0x' add ROSSubVersionCurrent 16 cvrs add log
				ExitLoop
			]
			[B
				TalkResponse $FF eq repeatReboot and [B
					% reboot again if ROS was missed and reboot is enabled
					% (OS responds with $FF if the command $A0 $01 is sent to stay in the ROS)
					1 RebootDevice
				] if
			] ifelse
		] repeat
		
		% restore the talk message timeout to the initial value
		MsgTimeout PIVar:TalkIntf.SetTimeout
		
		ROSrunning not [B
			'ROS not present.' log
		] if
		
		[A ROSrunning ROSVersionCurrent ROSSubVersionCurrent]
	]
	
	/LoadSW [P
		[A LoadFlag ChangeInterface ]	% LoadFlag = False -> Check only if Files exist // ChangeInterface = True -> Curve and CMD Table will not be deleted
		/OSSWFileName 'UPOS_' def
		/UPROSBareFileName 'UPROS_' def
		/OSBareSWFileName 'OSSW_' def
		/SWUPROSFile '' def
		
		/Result #1 def
		/MissingFile '' def
		
		PackInst:CheckROS
		/ROSSubVersionCurrent exch def
		/ROSVersionCurrent exch def
		/ROSRunning exch def
		/ROSPresent exch def
		
		% If installing over Config Ethernet on E1400V2 the ROS is not used.
		% Instead an UPOS is downloaded which contains the ROS together with the OS.
		InstPortName 'ETH' eq [B
			/UPROSAvailable FALSE def
			/ROSPresent FALSE def
			/ROSRunning FALSE def
		] if
		
		
		% Build SW File name
		% ROS present or UPROSAvailable defined
		ROSPresent UPROSAvailable or [B
			% ROS is present, bare OS and tree needed
			/SWFile FilePath OSDir add '\' add OSBareSWFileName add OSExt add '_V' add OSSWVersion cvs add 'S' add OSSWSubVersion cvs add def
			
			% remanent OS updater
			/SWUPROSFile FilePath OSDir add '\' add UPROSBareFileName add 'V' add ROSSWVersion cvs add 'S' add ROSSWSubVersion cvs add '.HX3' add def
		]
		[B
			% UPROS is not available, conventional UPOS needed
			UPOSExt '' ne [B
				/SWFile FilePath OSDir add '\' add OSSWFileName add UPOSExt add '_V' add OSSWVersion cvs add 'S' add OSSWSubVersion cvs add def 
			]
			[B
				/SWFile FilePath OSDir add '\' add OSSWFileName add EloTypeExt add '_V' add OSSWVersion cvs add 'S' add OSSWSubVersion cvs add def 
			] ifelse  
		] ifelse
			
		OSSWBetaInfo '' ne [B
			/SWFile SWFile '_' add OSSWBetaInfo add def
		] if
		
		PIVar:TalkVersion $20 eq [B
			/SWFile SWFile '.HX2' add def		
		] 
		[B
			PIVar:TalkVersion $40 eq [B
				ProgFlag [B
				     /SWFile SWFile '.HX2' add def 
				] [B
					'Installation error 0x012 occurred. Please contact support.' raisese 
				] ifelse
			]
			[B
				/SWFile SWFile '.HX3' add def		
			] ifelse  
		] ifelse
		
		
		% Build Tree File name
		OSTypeExt '' ne [B
		  /TreeFile FilePath OSDir add '\' add OSTreeFileName add OSTypeExt add '_V' add OSTreeVersion cvs add 'S' add OSTreeSubVersion cvs add def 		
		]
		[B
		  /TreeFile FilePath OSDir add '\' add OSTreeFileName add EloTypeExt add '_V' add OSTreeVersion cvs add 'S' add OSTreeSubVersion cvs add def 
		] ifelse  
		OSTreeBetaInfo '' ne [B
			/TreeFile TreeFile '_' add OSTreeBetaInfo add def
		] if
		/TreeFile TreeFile '.HX2' add def
		
		
		% Build DefaultPar File name
		OSTypeExt '' ne [B
		  /DefaultParFile FilePath OSDir add '\' add OSTreeFileName add OSTypeExt add '_V' add OSTreeVersion cvs add 'S' add OSTreeSubVersion cvs add def 		
		]
		[B
		  /DefaultParFile FilePath OSDir add '\' add OSTreeFileName add EloTypeExt add '_V' add OSTreeVersion cvs add 'S' add OSTreeSubVersion cvs add def 
		] ifelse  
		OSTreeBetaInfo '' ne [B
			/DefaultParFile DefaultParFile '_' add OSTreeBetaInfo add def
		] if
		/DefaultParFile DefaultParFile '.Gr3' add def				
		
		
		% Build 2S Tree File name
		OSTreeFileName2S ''  ne [B
			_2SOSTypeExt '' ne [B
			  /TreeFile2S FilePath SafetyFWDir add '\' add OSTreeFileName2S add _2SOSTypeExt add '_V' add OSTreeVersion2S cvs add 'S' add OSTreeSubVersion2S cvs add def 		
			][B
			  /TreeFile2S FilePath SafetyFWDir add '\' add OSTreeFileName2S add EloTypeExt add '_V' add OSTreeVersion2S cvs add 'S' add OSTreeSubVersion2S cvs add def 
			] ifelse  
			OSTreeBetaInfo2S '' ne [B
				/TreeFile2S TreeFile2S '_' add OSTreeBetaInfo2S add def
			] if
			/TreeFile2S TreeFile2S '.HX2' add def
		] if 
		
		
		% check if files are existing
		Result [B
			SWFile FileExist not [B
				/Result #0 def 
				/MissingFile SWFile def
			] if
		] if
		Result [B
			TreeFile FileExist not [B
				/Result #0 def 
				/MissingFile TreeFile def
			] if
		] if
		Result [B
			DefaultParFile FileExist not [B
				/Result #0 def 
				/MissingFile DefaultParFile def
			] if
		] if
		Result [B
			OSTreeFileName2S '' ne [B
				TreeFile2S FileExist not [B
					/Result #0 def 
					/MissingFile TreeFile2S	def
				] if 
			] if		
		] if
		
		
		Result LoadFlag and [B
			
			PIVar:TalkVersion $F0 and [B
				
				% E1250 / E1450 / B8050 / MB8050
				$30 [B
					% clear OS install command address
					OSInstallCommandAddress 0 WriteWordToElo
					
					PIVar:PortType 'ETH' eq ProgFlag not and [B
						/IPConfigMode IPConfigModeAddr ReadMemory def
						/CfgMasterTimeOut CfgMasterTimeOutAddr ReadMemory def
						/DefGWConfigMode DefGWConfigModeAddr ReadMemory def
						
						% read the static IP address, network mask and gateway
						/IPAddressLo IPAddressAddr ReadMemory def
						/IPAddressHi IPAddressAddr 2 add ReadMemory def
						/NetMaskLo NetMaskAddr ReadMemory def
						/NetMaskHi NetMaskAddr 2 add ReadMemory def		
						/DefaultGatewayLo DefaultGatewayAddr ReadMemory def
						/DefaultGatewayHi DefaultGatewayAddr 2 add ReadMemory def
						
						% read the working IP address, network mask and gateway
						/IPAddressWorkLo IPAddressAddrWorking ReadMemory def
						/IPAddressWorkHi IPAddressAddrWorking 2 add ReadMemory def
						/NetMaskWorkLo NetMaskAddrWorking ReadMemory def
						/NetMaskWorkHi NetMaskAddrWorking 2 add ReadMemory def		
						/DefaultGatewayWorkLo DefaultGatewayAddrWorking ReadMemory def
						/DefaultGatewayWorkHi DefaultGatewayAddrWorking 2 add ReadMemory def
						
						% write the static IP address, network mask and gateway
						IPAddressAddr IPAddressWorkLo WriteWordToElo
						IPAddressAddr 2 add IPAddressWorkHi WriteWordToElo
						NetMaskAddr NetMaskWorkLo WriteWordToElo
						NetMaskAddr 2 add NetMaskWorkHi WriteWordToElo
						DefaultGatewayAddr DefaultGatewayWorkLo WriteWordToElo
						DefaultGatewayAddr 2 add DefaultGatewayWorkHi WriteWordToElo
						
						% set the config mode to static
						IPConfigModeAddr 2 WriteWordToElo
						DefGWConfigModeAddr 1 WriteWordToElo
					] if		
					
					20 OSLoader:RebootWithoutStart
					ChangeInterface not [B
						'Erasing curve and command table firmware sectors...' log
						$AFE00000 PackInst:EraseFlash	% CURVE
						$AFE10000 PackInst:EraseFlash	% CT
					] if	
					
					% Read drive
					% Get SW CRC
					/CRC_drive_SW OS_SW_CRC_Addr PackInst:_GetBlock def
					
					% Get Tree CRC
					/CRC_drive_Tr OS_Tr_CRC_Addr PackInst:_GetBlock def
					
					% Get SW file name
					/Filename_read_SW OS_SW_FileName_Addr GetInstalledFileName uppercase def
					% Rename OS SW file name to match name with UPOS
					/Filename_read_SW Filename_read_SW 0 'UPOS' putsubstr def
					
					% Get Tree file name
					/Filename_read_Tr OS_Tr_FileName_Addr GetInstalledFileName uppercase def
					
					
					% Read file
					% Get SW CRC
					getcurrentdir '\' add SWFile add OS_SW_CRC_Addr_f SystGen_CRC crcfromfile
					/Res exch def
					/CRC_file_SW exch def
					
					% Get Tree CRC
					getcurrentdir '\' add TreeFile add OS_Tr_CRC_Addr SystGen_CRC crcfromfile
					/Res exch def
					/CRC_file_Tr exch def
					
					% Get SW file name
					/Filename_file_SW SWFile extfilename '' chfileext uppercase def
					
					% Get Tree file name
					/Filename_file_Tr TreeFile extfilename '' chfileext uppercase def
					
					% Check CRC
					CRC_file_SW CRC_invalid1 eq
					CRC_file_SW CRC_invalid2 eq or [B
						'File: ' SWFile extfilename add ' is corrupted!' add log
						/Result #0 def
					] if
					
					CRC_file_Tr CRC_invalid1 eq
					CRC_file_Tr CRC_invalid2 eq or [B
						'File: ' TreeFile extfilename add ' is corrupted!' add log
						/Result #0 def
					] if
					
					
					Result [B
						/InstallSW
							Filename_file_SW Filename_read_SW ne
							CRC_file_SW CRC_drive_SW ne or def
						
						/InstallTr
							Filename_file_Tr Filename_read_Tr ne
							CRC_file_Tr CRC_drive_Tr ne or def
						
						InstallSW InstallTr or [B
							'Erasing firmware sectors...' log
							1 EraseSWInstance
							2 EraseSWInstance
							3 EraseSWInstance
							
							% UPOS is written in MC part. For UPOS be able to start, MC installation valid flag must be true. Set all other installation valid flags to false
							OSInstallValidAddr   InstallationInvalid WriteWordToElo
							MCInstallValidAddr   InstallationValid   WriteWordToElo
							INTFInstallValidAddr InstallationInvalid WriteWordToElo
							APPLInstallValidAddr InstallationInvalid WriteWordToElo
							
							'Downloading ' SWFile add log
							SWFile dup loadobj exch PackInst:DownloadHX3File
							
							% AutoStart OS Updater after reset
							'Reset device...' log
							ResetDevice
							'Waiting for OS reply...' log
							45000 wait
							
							% Reset MC installation valid flag
							MCInstallValidAddr InstallationInvalid WriteWordToElo
						][B
							'Download OS SW firmware skipped. Already up to date...' log
							'Download OS Tree firmware skipped. Already up to date...' log
						] ifelse
						
						% Program FM04
						OSLoader:Download_FM04_SG5
						
						PIVar:PortType 'ETH' eq ProgFlag not and [B
							% write the static IP address, network mask and gateway to the old values
							IPAddressAddr IPAddressLo WriteWordToElo
							IPAddressAddr 2 add IPAddressHi WriteWordToElo
							NetMaskAddr NetMaskLo WriteWordToElo
							NetMaskAddr 2 add NetMaskHi WriteWordToElo
							DefaultGatewayAddr DefaultGatewayLo WriteWordToElo
							DefaultGatewayAddr 2 add DefaultGatewayHi WriteWordToElo
							
							% set the config modes to the old values
							IPConfigModeAddr IPConfigMode WriteWordToElo
							CfgMasterTimeOut 0 eq [B
								CfgMasterTimeOutAddr CfgMasterTimeOut WriteWordToElo		% only if Lock is disabled
							] if
							DefGWConfigModeAddr DefGWConfigMode WriteWordToElo
						] if
					] if
				]
				
				% A1100, C1100
				$50 [B
					/SystemStartupDelayAddress	$300906	def
					/ActualBaudrateAddress		$30089A	def
					
					ChangeInterface not [B
						'Erasing curve and command table firmware sectors...' log
						0 1 3 [B
							/SectorIndex exch def
							$D80000 $1000 SectorIndex mul add PackInst:EraseFlash	% CT
						] for	
						0 1 7 [B
							/SectorIndex exch def
							$D88000 $1000 SectorIndex mul add PackInst:EraseFlash	% CURVE
						] for
					] if	
					
					% Read drive
					% Get SW CRC
					/CRC_drive_SW OS_SW_CRC_Addr PackInst:_GetBlock def
					
					% Get Tree CRC
					/CRC_drive_Tr OS_Tr_CRC_Addr PackInst:_GetBlock def
					
					% Get SW file name
					/Filename_read_SW OS_SW_FileName_Addr GetInstalledFileName uppercase def
					% Rename OS SW file name to match name with UPOS
					/Filename_read_SW Filename_read_SW 0 'UPOS' putsubstr def
					
					% Get Tree file name
					/Filename_read_Tr OS_Tr_FileName_Addr GetInstalledFileName uppercase def
					
					
					% Read file
					% Get SW CRC
					getcurrentdir '\' add SWFile add OS_SW_CRC_Addr_f SystGen_CRC crcfromfile
					/Res exch def
					/CRC_file_SW exch def

					% Get Tree CRC
					getcurrentdir '\' add TreeFile add OS_Tr_CRC_Addr SystGen_CRC crcfromfile
					/Res exch def
					/CRC_file_Tr exch def
					
					% Get SW file name
					/Filename_file_SW SWFile extfilename '' chfileext uppercase def
					
					% Get Tree file name
					/Filename_file_Tr TreeFile extfilename '' chfileext uppercase def
					
					% Check CRC
					CRC_file_SW CRC_invalid1 eq
					CRC_file_SW CRC_invalid2 eq or [B
						'File: ' SWFile extfilename add ' is corrupted!' add log
						/Result #0 def
					] if
					
					CRC_file_Tr CRC_invalid1 eq
					CRC_file_Tr CRC_invalid2 eq or [B
						'File: ' TreeFile extfilename add ' is corrupted!' add log
						/Result #0 def
					] if
					
					
					Result [B
						/InstallSW
							Filename_file_SW Filename_read_SW ne
							CRC_file_SW CRC_drive_SW ne or def
						
						/InstallTr
							Filename_file_Tr Filename_read_Tr ne
							CRC_file_Tr CRC_drive_Tr ne or def
							
						InstallSW InstallTr or [B
							'Erasing firmware sectors...' log
							1 EraseSWInstance
							2 EraseSWInstance
							3 EraseSWInstance
							
							% UPOS is written in MC part. For UPOS be able to start, MC installation valid flag must be true. Set all other installation valid flags to false
							OSInstallValidAddr   InstallationInvalid WriteWordToElo
							MCInstallValidAddr   InstallationValid   WriteWordToElo
							INTFInstallValidAddr InstallationInvalid WriteWordToElo
							APPLInstallValidAddr InstallationInvalid WriteWordToElo
							
							% Save Actual Baudrate before defaulting OS Parameters
							/ActualBaudrate ActualBaudrateAddress ReadMemory def
							
							'Downloading ' SWFile add log
							SWFile dup loadobj exch PackInst:DownloadHX3File
							
							SystemStartupDelayAddress 0 WriteWordToElo
							
							% AutoStart OS Updater after reset
							'Reset device...' log
							ResetDevice
							'Waiting for OS reply...' log
							10000 wait
							
							% trigger Bootup bit on next re-boot
							/OSInstallCommand OSInstallCommandAddress ReadMemory def
							/OSInstallCommand OSInstallCommand $0002 or def
							OSInstallCommandAddress OSInstallCommand WriteWordToElo
							
							StartProgram

							10000 wait
							90[B
								OSInstallCommandAddress PIVar:TalkIntf.ReadMemory
								PIVar:TalkIntf.GetResult 0 eq[B
									/InstallCommandReadData PIVar:TalkIntf.GetData def
									/InstallCommandReadData InstallCommandReadData $2 and def
									InstallCommandReadData 0 eq[B
										exitloop
									] if
								]if
								500 Wait
							] repeat
							
							% Reload Actual Baudrate after defaulting OS Parameters
							ActualBaudrateAddress ActualBaudrate WriteWordToElo
							
							% Reset MC installation valid flag
							MCInstallValidAddr InstallationInvalid WriteWordToElo
						][B
							'Download OS SW firmware skipped. Already up to date...' log
							'Download OS Tree firmware skipped. Already up to date...' log
						] ifelse
					] if
				]

				% C1250, E1400V2
				$60 [B
					ChangeInterface OSLoader:DownloadOS_SG6
					/Result exch def
				]
				
				% C12502S
				$70 [B
					ChangeInterface OSLoader:DownloadOS_SG6
					/Result exch def
				]

			]
			[B
				%
			] case
			
%			'Clearing MC Parameter Section...' log
%			2 PIVar:TalkIntf.ClearInstancePar
%			'Clearing Intf Parameter Section...' log
%			3 PIVar:TalkIntf.ClearInstancePar
%			'Clearing Appl Parameter Section...' log
%			4 PIVar:TalkIntf.ClearInstancePar
			
			% Write new Firmware message to controller
			/OSInstallCommand OSInstallCommandAddress ReadMemory def
			/OSInstallCommand OSInstallCommand $0001 or def
			OSInstallCommandAddress OSInstallCommand WriteWordToElo
			
		] if
		[A /MissingFile /Result]
	]


	/DownloadOS_SG6 [P
		[A  ]

		/Result #1 def
		
		PIVar:PortType 'ETH' eq ProgFlag not and [B
			/IPConfigMode IPConfigModeAddr ReadMemory def
			/DefGWConfigMode DefGWConfigModeAddr ReadMemory def
			
			% read the static IP address, network mask and gateway
			/IPAddressLo IPAddressAddr ReadMemory def
			/IPAddressHi IPAddressAddr 2 add ReadMemory def
			/NetMaskLo NetMaskAddr ReadMemory def
			/NetMaskHi NetMaskAddr 2 add ReadMemory def
			/DefaultGatewayLo DefaultGatewayAddr ReadMemory def
			/DefaultGatewayHi DefaultGatewayAddr 2 add ReadMemory def
			
			% read the working IP address, network mask and gateway
			/IPAddressWorkLo IPAddressAddrWorking ReadMemory def
			/IPAddressWorkHi IPAddressAddrWorking 2 add ReadMemory def
			/NetMaskWorkLo NetMaskAddrWorking ReadMemory def
			/NetMaskWorkHi NetMaskAddrWorking 2 add ReadMemory def
			/DefaultGatewayWorkLo DefaultGatewayAddrWorking ReadMemory def
			/DefaultGatewayWorkHi DefaultGatewayAddrWorking 2 add ReadMemory def
			
			% write the static IP address, network mask and gateway
			IPAddressAddr IPAddressWorkLo WriteWordToElo
			IPAddressAddr 2 add IPAddressWorkHi WriteWordToElo
			NetMaskAddr NetMaskWorkLo WriteWordToElo
			NetMaskAddr 2 add NetMaskWorkHi WriteWordToElo
			DefaultGatewayAddr DefaultGatewayWorkLo WriteWordToElo
			DefaultGatewayAddr 2 add DefaultGatewayWorkHi WriteWordToElo
			
			% set the config mode to static
			IPConfigModeAddr 2 WriteWordToElo
			DefGWConfigModeAddr 1 WriteWordToElo
		] if

		/ROSUpgrade FALSE def

		ROSPresent [B
			'ROS present' log

			ROSRunning not [B
				250 50 TRUE OSLoader:StartROS
				/ROSSubVersionCurrent exch def
				/ROSVersionCurrent exch def
				/ROSrunning exch def
			]
			[B
				'ROS already running' log
				% "ROS already running" indicates possible invalid OS
				% no ROS update possible without valid OS
				% avoid ROS update by setting current version to wanted version
				/ROSSubVersionCurrent ROSSWSubVersion def
				/ROSVersionCurrent ROSSWVersion def
			] ifelse

			% check programmer flag, different ROS update behaviour on programmer
			ProgFlag not [B
				% not on programmer, only update for different main version
				
				% check ROS version
				ROSSWVersion ROSVersionCurrent ne [B
					% ROS needs to be up/downgraded

					/ROSUpgrade TRUE def
					'up/downgrade ROS' log
				] if
			]
			[B
				% programmer, update ROS even for different subversion
				ROSSWVersion ROSVersionCurrent ne ROSSWSubVersion ROSSubVersionCurrent ne or [B
					% ROS needs to be up/downgraded

					/ROSUpgrade TRUE def
					'up/downgrade ROS' log
				] if
			] ifelse

		] if
		
		ChangeInterface not [B
			'Erasing curve and command table firmware sectors...' log
			$AF000000 PackInst:EraseFlash % CURVE
			250 wait % give switch some time to process eth frames received while erasing flash which is blocking
			$AF080000 PackInst:EraseFlash % CT
			250 wait % give switch some time to process eth frames received while erasing flash which is blocking
		] if
		
		ROSrunning not ROSUpgrade or [B
			SWUPROSFile '' ne [B
				% Reset installation valid flags
				OSInstallValidAddr   InstallationInvalid WriteWordToElo
				MCInstallValidAddr   InstallationInvalid WriteWordToElo
				INTFInstallValidAddr InstallationInvalid WriteWordToElo
				APPLInstallValidAddr InstallationInvalid WriteWordToElo
				
				'Erasing firmware sectors...' log
				1 EraseSWInstance
				2 EraseSWInstance
				3 EraseSWInstance
				OSTreeFileName2S '' ne [B
					$8081C000 PackInst:EraseFlash % 2S Tree
				] if
				
				% ROS updater must be downloaded
				'Downloading ' SWUPROSFile add log
				20 OSLoader:RebootWithoutStart
				SWUPROSFile dup loadobj exch PackInst:DownloadHX3File % Load ROS Updater
				
				% UPOS is written in MC part. For UPOS be able to start, MC installation valid flag must be true
				MCInstallValidAddr InstallationValid WriteWordToElo
				
				% deactivate install new FPGA image bit to make sure nothing happens if device does not contain an FM04
				/OSInstallCommand OSInstallCommandAddress ReadMemory def
				/OSInstallCommand OSInstallCommand $FFEF and def
				OSInstallCommandAddress OSInstallCommand WriteWordToElo

				% wait for a longer time before checking for ROS as the OS must run the ROS updater
				1500 10000 TRUE OSLoader:StartROS
				/ROSSubVersionCurrent exch def
				/ROSVersionCurrent exch def
				/ROSrunning exch def

				ROSrunning not [B
					'ROS download failed!' log
				] if
				
				% Reset MC installation valid flag
				MCInstallValidAddr InstallationInvalid WriteWordToElo
			] if
		] if
		
		ROSrunning [B
			% ROS active

			/InstVal OSInstallValidAddr PackInst:ReadMemory def
			
			InstVal InstallationValid ne [B
				'Erasing OS SW firmware sectors...' log
				0 EraseSWInstance
			
				OSInstallValidAddr InstallationInvalid WriteWordToElo
				
				'Downloading ' SWFile add log
				SWFile dup loadobj exch PackInst:DownloadHX3File
				
				'Downloading ' TreeFile add log
				TreeFile dup loadobj exch PackInst:DownloadHX2File
			][B
				% Read drive
				% Get SW CRC
				/CRC_drive_SW OS_SW_CRC_Addr PackInst:_GetBlock def
				
				% Get Tree CRC
				/CRC_drive_Tr OS_Tr_CRC_Addr PackInst:_GetBlock def

				% Get SW file name
				/Filename_read_SW OS_SW_FileName_Addr GetInstalledFileName uppercase def
				
				% Get Tree file name
				/Filename_read_Tr OS_Tr_FileName_Addr GetInstalledFileName uppercase def
				
				
				% Read file
				% Get SW CRC
				getcurrentdir '\' add SWFile add OS_SW_CRC_Addr SystGen_CRC crcfromfile
				/Res exch def
				/CRC_file_SW exch def
				
				% Get Tree CRC
				getcurrentdir '\' add TreeFile add OS_Tr_CRC_Addr SystGen_CRC crcfromfile
				/Res exch def
				/CRC_file_Tr exch def

				% Get SW file name
				/Filename_file_SW SWFile extfilename '' chfileext uppercase def
				
				% Get Tree file name
				/Filename_file_Tr TreeFile extfilename '' chfileext uppercase def
			
				% Check CRC
				CRC_file_SW CRC_invalid1 eq
				CRC_file_SW CRC_invalid2 eq or [B
					'File: ' SWFile extfilename add ' is corrupted!' add log
					/Result #0 def
				] if
				
				CRC_file_Tr CRC_invalid1 eq
				CRC_file_Tr CRC_invalid2 eq or [B
					'File: ' TreeFile extfilename add ' is corrupted!' add log
					/Result #0 def
				] if
				
				
				Result [B
					/InstallSW
						Filename_file_SW Filename_read_SW ne
						CRC_file_SW CRC_drive_SW ne or def
					
					/InstallTr
						Filename_file_Tr Filename_read_Tr ne
						CRC_file_Tr CRC_drive_Tr ne or def
					
					InstallSW [B
						'Erasing OS SW firmware sector...' log
						10 EraseSWInstance
						
						OSInstallValidAddr InstallationInvalid WriteWordToElo
						
						'Downloading ' SWFile add log
						SWFile dup loadobj exch PackInst:DownloadHX3File
					][B
						'Download OS SW firmware skipped. Already up to date...' log
					] ifelse
					
					InstallTr [B
						'Erasing OS Tree firmware sector...' log
						100 EraseSWInstance
						
						OSInstallValidAddr InstallationInvalid WriteWordToElo
						
						'Downloading ' TreeFile add log
						TreeFile dup loadobj exch PackInst:DownloadHX2File
					][B
						'Download OS Tree firmware skipped. Already up to date...' log
					] ifelse
				] if
			] ifelse

			OSTreeFileName2S '' ne [B
				% Read drive
				% Get Tree CRC
				/CRC_drive_Tr SAFE_Tr_CRC_Addr PackInst:_GetBlock def
				
				% Get Tree file name
				/Filename_read_Tr SAFE_Tr_FileName_Addr GetInstalledFileName uppercase def
				
				
				% Read file
				% Get Tree CRC
				getcurrentdir '\' add TreeFile2S add SAFE_Tr_CRC_Addr SystGen_CRC crcfromfile
				/Res exch def
				/CRC_file_Tr exch def
				
				% Get Tree file name
				/Filename_file_Tr TreeFile2S extfilename '' chfileext uppercase def
				
				% Check CRC
				CRC_file_Tr CRC_invalid1 eq
				CRC_file_Tr CRC_invalid2 eq or [B
					'File: ' TreeFile2S extfilename add ' is corrupted!' add log
					/Result #0 def
				] if
				
				
				Result [B
					/InstallTr
						Filename_file_Tr Filename_read_Tr ne
						CRC_file_Tr CRC_drive_Tr ne or def
					
					InstallTr [B
						'Erasing 2S Tree firmware sector...' log
						104 EraseSWInstance
						
						'Downloading ' TreeFile2S add log
						TreeFile2S dup loadobj exch PackInst:DownloadHX2File
					][B
						'Download 2S Tree firmware skipped. Already up to date...' log
					] ifelse
				] if
			] if 
			
			ResetDevice

			% wait for OS to be running
			100 [B
				100 wait
				PackInst:CheckROS
				/OSROSSubVersionCurrent exch def
				/OSROSVersion exch def
				/ROSRunning exch def
				/ROSPresent exch def
				ROSRunning not ROSPresent and [B
					'OS running' log
					exitloop
				] if
			] repeat
			
			ROSRunning [B
				'Unable to start OS' log
			] if
		]
		[B
			% UPROS not available
			
			% Read drive
			% Get SW CRC
			/CRC_drive_SW OS_SW_CRC_Addr PackInst:_GetBlock def
			
			% Get Tree CRC
			/CRC_drive_Tr OS_Tr_CRC_Addr PackInst:_GetBlock def
			
			% Get SW file name
			/Filename_read_SW OS_SW_FileName_Addr GetInstalledFileName uppercase def
			% Rename OS SW file name to match name with UPOS
			/Filename_read_SW Filename_read_SW 0 'UPOS' putsubstr def
			
			% Get Tree file name
			/Filename_read_Tr OS_Tr_FileName_Addr GetInstalledFileName uppercase def
			
			
			% Read file
			% Get SW CRC
			getcurrentdir '\' add SWFile add OS_SW_CRC_Addr_f SystGen_CRC crcfromfile
			/Res exch def
			/CRC_file_SW exch def
			
			% Get Tree CRC
			getcurrentdir '\' add TreeFile add OS_Tr_CRC_Addr SystGen_CRC crcfromfile
			/Res exch def
			/CRC_file_Tr exch def
			
			% Get SW file name
			/Filename_file_SW SWFile extfilename '' chfileext uppercase def
			
			% Get Tree file name
			/Filename_file_Tr TreeFile extfilename '' chfileext uppercase def
			
			% Check CRC
			CRC_file_SW CRC_invalid1 eq
			CRC_file_SW CRC_invalid2 eq or [B
				'File: ' SWFile extfilename add ' is corrupted!' add log
				/Result #0 def
			] if
			
			CRC_file_Tr CRC_invalid1 eq
			CRC_file_Tr CRC_invalid2 eq or [B
				'File: ' TreeFile extfilename add ' is corrupted!' add log
				/Result #0 def
			] if
			
			
			Result [B
				/InstallSW
					Filename_file_SW Filename_read_SW ne
					CRC_file_SW CRC_drive_SW ne or def
				
				/InstallTr
					Filename_file_Tr Filename_read_Tr ne
					CRC_file_Tr CRC_drive_Tr ne or def
				
				InstallSW InstallTr or [B
					'Erasing firmware sectors...' log
					1 EraseSWInstance
					2 EraseSWInstance
					3 EraseSWInstance
					100 EraseSWInstance
					
					'Downloading ' SWFile add log
					20 OSLoader:RebootWithoutStart
					SWFile dup loadobj exch PackInst:DownloadHX3File

					'Downloading ' TreeFile add log
					TreeFile dup loadobj exch PackInst:DownloadHX2File
					
					% UPOS is written in MC part. For UPOS be able to start, MC installation valid flag must be true
					MCInstallValidAddr InstallationValid WriteWordToElo
					
					% Set OS and APPL installation valid flags to false
					OSInstallValidAddr InstallationInvalid WriteWordToElo
					INTFInstallValidAddr InstallationInvalid WriteWordToElo
					APPLInstallValidAddr InstallationInvalid WriteWordToElo
					
					% deactivate install new FPGA image bit to make sure nothing happens if device does not contain an FM04
					% and trigger Bootup bit on next re-boot
					/OSInstallCommand OSInstallCommandAddress ReadMemory def
					/OSInstallCommand OSInstallCommand $FFEF and def
					/OSInstallCommand OSInstallCommand $0002 or def
					OSInstallCommandAddress OSInstallCommand WriteWordToElo
					
					% AutoStart OS Updater after reset
					'Reset device...' log
					ResetDevice
					'Waiting for OS reply...' log
					10000 wait
					120[B
						OSInstallCommandAddress PIVar:TalkIntf.ReadMemory
						PIVar:TalkIntf.GetResult 0 eq[B
							/InstallCommandReadData PIVar:TalkIntf.GetData def
							/InstallCommandReadData InstallCommandReadData $2 and def
							InstallCommandReadData 0 eq[B
								exitloop
							] if
						]if
						500 Wait
					] repeat
					
					% Reset MC installation valid flag
					MCInstallValidAddr InstallationInvalid WriteWordToElo
				][B
					'Download OS SW firmware skipped. Already up to date...' log
					'Download OS Tree firmware skipped. Already up to date...' log
				] ifelse
			] if
		] ifelse

		% OS running
		
		% clear OS install command address
		OSInstallCommandAddress 0 WriteWordToElo

		% download second stage bootloader for netX
		netX90Based not[B
			netXBased [B
				/netXBootloaderData_lw $808C0004 ReadMemory def
				/netXBootloaderData_hw $808C0006 ReadMemory def
				
				netXBootloaderData_lw $AF00 ne
				netXBootloaderData_hw $F8BE ne or [B
					'Erasing netX bootloader sector...' log
					$808C0000 PackInst:EraseFlash % netX second stage bootloader
					250 wait % give switch some time to process eth frames received while erasing flash which is blocking
					
					/MissingFile '' def
					/ModuleParFile FilePath OSDir add '\netX\NETX52-BSL_V1_4_18_0_FM09_2_1_0.HX2' add def
					ModuleParFile FileExist not [B
						/MissingFile ModuleParFile def
					] if

					'Downloading ' ModuleParFile add log
					ModuleParFile dup loadobj exch PackInst:DownloadHX2File
				][B
					'Download netX bootloader skipped. Already up to date...' log
				] ifelse
			] if
		] if

		OSLoader:Download_FM04_SG6

		PIVar:PortType 'ETH' eq ProgFlag not and [B
			IPAddressAddr IPAddressLo WriteWordToElo
			IPAddressAddr 2 add IPAddressHi WriteWordToElo
			NetMaskAddr NetMaskLo WriteWordToElo
			NetMaskAddr 2 add NetMaskHi WriteWordToElo
			DefaultGatewayAddr DefaultGatewayLo WriteWordToElo
			DefaultGatewayAddr 2 add DefaultGatewayHi WriteWordToElo
			
			% set the config modes to the old values
			IPConfigModeAddr IPConfigMode WriteWordToElo
			DefGWConfigModeAddr DefGWConfigMode WriteWordToElo
		] if

		[A  /Result]
	]
	
	/Download_FM04_SG5 [P
		[A  ]

		IntfSel.Name 'POWERLINK' eq IntfSel.Name 'POWERLINK_ML' eq or [B
			
			/ModuleFWType		$0100 def	% PL
			/ModuleFWVersion	$0103 def	% latest compatibel FW Version: Version 1, Subversion 3
			/ModuleHWVersion	$0103 def	% latest HW Version: Version 1, Revision B
			
			/ModuleFWTypeAddress $A3000070 def
			/ModuleFWVersionAddress $A3000072 def
			/ModuleHWVersionAddress $A3000002 def
			
			/MissingFile '' def
			/ModuleParFile FilePath IntfSel.IntfDir add IntfSel.IntfModuleOSUP add def
				ModuleParFile FileExist not [B
				/MissingFile ModuleParFile def
			] if

			/ModuleFWTypeRead  ModuleFWTypeAddress ReadMemory def
			/ModuleFWVersionRead  ModuleFWVersionAddress ReadMemory def
			/ModuleHWVersionRead  ModuleHWVersionAddress ReadMemory def
			/ModuleType  $A3000000 ReadMemory def
			
			% check HW module version
			ModuleHWVersionRead ModuleHWVersion ge[B
			% Module HW >= V1.0.2
				ModuleType $40 eq [B
					ModuleFWTypeRead ModuleFWType ne ModuleFWVersionRead ModuleFWVersion lt ModuleFWVersionRead $FFFF eq or or [B
						
						% INTF SW must be deleted. OSUP for FPGA is placed in INTF SW sectors
						2 EraseSWInstance
						
						INTFInstallValidAddr InstallationInvalid WriteWordToElo
						
						'Downloading ' ModuleParFile add log
						ModuleParFile dup loadobj exch PackInst:DownloadHX2File	% load OSUP for FPGA
						
						% Write install new FPGA image controller
						/OSInstallCommand OSInstallCommandAddress ReadMemory def
						/OSInstallCommand OSInstallCommand $0010 or def
						OSInstallCommandAddress OSInstallCommand WriteWordToElo
						
						% AutoStart FPGA Updater after reset
						ResetDevice
						'Updating FPGA...' log
						80000 wait
						
						% erase FPGA image
						$80040000 PackInst:EraseFlash
						250 wait % give switch some time to process eth frames received while erasing flash which is blocking
						
						% write new FPGA version info
						ModuleFWTypeAddress ModuleFWType WriteWordToElo
						ModuleFWVersionAddress ModuleFWVersion WriteWordToElo
					]
					[B
						'Update POWERLINK module skipped. Already up to date...' log
					] ifelse
				]
				[B
					'Warning: POWERLINK module is not connected!' log
				] ifelse
			]
			[B
				/Result #0 def
				'Warning: POWERLINK module HW Version older than V1.0.2!' log
			] ifelse
		] if
		
		IntfSel.Name 'SERCOSIII' eq IntfSel.Name 'SERCOSIII_ML' eq or [B
			
			/ModuleFWType		$0200 def		% SC
			/ModuleFWVersion	$0102 def		% Version 1, Subversion 2 (sercon100 V2.11)
			
			/ModuleFWTypeAddress $A3000070 def
			/ModuleFWVersionAddress $A3000072 def
			
			/MissingFile '' def
			/ModuleParFile FilePath IntfSel.IntfDir add IntfSel.IntfModuleOSUP add def
				ModuleParFile FileExist not [B
				/MissingFile ModuleParFile def
			] if

			/ModuleFWTypeRead  ModuleFWTypeAddress ReadMemory def
			/ModuleFWVersionRead  ModuleFWVersionAddress ReadMemory def
			/ModuleType  $A3000000 ReadMemory def
			
			ModuleType $40 eq [B
				ModuleFWTypeRead ModuleFWType ne ModuleFWVersionRead ModuleFWVersion lt ModuleFWVersionRead $FFFF eq or or [B
					
					% INTF SW must be deleted. OSUP for FPGA is placed in INTF SW sectors
					2 EraseSWInstance
					
					INTFInstallValidAddr InstallationInvalid WriteWordToElo
					
					'Downloading ' ModuleParFile add log
					ModuleParFile dup loadobj exch PackInst:DownloadHX2File	% load OSUP for FPGA
					
					% Write install new FPGA image controller
					/OSInstallCommand OSInstallCommandAddress ReadMemory def
					/OSInstallCommand OSInstallCommand $0010 or def
					OSInstallCommandAddress OSInstallCommand WriteWordToElo
					
					% AutoStart FPGA Updater after reset
					ResetDevice
					'Updating FPGA...' log
					80000 wait
					
					% erase FPGA image
					$80040000 PackInst:EraseFlash
					250 wait % give switch some time to process eth frames received while erasing flash which is blocking
					
					% write new FPGA version info
					ModuleFWTypeAddress ModuleFWType WriteWordToElo
					ModuleFWVersionAddress ModuleFWVersion WriteWordToElo
			
				]
				[B
					'Update SERCOSIII module skipped. Already up to date...' log
				] ifelse
			]
			[B
				'Warning: SERCOSIII module is not connected!' log
			] ifelse
		] if
		
		[A  ]
	]
	
	/Download_FM04_SG6 [P
		[A  ]
		
		IntfSel.Name 'POWERLINK' eq [B
			
			/ModuleFWType		$0100 def	% PL
			/ModuleFWVersion	$0201 def	% latest compatible FW Version: Version 2, Subversion 1
			/ModuleHWVersion	$0103 def	% latest HW Version: Version 1, Revision B

			/ModuleFWTypeAddress $A3000070 def
			/ModuleFWVersionAddress $A3000072 def
			/ModuleHWVersionAddress $A3000002 def

			/MissingFile '' def
			/ModuleParFile FilePath IntfSel.IntfDir add IntfSel.IntfModuleOSUP add def
				ModuleParFile FileExist not [B
				/MissingFile ModuleParFile def
			] if

			/ModuleFWTypeRead  ModuleFWTypeAddress ReadMemory def
			/ModuleFWVersionRead  ModuleFWVersionAddress ReadMemory def
			/ModuleHWVersionRead  ModuleHWVersionAddress ReadMemory def
			/ModuleType  $A3000000 ReadMemory def

			% check HW module version
			ModuleHWVersionRead ModuleHWVersion ge[B
			% Module HW >= V1.0.2
				ModuleType $40 eq [B
					ModuleFWTypeRead ModuleFWType ne ModuleFWVersionRead ModuleFWVersion lt ModuleFWVersionRead $FFFF eq or or [B
						
						% INTF SW must be deleted. OSUP for FPGA is placed in INTF SW sectors
						2 EraseSWInstance
						
						INTFInstallValidAddr InstallationInvalid WriteWordToElo
						
						'Downloading ' ModuleParFile add log
						ModuleParFile dup loadobj exch PackInst:DownloadHX2File	% load image for FPGA

						% Write install new FPGA image controller
						/OSInstallCommand OSInstallCommandAddress ReadMemory def
						/OSInstallCommand OSInstallCommand $0010 or def
						OSInstallCommandAddress OSInstallCommand WriteWordToElo
						
						% AutoStart FPGA Updater after reset
						ResetDevice
						'Updating FPGA...' log
						80000 wait

						% erase FPGA image
						$80040000 PackInst:EraseFlash
						250 wait % give switch some time to process eth frames received while erasing flash which is blocking

						% write new FPGA version info
						ModuleFWTypeAddress ModuleFWType WriteWordToElo
						ModuleFWVersionAddress ModuleFWVersion WriteWordToElo

					]
					[B
						'Update POWERLINK module skipped. Already up to date...' log
					] ifelse
				]
				[B
					'Warning: POWERLINK module is not connected!' log
				] ifelse
			]
			[B
				/Result #0 def
				'Warning: POWERLINK module HW Version older than V1.0.2!' log
			]ifelse
		]if

		IntfSel.Name 'SERCOSIII' eq [B
			
			/ModuleFWType		$0200 def		% SC
			/ModuleFWVersion	$0202 def		% Version 2, Subversion 1 --> sercon100s V2.11

			/ModuleFWTypeAddress $A3000070 def
			/ModuleFWVersionAddress $A3000072 def

			/MissingFile '' def
			/ModuleParFile FilePath IntfSel.IntfDir add IntfSel.IntfModuleOSUP add def
				ModuleParFile FileExist not [B
				/MissingFile ModuleParFile def
			] if

			/ModuleFWTypeRead  ModuleFWTypeAddress ReadMemory def
			/ModuleFWVersionRead  ModuleFWVersionAddress ReadMemory def
			/ModuleType $A3000000 ReadMemory def

			ModuleType $40 eq [B
				ModuleFWTypeRead ModuleFWType ne ModuleFWVersionRead ModuleFWVersion lt ModuleFWVersionRead $FFFF eq or or [B
					
					% INTF SW must be deleted. OSUP for FPGA is placed in INTF SW sectors
					2 EraseSWInstance
					
					INTFInstallValidAddr InstallationInvalid WriteWordToElo
					
					'Downloading ' ModuleParFile add log
					ModuleParFile dup loadobj exch PackInst:DownloadHX2File	% load OSUP for FPGA

					% Write install new FPGA image controller
					/OSInstallCommand OSInstallCommandAddress ReadMemory def
					/OSInstallCommand OSInstallCommand $0010 or def
					OSInstallCommandAddress OSInstallCommand WriteWordToElo
					
					% AutoStart FPGA Updater after reset
					ResetDevice
					'Updating FPGA...' log
					80000 wait

					% erase FPGA image
					$80040000 PackInst:EraseFlash
					250 wait % give switch some time to process eth frames received while erasing flash which is blocking

					% write new FPGA version info
					ModuleFWTypeAddress ModuleFWType WriteWordToElo
					ModuleFWVersionAddress ModuleFWVersion WriteWordToElo
				]
				[B
					'Update SERCOSIII module skipped. Already up to date...' log
				] ifelse
			]
			[B
				'Warning: SERCOSIII module is not connected!' log
			] ifelse
		]if
		
		[A  ]
	]

]
