Browse Source

UPDATE 20230324

sangwq 2 years ago
parent
commit
241a8a2f5d

+ 29 - 2
Venus/Venus_Core/VenusDevice.cs

@@ -98,19 +98,46 @@
         LLBTSlitDoor,
         LLAESlitDoor,
         LLBESlitDoor,
-        ValvePurge,
-        ValveVent,
+        TMValveN2,
+        TMSoftPumpValve,
+        TMFastPumpValve,
+        TMPurgeValve,
+        TMVentValve,
+        LLASoftPumpValve,
+        LLAFastPumpValve,
+        LLAPurgeValve,
+        LLAVentValve,
+        LLBSoftPumpValve,
+        LLBFastPumpValve,
+        LLBPurgeValve,
+        LLBVentValve,
         ValveWaterRelay,
         TMPowerOn,
         TMInSafty,
         WaferLeakSensor,
         EFEMSideDoorClosed,
         TMPCWFlowSwitch,
+        LLAPCWFlowSwitch,
+        LLBPCWFlowSwitch,
         TMLidClosed,
         CDAPressureSwitch,
         VaccumPressureSwitch,
         N2PressureSwitch,
         TMPressureCtrl,
+        TMRobotNotExtendPMA,
+        TMRobotNotExtendPMB,
+        TMRobotNotExtendPMC,
+        TMRobotNotExtendPMD,
+        TMRobotNotExtendLLA,
+        TMRobotNotExtendLLB,
+        EfemRobotNotExtendLLA,
+        EfemRobotNotExtendLLB,
+        TMVacSwitch,
+        LLAVacSwitch,
+        LLBVacSwitch,
+        TMATMSwitch,
+        LLAATMSwitch,
+        LLBATMSwitch,
     }
 
     public enum StateData

BIN
Venus/Venus_RT/Config/DeviceModelVenus_MF.xml


+ 1 - 1
Venus/Venus_RT/Config/IoProviderConfig.xml

@@ -35,7 +35,7 @@
 
 
 	<IoProvider load_condition="1" module="TM" name="PLC" map_module="TM" map_file="_ioDefineVenus_MF.xml"  class="Venus_RT.Devices.FinsPlc" assembly="Venus_RT">
-		<Parameter  ip="192.168.10.11" port="9600"
+		<Parameter  ip="192.168.10.21" port="9600"
 					diBlockType="WR" doBlockType="WR" aiBlockType="D" aoBlockType="D"
 					diStartPosition="20" doStartPosition="0" aiStartPosition="2000" aoStartPosition="1000" ></Parameter>
 		<Blocks>

+ 36 - 9
Venus/Venus_RT/Config/System.sccfg

@@ -119,7 +119,19 @@
 		<config default="8" name="PMFStationNumber" nameView="PMF Station Number" description="PMF Station Number" max="99" min="0" paramter="" tag="" unit="" type="Integer" />
 
 		<config default="1" name="CheckLoadStation" nameView="Check Load Station Number" description="Station Number for Check Load" max="99" min="0" paramter="" tag="" unit="" type="Integer" />
-
+		
+		<config default="100" name="PumpBasePressure" nameView="Pump Base Pressure" description="" max="2000" min="0" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="2000" name="PumpCrossingPressure" nameView="Pump Crossing Pressure" description="" max="500000" min="200" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="60" name="PumpingTimeout" nameView="Pumping Timeout" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
+		<config default="60" name="VentingTimeout" nameView="Venting Timeout" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
+
+		<config default="2000" name="PurgeVentPressure" description="Purge Vent Pressure" max="760000" min="0" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="30" name="PurgeCycleCount" description="Purge Cycle Count" max="200" min="0" paramter="" tag="" unit="" type="Integer" />
+		<config default="120" name="PurgePumpTime" description="Purge Pump Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="180" name="LeakCheckPumpTime" description="Leak Check Pump Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="300" name="LeakCheckWaitTime" description="Leak Check Wait Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="30" name="LeakRate" description="Leak Rate" max="756000" min="0" paramter="" tag="" unit="mTorrPerMin" type="Double" />
+		
 		<configs name="TM_MFC1" nameView="MFC1" >
 			<config default="true" name="Enable" nameView="Enable" description="Enable gas 1 or not" tag="" unit="" type="Bool" />
 			<config default="O2" name="GasName" nameView="Gas Name" description="Name of NO.1 gas stick" tag="" unit="" type="String" />
@@ -139,15 +151,32 @@
 
 	<!--LLA-->
 	<configs name="LLA" nameView="LLA">
-
-
-
+		<config default="100" name="PumpBasePressure" nameView="Pump Base Pressure" description="" max="2000" min="0" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="2000" name="PumpCrossingPressure" nameView="Pump Crossing Pressure" description="" max="500000" min="200" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="60" name="PumpingTimeout" nameView="Pumping Timeout" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
+		<config default="60" name="VentingTimeout" nameView="Venting Timeout" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
+
+		<config default="2000" name="PurgeVentPressure" description="Purge Vent Pressure" max="760000" min="0" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="30" name="PurgeCycleCount" description="Purge Cycle Count" max="200" min="0" paramter="" tag="" unit="" type="Integer" />
+		<config default="120" name="PurgePumpTime" description="Purge Pump Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="180" name="LeakCheckPumpTime" description="Leak Check Pump Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="300" name="LeakCheckWaitTime" description="Leak Check Wait Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="30" name="LeakRate" description="Leak Rate" max="756000" min="0" paramter="" tag="" unit="mTorrPerMin" type="Double" />
 	</configs>
 
 	<!--LLB-->
 	<configs name="LLB" nameView="LLB">
-
-
+		<config default="100" name="PumpBasePressure" nameView="Pump Base Pressure" description="" max="2000" min="0" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="2000" name="PumpCrossingPressure" nameView="Pump Crossing Pressure" description="" max="500000" min="200" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="60" name="PumpingTimeout" nameView="Pumping Timeout" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
+		<config default="60" name="VentingTimeout" nameView="Venting Timeout" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
+
+		<config default="2000" name="PurgeVentPressure" description="Purge Vent Pressure" max="760000" min="0" paramter="" tag="" unit="mTorr" type="Double" />
+		<config default="30" name="PurgeCycleCount" description="Purge Cycle Count" max="200" min="0" paramter="" tag="" unit="" type="Integer" />
+		<config default="120" name="PurgePumpTime" description="Purge Pump Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="180" name="LeakCheckPumpTime" description="Leak Check Pump Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="300" name="LeakCheckWaitTime" description="Leak Check Wait Time" max="7200" min="0" paramter="" tag="" unit="second" type="Integer" />
+		<config default="30" name="LeakRate" description="Leak Rate" max="756000" min="0" paramter="" tag="" unit="mTorrPerMin" type="Double" />
 	</configs>
 
 	<!--PMA-->
@@ -427,7 +456,7 @@
 			<config default="1,2,3,4,5,6,7,8" name="LeakCheckGasLineNums" nameView="LeakCheck GasLineNums" description="GasLine numbers for Leak Check" tag="" unit="" type="String" />
 			<config default="120" name="PumpTimeLimit" nameView="Pump Time Limit" description="" max="3000" min="0" paramter="" tag="" unit="" type="Double" />
 			<config default="5" name="PumpValveDelay" nameView="Pump Valve Delay" description="" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
-			<config default="75" name="RoughPumpDownPressure" description="LoadLock Purge Vent Pressure" max="200" min="0" paramter="" tag="" unit="Torr" type="Integer" />
+			<config default="75" name="RoughPumpDownPressure" description="PM Rough Pumping Pressure" max="200" min="0" paramter="" tag="" unit="Torr" type="Integer" />
 			<config default="200" name="PumpVHe2FlowPressure" nameView="He2 Flow Pressure" description="" max="756000" min="0" paramter="" tag="" unit="mTorr" type="Integer" />
 			<config default="100" name="LoadLockPumpBasePressure" description="LoadLock Pump Base Pressure" max="756000" min="0" paramter="" tag="" unit="mTorr" type="Integer" />
 			<config default="120" name="LoadLockPumpTimeLimit" description="LoadLock Pump Time Limit" max="3000" min="0" paramter="" tag="" unit="second" type="Integer" />
@@ -570,9 +599,7 @@
 			<config default="400" name="PressureFullRange" nameView="PressureFullRange" description="Pressure Full Range of PendulumValve" max="100000" min="0" paramter="" tag="" unit="mtorr" type="Integer" />
 		</configs>
 
-
 		<!--Clean-->
-
 		<configs name="IdleClean" nameView="Idle Clean" visible="false">
 			<config default="false" name="IsEnabled" nameView="Is Enabled" description="IsEnabled" max="0" min="0" paramter="" tag="" unit="" type="Bool" />
 			<config default="" name="IdleCleanRecipe" nameView="Idle Clean Recipe" description="Purge recipe name" max="" min="" paramter="" tag="" unit="" type="String" />

+ 0 - 2
Venus/Venus_RT/Devices/IODevices/IoTMPressureCtl.cs

@@ -37,8 +37,6 @@ namespace Venus_RT.Devices
         public double TargetPressure { get; set; }
 
 
