SicMultiplate/Modules/Mainframe/LLs/Routines/Base/LoadLockBaseRoutine.cs

922 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Equipment;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.MachineVision.Keyence;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
using SicModules.Devices;
using SicModules.TMs;
namespace SicModules.LLs.Routines.Base
{
public class LoadLockBaseRoutine : ModuleRoutine, IRoutine
{
protected LoadLock LoadLockDevice
{
get { return _ll; }
}
protected TM TMDevice
{
get { return _tm; }
}
protected IoLift4 Lift
{
get { return _llLift; }
}
protected IoLoadRotation Rotation
{
get { return _llRotation; }
}
protected IoClaw WaferClaw
{
get { return _llWaferClaw; }
}
protected IoClaw TrayClaw
{
get { return _llTrayClaw; }
}
private LoadLock _ll = null;
private TM _tm = null;
private IoLift4 _llLift = null;
private IoLoadRotation _llRotation = null;
private IoClaw _llWaferClaw = null;
private IoClaw _llTrayClaw = null;
private KeyenceCVX300F _loadCCD = null;
public IoSensor _loadTrayHomeSensor; //Tray定位
//public IoSensor _loadWaferPlaced; //上下对射检测Wafer有无
public IoSensor _loadTrayPlaced; //检测托盘有无
public LoadLockBaseRoutine() : base(ModuleName.LoadLock.ToString())
{
_ll = DEVICE.GetDevice<SicLoadLock>($"{Module}.{Module}");
_tm = DEVICE.GetDevice<SicTM>($"{ModuleName.System}.{ModuleName.TM}");
_llLift = DEVICE.GetDevice<IoLift4>($"{Module}.LLLift");
_llWaferClaw = DEVICE.GetDevice<IoClaw>($"{Module}.LLWaferClaw");
_llTrayClaw = DEVICE.GetDevice<IoClaw>($"{Module}.LLTrayClaw");
_llRotation = DEVICE.GetDevice<IoLoadRotation>("Load.Rotation");
_loadCCD = DEVICE.GetDevice<KeyenceCVX300F>($"TM.KeyenceCVX300F");
_loadTrayHomeSensor = DEVICE.GetDevice<IoSensor>($"TM.LoadTrayHomeSensor");
_loadTrayPlaced = DEVICE.GetDevice<IoSensor>($"TM.LLTrayPresence");
}
protected override Result StartBody(params object[] args)
{
Notify("Start");
return Result.RUN;
}
public override void Abort()
{
LoadLockDevice.SetSlowPumpValve(false, out _);
LoadLockDevice.SetFastPumpValve(false, out _);
LoadLockDevice.SetSlowVentValve(false, out _);
LoadLockDevice.SetFastVentValve(false, out _);
base.Abort();
}
protected void LiftMove(int id, bool up, int timeout)
{
string note = up ? "Up" : "Down";
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set {Module} Lift to {note}");
if(up)
{
if (!Lift.MoveUp(out string reason))
{
Stop($"Set {Module} Lift to {note} failed:" + reason);
return false;
}
}
else
{
if (!Lift.MoveDown(out string reason))
{
Stop($"Set {Module} Lift to {note} failed:" + reason);
return false;
}
}
return true;
}, () =>
{
if(up)
{
return Lift.IsUp && !Lift.IsDown;
}
else
{
return !Lift.IsUp && Lift.IsDown;
}
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set {Module} Lift to {note} Timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void ResetRotationServo(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Reset {Module} Rotation servo");
if (!_llRotation.ServoReset(out string reason))
{
Stop($"Reset {Module} Rotation servo fail:" + reason);
return false;
}
return true;
}, () =>
{
if (_llRotation.IsServoError)
{
return false;
}
return true;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT)
{
Stop($"Reset {Module} Rotation servo Timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void RotationServoOn(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set {Module} Rotation servo on");
if (!_llRotation.ServoOn(true,out string reason))
{
Stop($"Set {Module} Rotation servo on fail:" + reason);
return false;
}
return true;
},() =>
{
if (!_llRotation.IsServoOn)
{
return false;
}
return true;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void MoveRelativeHome(int id, int timeout)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Set {Module} Rotation move relative home");
if (!_llRotation.MoveRelativeHome(out string reason))
{
Stop($"Set {Module} Rotation move relative home:" + reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void MoveLoadRotationHomeOffset(int id, float offset, int timeout)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Set {Module} Rotation move offset");
if (!_llRotation.JogCW(offset, out string reason))
{
Stop($"Set {Module} Rotation move offset:" + reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void WaitLoadRotationDone(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
//不做任何动作
return true;
},
() =>
{
//检测Rotation电机Error
if (_llRotation.IsServoError)
{
Stop($"Set {Module} Rotation Servo Error");
return null;
}
return !_llRotation.IsServoBusy;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT)
{
Stop($"Wait Load Rotation Done timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void MoveOneCircle(int id,int timeout)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Set {Module} Rotation One Circle Wafter check sensor");
if (!_llRotation.MoveOneCircle(out string reason))
{
Stop($"Set {Module} Rotation One Circle Wafter check sensor:" + reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
//Result WaitMoveOneCircleDoneResult;
//protected Result WaitMoveOneCircleDone(int id, int timeout)
//{
// Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
// {
// Notify($"Wait {Module} Rotation One Circle Wafter check sensor");
// WaitMoveOneCircleDoneResult = Result.RUN;
// return true;
// }, () =>
// {
// //检测到未放好Sensor信号
// if (!_loadWaferPlaced.Value)
// {
// //失败后Stop电机
// _llRotation.Stop(out _);
// Stop($"Set {Module} Rotation One Circle Wafter check sensor fail [TM DI-35]");
// WaitMoveOneCircleDoneResult = Result.VERIFYFAIL;
// return true;
// }
// //检测Rotation电机Error
// if (_llRotation.IsServoError)
// {
// //失败后Stop电机
// _llRotation.Stop(out _);
// Stop($"Set {Module} Rotation Servo Error");
// WaitMoveOneCircleDoneResult = Result.VERIFYFAIL;
// return true;
// }
// if (!_llRotation.IsServoBusy)
// {
// Notify($"{Module} Rotation One Circle Wafter check result ok");
// WaitMoveOneCircleDoneResult = Result.Succeed;
// return true;
// }
// return false;
// }, timeout * 1000);
// if (ret.Item1)
// {
// if (ret.Item2 == Result.FAIL)
// {
// throw (new RoutineFaildException());
// }
// else if (ret.Item2 == Result.TIMEOUT) //timeout
// {
// Stop($"Set {Module}Rotation One Circle Wafter check sensor Timeout, over {timeout} seconds");
// throw (new RoutineFaildException());
// }
// else
// throw (new RoutineBreakException());
// }
// return WaitMoveOneCircleDoneResult;
//}
Result WaitMoveOneCircleDoneResult;
public Queue<bool> DISensroQueuen = new Queue<bool>();
protected Result WaitMoveOneCircleDone(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Wait {Module} Rotation One Circle Wafter check sensor");
WaitMoveOneCircleDoneResult = Result.RUN;
DISensroQueuen = new Queue<bool>();
return true;
}, () =>
{
//检测到未放好Sensor信号
//if (!_loadWaferPlaced.Value)
//{
// //失败后Stop电机
// _llRotation.Stop(out _);
// Stop($"Set {Module} Rotation One Circle Wafter check sensor fail [TM DI-35]");
// WaitMoveOneCircleDoneResult = Result.VERIFYFAIL;
// return true;
//}
//检测Rotation电机Error
if (_llRotation.IsServoError)
{
//失败后Stop电机
_llRotation.Stop(out _);
Stop($"Set {Module} Rotation Servo Error");
return null;
}
if (!_llRotation.IsServoBusy)
{
//Notify($"{Module} Rotation One Circle Wafter check finish");
WaitMoveOneCircleDoneResult = Result.Succeed;
return true;
}
return false;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT)
{
Stop($"Set {Module}Rotation One Circle Wafter check sensor Timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
return WaitMoveOneCircleDoneResult;
}
protected void MoveHomePos(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"{Module} Rotation move Home Pos");
if (!_llRotation.MoveRelativeHome(out string reason))
{
Stop($"{Module} Rotation move Home Pos fail:" + reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void MoveCCD1Pos(int id,int timeout)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"{Module} Rotation move CCD Pos1");
if (!_llRotation.MoveCCD1Pos(out string reason))
{
Stop($"{Module} Rotation move CCD Pos1 fail:" + reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void MoveCCD2Pos(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"{Module} Rotation move CCD Pos2");
if (!_llRotation.MoveCCD2Pos(out string reason))
{
Stop($"{Module} Rotation move CCD Pos2 fail:" + reason);
return false;
}
return true;
}, () =>
{
if (!_llRotation.IsServoBusy)
{
return true;
}
return false;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set {Module} Rotation move CCD Pos2 Timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
protected void ClawMove(int id, IoClaw _claw,bool claw, int timeout)
{
string note = claw ? "Clawing" : "Opening";
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set {Module} {note}");
if (!_claw.SetValue(claw, out string reason))
{
Stop($"Set {Module} {note} failed:" + reason);
return false;
}
return true;
}, () =>
{
return _claw.State == (claw ? ClawStateEnum.Clamp : ClawStateEnum.Open);
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set {Module} {note} Timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
//public void CheckForelinePressure(int id,double basePressure, int timeout)
//{
// Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
// {
// Notify($"Check {Module} foreline pressure under {basePressure} mbar");
// return true;
// }, () =>
// {
// return LoadLockDevice.ForelinePressure <= basePressure;
// }, timeout * 1000);
// if (ret.Item1)
// {
// if (ret.Item2 == Result.FAIL)
// {
// throw (new RoutineFaildException());
// }
// else if (ret.Item2 == Result.TIMEOUT) //timeout
// {
// Stop($"{Module} foreline pressure can not lower than {basePressure} in {timeout} seconds");
// throw (new RoutineFaildException());
// }
// else
// throw (new RoutineBreakException());
// }
//}
public void SlowPump(int id, double switchPressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {Module} slow pump valve to {switchPressure} mbar");
if (!LoadLockDevice.SetSlowPumpValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return LoadLockDevice.ChamberPressure <= switchPressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
LoadLockDevice.SetSlowPumpValve(false, out string _);
Stop($"{Module} pressure can not pump to {switchPressure} in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void FastPump(int id, double basePressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {Module} fast pump valve to {basePressure} mbar");
if (!LoadLockDevice.SetFastPumpValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return LoadLockDevice.ChamberPressure <= basePressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
LoadLockDevice.SetSlowPumpValve(false, out string _);
LoadLockDevice.SetFastPumpValve(false, out string _);
Stop($"{Module} pressure can not pump to {basePressure} in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseSlowPumpValve(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {Module} slow pump valve");
if (!LoadLockDevice.SetSlowPumpValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseFastPumpValve(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {Module} fast pump valve");
if (!LoadLockDevice.SetFastPumpValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SlowVent(int id,double switchPressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {Module} slow vent valve to {switchPressure} mbar");
if (!LoadLockDevice.SetSlowVentValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return LoadLockDevice.ChamberPressure >= switchPressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
LoadLockDevice.SetSlowVentValve(false, out string _);
Stop($"{Module} pressure can not vent to {switchPressure} mbar in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SlowVent(int id,double switchPressure, double pressureDiff, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {Module} slow vent valve to {switchPressure} mbar");
if (!_ll.SetSlowVentValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return LoadLockDevice.ChamberPressure >= switchPressure - pressureDiff;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
_ll.SetSlowVentValve(false, out string _);
Stop($"{Module} pressure can not vent to {switchPressure} mbar in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseVentValveAndWait(int id, int timeout = 3)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Close {Module} slow vent valve");
if (!LoadLockDevice.SetSlowVentValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return LoadLockDevice.CheckSlowVentValve(false);
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT)
{
Stop($"Close {Module} slow vent valve in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseVentValve(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {Module} slow vent valve");
if (!LoadLockDevice.SetSlowVentValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CCDModeSet(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Set CCD Mode to 0");
_loadCCD.RunR0();
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
Result CCDTriggerResult;
public Result CCDTrigger(int id,int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Load CCD Check Trigger");
_loadCCD.ClearResult();
_loadCCD.GetResult(1);
CCDTriggerResult = Result.RUN;
return true;
}, () =>
{
if(_loadCCD._sResult != "")
{
if(_loadCCD._sResult.Contains("OK"))
{
CCDTriggerResult = Result.Succeed;
return true;
}
else
{
CCDTriggerResult = Result.VERIFYFAIL;
return true;
}
}
return false;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
return Result.VERIFYFAIL;
}
else if (ret.Item2 == Result.TIMEOUT)
{
return Result.TIMEOUT;
}
else
throw (new RoutineBreakException());
}
return CCDTriggerResult;
}
}
}