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;
}
}
}