-        private string PressureOutOfTolerance = "PressureOutOfTolerance";
-
         // Constructor
         //
         public IoTMPressureCtrl(string module, XmlElement node, string ioModule = "")

+ 385 - 25
Venus/Venus_RT/Devices/TM/JetTM.cs

@@ -30,14 +30,25 @@ namespace Venus_RT.Devices
         private readonly IoLid _LLALid;
         private readonly IoLid _LLBLid;
 
-        private readonly IoCylinder _LLASlitDoor;
-        private readonly IoCylinder _LLBSlitDoor;
-
-        private readonly IoValve _N2Valve;
-        private readonly IoValve _SoftPumpValve;
-        private readonly IoValve _FastPumpValve;
-        private readonly IoValve _PurgeValve;
-        private readonly IoValve _VentValve;
+        private readonly IoCylinder _LLATSlitDoor;
+        private readonly IoCylinder _LLBTSlitDoor;
+
+        private readonly IoCylinder _LLAESlitDoor;
+        private readonly IoCylinder _LLBESlitDoor;
+
+        private readonly IoValve _TMN2Valve;
+        private readonly IoValve _TMSoftPumpValve;
+        private readonly IoValve _TMFastPumpValve;
+        private readonly IoValve _TMPurgeValve;
+        private readonly IoValve _TMVentValve;
+        private readonly IoValve _LLASoftPumpValve;
+        private readonly IoValve _LLAFastPumpValve;
+        private readonly IoValve _LLAPurgeValve;
+        private readonly IoValve _LLAVentValve;
+        private readonly IoValve _LLBSoftPumpValve;
+        private readonly IoValve _LLBFastPumpValve;
+        private readonly IoValve _LLBPurgeValve;
+        private readonly IoValve _LLBVentValve;
         private readonly IoValve _WaferRelayValve;
 
         private readonly IoSensor _TMPowerOn;
@@ -45,44 +56,132 @@ namespace Venus_RT.Devices
         private readonly IoSensor _WaferLeakSensor;
         private readonly IoSensor _EFEMSideDoorClosed;
         private readonly IoSensor _TMPCWFlowSwitch;
+        private readonly IoSensor _LLAPCWFlowSwitch;
+        private readonly IoSensor _LLBPCWFlowSwitch;
         private readonly IoSensor _TMLidClosed;
 
         private readonly IoSensor _CDAPressureSwitch;
         private readonly IoSensor _VaccumPressureSwitch;
         private readonly IoSensor _N2PressureSwitch;
 
+        private readonly IoSensor _TMRobotNotExtendPMA;
+        private readonly IoSensor _TMRobotNotExtendPMB;
+        private readonly IoSensor _TMRobotNotExtendPMC;
+        private readonly IoSensor _TMRobotNotExtendPMD;
+        private readonly IoSensor _TMRobotNotExtendLLA;
+        private readonly IoSensor _TMRobotNotExtendLLB;
+        private readonly IoSensor _EfemRobotNotExtendLLA;
+        private readonly IoSensor _EfemRobotNotExtendLLB;
+        private readonly IoSensor _TMVacSwitch;
+        private readonly IoSensor _LLAVacSwitch;
+        private readonly IoSensor _LLBVacSwitch;
+        private readonly IoSensor _TMATMSwitch;
+        private readonly IoSensor _LLAATMSwitch;
+        private readonly IoSensor _LLBATMSwitch;
+
         private readonly IoTMPressureCtrl _presureCtrl;
 
         public bool TMLidClosed => _TMLid.OFFFeedback;
         public bool LLALidClosed => _LLALid.OFFFeedback;
         public bool LLBLidClosed => _LLBLid.OFFFeedback;
+        public bool IsLLASlitDoorClosed => _LLATSlitDoor.State == CylinderState.Close;
+        public bool IsLLASlitDoorOpen => _LLATSlitDoor.State == CylinderState.Open;
+        public bool IsELLASlitDoorClosed => _LLAESlitDoor.State == CylinderState.Close;
+        public bool IsELLASlitDoorOpen => _LLAESlitDoor.State == CylinderState.Open;
+        public bool IsLLBSlitDoorClosed => _LLBTSlitDoor.State == CylinderState.Close;
+        public bool IsLLBSlitDoorOpen => _LLBTSlitDoor.State == CylinderState.Open;
+        public bool IsLLBESlitDoorClosed => _LLBESlitDoor.State == CylinderState.Close;
+        public bool IsLLBESlitDoorOpen => _LLBESlitDoor.State == CylinderState.Open;
+        public bool IsTMVac => _TMVacSwitch.Value;
+        public bool IsLLAVac => _LLAVacSwitch.Value;
+        public bool IsLLBVac => _LLBVacSwitch.Value;
+        public bool IsTMATM => _TMATMSwitch.Value;
+        public bool IsLLAATM => _LLAATMSwitch.Value;
+        public bool IsLLBATM => _LLBATMSwitch.Value;
+        public bool IsTMPowerOn => _TMPowerOn.Value;
+        public bool IsTMInSafty => _TMInSafty.Value;
+        public bool IsLLAFastPumpOpen => _LLAFastPumpValve.Status;
+        public bool IsLLASoftPumpOpen => _LLASoftPumpValve.Status;
+        public bool IsLLBFastPumpOpen => _LLBFastPumpValve.Status;
+        public bool IsLLBSoftPumpOpen => _LLBSoftPumpValve.Status;
+        public bool IsLLAVentValveOpen => _LLAVentValve.Status;
+        public bool IsLLAPurgeValveOpen => _LLAPurgeValve.Status;
+        public bool IsLLBVentValveOpen => _LLBVentValve.Status;
+        public bool IsLLBPurgeValveOpen => _LLBPurgeValve.Status;
+
+        public bool IsTMVentValveOpen => _TMVentValve.Status;
+        public bool IsTMPurgeValveOpen => _TMPurgeValve.Status;
+        public bool IsTMFastPumpOpen => _TMFastPumpValve.Status;
+        public bool IsTMSoftPumpOpen => _TMSoftPumpValve.Status;
+        public bool TMRobotNotExtendToPMA => _TMRobotNotExtendPMA.Value;
+        public bool TMRobotNotExtendToPMB => _TMRobotNotExtendPMB.Value;
+        public bool TMRobotNotExtendToPMC => _TMRobotNotExtendPMC.Value;
+        public bool TMRobotNotExtendToPMD => _TMRobotNotExtendPMD.Value;
+        public bool TMRobotNotExtendToLLA => _TMRobotNotExtendLLA.Value;
+        public bool TMRobotNotExtendToLLB => _TMRobotNotExtendLLB.Value;
+        public bool EfemRobotNotExtendToLLA => _EfemRobotNotExtendLLA.Value;
+        public bool EfemRobotNotExtendToLLB => _EfemRobotNotExtendLLB.Value;
+
+        public double TMPressure => _presureCtrl.TMPressureGauge.Value;
+        public double LLAPressure => _presureCtrl.LLAPressureGauge.Value;
+        public double LLBPressure => _presureCtrl.LLBPressureGauge.Value;
+        public double TMForelinePressure => _presureCtrl.MFForelineGauge.Value;
+        public double LoadlockForelinePressure => _presureCtrl.LLForelineGauge.Value;
 
         public JetTM() : base("TM")
         {
-            _TMLid = DEVICE.GetDevice<IoLid>($"TM.{VenusDevice.TMLid}");
+            _TMLid  = DEVICE.GetDevice<IoLid>($"TM.{VenusDevice.TMLid}");
             _LLALid = DEVICE.GetDevice<IoLid>($"TM.{VenusDevice.LLALid}");
             _LLBLid = DEVICE.GetDevice<IoLid>($"TM.{VenusDevice.LLBLid}");
 
-            _LLASlitDoor = DEVICE.GetDevice<IoCylinder>($"TM.{VenusDevice.LLATSlitDoor}");
-            _LLBSlitDoor = DEVICE.GetDevice<IoCylinder>($"TM.{VenusDevice.LLBTSlitDoor}");
+            _LLATSlitDoor = DEVICE.GetDevice<IoCylinder>($"TM.{VenusDevice.LLATSlitDoor}");
+            _LLBTSlitDoor = DEVICE.GetDevice<IoCylinder>($"TM.{VenusDevice.LLBTSlitDoor}");
+            _LLAESlitDoor = DEVICE.GetDevice<IoCylinder>($"TM.{VenusDevice.LLAESlitDoor}");
+            _LLBESlitDoor = DEVICE.GetDevice<IoCylinder>($"TM.{VenusDevice.LLBESlitDoor}");
 
-            _N2Valve = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValveN2}");
-            _SoftPumpValve = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValveSoftPump}");
-            _FastPumpValve = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValveFastPump}");
-            _PurgeValve = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValvePurge}");
-            _VentValve = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValveVent}");
-            _WaferRelayValve = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValveWaterRelay}");
+            _TMN2Valve          = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.TMValveN2}");
+            _TMSoftPumpValve    = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.TMSoftPumpValve}");
+            _TMFastPumpValve    = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.TMFastPumpValve}");
+            _TMPurgeValve       = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.TMPurgeValve}");
+            _TMVentValve        = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.TMVentValve}");
+            _LLASoftPumpValve   = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLASoftPumpValve}");
+            _LLAFastPumpValve   = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLAFastPumpValve}");
+            _LLAPurgeValve      = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLAPurgeValve}");
+            _LLAVentValve       = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLAVentValve}");
+            _LLBSoftPumpValve   = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLBSoftPumpValve}");
+            _LLBFastPumpValve   = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLBFastPumpValve}");
+            _LLBPurgeValve      = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLBPurgeValve}");
+            _LLBVentValve       = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.LLBVentValve}");
+            _WaferRelayValve    = DEVICE.GetDevice<IoValve>($"TM.{VenusDevice.ValveWaterRelay}");
 
-            _TMPowerOn = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMPowerOn}");
-            _TMInSafty = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMInSafty}");
-            _WaferLeakSensor = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.WaferLeakSensor}");
+            _TMPowerOn          = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMPowerOn}");
+            _TMInSafty          = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMInSafty}");
+            _WaferLeakSensor    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.WaferLeakSensor}");
             _EFEMSideDoorClosed = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.EFEMSideDoorClosed}");
-            _TMPCWFlowSwitch = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMPCWFlowSwitch}");
-            _TMLidClosed = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMLidClosed}");
+            _TMPCWFlowSwitch    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMPCWFlowSwitch}");
+            _LLAPCWFlowSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.LLAPCWFlowSwitch}");
+            _LLBPCWFlowSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.LLBPCWFlowSwitch}");
+            _TMLidClosed        = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMLidClosed}");
+
+            _CDAPressureSwitch      = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.CDAPressureSwitch}");
+            _VaccumPressureSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.VaccumPressureSwitch}");
+            _N2PressureSwitch       = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.N2PressureSwitch}");
+
+            _TMRobotNotExtendPMA    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMRobotNotExtendPMA}");
+            _TMRobotNotExtendPMB    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMRobotNotExtendPMB}");
+            _TMRobotNotExtendPMC    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMRobotNotExtendPMC}");
+            _TMRobotNotExtendPMD    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMRobotNotExtendPMD}");
+            _TMRobotNotExtendLLA    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMRobotNotExtendLLA}");
+            _TMRobotNotExtendLLB    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMRobotNotExtendLLB}");
+            _EfemRobotNotExtendLLA  = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.EfemRobotNotExtendLLA}");
+            _EfemRobotNotExtendLLB  = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.EfemRobotNotExtendLLB}");
 
-            _CDAPressureSwitch = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.CDAPressureSwitch}");
-            _VaccumPressureSwitch = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.VaccumPressureSwitch}");
-            _N2PressureSwitch = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.N2PressureSwitch}");
+            _TMVacSwitch    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMVacSwitch}");
+            _LLAVacSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.LLAVacSwitch}");
+            _LLBVacSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.LLBVacSwitch}");
+            _TMATMSwitch    = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.TMATMSwitch}");
+            _LLAATMSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.LLAATMSwitch}");
+            _LLBATMSwitch   = DEVICE.GetDevice<IoSensor>($"TM.{VenusDevice.LLBATMSwitch}");
 
             _presureCtrl = DEVICE.GetDevice<IoTMPressureCtrl>($"TM.{VenusDevice.TMPressureCtrl}");
 
@@ -90,8 +189,269 @@ namespace Venus_RT.Devices
 
         public override void Monitor()
         {
+            _WaferRelayValve.TurnValve(_WaferLeakSensor.Value, out string _);
+        }
+
+        public void TurnSoftPumpValve(ModuleName mod, bool bOn)
+        {
+            switch(mod)
+            {
+                case ModuleName.TM:
+                    _TMSoftPumpValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLA:
+                    _LLASoftPumpValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLB:
+                    _LLBSoftPumpValve.TurnValve(bOn, out string _);
+                    break;
+
+            }
+        }
+
+        public void TurnFastPumpValve(ModuleName mod, bool bOn)
+        {
+            switch(mod)
+            {
+                case ModuleName.TM:
+                    _TMFastPumpValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLA:
+                    _LLAFastPumpValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLB:
+                    _LLBFastPumpValve.TurnValve(bOn, out string _);
+                    break;
+            }
+        }
+
+        public void TurnVentValve(ModuleName mod, bool bOn)
+        {
+            switch(mod)
+            {
+                case ModuleName.TM:
+                    _TMVentValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLA:
+                    _LLAVentValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLB:
+                    _LLBVentValve.TurnValve(bOn, out string _);
+                    break;
+            }
+        }
+
+        public void TurnPurgeValve(ModuleName mod, bool bOn)
+        {
+            switch(mod)
+            {
+                case ModuleName.TM:
+                    _TMPurgeValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLA:
+                    _LLAPurgeValve.TurnValve(bOn, out string _);
+                    break;
+                case ModuleName.LLB:
+                    _LLBPurgeValve.TurnValve(bOn, out string _);
+                    break;
+            }
+        }
+
+        public void TurnN2Valve(bool bOn)
+        {
+            _TMN2Valve.TurnValve(bOn, out string _);
+        }
+
+        public void CloseModuleAllValves(ModuleName mod)
+        {
+            TurnFastPumpValve(mod, false);
+            TurnSoftPumpValve(mod, false);
+            TurnVentValve(mod, false);
+            TurnPurgeValve(mod, false);
+
+            if (mod == ModuleName.TM)
+                TurnN2Valve(false);
+        }
+
+
+        public double GetModulePressure(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    return TMPressure;
+                case ModuleName.LLA:
+                    return LLAPressure;
+                case ModuleName.LLB:
+                    return LLBPressure;
+            }
+
+            return 0;
+        }
+
+        public bool IsModuleATM(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    return IsTMATM;
+                case ModuleName.LLA:
+                    return IsLLAATM;
+                case ModuleName.LLB:
+                    return IsLLBATM;
+            }
+
+            return false;
         }
 
+        public bool IsModuleVaccum(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    return IsTMVac;
+                case ModuleName.LLA:
+                    return IsLLAVac;
+                case ModuleName.LLB:
+                    return IsLLBVac;
+            }
+
+            return false;
+        }
+
+        public bool CheckLidClosed(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    if(!TMLidClosed)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.TM, "TM Lid not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLA:
+                    if(!LLALidClosed)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLA, "LLA Lid not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLB:
+                    if (!LLBLidClosed)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLB, "LLB Lid not closed");
+                        return false;
+                    }
+                    break;
+            }
 
+            return true;
+        }
+
+        public bool CheckVentValveClosed(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    if (IsTMVentValveOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.TM, "TM Vent Valve not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLA:
+                    if (IsLLAVentValveOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLA, "LLA Vent Valve not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLB:
+                    if (IsLLBVentValveOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLB, "LLB Vent Valve not closed");
+                        return false;
+                    }
+                    break;
+            }
+
+            return true;
+        }
+
+        public bool CheckPurgeValveClosed(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    if (IsTMPurgeValveOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.TM, "TM Purge Valve not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLA:
+                    if (IsLLAPurgeValveOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLA, "LLA Purge Valve not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLB:
+                    if (IsLLBPurgeValveOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLB, "LLB Purge Valve not closed");
+                        return false;
+                    }
+                    break;
+            }
+
+            return true;
+        }
+
+        public bool CheckPumpValveClosed(ModuleName mod)
+        {
+            switch (mod)
+            {
+                case ModuleName.TM:
+                    if (IsTMFastPumpOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.TM, "TM Fast Pump Valve not closed");
+                        return false;
+                    }
+                    else if(IsTMSoftPumpOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.TM, "TM Soft Pump Valve not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLA:
+                    if (IsLLAFastPumpOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLA, "LLA Fast Pump Valve not closed");
+                        return false;
+                    }
+                    else if(IsLLASoftPumpOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLA, "LLA Soft Pump Valve not closed");
+                        return false;
+                    }
+                    break;
+                case ModuleName.LLB:
+                    if (IsLLBFastPumpOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLB, "LLB Fast Pump Valve not closed");
+                        return false;
+                    }
+                    else if(IsLLBSoftPumpOpen)
+                    {
+                        LOG.Write(eEvent.ERR_TM, ModuleName.LLB, "LLB Soft Pump Valve not closed");
+                        return false;
+                    }
+                    break;
+            }
+
+            return true;
+        }
     }
 }

+ 23 - 88
Venus/Venus_RT/Devices/TM/SIASUNRobot.cs

@@ -6,13 +6,10 @@ using Aitex.Core.RT.SCCore;
 using Aitex.Core.Util;
 using Aitex.Sorter.Common;
 using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.SubstrateTrackings;
 using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
 using Aitex.Core.RT.Log;
-
-using System.Threading;
-using System.Threading.Tasks;
-using System.Collections.Concurrent;
-using System.Runtime.CompilerServices;
+using System.Text.RegularExpressions;
 
 namespace Venus_RT.Devices
 {
@@ -44,6 +41,8 @@ namespace Venus_RT.Devices
 
         private string Hand2Arm(Hand hand) => hand == Hand.Blade1 ? "A" : "B";
 
+        private readonly Regex _rex_check_load = new Regex(@"LOAD\s+(A|B)\s+(\w+)\s*");
+
         public SIASUNRobot()
         {
             _socket = new AsyncSocket("");
@@ -82,7 +81,7 @@ namespace Venus_RT.Devices
             if (_currentOP != OPStep.Home && _currentOP != OPStep.CheckLoad_ArmA && CheckRobotStatus() == false)
                 return false;
 
-            _currentOP = OPStep.CheckLoad_ArmA;
+            _currentOP = hand == Hand.Blade2 ? OPStep.CheckLoad_ArmB : OPStep.CheckLoad_ArmA;
             _status = RState.Running;
             _socket.Write($"CHECK LOAD {_checkLoadStation} ARM {Hand2Arm(hand)}\r");
             return true;
@@ -223,8 +222,10 @@ namespace Venus_RT.Devices
                     break;
                 case OPStep.CheckLoad_ArmA:
                     {
-                        if(RevMsg.Contains("_RDY"))
+                        if(_rex_check_load.IsMatch(RevMsg))
                         {
+                            GetCheckLoadResult(RevMsg);
+
                             CheckLoad(Hand.Blade2);
                         }
                         else
@@ -233,8 +234,10 @@ namespace Venus_RT.Devices
                     break;
                 case OPStep.CheckLoad_ArmB:
                     {
-                        if (RevMsg.Contains("_RDY"))
+                        if (_rex_check_load.IsMatch(RevMsg))
                         {
+                            GetCheckLoadResult(RevMsg);
+
                             _currentOP = OPStep.Idle;
                             _status = RState.End;
                         }
@@ -246,6 +249,18 @@ namespace Venus_RT.Devices
             }
         }
 
+        private void GetCheckLoadResult(string strRev)
+        {
+            Match result = _rex_check_load.Match(strRev);
+
+            string Arm = result.Groups[1].Value;
+            string WaferStatus = result.Groups[2].Value;
+            if(WaferStatus == "ON")
+            {
+                WaferManager.Instance.CreateWafer(ModuleName.TM, Arm == "A" ? 0 : 1, Aitex.Core.Common.WaferStatus.Unknown);
+            }
+        }
+
         private void OnErrorHappen(ErrorEventArgs args)
         {
             Singleton<RouteManager>.Instance.TM.PostMsg(TMEntity.MSG.Error);
@@ -257,84 +272,4 @@ namespace Venus_RT.Devices
             LOG.Write(eEvent.ERR_TM, ModuleName.TM, $"Receive wrong message:{revMsg} while {_currentOP}");
         }
     }
-
-
-    public static class TaskLogger
-    {
-        public enum TaskLogLevel { None, Pending }
-        public static TaskLogLevel LogLevel { get; set; }
-        public sealed class TaskLogEntry
-        {
-            public Task Task { get; internal set; }
-            public String Tag { get; internal set; }
-            public DateTime LogTime { get; internal set; }
-            public String CallerMemberName { get; internal set; }
-            public String CallerFilePath { get; internal set; }
-            public Int32 CallerLineNumber { get; internal set; }
-            public override string ToString()
-            {
-                return String.Format("LogTime={0}, Tag={1}, Member={2}, File={3}({4})",
-                LogTime, Tag ?? "(none)", CallerMemberName, CallerFilePath, CallerLineNumber);
-            }
-        }
-        private static readonly ConcurrentDictionary<Task, TaskLogEntry> s_log =
-        new ConcurrentDictionary<Task, TaskLogEntry>();
-        public static IEnumerable<TaskLogEntry> GetLogEntries() { return s_log.Values; }
-        public static Task<TResult> Log<TResult>(this Task<TResult> task, String tag = null,
-        [CallerMemberName] String callerMemberName = null,
-        [CallerFilePath] String callerFilePath = null,
-        [CallerLineNumber] Int32 callerLineNumber = -1)
-        {
-            return (Task<TResult>)Log((Task)task, tag, callerMemberName, callerFilePath, callerLineNumber);
-        }
-        public static Task Log(this Task task, String tag = null,
-        [CallerMemberName] String callerMemberName = null,
-        [CallerFilePath] String callerFilePath = null,
-        [CallerLineNumber] Int32 callerLineNumber = -1)
-        {
-            if (LogLevel == TaskLogLevel.None) return task;
-            var logEntry = new TaskLogEntry
-            {
-                Task = task,
-                LogTime = DateTime.Now,
-                Tag = tag,
-                CallerMemberName = callerMemberName,
-                CallerFilePath = callerFilePath,
-                CallerLineNumber = callerLineNumber
-            };
-            s_log[task] = logEntry;
-            task.ContinueWith(t => { TaskLogEntry entry; s_log.TryRemove(t, out entry); },
-            TaskContinuationOptions.ExecuteSynchronously);
-            return task;
-        }
-    }
-//    class Tester
-//    { 
-
-//        public static async Task Go()
-//        {
-//#if DEBUG
-//            // Using TaskLogger incurs a memory and performance hit; so turn it on in debug builds
-//            TaskLogger.LogLevel = TaskLogger.TaskLogLevel.Pending;
-//#endif
-//            // Initiate 3 task; for testing the TaskLogger, we control their duration explicitly
-//            var tasks = new List<Task> {
-//                Task.Delay(2000).Log("2s op"),
-//                Task.Delay(5000).Log("5s op"),
-//                Task.Delay(6000).Log("6s op")
-//            };
-//            try
-//            {
-//                // Wait for all tasks but cancel after 3 seconds; only 1 task above should complete in time
-//                // Note: WithCancellation is my extension method described later in this chapter
-//                await Task.WhenAll(tasks).
-//                WithCancellation(new CancellationTokenSource(3000).Token);
-//            }
-//            catch (OperationCanceledException) { }
-//            // Ask the logger which tasks have not yet completed and sort
-//            // them in order from the one that’s been waiting the longest
-//            foreach (var op in TaskLogger.GetLogEntries().OrderBy(tle => tle.LogTime))
-//                Console.WriteLine(op);
-//        }
-//    }
 }

+ 204 - 7
Venus/Venus_RT/Modules/LLs/LLEntity.cs

@@ -1,24 +1,40 @@
 using System;
+using Aitex.Core.Util;
 using Aitex.Core.RT.Fsm;
 using Aitex.Core.RT.Log;
 using MECF.Framework.Common.Equipment;
