using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using Virgo_DRT.Module; using Virgo_DRT.Modules; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using Virgo_DRT.Devices; namespace Virgo_DRT.Scheduler { public class SchedulerPM : SchedulerModule { public override bool IsAvailable { get { return _entity.IsIdle && _entity.IsOnline && CheckTaskDone(); } } public override bool IsOnline { get { return _entity.IsOnline; } } public override bool IsError { get { return _entity.IsError; } } private PMEntity _entity = null; private ModuleName _taskRobot; private EnumTransferType _taskTransferType; private int _taskSlot; private int _entityTaskToken = (int)FSM_MSG.NONE; private DeviceTimer _timerProcess = new DeviceTimer(); private JetPM _pm; private float _paramTemp; public float Temperature { get { return _pm.SubstrateTempFB; } } public SchedulerPM(ModuleName chamber) : base(chamber.ToString()) { switch (chamber) { case ModuleName.PMA: _entity = Singleton.Instance.PMA; break; case ModuleName.PMB: _entity = Singleton.Instance.PMB; break; } _pm = DEVICE.GetDevice(Module.ToString()); } public override bool IsReadyForPick(ModuleName robot, int slot) { return _entity.IsPrepareTransferReady(robot, EnumTransferType.Pick, slot) && WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), slot); } public override bool IsReadyForPlace(ModuleName robot, int slot) { return _entity.IsPrepareTransferReady(robot, EnumTransferType.Place, slot) && WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), slot); } public bool IsTemperatureReady(float temp) { return Math.Abs(Temperature -temp) < SC.GetValue("System.MaxTemperatureToleranceTransferWafer"); } public override bool PrepareTransfer(ModuleName robot, EnumTransferType type, int slot) { _task = TaskType.PrepareTransfer; _taskRobot = robot; _taskSlot = slot; _taskTransferType = type; _entityTaskToken = _entity.InvokePrepareTransfer(robot, type, slot); LogTaskStart(_task, $"{robot} {type} slot {slot + 1}"); return _entityTaskToken != (int)FSM_MSG.NONE; } public bool PrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp) { _task = TaskType.PrepareTransfer; _taskRobot = robot; _taskSlot = slot; _taskTransferType = type; _entityTaskToken = _entity.InvokePrepareTransfer(robot, type, slot, temp); LogTaskStart(_task, $"{robot} {type} slot {slot + 1}"); return _entityTaskToken != (int)FSM_MSG.NONE; } public override bool PostTransfer(ModuleName robot, EnumTransferType type, int slot) { StopWaitTransfer(robot); _task = TaskType.PostTransfer; _taskRobot = robot; _taskSlot = slot; _taskTransferType = type; _entityTaskToken = _entity.InvokePostTransfer(robot, type, slot); LogTaskStart(_task, $"{robot} {type} slot {slot + 1}"); return _entityTaskToken != (int)FSM_MSG.NONE; } public override bool PostTransfer(ModuleName robot ) { StopWaitTransfer(robot); _task = TaskType.PostTransfer; _taskRobot = robot; _taskSlot = _inTransferSlot; _taskTransferType = _inTransferType; _entityTaskToken = _entity.InvokePostTransfer(robot, _inTransferType, _inTransferSlot); LogTaskStart(_task, $"{robot} {_inTransferType} slot {_inTransferSlot + 1}"); return _entityTaskToken != (int)FSM_MSG.NONE; } public override bool Process(string recipeName, bool isCleanRecipe, bool withWafer) { _task = TaskType.Process; LogTaskStart(_task, $"recipe: {recipeName}, clean: {isCleanRecipe}, with wafer: {withWafer}"); if (SC.GetValue("System.IsATMMode")) { int time = SC.GetValue("System.ATMCyclePMDelayTime"); _timerProcess.Start(time * 1000); EV.PostInfoLog("Scheduler", $"System run in ATM mode, process skipped, delay {time} seconds"); WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.InProcess); return true; } else { _entityTaskToken = _entity.InvokeProcess(recipeName); return _entityTaskToken != (int)FSM_MSG.NONE; } } public override bool Preheating(float temperature) { _task = TaskType.Heating; _paramTemp = temperature; _entityTaskToken = _entity.InvokePreHeat(temperature); LogTaskStart(_task, $"preheat to {temperature}"); return _entityTaskToken != (int)FSM_MSG.NONE; } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: ret = true; break; case TaskType.PrepareTransfer: ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsPrepareTransferReady(_taskRobot, _taskTransferType, _taskSlot); break; case TaskType.PostTransfer: ret = _entity.CheckAcked(_entityTaskToken) ; break; case TaskType.Heating: ret = _entity.CheckAcked(_entityTaskToken) && IsTemperatureReady(_paramTemp); break; case TaskType.Process: if (SC.GetValue("System.IsATMMode")) { ret = _timerProcess.IsTimeout() && _entity.IsIdle; if (ret) WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Completed); } else { ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsProcessed(); } break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } public bool Monitor() { return true; } public void SetPMAuto() { _entity.SetAuto(); } } }