using System; using System.Collections.Generic; using System.Threading; using System.Diagnostics; using System.Linq; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.RT.Device.Custom; using Aitex.Sorter.Common; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using VirgoCommon; using VirgoRT.Devices; using VirgoRT.Modules; using VirgoRT.Modules.PMs; namespace VirgoRT.Module { public class RecipeRunningInfo { public Guid InnerId { get; set; } public RecipeHead Head { get; set; } public List RecipeStepList { get; set; } public string RecipeName { get; set; } public DateTime BeginTime { get; set; } public DateTime EndTime { get; set; } public int StepNumber { get; set; } public string StepName { get; set; } public double StepTime { get; set; } public double StepElapseTime { get; set; } public double TotalTime { get; set; } public double TotalElapseTime { get; set; } } public class PMEntity : Entity, IModuleEntity { public enum MSG { Home, Transfer, PrepareTransfer, PostTransfer, Reset, Abort, Error, LaunchPump, Pump, Vent, CyclePurge, Heat, TransferHandoff, StartTransfer, LeakCheck, DeleteLeakCheck, MoveLiftPin, WaitLiftpin, MoveGuidePin, MFCVerification, AllMFCVerification, Clean, CleanReady, Process, RunRecipe, PostProcess, RecipeSkipStep, RecipeUpdate, RecipeResume, RecipePause, RecipeAbort, PreProcess, AutoMode, ManualMode, LockLid, OpenSlitDoor, CloseSlitDoor, Online, Offline, GasFlow, StopGasFlow, RfPower, MaxMsg } // ----------------------------Fields-------------------------- // private int _bigWafer = 0; private int _midWafer = 0; private int _smallWafer = 0; private bool _enableBias; private int _liftpinDelayTime = 0; private StatsDataItem _statProcessedWafer; private StatsDataItemRFAndPump _statRfOnTime; private StatsDataItemRFAndPump _statBiasRfOnTime; private StatsDataItemRFAndPump _statPumpOnTime; private readonly JetPM _chamber; private string _processStatus; private DateTime _recipeStartTime; //routine private readonly VentRoutine _ventRoutine; private readonly PumpDownRoutine _pumpRoutine; private readonly StartPumpRoutine _startPumpRoutine; private readonly TemperatureControlRoutine _temperatureControlRoutine; private readonly GasFlowRoutine _gasFlowRoutine; private readonly RfPowerRoutine _rfPowerRoutine; private readonly CyclePurgeRoutine _cyclePurgeRoutine; private readonly CleanRoutine _cleanRoutine; private readonly ProcessRoutine _processRoutine; private readonly PreProcessRoutine _preProcessRoutine; private readonly PostProcessRoutine _postProcessRoutine; private readonly LeakCheckRoutine _leakCheckRoutine; private readonly PMPrepareTransferRoutine _prepareTrans; private readonly PMPostTransferRoutine _postTrans; private readonly PMHomeRoutine _home; private readonly PMMfcVerificationRoutine _mfcVerification; private readonly PMAllMfcVerificationRoutine _allMfcVerification; private AutoFlag _AutoMode; private bool _isOnline; private bool _isAlarm; private DateTime _pumpStartTime; private TimeSpan _pumpElapsedTime; private DateTime _rfStartTime; private DateTime _tcStartTime; private TimeSpan _rfElapsedTime; private TimeSpan _tcElapsedTime; private MovementPosition _goalLiftPin; private ushort _ActivatedActionID; private Stopwatch _LifpinSleepTimer; // --------------------------Properties------------------------ // public ModuleName Module { get; } public Action TransferPrepared; public bool IsIdle { get { return fsm.State == (int)PMState.Idle; } } public bool IsError { get { return fsm.State == (int)PMState.Error; } } public bool IsAutoMode => _AutoMode == AutoFlag.Auto; public RecipeRunningInfo RecipeRunningInfo { get { return _recipeRunningInfo; } } public int Invoke(string function, params object[] args) { switch (function) { case "Home": CheckToPostMessage((int)MSG.Home); return (int)MSG.Home; } return (int)FSM_MSG.NONE; } public bool CheckAcked(int msg) { return fsm.CheckExecuted(msg); } public bool IsInit { get { return fsm.State == (int)PMState.Init; } } public bool IsBusy { get { return !IsInit && !IsError && !IsIdle; } } public bool IsProcessing { get { return fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess ; } } private DateTime _leakCheckStartTime; private TimeSpan _leakCheckElapsedTime; private string LeakCheckElapseTime { get { if ((fsm.State == (int)PMState.LeakCheck)) _leakCheckElapsedTime = DateTime.Now - _leakCheckStartTime; return string.Format("{0}:{1}:{2}", ((int)_leakCheckElapsedTime.TotalHours).ToString("00"), _leakCheckElapsedTime.Minutes.ToString("00"), _leakCheckElapsedTime.Seconds.ToString("00")); } } private string PumpTime { get { if ((fsm.State == (int)PMState.Pumping) || (fsm.State == (int)PMState.PreProcess)) _pumpElapsedTime = DateTime.Now - _pumpStartTime; return string.Format("{0}:{1}:{2}", ((int)_pumpElapsedTime.TotalHours).ToString("00"), _pumpElapsedTime.Minutes.ToString("00"), _pumpElapsedTime.Seconds.ToString("00")); } } private int StepNo { get { if ( (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess)) { return _processRoutine.CurStepNum + 1; } return 0; } } private int RecipeSteps { get { if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess)) { return _preProcessRoutine.CurrentRecipeStepList.Count; } return 0; } } private string RecipeStepName { get { if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess)) { return _processRoutine.CurStepComment; } return null; } } private double LeakRate { get { return _leakCheckRoutine.LeakRate; } } private string RecipeName { get { if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess)) { return _preProcessRoutine.CurrentRecipeRunningName.Split('\\').Last(); } return null; } } private string RFTime { get { if (fsm.State == (int)PMState.RfPowering) _rfElapsedTime = DateTime.Now - _rfStartTime; return $"{((int)_rfElapsedTime.TotalHours).ToString("00")}:{_rfElapsedTime.Minutes.ToString("00")}:{_rfElapsedTime.Seconds.ToString("00")}"; } } private string TCTime { get { if (fsm.State == (int)PMState.Heating) _tcElapsedTime = DateTime.Now - _tcStartTime; return $"{((int)_tcElapsedTime.TotalHours).ToString("00")}:{_tcElapsedTime.Minutes.ToString("00")}:{_tcElapsedTime.Seconds.ToString("00")}"; } } private TimeSpan _recipeElapsedTime; public string RecipeElapsedTime { get { if (fsm.State == (int)PMState.LoadProcessRecipe || fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess) _recipeElapsedTime = DateTime.Now - _recipeStartTime; return string.Format("{0}:{1}:{2}", ((int)_recipeElapsedTime.TotalHours).ToString("00"), _recipeElapsedTime.Minutes.ToString("00"), _recipeElapsedTime.Seconds.ToString("00")); } } public double RecipeTotalElapsedSeconds { get { if (fsm.State == (int)PMState.LoadProcessRecipe || fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess) _recipeElapsedTime = DateTime.Now - _recipeStartTime; return _recipeElapsedTime.TotalSeconds; } } public bool IsOnline { get { return _isOnline; } } private RecipeRunningInfo _recipeRunningInfo = new RecipeRunningInfo(); // --------------------------Constructor----------------------- // public PMEntity(ModuleName module) { this.Module = module; //_chamber = new JetPM(ModuleHelper.Converter(Name)); _smallWafer = SC.GetValue($"System.SmallWafer"); _midWafer = SC.GetValue($"System.MidWafer"); _bigWafer = SC.GetValue($"System.BigWafer"); _enableBias = SC.GetValue($"{Module}.BiasRf.EnableBiasRF"); _chamber = DEVICE.GetDevice(Module.ToString()); _isAlarm = false; _LifpinSleepTimer = new Stopwatch(); LeakCheckResultManager.Instance.Initialize(Module.ToString()); fsm = new StateMachine(Module.ToString(), (int)PMState.Init, 50); _ventRoutine = new VentRoutine(_chamber); _pumpRoutine = new PumpDownRoutine(_chamber); _startPumpRoutine = new StartPumpRoutine(_chamber); _temperatureControlRoutine = new TemperatureControlRoutine(_chamber); _prepareTrans = new PMPrepareTransferRoutine(_chamber, _ventRoutine); _postTrans = new PMPostTransferRoutine(_chamber); _gasFlowRoutine = new GasFlowRoutine(_chamber); _rfPowerRoutine = new RfPowerRoutine(_chamber, true); _cyclePurgeRoutine = new CyclePurgeRoutine(_chamber); _leakCheckRoutine = new LeakCheckRoutine(_chamber, _pumpRoutine); _cleanRoutine = new CleanRoutine(_chamber); _preProcessRoutine = new PreProcessRoutine(_chamber, _pumpRoutine); _processRoutine = new ProcessRoutine(_chamber, this); _postProcessRoutine = new PostProcessRoutine(_chamber, _ventRoutine); _home = new PMHomeRoutine(_chamber); _mfcVerification = new PMMfcVerificationRoutine(_chamber, _pumpRoutine); _allMfcVerification = new PMAllMfcVerificationRoutine(_chamber, _pumpRoutine); //Idle EnterExitTransition((int)PMState.Idle, FnIdle, (int)FSM_MSG.NONE, null); EnterExitTransition(PMState.Error, fEnterError, FSM_MSG.NONE, null); //Error Transition(PMState.Init, MSG.Error, FnError, PMState.Error); Transition(PMState.Error, MSG.Reset, FnReset, PMState.Idle); //AnyStateTransition(MSG.Error, FnError, PMState.Error); AnyStateTransition(FSM_MSG.WARNING, fWarning, FSM_STATE.SAME); AnyStateTransition((int)FSM_MSG.ALARM, fAlarm, (int)PMState.Error); AnyStateTransition(MSG.AutoMode, FnSetAuto, FSM_STATE.SAME); AnyStateTransition(MSG.ManualMode, FnSetManual, FSM_STATE.SAME); AnyStateTransition(MSG.Online, FnSetOnline, FSM_STATE.SAME); AnyStateTransition(MSG.Offline, FnSetOffline, FSM_STATE.SAME); //Home EnterExitTransition((int)PMState.Homing, FnEnterHome, (int)FSM_MSG.NONE, FnExitHome); Transition(PMState.Init, MSG.Home, FnStartHome, PMState.Homing); Transition(PMState.Error, MSG.Home, FnStartHome, PMState.Homing); Transition(PMState.Idle, MSG.Home, FnStartHome, PMState.Homing); Transition(PMState.Homing, FSM_MSG.TIMER, FnMonitorHome, PMState.Idle); Transition(PMState.Homing, MSG.Error, null, PMState.Init); Transition(PMState.Homing, MSG.Abort, FnAbortTask, PMState.Init); // Gas Flow sequence Transition(PMState.Idle, MSG.GasFlow, FnStartGasFlow, PMState.GasFlowing); Transition(PMState.GasFlowing, MSG.GasFlow, FnStartGasFlow, PMState.GasFlowing); Transition(PMState.GasFlowing, FSM_MSG.TIMER, FnGasFlowTimeout, PMState.Idle); Transition(PMState.GasFlowing, MSG.StopGasFlow, FnStopGasFlow, PMState.Idle); Transition(PMState.GasFlowing, MSG.Abort, FnAbortGasFlow, PMState.Idle); //RF Power sequence Transition(PMState.Idle, MSG.RfPower, FnStartRfPower, PMState.RfPowering); Transition(PMState.GasFlowing, MSG.RfPower, FnStartRfPower, PMState.RfPowering); Transition(PMState.RfPowering, FSM_MSG.TIMER, FnRfPowerTimeout, PMState.Idle); Transition(PMState.RfPowering, MSG.Abort, FnAbortRfPower, PMState.Idle); // Heat substrate Transition(PMState.Idle, MSG.Heat, FnHeat, PMState.Heating); Transition(PMState.Heating, FSM_MSG.TIMER, FnHeatTimeout, PMState.Idle); Transition(PMState.Heating, MSG.Abort, FnAbortHeating, PMState.Idle); //Launch Pump sequence Transition(PMState.Idle, MSG.LaunchPump, FnLaunchPump, PMState.LaunchingPump); Transition(PMState.LaunchingPump, FSM_MSG.TIMER, FnLaunchPumpTimeout, PMState.Idle); Transition(PMState.LaunchingPump, MSG.Abort, FnAbortStartPumping, PMState.Idle); //Pump sequence Transition(PMState.Idle, MSG.Pump, FnStartPumpDown, PMState.Pumping); Transition(PMState.Venting, MSG.Pump, FnVentToPumping, PMState.Pumping); Transition(PMState.Pumping, FSM_MSG.TIMER, FnPumpDownTimeout, PMState.Idle); Transition(PMState.Pumping, MSG.Abort, FnAbortPumping, PMState.Idle); //vent sequence Transition(PMState.Idle, MSG.Vent, FnStartVent, PMState.Venting); Transition(PMState.Pumping, MSG.Vent, FnPumpingToVent, PMState.Venting); Transition(PMState.Venting, FSM_MSG.TIMER, FnVentTimeout, PMState.Idle); Transition(PMState.Venting, MSG.Abort, FnAbortVent, PMState.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.Idle, MSG.DeleteLeakCheck, FnDeleteLeakCheck, PMState.Idle); Transition(PMState.LeakCheck, FSM_MSG.TIMER, FnLeakCheckTimeout, PMState.Idle); Transition(PMState.LeakCheck, MSG.Abort, FnAbortLeakCheck, PMState.Idle); //MFC verification Transition(PMState.Idle, MSG.MFCVerification, FnStartMFCVerification, PMState.MFCVerification); Transition(PMState.MFCVerification, FSM_MSG.TIMER, FnMFCVerificationTimeout, PMState.Idle); Transition(PMState.MFCVerification, MSG.Abort, FnAbortMFCVerification, PMState.Idle); //MFC verification Transition(PMState.Idle, MSG.AllMFCVerification, FnStartAllMFCVerification, PMState.AllMFCVerification); Transition(PMState.AllMFCVerification, FSM_MSG.TIMER, FnAllMFCVerificationTimeout, PMState.Idle); Transition(PMState.AllMFCVerification, MSG.Abort, FnAbortAllMFCVerification, PMState.Idle); // Transfer Transition(PMState.Idle, MSG.PrepareTransfer, FnStartPrepareTransfer, PMState.PrepareTransfer); Transition(PMState.PrepareTransfer, FSM_MSG.TIMER, FnPreTransferTimeout, PMState.Idle); Transition(PMState.PrepareTransfer, MSG.Abort, FnAbortTask, PMState.Idle); Transition(PMState.Idle, MSG.PostTransfer, FnStartPostTransfer, PMState.PostTransfer); Transition(PMState.PostTransfer, FSM_MSG.TIMER, FnPostTransferTimeout, PMState.Idle); Transition(PMState.PostTransfer, MSG.Abort, FnAbortTask, PMState.Idle); //EnterExitTransition(PMState.TransferHandoff, null, FSM_MSG.NONE, fExitTransfer); //Transition(PMState.Idle, MSG.TransferHandoff, FnStartTransferHandoff, PMState.TransferHandoff); //Transition(PMState.TransferHandoff, FSM_MSG.TIMER, FnHandoffTime, PMState.Idle); //Transition(PMState.TransferHandoff, MSG.Abort, FnAbortTask, PMState.Idle); // lift pin Transition(PMState.Idle, MSG.MoveLiftPin, FnSetLiftpin, PMState.LiftpinMoving); Transition(PMState.Idle, MSG.WaitLiftpin, null, PMState.LiftpinWaiting); Transition(PMState.LiftpinWaiting, FSM_MSG.TIMER, FnWaitLiftpinTimeout, PMState.LiftpinMoving); Transition(PMState.LiftpinMoving, FSM_MSG.TIMER, FnLiftpinTimeout, PMState.Idle); // OpenSlitDoor Transition(PMState.Idle, MSG.OpenSlitDoor, FnOpenSlitDoor, PMState.OpeningSlitDoor); Transition(PMState.OpeningSlitDoor, FSM_MSG.TIMER, FnOpenSlitDoorTimeout, PMState.Idle); // CloseSlitDoor Transition(PMState.Idle, MSG.CloseSlitDoor, FnCloseSlitDoor, PMState.ClosingSlitDoor); Transition(PMState.ClosingSlitDoor, FSM_MSG.TIMER, FnCloseSlitDoorTimeout, PMState.Idle); // guide pin Transition(PMState.Idle, MSG.MoveGuidePin, FnSetGuidePin, PMState.GuidePinMoving); Transition(PMState.GuidePinMoving, FSM_MSG.TIMER, FnGuidePinTimeout, PMState.Idle); // PreClean sequence Transition(PMState.Idle, MSG.Clean, FnPreClean, PMState.PreClean); Transition(PMState.PreClean, FSM_MSG.TIMER, FnPreCleanTimeout, PMState.LoadProcessRecipe); // PreProcess sequence Transition(PMState.Idle, MSG.RunRecipe, FnProcessLoadRecipe, PMState.LoadProcessRecipe); Transition(PMState.LoadProcessRecipe, MSG.PreProcess, FnStartPreProcess, PMState.PreProcess); Transition(PMState.LoadProcessRecipe, MSG.Abort, null, PMState.Idle); Transition(PMState.LoadProcessRecipe, MSG.Error, null, PMState.Idle); Transition(PMState.PreProcess, FSM_MSG.TIMER, FnPreProcessTimeout, PMState.PreProcess); Transition(PMState.PreProcess, MSG.Abort, FnAbortPreProcess, PMState.Idle); Transition(PMState.PreProcess, MSG.RecipeAbort, FnAbortPreProcess, PMState.Idle); Transition(PMState.PreProcess, MSG.Error, FnAbortPreProcess, PMState.Error); // Process Transition(PMState.PreProcess, MSG.Process, FnStartProcess, PMState.Processing); Transition(PMState.Processing, FSM_MSG.TIMER, FnProcessTimeout, PMState.Processing); Transition(PMState.Processing, MSG.Error, FnAbortProcess, PMState.Error); Transition(PMState.Processing, MSG.RecipeAbort, FnAbortProcess, PMState.PostProcess); Transition(PMState.Processing, MSG.RecipePause, FnPauseProcess, PMState.Processing); Transition(PMState.Processing, MSG.RecipeResume, FnResumeRecipe, PMState.Processing); Transition(PMState.Processing, MSG.RecipeUpdate, FnUpdateRecipe, PMState.Processing); Transition(PMState.Processing, MSG.RecipeSkipStep, FnSkipStep, PMState.Processing); EnterExitTransition(PMState.Processing, FnEnterProcess, FSM_MSG.NONE, FnExitProcess); //PostProcess sequence Transition(PMState.Processing, MSG.PostProcess, FnStartPostProcess, PMState.PostProcess); Transition(PMState.PostProcess, FSM_MSG.TIMER, FnPostProcessTimeout, PMState.Idle); Transition(PMState.PostProcess, MSG.Abort, FnAbortPostProcess, PMState.Idle); Transition(PMState.PostProcess, MSG.RecipeAbort, FnAbortPostProcess, PMState.Idle); Transition(PMState.PostProcess, MSG.Error, FnAbortPostProcess, PMState.Error); EnterExitTransition(PMState.PostProcess, null, FSM_MSG.NONE, fExitPostProcess); Running = true; } protected override bool Init() { DATA.Subscribe($"{Module}.FsmState", () => ((PMState)fsm.State).ToString()); DATA.Subscribe($"{Module}.FsmPrevState", () => ((PMState)fsm.PrevState).ToString()); DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage); DATA.Subscribe($"{Module}.PMState", () => fsm.State); DATA.Subscribe($"{Module}.IsAutoMode", () => IsAutoMode); DATA.Subscribe($"{Module}.IsOnline", () => _isOnline); DATA.Subscribe($"{Module}.IsAlarm", () => _isAlarm); DATA.Subscribe($"{Module}.ProcessStatus", () => _processStatus); DATA.Subscribe($"{Module}.PumpTime", () => PumpTime); DATA.Subscribe($"{Module}.TCTime", () => TCTime); DATA.Subscribe($"{Module}.StepNo", () => StepNo); DATA.Subscribe($"{Module}.RecipeStepName", () => RecipeStepName); DATA.Subscribe($"{Module}.RecipeName", () => RecipeName); DATA.Subscribe($"{Module}.LeakRate", () => LeakRate); DATA.Subscribe($"{Module}.LeakCheckElapseTime", () => LeakCheckElapseTime); DATA.Subscribe($"{Module}.SmallWafer", () => _smallWafer); DATA.Subscribe($"{Module}.BigWafer", () => _bigWafer); DATA.Subscribe($"{Module}.MidWafer", () => _midWafer); DATA.Subscribe($"{Module}.RecipeSteps", () => RecipeSteps); DATA.Subscribe($"{Module}.RecipeProcessTime", () => RecipeElapsedTime); DATA.Subscribe($"{Module}.RecipeTotalElapsedSeconds", () => RecipeTotalElapsedSeconds); DATA.Subscribe($"{Module}.RecipeStepTimeElapsed", () => (_processRoutine.CurStepElpasedTime / 1000).ToString("F0")); DATA.Subscribe($"{Module}.RecipeStepTimeSetPoint", () => (_processRoutine.CurStepTotalTime / 1000).ToString("F0")); OP.Subscribe($"{Module}.{RtOperation.GasFlow}", (cmd, args) => CheckToPostMessage((int)MSG.GasFlow, args)); OP.Subscribe($"{Module}.{RtOperation.RfPower}", (cmd, args) => CheckToPostMessage((int)MSG.RfPower, args)); OP.Subscribe($"{Module}.{RtOperation.MoveLiftPin}", (cmd, args) => CheckToPostMessage((int)MSG.MoveLiftPin, args[0], 0, true)); OP.Subscribe($"{Module}.{RtOperation.MoveGuidePin}", (cmd, args) => CheckToPostMessage((int)MSG.MoveGuidePin, args[0], args[1])); OP.Subscribe($"{Module}.Home", (cmd, args) => CheckToPostMessage((int)MSG.Home)); OP.Subscribe($"{Module}.{RtOperation.Reset}", (cmd, args) => CheckToPostMessage((int)MSG.Reset)); OP.Subscribe($"{Module}.{RtOperation.Abort}", (cmd, args) => CheckToPostMessage((int)MSG.Abort)); OP.Subscribe($"{Module}.PrepareTransfer", (cmd, args) => CheckToPostMessage((int)MSG.PrepareTransfer, args[0])); OP.Subscribe($"{Module}.TransferHandoff", (cmd, args) => CheckToPostMessage((int)MSG.TransferHandoff, args[0])); OP.Subscribe($"{Module}.{RtOperation.Pump}", (cmd, args) => CheckToPostMessage((int)MSG.Pump)); OP.Subscribe($"{Module}.{RtOperation.StartPump}", (cmd, args) => CheckToPostMessage((int)MSG.LaunchPump)); OP.Subscribe($"{Module}.{RtOperation.Vent}", (cmd, args) => CheckToPostMessage((int)MSG.Vent)); OP.Subscribe($"{Module}.{RtOperation.Purge}", (cmd, args) => CheckToPostMessage((int)MSG.CyclePurge)); OP.Subscribe($"{Module}.{RtOperation.LeakCheck}", (cmd, args) => CheckToPostMessage((int)MSG.LeakCheck, args)); OP.Subscribe($"{Module}.{RtOperation.DeleteLeakCheck}", (cmd, args) => CheckToPostMessage((int)MSG.DeleteLeakCheck, args)); OP.Subscribe($"{Module}.{RtOperation.LockLid}", (cmd, args) => CheckToPostMessage((int)MSG.LockLid, true)); OP.Subscribe($"{Module}.{RtOperation.UnlockLid}", (cmd, args) => CheckToPostMessage((int)MSG.LockLid, false)); OP.Subscribe($"{Module}.{RtOperation.RunRecipe}", (cmd, args) => CheckToPostMessage((int)MSG.RunRecipe, (string)args[0], "", true)); OP.Subscribe($"{Module}.{RtOperation.SkipCurrentStep}", (cmd, args) => CheckToPostMessage((int)MSG.RecipeSkipStep)); OP.Subscribe($"{Module}.{RtOperation.AbortRecipe}", (cmd, args) => CheckToPostMessage((int)MSG.RecipeAbort)); OP.Subscribe($"{Module}.{RtOperation.PmAuto}", (cmd, args) => CheckToPostMessage((int)MSG.AutoMode)); OP.Subscribe($"{Module}.{RtOperation.PmManual}", (cmd, args) => CheckToPostMessage((int)MSG.ManualMode)); OP.Subscribe($"{Module}.{RtOperation.PmOnline}", (cmd, args) => CheckToPostMessage((int)MSG.Online)); OP.Subscribe($"{Module}.{RtOperation.PmOffline}", (cmd, args) => CheckToPostMessage((int)MSG.Offline)); OP.Subscribe($"{Module}.{RtOperation.Heat}", (cmd, args) => CheckToPostMessage((int)MSG.Heat, args[0])); OP.Subscribe($"{Module}.{RtOperation.MFCVerification}", (cmd, args) => CheckToPostMessage((int)MSG.MFCVerification, args)); OP.Subscribe($"{Module}.{RtOperation.AllMFCVerification}", (cmd, args) => CheckToPostMessage((int)MSG.AllMFCVerification, args)); StatsDataManager.Instance.Subscribe($"{Module}.ProcessedWaferCount", "Processed Wafer Count", 0); StatsDataManager.Instance.Subscribe($"{Module}.RfOnTime", "Rf On Time"); if (_enableBias) StatsDataManager.Instance.Subscribe($"{Module}.BiasRfOnTime", "Bias Rf On Time"); StatsDataManager.Instance.Subscribe($"{Module}.PumpOnTime", "Pump On Time"); _statProcessedWafer = StatsDataManager.Instance.GetItem($"{Module}.ProcessedWaferCount"); _statRfOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.RfOnTime"); if (_enableBias) _statBiasRfOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.BiasRfOnTime"); _statPumpOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.PumpOnTime"); DATA.Subscribe($"{Module}.ProcessedWaferCount", () => _statProcessedWafer.Value); DATA.Subscribe($"{Module}.RfOnTime", () => _statRfOnTime.fromLastPM); if (_enableBias) DATA.Subscribe($"{Module}.BiasRfOnTime", () => _statBiasRfOnTime.fromLastPM); DATA.Subscribe($"{Module}.PumpOnTime", () => _statPumpOnTime.fromLastPM); return true; } // Methods // private bool CheckToPostMessage(int msg, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { EV.PostWarningLog(Module.ToString(), $"{Module} is in { (PMState)fsm.State} state,can not do {(MSG)msg}"); return false; } fsm.PostMsg(msg, args); return true; } private bool FnAbortTask(object[] param) { //_task.Abort(); return true; } private bool FnSetAuto(object[] param) { this._AutoMode = AutoFlag.Auto; return true; } private bool FnSetManual(object[] param) { if (fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess) { EV.PostWarningLog(Module.ToString(), $"{Module} is in {(PMState)fsm.State},can not do SetAutoMode"); return false; } this._AutoMode = AutoFlag.Manual; if (IsOnline) { EV.PostWarningLog(Module.ToString(), $"{Module} is online,change to offline due to the chamber change to manual mode"); this._isOnline = false; } return true; } private bool FnSetOnline(object[] param) { if (!IsAutoMode) { EV.PostWarningLog(Module.ToString(), $"{Module} in manual mode,can not set online."); return false; } if (!_chamber.CheckSlitDoorClose()) { EV.PostWarningLog(Module.ToString(), $"{Module} slit door is open,can not set online."); return false; } this._isOnline = true; return true; } private bool FnSetOffline(object[] param) { this._isOnline = false; return true; } #region Gas&RF private bool FnStartGasFlow(object[] objs) { Result ret = _gasFlowRoutine.Start(objs); if (ret == Result.FAIL || ret == Result.TIMEOUT) { return false; //do noting } return true; } private bool FnGasFlowTimeout(object[] objs) { Result ret = _gasFlowRoutine.Monitor(); if (ret == Result.FAIL || ret == Result.TIMEOUT) { PostMsg(MSG.Abort); return true; } return false; } private bool FnAbortGasFlow(object[] objs) { _gasFlowRoutine.Abort(); return true; } private bool FnStopGasFlow(object[] objs) { _gasFlowRoutine.StopFlow2(); return true; } private bool FnStartRfPower(object[] objs) { _rfStartTime = DateTime.Now; Result ret = _rfPowerRoutine.Start(objs); if (ret == Result.DONE) { return false; } if (ret == Result.FAIL || ret == Result.TIMEOUT) { return false; //do noting } return true; } private bool FnRfPowerTimeout(object[] objs) { Result ret = _rfPowerRoutine.Monitor(); if (ret == Result.DONE) return true; else if (ret == Result.FAIL || ret == Result.TIMEOUT) { //do nothing return true; } return false; ; } private bool FnAbortRfPower(object[] objs) { _rfPowerRoutine.Abort(); if (_gasFlowRoutine._gasStatus) _gasFlowRoutine.Abort(); return true; } private bool FnHeat(object[] objs) { _tcStartTime = DateTime.Now; return _temperatureControlRoutine.Start(objs) == Result.RUN; } private bool FnHeatTimeout(object[] param) { Result ret = _temperatureControlRoutine.Monitor(); if (ret == Result.DONE) { return true; } if (ret == Result.FAIL || ret == Result.TIMEOUT) { //do nothing return true; } return false; } private bool FnAbortHeating(object[] param) { _temperatureControlRoutine.Abort(); return true; } #endregion Gas&RF #region Subroutine private bool FnStartLeakCheck(object[] param) { _leakCheckStartTime = DateTime.Now; return _leakCheckRoutine.Start(param) == Result.RUN; } private bool FnLeakCheckTimeout(object[] param) { Result res = _leakCheckRoutine.Monitor(); return res == Result.DONE || res == Result.FAIL; } private bool FnDeleteLeakCheck(object[] param) { _leakCheckRoutine.DeleteLeadCheck(param); return true; } private bool FnAbortLeakCheck(object[] param) { _leakCheckRoutine.Abort(); return true; } private bool FnStartMFCVerification(object[] param) { _mfcVerification.Init((string)param[0], (float)param[1], (int)param[2]); return _mfcVerification.Start(param) == Result.RUN; } private bool FnMFCVerificationTimeout(object[] param) { Result res = _mfcVerification.Monitor(); return res == Result.DONE || res == Result.FAIL; } private bool FnAbortMFCVerification(object[] param) { _mfcVerification.Abort(); return true; } private bool FnStartAllMFCVerification(object[] param) { _allMfcVerification.Init((string[])param[0], (bool[])param[1]); return _allMfcVerification.Start(param) == Result.RUN; } private bool FnAllMFCVerificationTimeout(object[] param) { Result res = _allMfcVerification.Monitor(); return res == Result.DONE || res == Result.FAIL; } private bool FnAbortAllMFCVerification(object[] param) { _allMfcVerification.Abort(); return true; } private bool FnStartVent(object[] param) { Result ret = _ventRoutine.Start(); if (ret == Result.DONE) { return false; } else if (ret == Result.FAIL) { return false; //do noting } return true; } private bool FnVentTimeout(object[] param) { Result ret = _ventRoutine.Monitor(); if (ret == Result.DONE) { return true; } if (ret == Result.FAIL) { //do nothing return true; } return false; } private bool FnVentToPumping(object[] param) { _ventRoutine.Abort(); return FnStartPumpDown(param); } private bool FnAbortVent(object[] param) { _ventRoutine.Abort(); return true; } private bool FnLaunchPump(object[] param) { _pumpStartTime = DateTime.Now; return _startPumpRoutine.Start() == Result.RUN; } private bool FnLaunchPumpTimeout(object[] param) { Result ret = _startPumpRoutine.Monitor(); if (ret == Result.DONE) { return true; } if (ret == Result.FAIL || ret == Result.TIMEOUT) { PostMsg(MSG.Abort); return false; } return false; } private bool FnAbortStartPumping(object[] param) { _startPumpRoutine.Abort(); return true; } private bool FnStartPumpDown(object[] param) { _pumpStartTime = DateTime.Now; return _pumpRoutine.Start() == Result.RUN; } private bool FnPumpDownTimeout(object[] param) { Result ret = _pumpRoutine.Monitor(); if (ret == Result.DONE) { return true; } if (ret == Result.FAIL || ret == Result.TIMEOUT) { //do nothing return true; } return false; } private bool FnPumpingToVent(object[] param) { _pumpRoutine.Abort(); return FnStartVent(param); } private bool FnAbortPumping(object[] param) { _pumpRoutine.Abort(); return true; } private bool FnStartPurge(object[] param) { return _cyclePurgeRoutine.Start(param) == Result.RUN; } private bool FnPurgeTimeout(object[] param) { Result ret = _cyclePurgeRoutine.Monitor(); if (ret == Result.DONE) { return true; } else if (ret == Result.FAIL || ret == Result.TIMEOUT) { return true; } return false; } private bool FnAbortPurge(object[] param) { _cyclePurgeRoutine.Abort(); return true; } #endregion Subroutine #region Transfer private bool FnStartPrepareTransfer(object[] param) { if (param.Length > 2) _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), (float)param[1], (WaferSize)param[2]); else if (param.Length > 1) _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), (float)param[1]); else _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), 0); Result ret = _prepareTrans.Start(); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FnPreTransferTimeout(object[] param) { Result ret = _prepareTrans.Monitor(); if (ret == Result.FAIL) { PostMsg(MSG.Abort); return false; } return ret == Result.DONE; } private bool FnStartPostTransfer(object[] param) { Result ret = _postTrans.Start(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } return ret == Result.RUN; } private bool FnPostTransferTimeout(object[] param) { Result ret = _postTrans.Monitor(); if (ret == Result.FAIL) { PostMsg(MSG.Abort); return false; } return ret == Result.DONE; } private bool FnSetLiftpin(object[] param) { MovementPosition pos = (MovementPosition)param[0]; _ActivatedActionID = (ushort)param[1]; bool isPick = (bool)param[2]; bool isDelay = (bool)param[3]; _goalLiftPin = pos; _liftpinDelayTime = SC.GetValue(isPick ? $"{Module}.PinDownDelayTimePick" : $"{Module}.PinDownDelayTimePlace") * 1000; if (_liftpinDelayTime > 0&& isDelay) { EV.PostInfoLog(Module.ToString(), $"执行 lift pin {pos} Delayrecorder"); _LifpinSleepTimer.Restart(); CheckToPostMessage((int)MSG.WaitLiftpin); return false; } _chamber.SetLiftPin(pos, out _); EV.PostInfoLog(Module.ToString(), $"执行 lift pin {pos}"); return true; } private bool FnWaitLiftpinTimeout(object[] param) { if (_LifpinSleepTimer.ElapsedMilliseconds > _liftpinDelayTime) { _chamber.SetLiftPin(_goalLiftPin, out _); EV.PostInfoLog(Module.ToString(), $"执行 lift pin {_goalLiftPin}"); _LifpinSleepTimer.Reset(); return true; } return false; } private bool FnLiftpinTimeout(object[] param) { if (_chamber.LiftPinPosition == _goalLiftPin) { EV.PostInfoLog(Module.ToString(), $"lift pin 当前位置 {_chamber.LiftPinPosition}"); Singleton.Instance.EFEM.PostMsg( _goalLiftPin == MovementPosition.Up ? EfemEntity.MSG.PMLiftPinUp : EfemEntity.MSG.PMLiftPinDown, _ActivatedActionID); _goalLiftPin = MovementPosition.Unknown; _ActivatedActionID = 0; return true; } return false; } private bool FnOpenSlitDoor(object[] param) { _ActivatedActionID = (ushort)param[0]; _chamber.SetSlitDoor(true, out _); EV.PostInfoLog(Module.ToString(), $"Start opening {Module} slit door"); return true; } private bool FnOpenSlitDoorTimeout(object[] param) { if (_chamber.CheckSlitDoorOpen() ) { EV.PostInfoLog(Module.ToString(), $"{Module} slit door is opened"); Singleton.Instance.EFEM.PostMsg( EfemEntity.MSG.PMSlitDoorOpened, _ActivatedActionID); _ActivatedActionID = 0; return true; } return false; } private bool FnCloseSlitDoor(object[] param) { _ActivatedActionID = (ushort)param[0]; _chamber.SetSlitDoor(false, out _); EV.PostInfoLog(Module.ToString(), $"Start closing {Module} slit door"); return true; } private bool FnCloseSlitDoorTimeout(object[] param) { if (_chamber.CheckSlitDoorClose()) { EV.PostInfoLog(Module.ToString(), $"{Module} slit door is closed"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.PMSlitDoorClosed, _ActivatedActionID); _ActivatedActionID = 0; return true; } return false; } private bool FnSetGuidePin(object[] param) { WaferSize ws = (WaferSize)param[0]; MovementPosition pos = (MovementPosition)param[1]; _chamber.SetGuidePin(ws, pos); return true; } private bool FnGuidePinTimeout(object[] param) { return true; } private bool FnPreClean(object[] param) { _cleanRoutine.param = param; _chamber.SetSlitDoor(false, out _); return true; } private bool FnPreCleanTimeout(object[] param) { if (_chamber.IsSlitDoorClosed) { if (!FnProcessLoadRecipe(_cleanRoutine.param)) { EV.PostAlarmLog(_chamber.Module.ToString(), "Clean recipe read failed"); PostMsg(FSM_MSG.ALARM); return false; } return true; } return false; } #endregion Transfer #region Process private bool FnProcessLoadRecipe(object[] param) { _processStatus = "Succeed to load recipe"; _recipeStartTime = DateTime.Now; Result ret = _preProcessRoutine.LoadRecipe(param); if (ret == Result.DONE) { PostMsg(MSG.PreProcess); } else if (ret == Result.FAIL) { _processStatus = "Failed to load recipe"; return false; } return true; } private bool FnStartPreProcess(object[] param) { _pumpStartTime = DateTime.Now; //_processStatus = Resources.PMEntity_fStartPreProcess_PreparingRunningRecipe; Result ret = _preProcessRoutine.Start(param); if (ret == Result.DONE) { return false; } if (ret == Result.FAIL || ret == Result.VERIFYFAIL) { //_processStatus = Resources.PMEntity_fStartPreProcess_PreparingRunningRecipeFailed; PostMsg(MSG.Error); return false; //do noting } WaferManager.Instance.UpdateWaferProcessStatus(this.Module, 0, EnumWaferProcessStatus.InProcess); return true; } private bool FnPreProcessTimeout(object[] param) { //_processStatus = Resources.PMEntity_fPreProcess_RunRecipePumpingDown; Result ret = _preProcessRoutine.Monitor(); if (ret == Result.DONE) { PostMsg(MSG.Process, _preProcessRoutine.CurrentRecipeBaseName, _preProcessRoutine.CurrentRecipeRunningName, 0, _preProcessRoutine.CurrentLotName, _preProcessRoutine.CurrentRecipeContent, _preProcessRoutine.CurrentRecipeHead, _preProcessRoutine.CurrentRecipeStepList); return true; } if (ret == Result.FAIL) { //_processStatus = Resources.PMEntity_fPreProcess_RunRecipePumpingDownFailed; PostMsg(MSG.Error); return true; } return false; ; } private bool FnAbortPreProcess(object[] param) { //_processStatus = Resources.PMEntity_fAbortPreProcess_RunRecipePumpingDownAborted; WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed); _preProcessRoutine.Abort(); return true; } private bool FnStartProcess(object[] param) { //_processStatus = Resources.PMEntity_fStartProcess_StartRunningRecipe; Result ret = _processRoutine.Start(param); if (ret == Result.DONE) { return true; } else if (ret == Result.FAIL || ret == Result.VERIFYFAIL) { //_processStatus = Resources.PMEntity_fStartProcess_RunRecipeFailed; PostMsg(MSG.Error); return true; //do noting } return true; } private bool FnProcessTimeout(object[] param) { //_processStatus = Resources.PMEntity_fProcess_RunningRecipe; Result ret = _processRoutine.Monitor(); { if (ret == Result.DONE) { PostMsg(MSG.PostProcess, _processRoutine.CurrentRecipeRunningName, _processRoutine.CurrentRecipeContent); return true; } else if (ret == Result.FAIL) { //_processStatus = Resources.PMEntity_fStartProcess_RunRecipeFailed; PostMsg(MSG.Error); return true; } return false; } } private bool FnAbortProcess(object[] param) { //_processStatus = Resources.PMEntity_fAbortProcess_RunningRecipeAborted; _processRoutine.AbortRecipe(); WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed); _processRoutine.Abort(); Result ret = _postProcessRoutine.Start(new object[] { _processRoutine.CurrentRecipeRunningName, _processRoutine.CurrentRecipeContent }); if (ret == Result.DONE) { return false; } else if (ret == Result.FAIL) { PostMsg(MSG.Error); //_processStatus = Resources.PMEntity_fAbortProcess_RunRecipeAborted; return false; //do noting } return true; } private bool FnPauseProcess(object[] param) { return true; } private bool FnResumeRecipe(object[] param) { return true; } private bool FnUpdateRecipe(object[] param) { return true; } private bool FnSkipStep(object[] param) { _processRoutine.SkipCurrentRecipeStep(); return true; } private bool FnExitProcess(object[] param) { //_statProcessedWafer StatsDataManager.Instance.Increase(_statProcessedWafer.Name); _processRoutine.Exit(); return true; } private bool FnEnterProcess(object[] param) { return true; } private bool FnStartPostProcess(object[] param) { //_processStatus = Resources.PMEntity_fStartPostProcess_RunRecipePostProcess; Result ret = _postProcessRoutine.Start(param); if (ret == Result.DONE) { return false; } else if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } return true; } private bool FnPostProcessTimeout(object[] param) { //_processStatus = Resources.PMEntity_fPostProcess_RunRecipeCyclePurge; Result ret = _postProcessRoutine.Monitor(); if (ret == Result.DONE) { WaferManager.Instance.UpdateWaferProcessStatus(this.Module, 0, EnumWaferProcessStatus.Completed); //_processStatus = Resources.PMEntity_fPostProcess_RecipeCompleted; return true; } else if (ret == Result.FAIL) { //_processStatus = Resources.PMEntity_fPostProcess_RunRecipeCyclePurgeError; PostMsg(MSG.Error); return true; } return false; } private bool FnAbortPostProcess(object[] param) { //_processStatus = Resources.PMEntity_fAbortPostProcess_RecipeAborted; WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed); _postProcessRoutine.Abort(); return true; } private bool fExitPostProcess(object[] objs) { _postProcessRoutine.Exit(); //EV.Notify(EventLotFinished, new SerializableDictionary() //{ // {DVIDName.LotId, preProcessRoutine.CurrentLotName}, // {DVIDName.JobId, preProcessRoutine.CurrentJobName}, // {DVIDName.RecipeId, preProcessRoutine.CurrentRecipeBaseName } //}); return true; } #endregion PROCESS private string GetFsmLastMessage() { int msg = fsm.LastMsg; if (msg >= (int)MSG.Home && msg <= (int)MSG.MaxMsg) return ((MSG)msg).ToString(); if (msg == (int)FSM_MSG.TIMER) return "Timer"; return msg.ToString(); } protected override void Term() { } private bool FnReset(object[] param) { _isAlarm = false; if ((PMState)fsm.State == PMState.Error) return true; return false; } public bool Check(int msg, out string reason, object[] objs) { reason = ""; return true; } public bool IsProcessed() { return IsIdle; } public bool IsPrepareTransferReady(ModuleName robot, EnumTransferType type, int slot, Hand blade) { if (type == EnumTransferType.Pick) { return _chamber.CheckEnableTransfer(type, WaferManager.Instance.GetWafer(_chamber.Module, 0).Size); } else if (type == EnumTransferType.Place) { WaferSize ws= WaferManager.Instance.GetWafer(robot, (int)blade).Size; string SupportedWaferSize = SC.GetStringValue($"{Module}.SupportedWaferSize"); if (!SupportedWaferSize.Split(',').Contains(ws.ToString().Replace("WS", ""))) return false; return _chamber.CheckEnableTransfer(type, ws); } return false; } public void Home() { CheckToPostMessage((int)MSG.Home); } private bool FnExitHome(object[] param) { return true; } private bool FnEnterHome(object[] param) { return true; } private bool FnStartHome(object[] objs) { Result ret = _home.Start(); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FnMonitorHome(object[] objs) { Result ret = _home.Monitor(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } return ret == Result.DONE; } private bool fExitTransfer(object[] objs) { return true; } private bool fEnterError(object[] objs) { //if (IsProcessMode) //{ // EV.Notify(EventLotFinished, new SerializableDictionary() // { // {DVIDName.LotId, preProcessRoutine.CurrentLotName}, // {DVIDName.JobId, preProcessRoutine.CurrentJobName}, // {DVIDName.RecipeId, preProcessRoutine.CurrentRecipeBaseName } // }); //} _chamber.GeneratorPowerOn(false); _chamber.GeneratorBiasPowerOn(false); _chamber.StopAllGases(); return true; } private bool FnError(object[] objs) { Running = false; if (((PMState)fsm.State == PMState.Processing) || ((PMState)fsm.State == PMState.PreProcess) || ((PMState)fsm.State == PMState.Homing) || ((PMState)fsm.State == PMState.LoadProcessRecipe)) return false; if (IsProcessing) { WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed); } return true; } private bool fWarning(object[] objs) { //IsWarning = false; return true; } private bool fAlarm(object[] objs) { _isAlarm = true; if (fsm.State == (int)PMState.Init) return false; if (fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.PostProcess) { PostMsg(MSG.Error); return false; } //IsAlarm = true; return true; } private bool FnIdle(object[] objs) { Running = false; return true; } public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot) { if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString())) return (int)MSG.PrepareTransfer; return (int)FSM_MSG.NONE; } public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp) { if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString(), temp)) return (int)MSG.PrepareTransfer; return (int)FSM_MSG.NONE; } public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp, WaferSize size) { if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString(), temp, size)) return (int)MSG.PrepareTransfer; return (int)FSM_MSG.NONE; } public int InvokePostTransfer(ModuleName robot, EnumTransferType type, int slot) { if (CheckToPostMessage((int)MSG.PostTransfer, type.ToString())) return (int)MSG.PostTransfer; return (int)FSM_MSG.NONE; } public int InvokeClean(string recipeName, string waferID, bool withWafer) { if (CheckToPostMessage((int)MSG.Clean, recipeName, waferID, withWafer)) { return (int)MSG.Clean; } return (int)FSM_MSG.NONE; } public int InvokeProcess(string recipeName, string waferID, bool withWafer) { if (CheckToPostMessage((int)MSG.RunRecipe, recipeName, waferID, withWafer)) return (int)MSG.RunRecipe; return (int)FSM_MSG.NONE; } public int InvokePreHeat(float temperature) { if (CheckToPostMessage((int)MSG.Heat, (double)temperature)) return (int)MSG.Heat; return (int)FSM_MSG.NONE; } public void InvokeReset() { PostMsg((int)MSG.Reset); } public void SetAuto() { this._AutoMode = AutoFlag.Auto; } #region EndPoint public bool CheckEndPoint() { EPDDevice epd = DEVICE.GetDevice($"{Module}.EPD"); if (epd == null) return false; return epd.IsEnd; } public void StartEndPoint(string config, int index) { EPDDevice epd = DEVICE.GetDevice($"{Module}.EPD"); if (epd == null) return; epd.StepStart(config, index); } public void StopEndPoint() { EPDDevice epd = DEVICE.GetDevice($"{Module}.EPD"); if (epd == null) return; epd.StepStop(); } public void EndPointRecipeStop() { EPDDevice epd = DEVICE.GetDevice($"{Module}.EPD"); if (epd == null) return; epd.RecipeStop(); } public void EndPointRecipeStart(string recipeName) { EPDDevice epd = DEVICE.GetDevice($"{Module}.EPD"); if (epd == null) return; epd.RecipeStart(recipeName); } #endregion } }