-
+using Venus_RT.Modules.TM;
+using Venus_RT.Devices;
+using Venus_Core;
 namespace Venus_RT.Modules
 {
     class LLEntity : Entity, IEntity, IModuleEntity
     {
         public enum STATE
         {
-            Unknown,            // 0
-            Initializing,       // 1
-            Idle,               // 2
-            Error,              // 3
-            Init,               // 4
+            Unknown,
+            Init,
+            Initializing,
+            Idle,
+            Error,
+            Pumping,
+            Venting,
+            Purging,
+            Leakchecking,
         }
 
         public enum MSG
         {
-            Home,               // 0
+            Home,
+            Online,
+            Offline,
+            Pump,
+            Vent,
+            Purge,
+            CyclePurge,
+            LeakCheck,
+            Error,
+            Abort,
 
 
         }
@@ -50,9 +66,61 @@ namespace Venus_RT.Modules
 
         public bool IsOnline { get; internal set; }
 
+        private readonly JetTM _JetTM;
+        private readonly MFPumpRoutine _pumpingRoutine;
+        private readonly MFVentRoutine _ventingRoutine;
+        private readonly MFLeakCheckRoutine _leakCheckRoutine;
+        private readonly MFPurgeRoutine _purgeRoutine;
         public LLEntity(ModuleName module)
         {
             Module = module;
+            _JetTM = Singleton<JetTM>.Instance;
+
+            _pumpingRoutine     = new MFPumpRoutine(_JetTM, Module);
+            _ventingRoutine     = new MFVentRoutine(_JetTM, Module);
+            _leakCheckRoutine   = new MFLeakCheckRoutine(_JetTM, Module);
+            _purgeRoutine       = new MFPurgeRoutine(_JetTM, Module);
+
+            InitFsmMap();
+        }
+
+        private void InitFsmMap()
+        {
+            fsm = new StateMachine<TMEntity>(Module.ToString(), (int)STATE.Init, 50);
+            fsm.EnableRepeatedMsg(true);
+
+            AnyStateTransition(FSM_MSG.TIMER,   fnMonitor,      FSM_STATE.SAME);
+
+
+            AnyStateTransition(MSG.Error,       fnError,        STATE.Error);
+            AnyStateTransition(MSG.Online,      fnOnline,       FSM_STATE.SAME);
+            AnyStateTransition(MSG.Offline,     fnOffline,      FSM_STATE.SAME);
+            AnyStateTransition(MSG.Home,        fnHome,         STATE.Initializing);
+
+            // Home
+            Transition(STATE.Initializing,      FSM_MSG.TIMER,      fnHoming,           STATE.Idle);
+
+            //vent sequence
+            Transition(STATE.Idle,              MSG.Vent,           FnStartVent,        STATE.Venting);
+            Transition(STATE.Venting,           FSM_MSG.TIMER,      FnVentTimeout,      STATE.Idle);
+            Transition(STATE.Venting,           MSG.Abort,          FnAbortVent,        STATE.Idle);
+
+            //Pump sequence
+            Transition(STATE.Idle,              MSG.Pump,           FnStartPump,        STATE.Pumping);
+            Transition(STATE.Pumping,           FSM_MSG.TIMER,      FnPumpTimeout,      STATE.Idle);
+            Transition(STATE.Pumping,           MSG.Abort,          FnAbortPump,        STATE.Idle);
+
+            // Purge sequence
+            Transition(PMState.Idle,            MSG.CyclePurge,     FnStartPurge,       PMState.Purging);
+            Transition(PMState.Purging,         FSM_MSG.TIMER,      FnPurgeTimeout,     PMState.Idle);
+            Transition(PMState.Purging,         MSG.Abort,          FnAbortPurge,       PMState.Idle);
+
+            // Leak check sequence
+            Transition(PMState.Idle,            MSG.LeakCheck,      FnStartLeakCheck,   PMState.LeakCheck);
+            Transition(PMState.LeakCheck,       FSM_MSG.TIMER,      FnLeakCheckTimeout, PMState.Idle);
+            Transition(PMState.LeakCheck,       MSG.Abort,          FnAbortLeakCheck,   PMState.Idle);
+
+            Running = true;
         }
 
         public int Invoke(string function, params object[] args)
@@ -85,5 +153,134 @@ namespace Venus_RT.Modules
 
             return true;
         }
+
+        private bool fnMonitor(object[] param)
+        {
+            return true;
+        }
+
+        private bool fnError(object[] param)
+        {
+            IsOnline = false;
+            return true;
+        }
+
+        private bool fnOnline(object[] param)
+        {
+            return true;
+        }
+
+        private bool fnOffline(object[] param)
+        {
+            IsOnline = false;
+            return true;
+        }
+
+        private bool fnAbort(object[] param)
+        {
+            return true;
+        }
+
+        private bool fnHome(object[] param)
+        {
+            return true;
+        }
+
+        private bool fnHoming(object[] param)
+        {
+            return true;
+        }
+
+        private bool FnStartVent(object[] param)
+        {
+            return _ventingRoutine.Start() == RState.Running;
+        }
+
+        private bool FnVentTimeout(object[] param)
+        {
+            RState ret = _ventingRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+
+        private bool FnAbortVent(object[] param)
+        {
+            _ventingRoutine.Abort();
+            return true;
+        }
+
+        private bool FnStartPump(object[] param)
+        {
+            return _pumpingRoutine.Start() == RState.Running;
+        }
+
+        private bool FnPumpTimeout(object[] param)
+        {
+            RState ret = _pumpingRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+
+        private bool FnAbortPump(object[] param)
+        {
+            _pumpingRoutine.Abort();
+            return true;
+        }
+
+        private bool FnStartPurge(object[] param)
+        {
+            return _purgeRoutine.Start() == RState.Running;
+        }
+
+        private bool FnPurgeTimeout(object[] param)
+        {
+            RState ret = _purgeRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+
+        private bool FnAbortPurge(object[] param)
+        {
+            _purgeRoutine.Abort();
+            return true;
+        }
+
+        private bool FnStartLeakCheck(object[] param)
+        {
+            return _leakCheckRoutine.Start() == RState.Running;
+        }
+
+        private bool FnLeakCheckTimeout(object[] param)
+        {
+            RState ret = _leakCheckRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+
+        private bool FnAbortLeakCheck(object[] param)
+        {
+            _leakCheckRoutine.Abort();
+            return true;
+        }
     }
 }

+ 1 - 1
Venus/Venus_RT/Modules/PMs/LoadLockLeakCheckRoutine.cs

@@ -44,7 +44,7 @@ namespace Venus_RT.Modules.PMs
                 _chamber.CloseValves();
                 _basePressureLL = SC.GetValue<int>($"{Module}.Pump.LoadLockPumpBasePressure");
                 _leakcheckPumpTimeLL = SC.GetValue<int>($"{Module}.Pump.LoadLockLeakCheckPumpTime");
-                _leakcheckWaitTimeLL = SC.GetValue<int>($"{Module}.Pump.LoadLockLeakCheckPumpTime");
+                _leakcheckWaitTimeLL = SC.GetValue<int>($"{Module}.Pump.LoadLockLeakCheckWaitTime");
                 _leakRate = SC.GetValue<double>($"{Module}.Pump.LoadLockLeakRate");
 
                 return Runner.Start(Module, Name);

+ 1 - 1
Venus/Venus_RT/Modules/PMs/LoadLockPurgeRoutine.cs

@@ -44,7 +44,7 @@ namespace Venus_RT.Modules.PMs
 
                 _chamber.CloseValves();
                 _basePressureLL         = SC.GetValue<int>($"{Module}.Pump.LoadLockPumpBasePressure");
-                _purgeVentPressureLL    = SC.GetValue<int>($"{Module}.Pump.LoadLockPurgeVentPressure");
+                _purgeVentPressureLL    = SC.GetValue<int>($"{Module}.Pump.LoadLockPurgeVentPressure") * 1000;
                 _purgeCycleCounter      = SC.GetValue<int>($"{Module}.Pump.LoadLockPurgeCycleCount");
                 _purgePumpTime          = SC.GetValue<int>($"{Module}.Pump.LoadLockPurgePumpTime");
 

+ 1 - 1
Venus/Venus_RT/Modules/PMs/LoadLockVentRoutine.cs

@@ -17,7 +17,7 @@ namespace Venus_RT.Modules.PMs
 
         private int _overVentTime = 2000;
         private int _checkATMTimeout = 90000;
-        private int _ATMPressureLL = 720000;
+        //private int _ATMPressureLL = 720000;
 
         public LoadLockVentRoutine(JetPM chamber) : base(chamber)
         {

+ 1 - 1
Venus/Venus_RT/Modules/PMs/PMEntity.cs

@@ -433,7 +433,7 @@ namespace Venus_RT.Modules.PMs
             Transition(PMState.LeakCheck,       FSM_MSG.TIMER,      FnPMLeakCheckTimeout,       PMState.Idle);
             Transition(PMState.LeakCheck,       MSG.Abort,          FnAbortPMLeakCheck,         PMState.Idle);
 
-            //PM Leak check sequence
+            //PM GasBox Leak check sequence
             Transition(PMState.Idle,                MSG.GasLeakCheck,   FnStartGasBoxLeakCheck,     PMState.GasBoxLeakCheck);
             Transition(PMState.GasBoxLeakCheck,     FSM_MSG.TIMER,      FnGasBoxLeakCheckTimeout,   PMState.Idle);
             Transition(PMState.GasBoxLeakCheck,     MSG.Abort,          FnAbortGasBoxLeakCheck,     PMState.Idle);

+ 1 - 0
Venus/Venus_RT/Modules/RouteManager.cs

@@ -120,6 +120,7 @@ namespace Venus_RT.Modules
         {
             PMA?.Initialize();
             PMB?.Initialize();
+            TM?.Initialize();
             return true;
         }
         void SubscribeOperation()

+ 58 - 0
Venus/Venus_RT/Modules/TM/MFHomeRoutine.cs

@@ -0,0 +1,58 @@
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Venus_RT.Devices;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.Equipment;
+using Venus_Core;
+
+namespace Venus_RT.Modules.TM
+{
+    class MFHomeRoutine : ModuleRoutineBase, IRoutine
+    {
+        private enum HomeStep
+        {
+            kHoming,
+            kEnd,
+        }
+
+        private int _homingTimeout = 30000;
+        private readonly JetTM _JetTM;
+        private readonly ITransferRobot _robot;
+        public MFHomeRoutine(JetTM jetTM, ITransferRobot robot) : base(ModuleName.TM)
+        {
+            _JetTM = jetTM;
+            _robot = robot;
+            Name = "TM Home";
+        }
+
+        public RState Start(params object[] objs)
+        {
+            Reset();
+            _homingTimeout = SC.GetValue<int>($"{Module}.HomeTimeout") * 1000;
+
+            return Runner.Start(Module, Name);
+        }
+
+        public RState Monitor()
+        {
+            Runner.Run((int)HomeStep.kHoming,   HomeTM,     CheckHomeReady,     _homingTimeout)
+                .End((int)HomeStep.kEnd,        NullFun,    _delay_50ms);
+
+            return Runner.Status;
+        }
+
+        private bool HomeTM()
+        {
+            return _robot.Home();
+        }
+
+        private bool CheckHomeReady()
+        {
+            return _robot.Status == RState.End;
+        }
+
+        public void Abort()
+        {
+        }
+    }
+}

+ 126 - 0
Venus/Venus_RT/Modules/TM/MFLeakCheckRoutine.cs

@@ -0,0 +1,126 @@
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Venus_RT.Devices;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.Equipment;
+using Venus_Core;
+
+namespace Venus_RT.Modules.TM
+{
+    class MFLeakCheckRoutine : ModuleRoutineBase, IRoutine
+    {
+        private enum LeakCheckStep
+        {
+            kCloseValves,
+            kPumpToCrossing,
+            kPumpToBasePressure,
+            kPumpingDelay,
+            kLeakCheckDelay,
+            kLeakCheckCalc,
+            kPumpToCrossing_2,
+            kPumpToBasePressure_2,
+            kEnd,
+        }
+        public double LeakRate { get; private set; }
+
+        private double _basePressure = 100;
+        private double _CrossingPressure = 2000;
+        private int _leakcheckPumpTime = 180;
+        private int _leakcheckWaitTime = 300;
+
+        private double _startPressure = 0;
+        private double _endPressure = 0;
+        private double _leakRate = 30.0;
+
+        private readonly JetTM _JetTM;
+
+        public MFLeakCheckRoutine(JetTM tm, ModuleName mod) : base(mod)
+        {
+            Name = $"{Module} Leakcheck";
+            _JetTM = tm;
+        }
+
+        public RState Start(params object[] objs)
+        {
+            if (_JetTM.CheckLidClosed(Module) &&
+                _JetTM.CheckVentValveClosed(Module) &&
+                _JetTM.CheckPurgeValveClosed(Module) &&
+                _JetTM.CheckPumpValveClosed(Module))
+            {
+                Reset();
+
+                _JetTM.CloseModuleAllValves(Module);
+
+                _basePressure = SC.GetValue<double>($"{Module}.PumpBasePressure");
+                _CrossingPressure = SC.GetValue<double>($"{Module}.PumpCrossingPressure");
+                _leakcheckPumpTime = SC.GetValue<int>($"{Module}.LeakCheckPumpTime");
+                _leakcheckWaitTime = SC.GetValue<int>($"{Module}.LeakCheckWaitTime");
+                _leakRate = SC.GetValue<double>($"{Module}.Pump.LeakRate");
+
+                return Runner.Start(Module, Name);
+            }
+            return RState.Failed;
+        }
+
+        public RState Monitor()
+        {
+            Runner.Delay((int)LeakCheckStep.kCloseValves,       _delay_1s)
+                .Run((int)LeakCheckStep.kPumpToCrossing,        HOFs.WrapAction(_JetTM.TurnSoftPumpValve, Module, true),    () => { return _JetTM.GetModulePressure(Module) <= _CrossingPressure; })
+                .Run((int)LeakCheckStep.kPumpToBasePressure,    SwitchFastPump,                                             () => { return _JetTM.GetModulePressure(Module) <= _basePressure; })
+                .Delay((int)LeakCheckStep.kPumpingDelay,        _leakcheckPumpTime * 1000)
+                .Run((int)LeakCheckStep.kLeakCheckDelay,        StartLeakCheck,                                             _leakcheckWaitTime * 1000)
+                .Run((int)LeakCheckStep.kLeakCheckCalc,         CalcLeakCheckResult,                                        _delay_50ms)
+                .Run((int)LeakCheckStep.kPumpToCrossing_2,      HOFs.WrapAction(_JetTM.TurnSoftPumpValve, Module, true),    () => { return _JetTM.GetModulePressure(Module) <= _CrossingPressure; })
+                .Run((int)LeakCheckStep.kPumpToBasePressure_2,  SwitchFastPump,                                             () => { return _JetTM.GetModulePressure(Module) <= _basePressure; })
+                .End((int)LeakCheckStep.kEnd,                   LeakCheckEnd,                                               _delay_50ms);
+
+            return Runner.Status;
+        }
+
+        public void Abort()
+        {
+            _JetTM.CloseModuleAllValves(Module);
+        }
+
+        bool StartLeakCheck()
+        {
+            _JetTM.TurnFastPumpValve(Module, false);
+            _startPressure = _JetTM.GetModulePressure(Module);
+
+            Notify($"{Module} 压力开始值 {_startPressure} mt");
+            return true;
+        }
+
+        bool CalcLeakCheckResult()
+        {
+            _endPressure = _JetTM.GetModulePressure(Module);
+
+            LeakRate = (_endPressure - _startPressure) * 60.0 / _leakcheckWaitTime;
+
+            if (LeakRate < _leakRate)
+            {
+                Notify($"{Module} Leakcheck完成, 压力结束值: {_startPressure} mt, 漏率:{LeakRate} mt/min");
+            }
+            else
+            {
+                Stop($"{Module} Leakcheck失败, 腔体漏率 [{LeakRate}] mt/min, 高于 [{_leakRate}] mt/min");
+            }
+
+            return true;
+        }
+
+        bool LeakCheckEnd()
+        {
+            _JetTM.CloseModuleAllValves(Module);
+            return true;
+        }
+
+        private bool SwitchFastPump()
+        {
+            _JetTM.TurnSoftPumpValve(Module, false);
+            _JetTM.TurnFastPumpValve(Module, true);
+
+            return true;
+        }
+    }
+}

+ 91 - 0
Venus/Venus_RT/Modules/TM/MFPumpRoutine.cs

@@ -0,0 +1,91 @@
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Venus_RT.Devices;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.Equipment;
+using Venus_Core;
+
+namespace Venus_RT.Modules.TM
+{
+    class MFPumpRoutine : ModuleRoutineBase, IRoutine
+    {
+        private enum PumpStep
+        {
+            kWaitPeerModule,
+            kSoftPump,
+            kFastPump,
+            kClosePumpValves,
+        }
+
+        private double _pumpBasePressure;
+        private double _pumpCrossingPressure;
+        private int _pumpingTimeout;
+        private readonly JetTM _JetTM;
+        public MFPumpRoutine(JetTM jetTM, ModuleName mod) : base(mod)
+        {
+            _JetTM = jetTM;
+            Name = "Pump Down";
+        }
+
+        public RState Start(params object[] objs)
+        {
+            if (_JetTM.CheckLidClosed(Module) && 
+                _JetTM.CheckVentValveClosed(Module) && 
+                _JetTM.CheckPurgeValveClosed(Module))
+            {
+                Reset();
+                _pumpBasePressure = SC.GetValue<double>($"{Module}.PumpBasePressure");
+                _pumpCrossingPressure = SC.GetValue<double>($"{Module}.PumpCrossingPressure");
+                _pumpingTimeout = SC.GetValue<int>($"{Module}.PumpCrossingPressure") * 1000;
+
+                return Runner.Start(Module, Name);
+            }
+
+            return RState.Failed;
+        }
+
+        public RState Monitor()
+        {
+            Runner.Wait((int)PumpStep.kWaitPeerModule,  WaitPeerModule)
+                .Run((int)PumpStep.kSoftPump,           HOFs.WrapAction(_JetTM.TurnSoftPumpValve, Module, true),    () => { return _JetTM.GetModulePressure(Module) < _pumpCrossingPressure; }, _pumpingTimeout)
+                .Run((int)PumpStep.kFastPump,           SwitchFastPump,                                             () => { return _JetTM.GetModulePressure(Module) < _pumpBasePressure; },     _pumpingTimeout)
+                .End((int)PumpStep.kClosePumpValves,    ClosePumpValves,                                            _delay_50ms);
+
+            return Runner.Status;
+        }
+
+        private bool WaitPeerModule()
+        {
+            if(Module == ModuleName.LLA)
+            {
+                return !_JetTM.IsLLBFastPumpOpen && !_JetTM.IsLLBSoftPumpOpen;
+            }
+            else if (Module == ModuleName.LLB)
+            {
+                return !_JetTM.IsLLAFastPumpOpen && !_JetTM.IsLLASoftPumpOpen;
+            }
+
+            return true;
+        }
+
+        private bool SwitchFastPump()
+        {
+            _JetTM.TurnSoftPumpValve(Module, false);
+            _JetTM.TurnFastPumpValve(Module, true);
+
+            return true;
+        }
+        private bool ClosePumpValves()
+        {
+            _JetTM.TurnSoftPumpValve(Module, false);
+            _JetTM.TurnFastPumpValve(Module, false);
+
+            return true;
+        }
+
+        public void Abort()
+        {
+            ClosePumpValves();
+        }
+    }
+}

+ 97 - 0
Venus/Venus_RT/Modules/TM/MFPurgeRoutine.cs

@@ -0,0 +1,97 @@
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Venus_RT.Devices;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.Equipment;
+using Venus_Core;
+
+namespace Venus_RT.Modules.TM
+{
+    class MFPurgeRoutine : ModuleRoutineBase, IRoutine
+    {
+        private enum PurgeStep
+        {
+            kCloseValves,
+            kPumpToCrossing,
+            kPumpToBase,
+            kPurgeDelay_1,
+            kPurgeVent,
+            kPurgeDelay_2,
+            kPurgePumpToCrossing,
+            kPurgePumpToBase,
+            kPurgePumpDelay,
+            kPurgeEnd,
+            kEnd,
+        }
+
+        public int PurgeCounter { get; private set; }
+
+        private double _basePressure = 100;
+        private double _CrossingPressure = 2000;
+        private double _purgeVentPressure = 10;
+        private int _purgeCycleCounter = 30;
+        private int _purgePumpTime = 120;
+
+        private readonly JetTM _JetTM;
+
+
+        public MFPurgeRoutine(JetTM tm, ModuleName mod) : base(mod)
+        {
+            Name = $"{Module} Purge";
+            _JetTM = tm;
+        }
+
+        public RState Start(params object[] objs)
+        {
+            if (_JetTM.CheckLidClosed(Module) &&
+                _JetTM.CheckVentValveClosed(Module) &&
+                _JetTM.CheckPurgeValveClosed(Module) &&
+                _JetTM.CheckPumpValveClosed(Module))
+            {
+                Reset();
+                _JetTM.CloseModuleAllValves(Module);
+
+                _basePressure = SC.GetValue<double>($"{Module}.PumpBasePressure");
+                _CrossingPressure = SC.GetValue<double>($"{Module}.PumpCrossingPressure");
+                _purgeVentPressure = SC.GetValue<double>($"{Module}.PurgeVentPressure");
+                _purgeCycleCounter = SC.GetValue<int>($"{Module}.PurgeCycleCount");
+                _purgePumpTime = SC.GetValue<int>($"{Module}.PurgePumpTime");
+
+                PurgeCounter = 0;
+                return Runner.Start(Module, Name);
+            }
+
+            return RState.Failed;
+        }
+
+        public RState Monitor()
+        {
+            Runner.Delay((int)PurgeStep.kCloseValves, _delay_1s)
+                .Run((int)PurgeStep.kPumpToCrossing,            HOFs.WrapAction(_JetTM.TurnSoftPumpValve, Module, true),    () => { return _JetTM.GetModulePressure(Module) < _CrossingPressure; })
+                .Run((int)PurgeStep.kPumpToBase,                SwitchFastPump,                                             () => { return _JetTM.GetModulePressure(Module) < _basePressure; })
+                .LoopStart((int)PurgeStep.kPurgeDelay_1,        "Purge",            _purgeCycleCounter,                     HOFs.WrapAction(_JetTM.TurnSoftPumpValve, Module, false),           _delay_1s)
+                .LoopRun((int)PurgeStep.kPurgeVent,             HOFs.WrapAction(_JetTM.TurnVentValve, Module, true),        () => { return _JetTM.GetModulePressure(Module) >= _purgeVentPressure; })
+                .LoopRun((int)PurgeStep.kPurgeDelay_2,          HOFs.WrapAction(_JetTM.TurnVentValve, Module, false),       _delay_1s)
+                .LoopRun((int)PurgeStep.kPurgePumpToCrossing,   HOFs.WrapAction(_JetTM.TurnSoftPumpValve, Module, true),    () => { return _JetTM.GetModulePressure(Module) < _basePressure; })
+                .LoopRun((int)PurgeStep.kPurgePumpToBase,       SwitchFastPump,                                             () => { return _JetTM.GetModulePressure(Module) < _basePressure; })
+                .LoopRun((int)PurgeStep.kPurgePumpDelay,        NullFun,                                                    _purgePumpTime * 1000)
+                .LoopEnd((int)PurgeStep.kPurgeEnd,              HOFs.WrapAction(_JetTM.CloseModuleAllValves, Module),       _delay_1s)
+                .End((int)PurgeStep.kEnd,                       NullFun,                                                    _delay_50ms);
+
+            return Runner.Status;
+        }
+
+        public void Abort()
+        {
+            _JetTM.CloseModuleAllValves(Module);
+        }
+
+        private bool SwitchFastPump()
+        {
+            _JetTM.TurnSoftPumpValve(Module, false);
+            _JetTM.TurnFastPumpValve(Module, true);
+
+            return true;
+        }
+    }
+}

+ 54 - 0
Venus/Venus_RT/Modules/TM/MFVentRoutine.cs

@@ -0,0 +1,54 @@
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Venus_RT.Devices;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.Equipment;
+using Venus_Core;
+
+namespace Venus_RT.Modules.TM
+{
+    class MFVentRoutine : ModuleRoutineBase, IRoutine
+    {
+        private enum VentStep
+        {
+            kVenting,
+            kCloseVentValves,
+        }
+
+        private int _ventingTimeout;
+        private readonly JetTM _JetTM;
+        public MFVentRoutine(JetTM jetTM, ModuleName mod) : base(mod)
+        {
+            _JetTM = jetTM;
+            Name = "Vent";
+        }
+
+        public RState Start(params object[] objs)
+        {
+            if (_JetTM.CheckLidClosed(Module) &&
+                _JetTM.CheckPumpValveClosed(Module) &&
+                _JetTM.CheckPurgeValveClosed(Module))
+            {
+                Reset();
+                _ventingTimeout = SC.GetValue<int>($"{Module}.VentingTimeout") * 1000;
+
+                return Runner.Start(Module, Name);
+            }
+
+            return RState.Failed;
+        }
+
+        public RState Monitor()
+        {
+            Runner.Run((int)VentStep.kVenting,          HOFs.WrapAction(_JetTM.TurnVentValve, Module, true),    HOFs.Apply(_JetTM.IsModuleATM, Module),     _ventingTimeout)
+                .End((int)VentStep.kCloseVentValves,    HOFs.WrapAction(_JetTM.TurnVentValve, Module, false),    _delay_50ms);
+
+            return Runner.Status;
+        }
+
+        public void Abort()
+        {
+            _JetTM.TurnVentValve(Module, false);
+        }
+    }
+}

+ 189 - 17
Venus/Venus_RT/Modules/TM/TMEntity.cs

@@ -1,14 +1,16 @@
 using System;
 using Aitex.Core.RT.Fsm;
 using Aitex.Core.RT.Log;
-
+using Aitex.Core.Util;
+using Venus_Core;
 using Aitex.Sorter.Common;
 using MECF.Framework.Common.Equipment;
 using Venus_RT.Devices;
+using Venus_RT.Modules.TM;
 
 namespace Venus_RT.Modules
 {
-    class TMEntity : Entity, IEntity, IModuleEntity
+    class TMEntity : Entity, IModuleEntity
     {
         public enum STATE
         {
@@ -39,6 +41,7 @@ namespace Venus_RT.Modules
             Pump,
             Vent,
             Purge,
+            CyclePurge,
             LeakCheck,
             Pick, 
             Place,
@@ -72,10 +75,22 @@ namespace Venus_RT.Modules
 
         private readonly JetTM _tm;
         private readonly ITransferRobot _robot;
+
+        private readonly MFHomeRoutine _homeRoutine;
+        private readonly MFPumpRoutine _pumpingRoutine;
+        private readonly MFVentRoutine _ventingRoutine;
+        private readonly MFLeakCheckRoutine _leakCheckRoutine;
+        private readonly MFPurgeRoutine _purgeRoutine;
         public TMEntity()
         {
-            _tm = new JetTM();
-            _robot = new SIASUNRobot();
+            _tm                 = Singleton<JetTM>.Instance;
+            _robot              = new SIASUNRobot();
+
+            _homeRoutine = new MFHomeRoutine(_tm, _robot);
+            _pumpingRoutine     = new MFPumpRoutine(_tm, ModuleName.TM);
+            _ventingRoutine     = new MFVentRoutine(_tm, ModuleName.TM);
+            _leakCheckRoutine   = new MFLeakCheckRoutine(_tm, ModuleName.TM);
+            _purgeRoutine       = new MFPurgeRoutine(_tm, ModuleName.TM);
 
             InitFsmMap();
         }
@@ -88,33 +103,47 @@ namespace Venus_RT.Modules
         private void InitFsmMap()
         {
             fsm = new StateMachine<TMEntity>("TM", (int)STATE.Init, 50);
-            fsm.EnableRepeatedMsg(true);
 
-            AnyStateTransition(FSM_MSG.TIMER,   fnMonitor,      FSM_STATE.SAME);
+            //AnyStateTransition(FSM_MSG.TIMER,   fnMonitor,      FSM_STATE.SAME);
 
 
             AnyStateTransition(MSG.Error,       fnError,        STATE.Error);
             AnyStateTransition(MSG.Online,      fnOnline,       FSM_STATE.SAME);
             AnyStateTransition(MSG.Offline,     fnOffline,      FSM_STATE.SAME);
-            //AnyStateTransition(MSG.Abort,       fnAbort,        STATE.Idle);
             AnyStateTransition(MSG.Home,        fnHome,         STATE.Initializing);
 
             // Home
             Transition(STATE.Initializing,      FSM_MSG.TIMER,      fnHoming,           STATE.Idle);
 
-            //vent sequence
+            Transition(STATE.Idle,              FSM_MSG.TIMER,      fnMonitor,          STATE.Idle);
+            Transition(STATE.Init,              FSM_MSG.TIMER,      fnMonitor,          STATE.Init);
+
+            // Vent sequence
             Transition(STATE.Idle,              MSG.Vent,           FnStartVent,        STATE.Venting);
             Transition(STATE.Venting,           FSM_MSG.TIMER,      FnVentTimeout,      STATE.Idle);
             Transition(STATE.Venting,           MSG.Abort,          FnAbortVent,        STATE.Idle);
 
-            //Pump sequence
+            // Pump sequence
             Transition(STATE.Idle,              MSG.Pump,           FnStartPump,        STATE.Pumping);
             Transition(STATE.Pumping,           FSM_MSG.TIMER,      FnPumpTimeout,      STATE.Idle);
             Transition(STATE.Pumping,           MSG.Abort,          FnAbortPump,        STATE.Idle);
+
+            // Purge sequence
+            Transition(STATE.Idle,              MSG.CyclePurge,     FnStartPurge,       STATE.Purging);
+            Transition(STATE.Purging,           FSM_MSG.TIMER,      FnPurgeTimeout,     STATE.Idle);
+            Transition(STATE.Purging,           MSG.Abort,          FnAbortPurge,       STATE.Idle);
+
+            // Leak check sequence
+            Transition(STATE.Idle,              MSG.LeakCheck,      FnStartLeakCheck,   STATE.Leakchecking);
+            Transition(STATE.Leakchecking,      FSM_MSG.TIMER,      FnLeakCheckTimeout, STATE.Idle);
+            Transition(STATE.Leakchecking,      MSG.Abort,          FnAbortLeakCheck,   STATE.Idle);
+
+            Running = true;
         }
 
         private bool fnMonitor(object[] param)
         {
+            _debugRoutine();
             return true;
         }
 
@@ -143,46 +172,116 @@ namespace Venus_RT.Modules
 
         private bool fnHome(object[] param)
         {
-            return true;
+            return _homeRoutine.Start() == RState.Running;
         }
 
         private bool fnHoming(object[] param)
         {
-            return true;
+            RState ret = _homeRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
         }
 
         private bool FnStartVent(object[] param)
         {
-            return true;
+            return _ventingRoutine.Start() == RState.Running ;
         }
 
         private bool FnVentTimeout(object[] param)
         {
-            return true;
+            RState ret = _ventingRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
         }
 
         private bool FnAbortVent(object[] param)
         {
+            _ventingRoutine.Abort();
             return true;
         }
 
         private bool FnStartPump(object[] param)
         {
-            return true;
+            return _pumpingRoutine.Start() == RState.Running;
         }
 
         private bool FnPumpTimeout(object[] param)
         {
-            return true;
+            RState ret = _pumpingRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
         }
 
         private bool FnAbortPump(object[] param)
         {
+            _pumpingRoutine.Abort();
+            return true;
+        }
+
+        private bool FnStartPurge(object[] param)
+        {
+            return _purgeRoutine.Start() == RState.Running;
+        }
+
+        private bool FnPurgeTimeout(object[] param)
+        {
+            RState ret = _purgeRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+
+        private bool FnAbortPurge(object[] param)
+        {
+            _purgeRoutine.Abort();
+            return true;
+        }
+
+        private bool FnStartLeakCheck(object[] param)
+        {
+            return _leakCheckRoutine.Start() == RState.Running;
+        }
+
+        private bool FnLeakCheckTimeout(object[] param)
+        {
+            RState ret = _leakCheckRoutine.Monitor();
+            if (ret == RState.Failed || ret == RState.Timeout)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+
+            return ret == RState.End;
+        }
+
+        private bool FnAbortLeakCheck(object[] param)
+        {
+            _leakCheckRoutine.Abort();
             return true;
         }
         public bool Check(int msg, out string reason, params object[] args)
         {
-            throw new NotImplementedException();
+            reason = "";
+            return true;
         }
 
         public int Invoke(string function, params object[] args)
@@ -202,7 +301,6 @@ namespace Venus_RT.Modules
             return fsm.CheckExecuted(msg);
         }
 
-
         public bool CheckToPostMessage(int msg, params object[] args)
         {
             if (!fsm.FindTransition(fsm.State, msg))
@@ -216,5 +314,79 @@ namespace Venus_RT.Modules
 
             return true;
         }
+
+        private void _debugRoutine()
+        {
+            int flag = 0;
+            // Test Home routine
+            if (flag == 1)
+            {
+                PostMsg(MSG.Home);
+            }
+            else if (flag == 2)
+            {
+                PostMsg(MSG.Vent);
+            }
+            else if (flag == 3)
+            {
+                PostMsg(MSG.Pump);
+            }
+            //else if (flag == 4)
+            //{
+            //    PostMsg(MSG.PumpLoadLock);
+            //}
+            //else if (flag == 5)
+            //{
+            //    PostMsg(MSG.VentLoadLock);
+            //}
+            //else if (flag == 6)
+            //{
+            //    PostMsg(MSG.PurgeLoadLock);
+            //}
+            //else if (flag == 7)
+            //{
+            //    PostMsg(MSG.LaunchPump);
+            //}
+            //else if (flag == 8)
+            //{
+            //    PostMsg(MSG.LaunchTurboPump);
+            //}
+            //else if (flag == 9)
+            //{
+            //    PostMsg(MSG.LoadLockLeakCheck);
+            //}
+            //else if (flag == 10)
+            //{
+            //    PostMsg(MSG.CyclePurge);
+            //}
+            //else if (flag == 11)
+            //{
+            //    PostMsg(MSG.GasLinePurge);
+            //}
+            //else if (flag == 12)
+            //{
+            //    PostMsg(MSG.LeakCheck);
+            //}
+            //else if (flag == 13)
+            //{
+            //    PostMsg(MSG.GasLeakCheck);
+            //}
+            //else if (flag == 14)
+            //{
+            //    PostMsg(MSG.LLPlace);
+            //}
+            //else if (flag == 15)
+            //{
+            //    PostMsg(MSG.LLPick);
+            //}
+            //else if (flag == 16)
+            //{
+            //    PostMsg(MSG.RunRecipe, "7777");
+            //}
+            //else if (flag == 17)
+            //{
+            //    PostMsg(MSG.MFCVerification, "MFC2", (double)50, 10);
+            //}
+        }
     }
 }

+ 5 - 0
Venus/Venus_RT/Venus_RT.csproj

@@ -210,6 +210,11 @@
     <Compile Include="Modules\Schedulers\SchedulerModule.cs" />
     <Compile Include="Modules\Schedulers\SchedulerPM.cs" />
     <Compile Include="Modules\Schedulers\TransferModule.cs" />
+    <Compile Include="Modules\TM\MFHomeRoutine.cs" />
+    <Compile Include="Modules\TM\MFLeakCheckRoutine.cs" />
+    <Compile Include="Modules\TM\MFPumpRoutine.cs" />
+    <Compile Include="Modules\TM\MFPurgeRoutine.cs" />
+    <Compile Include="Modules\TM\MFVentRoutine.cs" />
     <Compile Include="Modules\TM\TMEntity.cs" />
     <Compile Include="Properties\AssemblyInfo.cs">
       <SubType>Code</SubType>

+ 3 - 3
Venus/Venus_Simulator/Devices/TMSimulatorServer.cs

@@ -10,9 +10,9 @@ namespace Venus_Simulator.Devices
 {
     class TMSimulatorServer : SocketDeviceSimulator
     {
-        private readonly Regex _check_load  = new Regex(@"CHECK LOAD\s+(\d+)\s+ARM\s+(A|B)\s+");
-        private readonly Regex _move_arm    = new Regex(@"(PLACE|PICK)\s+(\d+)\s+SLOT\s+(\d+)\s+ARM\s+(A|B)\s+(\w{4})\s+");
-        private readonly Regex _move_wafer = new Regex(@"(PLACE|PICK)\s+(\d+)\s+SLOT\s+(\d+)\s+ARM\s+(A|B)\s+");
+        private readonly Regex _check_load  = new Regex(@"CHECK LOAD\s+(\d+)\s+ARM\s+(A|B)\s*");
+        private readonly Regex _move_arm    = new Regex(@"(PLACE|PICK)\s+(\d+)\s+SLOT\s+(\d+)\s+ARM\s+(A|B)\s+(\w{4})\s*");
+        private readonly Regex _move_wafer = new Regex(@"(PLACE|PICK)\s+(\d+)\s+SLOT\s+(\d+)\s+ARM\s+(A|B)\s*");
 
         private PeriodicJob _HwThread;
         public TMSimulatorServer() : base(1102, -1, "\r", ' ')

+ 4 - 2
Venus/Venus_Simulator/Instances/SimulatorSystem.cs

@@ -206,7 +206,7 @@ namespace Venus_Simulator.Instances
                 //MonitorTemperature(ModuleName.PMA);
                 MonitorGas(ModuleName.PMA);
                 //MonitorRF(ModuleName.PMA);
-                //ChangeTime(ModuleName.PMA);
+                ChangeTime(ModuleName.PMA);
                 //MonitorIOPumpCtrl(ModuleName.PMA);
 
                 //// PMB
@@ -219,7 +219,9 @@ namespace Venus_Simulator.Instances
                 //ChangeTime(ModuleName.PMB);
                 //MonitorIOPumpCtrl(ModuleName.PMB);
 
-          
+                ChangeTime(ModuleName.TM);
+
+
             }
             catch (Exception e)
             {