using System; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using EFEM.RT.Modules; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; namespace EFEM.RT.Routines { internal class AlignRoutine : CommonRoutine, IRoutine { enum Align { AlignForReader, WaitAlignForReader, AlignerRelease, WaitAlignerRelease, AlignerMoveUp, WaitAlignerMoveUp, ReaderWaferID, ReaderWaferID2, Align, WaitAlign, AlignerRelease2, WaitAlignerRelease2, AlignerMoveUp2, WaitAlignerMoveUp2, } private SCConfigItem _scAlignTimeout = null; private SCConfigItem _scReaderTimeout = null; private SCConfigItem _scReadLaserNotch = null; private int _timeoutAlign = 0; private int _timeoutReadID = 0; private double _fReadLaserNotch = 0; public AlignRoutine(string module, string name) { } public bool Initalize() { _scAlignTimeout = SC.GetConfigItem(SorterCommon.ScPathName.Aligner_TimeLimitForAlignWafer); _scReaderTimeout = SC.GetConfigItem(SorterCommon.ScPathName.OcrReader_TimeLimitForWID); _scReadLaserNotch = SC.GetConfigItem(SorterCommon.ScPathName.Aligner_AlignerReadAngle); return true; } public double Notch { get; set; } public MoveOption Option { get; set; } public bool VerifyAny { get; set; } public bool VerifyLaserMaker { get; set; } public string LaserMaker { get; set; } public bool VerifyT7Code { get; set; } public string T7Code { get; set; } public Result Start(params object[] objs) { _timeoutAlign = _scAlignTimeout.IntValue; _timeoutReadID = _scReaderTimeout.IntValue; _fReadLaserNotch = _scReadLaserNotch.DoubleValue; Reset(); EV.PostMessage(ModuleName.Robot.ToString(), EventEnum.AlignBegins, string.Format("{0:F2}",Notch)); return Result.RUN; } public Result Monitor() { try { bool bAlignerForRead = false; if ((Option & MoveOption.ReadID) == MoveOption.ReadID || (Option & MoveOption.ReadID2) == MoveOption.ReadID2) { bAlignerForRead = true; AlignWafer((int)Align.AlignForReader, "Aligning to read wafer ID", _fReadLaserNotch, Notify, Stop); WaitAlignerMotion((int)Align.WaitAlignForReader, aligner, "Wait to finish reading wafer ID", _timeoutAlign, Notify, Stop); ReleaseAligner((int)Align.AlignerRelease, "Aligner ungrip", Notify, Stop); WaitAlignerMotion((int)Align.WaitAlignerRelease, aligner, "Wait aligner ungrip", _timeoutAlign, Notify, Stop); AlignerMoveUp((int)Align.AlignerMoveUp, "Aligner move up", Notify, Stop); WaitAlignerMotion((int)Align.WaitAlignerMoveUp, aligner, "Wait aligner moved up", _timeoutAlign, Notify, Stop); } if ((Option & MoveOption.ReadID) == MoveOption.ReadID) { ReadWaferID((int)Align.ReaderWaferID, "Read wafer ID", _timeoutReadID, true, Notify, Stop); } if ((Option & MoveOption.ReadID2) == MoveOption.ReadID2) { ReadWaferID((int)Align.ReaderWaferID2, "Read wafer ID2", _timeoutReadID, false, Notify, Stop); } if (!bAlignerForRead || (Math.Abs(Notch - _fReadLaserNotch) > 0.01)) { AlignWafer((int)Align.Align, "Align wafer", Notch, Notify, Stop); WaitAlignerMotion((int)Align.WaitAlign, aligner, "Wait to finish aligning", _timeoutAlign, Notify, Stop); ReleaseAligner((int)Align.AlignerRelease2, "Aligner ungrip", Notify, Stop); WaitAlignerMotion((int)Align.WaitAlignerRelease2, aligner, "Wait aligner ungrip", _timeoutAlign, Notify, Stop); AlignerMoveUp((int)Align.AlignerMoveUp2, "Aligner move up", Notify, Stop); WaitAlignerMotion((int)Align.WaitAlignerMoveUp2, aligner, "Wait aligner moved up", _timeoutAlign, Notify, Stop); } } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } WaferManager.Instance.UpdateWaferNotch(ModuleName.Aligner, 0, aligner.Notch); bool bVerifyLMOK = true; if ((Option & MoveOption.ReadID) == MoveOption.ReadID) { WaferManager.Instance.UpdateWaferLaser(ModuleName.Aligner, 0, widreader.LaserMaker); if (VerifyLaserMaker) { if(LaserMaker != widreader.LaserMaker) { bVerifyLMOK = false; string reason = string.Format("LaserMaker1 unmatch. Host:{0};Reader:{1}.", LaserMaker, widreader.LaserMaker); EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, reason); } } } bool bVerifyT7OK = true; if ((Option & MoveOption.ReadID2) == MoveOption.ReadID2) { WaferManager.Instance.UpdateWaferT7Code(ModuleName.Aligner, 0, widreader.T7Code); if (VerifyT7Code) { if (T7Code != widreader.T7Code) { bVerifyT7OK = false; string reason = string.Format("LaserMaker2 unmatch. Host:{0};Reader:{1}.", T7Code, widreader.T7Code); EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, reason); } } } bool bVerifyOK = bVerifyLMOK & bVerifyT7OK; if (VerifyAny) bVerifyOK = bVerifyLMOK | bVerifyT7OK; if(bVerifyOK) { if (SC.GetValue(SorterCommon.ScPathName.OcrReader_EnablePauseOnWaferIdVerifyFailed)) { Singleton.Instance.PostMsg(RouteManager.MSG.Pause); } } EV.PostMessage(ModuleName.Robot.ToString(), EventEnum.AlignEnds); return Result.DONE; } public new void Abort() { base.Abort(); } public void AlignWafer(int id, string name, double notch,Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format(name)); string reason = string.Empty; return aligner.Align(notch, out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } public void AlignerMoveUp(int id, string name, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("{0} Lift up", aligner.Name)); string reason = string.Empty; return aligner.LiftUp(out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } public void ReleaseAligner(int id, string name, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("{0} Ungrip", aligner.Name)); string reason = string.Empty; return aligner.Release(Hand.Both, out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } protected void ReadWaferID(int id, string name, int time, bool bLaserMarker, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, () => { notify(name); string reason = string.Empty; if (!widreader.Read(bLaserMarker, out reason)) { error(String.Format("Read Wafer ID failed,{0}", reason)); } return true; }, () => { if (!widreader.Busy) { return true; } return false; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { error(String.Format(" read WaferID timeout after {0} seconds", time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } } }