using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using Aitex.Sorter.Common; using CyberX8_Core; using CyberX8_RT.Devices.EFEM; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace CyberX8_RT.Modules.SRD { internal class SRDAWCCycleRoutine : ModuleRoutineBase, IRoutine { private enum AWCStep { Ready, Speed50Percent, WaitSpeed50Percent, Speed80Percent, WaitSpeed80Percent, PickfromSRD, WaitPickfromSRD, LoopDelayPickSRD, PlacetoAligner0, WaitPlacetoAligner0, LoopDelayPlaceAligner0, Align0Degree, WaitAlign0Degree, LoopDelayAligner0, PickfromAligner0, WaitPickfromAligner0, LoopDelayPickAligner0, PlacetoAligner120, WaitPlacetoAligner120, LoopDelayPlaceAligner120, Align120Degree, WaitAlign120Degree, LoopDelayAligner120, PickfromAligner120, WaitPickfromAligner120, LoopDelayPickAligner120, PlacetoAligner240, WaitPlacetoAligner240, LoopDelayPlaceAligner240, Align240Degree, WaitAlign240Degree, LoopDelayAligner240, PickfromAligner240, WaitPickfromAligner240, LoopDelayPickAligner240, PlacetoSRD, WaitPlacetoSRD, LoopDelayPlaceSRD, HomeSRD, WaitHomeSRD, CycleEnd, End } #region 内部变量 /// /// 次数 /// private int _cycleCount = 0; /// /// 超时时间 /// private int _timeOut = 2000; /// /// Efem Enitity /// private EfemEntity _efemEntity; /// /// Efem Device /// private EfemBase _efemDevice; /// /// SRD Module Name /// private ModuleName _srdModuleName; /// /// SRD Entity /// private SRDEntity _srdEntity; #endregion #region 属性 /// /// 当前子状态机 /// public string CurrentStateMachine { get { return Runner.CurrentStep.ToString(); } } #endregion /// /// 构造函数 /// /// public SRDAWCCycleRoutine(ModuleName module) : base(module) { Name = "AWCCycle"; _srdModuleName = module; } /// /// Abort /// public void Abort() { Runner.Stop("SRD AWC Cycle Abort"); } /// /// Monitor /// /// public RState Monitor() { Runner.LoopStart(AWCStep.Ready, "AWC Cycle", _cycleCount, NullFun, CheckReady, _timeOut) //Robot speed 50% and pick wafer from SRD .LoopRun(AWCStep.Speed50Percent, ()=> { return RobotSpeed(50); }, _delay_2s) .LoopRunWithStopStatus(AWCStep.WaitSpeed50Percent, CheckOperationComplete, CheckOperationError) .LoopRun(AWCStep.PickfromSRD, PickFromSRD, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPickfromSRD, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPickSRD, _delay_2s) //Robot place wafer to Aligner, Align wafer 0 deg, pick from Aligner .LoopRun(AWCStep.PlacetoAligner0, PlacetoAligner, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPlacetoAligner0, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPlaceAligner0, _delay_2s) .LoopRun(AWCStep.Align0Degree, () => { return Align(0); }, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitAlign0Degree, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayAligner0, _delay_2s) .LoopRun(AWCStep.PickfromAligner0, PickfromAligner, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPickfromAligner0, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPickAligner0, _delay_2s) //Robot place wafer to Aligner, Align wafer 120 deg, pick from Aligner .LoopRun(AWCStep.PlacetoAligner120, PlacetoAligner, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPlacetoAligner120, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPlaceAligner120, _delay_2s) .LoopRun(AWCStep.Align120Degree, () => { return Align(120); }, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitAlign120Degree, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayAligner120, _delay_2s) .LoopRun(AWCStep.PickfromAligner120, PickfromAligner, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPickfromAligner120, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPickAligner120, _delay_2s) //Robot place wafer to Aligner, Align wafer 240 deg, pick from Aligner .LoopRun(AWCStep.PlacetoAligner240, PlacetoAligner, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPlacetoAligner240, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPlaceAligner240, _delay_2s) .LoopRun(AWCStep.Align240Degree, () => { return Align(240); }, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitAlign240Degree, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayAligner240, _delay_2s) .LoopRun(AWCStep.PickfromAligner240, PickfromAligner, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPickfromAligner240, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPickAligner240, _delay_2s) //Robot speed80% place wafer to SRD .LoopRun(AWCStep.Speed80Percent, () => { return RobotSpeed(80); }, _delay_2s) .LoopRunWithStopStatus(AWCStep.WaitSpeed80Percent, CheckOperationComplete, CheckOperationError) .LoopRun(AWCStep.PlacetoSRD, PlacetoSRD, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitPlacetoSRD, CheckOperationComplete, CheckOperationError) .LoopDelay(AWCStep.LoopDelayPlaceSRD, _delay_2s) .LoopRun(AWCStep.HomeSRD, HomeSRD, _delay_50ms) .LoopRunWithStopStatus(AWCStep.WaitHomeSRD, CheckHomeSRDComplete, CheckHomeSRDError) .LoopEnd(AWCStep.CycleEnd, NullFun, CheckOperationComplete) .End(AWCStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// 检验Ready状态 /// /// private bool CheckReady() { //检查是否有Wafer if (!WaferManager.Instance.CheckHasWafer(_srdModuleName, 0)) { LOG.Write(eEvent.ERR_SRD, Module, $"{Module} don't have wafer, can't do AWC Cycle"); return false; } _srdEntity = Singleton.Instance.GetModule(Module.ToString()); //检查SRD Home if (!_srdEntity.IsHomed) { LOG.Write(eEvent.ERR_SRD, Module, $"{Module} is not homed, can't do AWC Cycle. Please home it first"); return false; } //检查SRD门是否关闭 if (_srdEntity.IsSrdDoorClosed) { LOG.Write(eEvent.ERR_SRD, Module, $"{Module} door closed, can't do AWC Cycle"); return false; } //检查SRD真空是否开启 if (!_srdEntity.IsSrdChuckVacuum) { LOG.Write(eEvent.ERR_SRD, Module, $"{Module} Vacuum on, can't do AWC Cycle"); return false; } //检查EFEM状态 if (_efemEntity.IsIdle) return true; return false; } /// /// Robot speed /// /// private bool RobotSpeed(int speed) { _efemEntity.CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM.ToString(), (int)EfemEntity.MSG.SetRobotSpeed, speed); return true; } /// /// Pick from SRD /// /// private bool PickFromSRD() { Queue moveItems = new Queue(); MoveItem moveItem = new MoveItem(_srdModuleName, 0, ModuleName.EfemRobot, 0, Hand.Blade1); moveItems.Enqueue(moveItem); return _efemEntity.CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Pick, moveItems); } /// /// Place to SRD /// /// private bool PlacetoSRD() { Queue moveItems = new Queue(); MoveItem moveItem = new MoveItem(ModuleName.EfemRobot, 0, _srdModuleName, 0, Hand.Blade1); moveItems.Enqueue(moveItem); return _efemEntity.CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Place, moveItems); } /// /// Pick from Aligner /// /// private bool PickfromAligner() { Queue moveItems = new Queue(); MoveItem moveItem = new MoveItem(ModuleName.Aligner1, 0, ModuleName.EfemRobot, 0, Hand.Blade1); moveItems.Enqueue(moveItem); return _efemEntity.CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Pick, moveItems); } /// /// Place to Aligner /// /// private bool PlacetoAligner() { Queue moveItems = new Queue(); MoveItem moveItem = new MoveItem(ModuleName.EfemRobot, 0, ModuleName.Aligner1, 0, Hand.Blade1); moveItems.Enqueue(moveItem); return _efemEntity.CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Place, moveItems); } /// /// Align to target degree /// /// /// private bool Align(int degree) { return _efemEntity.CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM.ToString(), (int)EfemEntity.MSG.Align, ModuleName.Aligner1, 0, degree); ; } /// /// 检查Operation是否完成 /// /// private bool CheckOperationComplete() { if (_efemEntity.IsIdle && _efemEntity.RobotStatus == RState.End) { //LOG.WriteLog(eEvent.ERR_PREWET, _srdModuleName.ToString(), $"Efem RSstate is {_efemEntity.RobotStatus}"); return true; } return false; } /// /// 检查是Operation是否报错 /// /// private bool CheckOperationError() { if (_efemEntity.IsError || _efemEntity.RobotStatus == RState.Failed || _efemEntity.RobotStatus == RState.Timeout) { _srdEntity.SetIsAWCCycling(false); LOG.WriteLog(eEvent.ERR_SRD, _srdModuleName.ToString(), $"Step {Runner.CurrentStep} is Error"); return true; } return false; } /// /// Home SRD /// /// private bool HomeSRD() { return _srdEntity.CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.HomeAll); } /// /// 检查SRD Home是否完成 /// /// private bool CheckHomeSRDComplete() { if(_srdEntity.IsHomed) return true; return false; } /// /// 检查SRD Home是否报错 /// /// private bool CheckHomeSRDError() { if (_srdEntity.IsError) { _srdEntity.SetIsAWCCycling(false); LOG.WriteLog(eEvent.ERR_SRD, _srdModuleName.ToString(), $"Step {Runner.CurrentStep} is Error"); return true; } return false; } /// /// Start /// /// /// public RState Start(params object[] objs) { _cycleCount = (int)objs[0]; _efemEntity = Singleton.Instance.GetModule(ModuleName.EFEM.ToString()); _efemDevice = _efemEntity.EfemDevice; Runner.Start(Module, Name); return RState.Running; } } }