using System; using System.Windows; using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using Aitex.Sorter.RT.Module; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.OcrReaders; using MECF.Framework.Common.DBCore; using FACore; using Aitex.Sorter.RT.SorterCommonFrame.SorterJobControl; using Aitex.Sorter.RT.SorterCommonFrame.Modules; using Aitex.Sorter.RT.Module.Recipe; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Aligners.AlignersBase; using System.Threading; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using System.Text; using Aitex.Core.RT.Log; namespace Aitex.Sorter.RT.SorterCommonFrame.Routines { internal class AlignRoutine : CommonRoutineSorter, IRoutine { private enum Align { AlignForReader, WaitAlignForReader, ReaderWaferID, ReaderWaferID2, VerifyLM1WaitInput, VerifyLM2WaitInput, VerifyLM1WithHostDefine, VerifyLM2WithHostDefine, Align, WaitAlign, SendEventPreAlign, SendEventPostAlign, SendEventLM1, SendEventLM2, ReleaseAligner, WaitComplete, Finish, UpdateWaferNextStation, UpdataWaferProcessState, WaitOcrReady1, WaitOcrReady2, WaitOcrReady3, WaitOcrReady4, WaitOcrReady5, WaitOcrReady6, SaveOcrImage1, SaveOcrImage2, Retry, Retry2 =100, SetRetryFlag1, SetRetryFlag2, SetRetryFlag3, } private enum AlignEventType { PreAlignEnd, PostAlignEnd, ReadLM1, ReadLM2, } private ReadWaferIDRecipe _aligneRecipe; public ReadWaferIDRecipe AlignerRecipe { get => _aligneRecipe; set { _aligneRecipe = value; } } private ModuleName _alignerModulename = ModuleName.Aligner; public ModuleName AlignerModulename { get => _alignerModulename; set { _alignerModulename = value; } } private bool _isRemoteJob= false; public bool IsRemoteJob { get => _isRemoteJob; set { IsRemoteJob = value; } } public bool IsNeedRetryLaserMark1; public bool IsNeedRetryLaserMark2; public bool IsVerifyLM1WaitManualInput { get; private set; } public bool IsVerifyLM1WithHostDefine { get; private set; } public bool IsVerifyLM2WaitManualInput { get; private set; } public bool IsVerifyLM2WithHostDefine { get; private set; } private int _timeoutAlign => Aligner.TimeLimitAlignWafer; private int _timeoutReadOcr => Aligner.TimeLimitReadOcr; private int _timeoutVerifyOcr => Aligner.TimeLimitVerifyOcr; private int _retryTimes { get { if (SC.ContainsItem("Process.OcrRetryTimes")) return SC.GetValue("Process.OcrRetryTimes"); return 0; } } public const string EventStartAlign = "WAFER_ALIGN_START"; public const string EventEndAlign = "WAFER_ALIGN_END"; public const string AlarmAlignFailed = "AlignerAligningFailed"; public const string EventWaferIdRead = "WAFER_LM_READ"; public const string EventWaferIdReadFail = "WAFER_LM_READ_FAILED"; public const string EventWaferIdVerifyFailed = "AlignerVerifyLaserMarkFailed"; public const string EventWaferIdVerifySucceeded = "WAFER_LM_VERIFY_SUCCEEDED"; public const string EventStartReturnLot = "START_RETURN_LOT"; public AlignRoutine(string module, string name) { Name = module + name; } public bool Initalize() { Reset(); IsRoutineActive = false; return true; } private bool IsOnSortingByID { get { if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.SortingByID) return true; if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.Canceling) return SorterJobManager.Instance.IsOnCancelSortingByID; return false; } } private bool IsOnDispatchByID { get { if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.DispatchingByID) return true; return false; } } private bool IsOnSortingBySlot { get { if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.SortingBySlot) return true; if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.Canceling) return SorterJobManager.Instance.IsOnCancelSortingBySlot; return false; } } private double ConvertPreAlignAngle(double anglesp) { if (Aligner.IsReversePreAlignDirection) return anglesp * -1; return anglesp; } private double ConvertPostAlignAngle(double anglesp) { if (Aligner.IsReversePostAlignDirection) return anglesp * -1; return anglesp; } private bool _isSaveImageInRoutine { get { if (SC.ContainsItem("Process.SaveOcrImage")) return SC.GetValue("Process.SaveOcrImage"); return false; } } public Result Start(params object[] paras) { Reset(); Aligner = DEVICE.GetDevice(_alignerModulename.ToString()); var wafer = WaferManager.Instance.GetWafers(AlignerModulename)[0]; WaferManager.Instance.UpdateWaferProcessStatus(AlignerModulename, 0, EnumWaferProcessStatus.InProcess); if (!wafer.IsEmpty) { var carrierId = wafer.OriginCarrierID; var slotNumber = wafer.OriginSlot+1; var dvid = new SerializableDictionary() { {DVIDName.LOT_ID, wafer.LotId}, {DVIDName.WAFER_ID, wafer.WaferID}, {DVIDName.CAR_ID, carrierId}, {DVIDName.SLOT_NO, slotNumber}, {DVIDName.ARRIVE_POS_NAME, "ALN1"}, }; EV.Notify(EventStartAlign, dvid); } IsVerifyLM1WaitManualInput = _aligneRecipe.IsVerifyLaserMarker1 && (_aligneRecipe.IsVerifyLaserMarkLength || _aligneRecipe.IsVerifyLaserMarkSlotForNCD || _aligneRecipe.IsVerifyChecksumLaserMarker1); IsVerifyLM1WithHostDefine = _aligneRecipe.IsVerifyLaserMarker1 && _aligneRecipe.IsVerifyWithHostDefine; IsVerifyLM2WaitManualInput = _aligneRecipe.IsVerifyLaserMarker2 && (_aligneRecipe.IsVerifyLaserMarkLength || _aligneRecipe.IsVerifyLaserMarkSlotForNCD || _aligneRecipe.IsVerifyChecksumLaserMarker2); IsVerifyLM2WithHostDefine = _aligneRecipe.IsVerifyLaserMarker2 && _aligneRecipe.IsVerifyWithHostDefine; if (_aligneRecipe.IsReadLaserMarker1 && _aligneRecipe.OcrReaderJob1.Count <= 0) { EV.Notify(AlarmAlignFailed); return Result.FAIL; } if (_aligneRecipe.IsReadLaserMarker2 && _aligneRecipe.OcrReaderJob2.Count <= 0) { EV.Notify(AlarmAlignFailed); return Result.FAIL; } if (_aligneRecipe.IsReadLaserMarker1) { if (string.IsNullOrEmpty(_aligneRecipe.OcrReaderJob1[0])) { EV.PostAlarmLog("System", $"Invalid job1 setting in sub recipe:{_aligneRecipe.RecipeName}."); EV.Notify(AlarmAlignFailed); return Result.FAIL; } } if (_aligneRecipe.IsReadLaserMarker2) { if (string.IsNullOrEmpty(_aligneRecipe.OcrReaderJob2[0])) { EV.PostAlarmLog("System", $"Invalid job2 setting in sub recipe:{_aligneRecipe.RecipeName}."); EV.Notify(AlarmAlignFailed); return Result.FAIL; } } Reset(); EV.PostInfoLog("System", "Start to implement alignment routine"); IsRoutineActive = true; return Monitor(); } public Result Monitor() { if (!IsRoutineActive) return Result.DONE; var ret = MonitorRoutine(); if (ret == Result.FAIL) { IsRoutineActive = false; } if (ret == Result.DONE) { IsRoutineActive = false; } return ret; } private Result MonitorRoutine() { try { if (_aligneRecipe != null) { if (_aligneRecipe.IsPreAlign) { RtPreAlignWafer((int)Align.AlignForReader, "Pre align the wafer", ConvertPreAlignAngle(_aligneRecipe.PreAlignAngle), Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitAlignerMotion((int)Align.WaitAlignForReader, Aligner, "Wait to finish the pre-alignment", _timeoutAlign, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (_aligneRecipe.IsReadLaserMarker1) { RtWaitReaderReady((int)Align.WaitOcrReady1, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtReadWaferID((int)Align.ReaderWaferID, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 0, _aligneRecipe.OcrReaderJob1[0], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitReaderReady((int)Align.WaitOcrReady2, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_isSaveImageInRoutine) { RtSaveOcrPicture((int)Align.SaveOcrImage1, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtSetRetryLaserMarkFlag((int)Align.SetRetryFlag1,0, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if(IsNeedRetryLaserMark1) { for(int i=0;i<_retryTimes;i++) { RtAlignWaferForRetry((int)Align.Retry + 1 + i * 8, i+1,ConvertPreAlignAngle(_aligneRecipe.PreAlignAngle), Aligner.OCRs[_aligneRecipe.LaserMarkerWaferReaderIndex1 - 1], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitAlignerMotion((int)Align.Retry + 2 + i * 8, Aligner, "Wait to finish the pre-alignment for retry ocr read", _timeoutAlign, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitReaderReady((int)Align.Retry + 3 + i * 8, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtReadWaferIDForRetry((int)Align.Retry + 4 + i * 8,i+1, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 0, _aligneRecipe.OcrReaderJob1[0], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitReaderReady((int)Align.Retry + 5 + i * 8, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_isSaveImageInRoutine) { RtSaveOcrPicture((int)Align.Retry + 6 + i * 8, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtSetRetryLaserMarkFlag((int)Align.Retry + 7 + i*8, 0, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } //RtWaitReaderReady((int)Align.WaitOcrReady3, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, // Notify, Stop); //if (ExecuteResult.Item1) //{ // if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; // if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; // if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; // if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; //} RtSendReadResult((int)Align.SendEventLM1, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 0, _aligneRecipe.OcrReaderJob1[0], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (IsVerifyLM1WaitManualInput) { RtVerifyWaferIDAndWaitManualInput((int)Align.VerifyLM1WaitInput, _alignerModulename, _timeoutVerifyOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 0, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (IsVerifyLM1WithHostDefine) { RtVerifyWaferIDWithHostDefine((int)Align.VerifyLM1WithHostDefine, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 0, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } if (_aligneRecipe.IsReadLaserMarker2) { RtWaitReaderReady((int)Align.WaitOcrReady4, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtReadWaferID((int)Align.ReaderWaferID2, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 1, _aligneRecipe.OcrReaderJob2[0], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitReaderReady((int)Align.WaitOcrReady5, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_isSaveImageInRoutine) { RtSaveOcrPicture((int)Align.SaveOcrImage2, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtSetRetryLaserMarkFlag((int)Align.SetRetryFlag1, 1, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if(IsNeedRetryLaserMark2) { for(int j=0;j<_retryTimes;j++) { RtAlignWaferForRetry((int)Align.Retry2+j*8,j+1, ConvertPreAlignAngle(_aligneRecipe.PreAlignAngle), Aligner.OCRs[_aligneRecipe.LaserMarkerWaferReaderIndex1 - 1], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitAlignerMotion((int)Align.Retry2 + 1 + j * 8, Aligner, "Wait to finish the pre-alignment for retry ocr read", _timeoutAlign, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitReaderReady((int)Align.Retry2 + 2 + j * 8, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtReadWaferIDForRetry((int)Align.Retry2 + 3 + j * 8,j+1, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 1, _aligneRecipe.OcrReaderJob2[0], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitReaderReady((int)Align.Retry2 + 4 + j * 8, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_isSaveImageInRoutine) { RtSaveOcrPicture((int)Align.Retry2 + 5 + j * 8, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtSetRetryLaserMarkFlag((int)Align.Retry2 + 6 + j * 8, 1, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } //RtWaitReaderReady((int)Align.WaitOcrReady6, _timeoutReadOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, // Notify, Stop); //if (ExecuteResult.Item1) //{ // if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; // if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; // if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; // if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; //} RtSendReadResult((int)Align.SendEventLM2, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 1, _aligneRecipe.OcrReaderJob2[0], Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (IsVerifyLM2WaitManualInput) { RtVerifyWaferIDAndWaitManualInput((int)Align.VerifyLM2WaitInput, _alignerModulename, _timeoutVerifyOcr, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 0, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (IsVerifyLM2WithHostDefine) { RtVerifyWaferIDWithHostDefine((int)Align.VerifyLM2WithHostDefine, _alignerModulename, _aligneRecipe.LaserMarkerWaferReaderIndex1 - 1, 1, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } if (_aligneRecipe.IsPostAlign) { RtPostAlignWafer((int)Align.Align, "Post align the wafer", ConvertPostAlignAngle(_aligneRecipe.PostAlignAngle) + Aligner.PostAlignCompensationAngleValue, Notify); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitAlignerMotion((int)Align.WaitAlign, Aligner, "Wait to finish post-alignment", _timeoutAlign, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } if (IsOnSortingByID) { RtUpdateWaferNextStationOnSortingByHost((int)Align.UpdateWaferNextStation, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (IsOnSortingBySlot) { RtUpdateWaferNextStationOnSortingBySlot((int)Align.UpdateWaferNextStation, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (IsOnDispatchByID) { RtUpdateWaferNextStationOnDispatchByID((int)Align.UpdateWaferNextStation, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtUpdateWaferSingleStepProcessState((int)Align.UpdataWaferProcessState, "Update wafer to processed.", AlignerModulename, 0, Hand.Both, EnumWaferProcessStatus.Completed, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } EV.PostInfoLog("System", $"Complete wafer align routine."); IsRoutineActive = false; return Result.DONE; } catch (Exception ex) { LOG.Write(ex); IsRoutineActive = false; return Result.FAIL; } } public new void Abort() { base.Abort(); } public Tuple RtUpdateWaferNextStationOnSortingByHost(int id, Action notify, Action error) { Tuple ret = Execute(id, () => { notify("Update wafer to next station sorting by host."); var wafer = WaferManager.Instance.GetWafer(AlignerModulename, 0); int slot = Singleton.Instance.GetSlot(wafer.LaserMarker); if (slot == -1) { wafer.DestinationStation = wafer.OriginStation; wafer.NextStation = wafer.OriginStation; wafer.DestinationSlot = wafer.OriginSlot; wafer.NextStationSlot = wafer.OriginSlot; EV.PostAlarmLog("System", $"Can't find the postion for wafer with ID:{wafer.LaserMarker}."); Singleton.Instance.CheckToPostMsg(RouteManagerSorter.MSG.CancelJob); return true; } wafer.DestinationStation = Singleton.Instance.SortByHostDestPort; wafer.NextStation = Singleton.Instance.SortByHostDestPort; wafer.DestinationSlot = slot-1; wafer.NextStationSlot = slot-1; if (Singleton.Instance.SortByHostSourcePort != Singleton.Instance.SortByHostDestPort && WaferManager.Instance.CheckHasWafer((ModuleName)wafer.NextStation, wafer.NextStationSlot)) { wafer.DestinationStation = wafer.OriginStation; wafer.NextStation = wafer.OriginStation; wafer.DestinationSlot = wafer.OriginSlot; wafer.NextStationSlot = wafer.OriginSlot; EV.PostAlarmLog("System", $"The destination was occuppied for wafer with ID:{wafer.LaserMarker}."); Singleton.Instance.CheckToPostMsg(RouteManagerSorter.MSG.CancelJob); return true; } return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { error(String.Format("Failed to update wafer information to nex station OnSortingByHost.")); } } return ret; } public Tuple RtUpdateWaferNextStationOnSortingBySlot(int id, Action notify, Action error) { Tuple ret = Execute(id, () => { notify("Update wafer to next station sorting by slot."); var wafer = WaferManager.Instance.GetWafer(AlignerModulename, 0); int slot = ParseSlot(wafer.LaserMarker,Singleton.Instance.SortByHostSlotIndex); if (slot == -1) { wafer.DestinationStation = wafer.OriginStation; wafer.NextStation = wafer.OriginStation; wafer.DestinationSlot = wafer.OriginSlot; wafer.NextStationSlot = wafer.OriginSlot; Singleton.Instance.CheckToPostMsg(RouteManagerSorter.MSG.CancelJob); EV.PostAlarmLog("System", $"Can't find the postion for wafer with ID:{wafer.LaserMarker}."); return true; } wafer.DestinationStation = Singleton.Instance.SortByHostDestPort; wafer.NextStation = Singleton.Instance.SortByHostDestPort; wafer.DestinationSlot = slot - 1; wafer.NextStationSlot = slot - 1; if (Singleton.Instance.SortByHostSourcePort != Singleton.Instance.SortByHostDestPort && WaferManager.Instance.CheckHasWafer((ModuleName)wafer.NextStation,wafer.NextStationSlot)) { wafer.DestinationStation = wafer.OriginStation; wafer.NextStation = wafer.OriginStation; wafer.DestinationSlot = wafer.OriginSlot; wafer.NextStationSlot = wafer.OriginSlot; Singleton.Instance.CheckToPostMsg(RouteManagerSorter.MSG.CancelJob); EV.PostAlarmLog("System", $"The destination was occuppied for wafer with ID:{wafer.LaserMarker}."); return true; } return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { error(String.Format("Failed to update wafer information to next station OnSortingBySlot.")); } } return ret; } private int ParseSlot(string waferID,int index) { if (waferID.Length < index + 1) return -1; string strSlot = waferID.Substring(index - 1, 2); int ret; if(int.TryParse(strSlot,out ret)) { if (ret <= 0) return - 1; if (ret > 25) return -1; return ret; } return -1; } public void RtAlignWaferForRetry(int id,int timeNo, double notch,OCRReaderBaseDevice reader, Action notify) { var ret = Execute(id, () => { var reason = string.Empty; if (reader.ReadOK) { notify($"Skip the re-alignment for read ocr base on the result OK"); return true; } notify($"start to re-align the wafer to read ocr for the {timeNo}st time"); Aligner.Align(notch, out reason); return true; }); } private void RtReadWaferIDForRetry(int id,int timeNo, ModuleName name, int ocrindex, int waferIDindex, string job, Action notify) { var ret = Execute(id, () => { var reason = string.Empty; if(Aligner.OCRs[ocrindex].ReadOK) { notify($"Skip re-read laser mark with reader:{ocrindex} for the NO.{waferIDindex + 1} ID."); return true; } notify($"Start re-read laser mark with reader:{ocrindex} for the NO.{waferIDindex + 1} ID for the {timeNo}st time"); if (!Aligner.OCRs[ocrindex].ReadWaferID(job, waferIDindex)) { var wafer = WaferManager.Instance.GetWafers(name)[0]; var destlp = DEVICE.GetDevice(((ModuleName)wafer.DestinationStation).ToString()); string destcarrierID = destlp == null ? "" : destlp.CarrierId; var dvid = new SerializableDictionary() { {DVIDName.LOT_ID, wafer.LotId}, {DVIDName.WAFER_ID, wafer.WaferID}, {DVIDName.SOURCE_CAR_ID, wafer.OriginCarrierID}, {DVIDName.CarrierID,wafer.OriginCarrierID}, {DVIDName.SOURCE_SLOT, (wafer.OriginSlot +1)}, {DVIDName.ARRIVE_POS_NAME, Aligner.RobotModuleName.ToString()}, {DVIDName.LASERMARK, Aligner.OCRs[ocrindex].CurrentLaserMark}, {DVIDName.LM_READER_NO,ocrindex+1}, {DVIDName.OCR_SCORE, waferIDindex == 0? Aligner.OCRs[ocrindex].LaserMark1Score: Aligner.OCRs[ocrindex].LaserMark2Score}, {DVIDName.LM_NO, waferIDindex+1}, {"DestCarrier",destcarrierID}, {"DestSlot",wafer.DestinationSlot+1}, { "SourcePort",wafer.OriginStation}, { "DestPort",wafer.DestinationStation}, }; EV.Notify(EventWaferIdReadFail, dvid); EV.PostAlarmLog(Aligner.RobotModuleName.ToString(), $"Wafer:{wafer.WaferID} failed to read laser mark."); EV.Notify(AlarmID.ReadWaferLaserMarkFailed); } return true; }); } public void RtPreAlignWafer(int id,string msg, double notch, Action notify) { var ret = Execute(id, () => { notify($"{msg} to {notch}."); var reason = string.Empty; Aligner.PreAlign(notch, out reason); return true; }); } public void RtPostAlignWafer(int id, string msg, double notch, Action notify) { var ret = Execute(id, () => { notify($"{msg} to {notch}."); var reason = string.Empty; Aligner.PostAlign(notch, out reason); return true; }); } public void RtUpdateWaferNextStationOnDispatchByID(int id, Action notify, Action error) { var ret= Execute(id, () => { var wafer = WaferManager.Instance.GetWafer(AlignerModulename, 0); notify($"Update wafer:{wafer.WaferID} to next station on dispatch by ID."); int station, slotindex; if (Singleton.Instance.IdentifyStationAndSlot(wafer.LaserMarker, out station, out slotindex)) { wafer.DestinationStation = station; wafer.NextStation = station; wafer.DestinationSlot = slotindex; wafer.NextStationSlot = slotindex; EV.PostInfoLog("System", $"Wafer:{wafer.WaferID} with laser mark:{wafer.LaserMarker} from carrier:{wafer.OriginCarrierID} " + $"is identify to dispatch to station:{(ModuleName)station} slot:{slotindex + 1}."); } else { wafer.NextStation = wafer.DestinationStation; wafer.NextStationSlot = wafer.DestinationSlot; EV.PostInfoLog("System", $"Wafer:{wafer.WaferID} with laser mark:{wafer.LaserMarker} from carrier:{wafer.OriginCarrierID} " + $"can't be identify will be return."); } return true; }); } private void RtReadWaferID(int id, ModuleName name, int ocrindex, int waferIDindex, string job, Action notify) { var ret = Execute(id, () => { notify($"Start read laser mark with reader:{ocrindex} for the NO.{waferIDindex + 1} ID."); var reason = string.Empty; if (!Aligner.OCRs[ocrindex].ReadWaferID(job, waferIDindex)) { var wafer = WaferManager.Instance.GetWafers(name)[0]; var destlp = DEVICE.GetDevice(((ModuleName)wafer.DestinationStation).ToString()); string destcarrierID = destlp == null ? "" : destlp.CarrierId; var dvid = new SerializableDictionary() { {DVIDName.LOT_ID, wafer.LotId}, {DVIDName.WAFER_ID, wafer.WaferID}, {DVIDName.CarrierID,wafer.OriginCarrierID}, {DVIDName.SOURCE_CAR_ID, wafer.OriginCarrierID}, {DVIDName.SOURCE_SLOT, (wafer.OriginSlot +1)}, {DVIDName.ARRIVE_POS_NAME, Aligner.RobotModuleName.ToString()}, {DVIDName.LASERMARK, Aligner.OCRs[ocrindex].CurrentLaserMark}, {DVIDName.LM_READER_NO,ocrindex+1}, {DVIDName.OCR_SCORE, waferIDindex == 0? Aligner.OCRs[ocrindex].LaserMark1Score: Aligner.OCRs[ocrindex].LaserMark2Score}, {DVIDName.LM_NO, waferIDindex+1}, {"DestCarrier",destcarrierID}, {"DestSlot",wafer.DestinationSlot+1}, { "SourcePort",wafer.OriginStation}, { "DestPort",wafer.DestinationStation}, }; EV.Notify(EventWaferIdReadFail, dvid); EV.PostAlarmLog(Aligner.RobotModuleName.ToString(), $"Wafer:{wafer.WaferID} failed to read laser mark."); EV.Notify(AlarmID.ReadWaferLaserMarkFailed); } return true; }); } public void RtSendReadResult(int id, ModuleName name, int ocrindex, int waferIDindex, string job, Action notify) { var ret = Execute(id, () => { notify($"{name} start to send read result."); var wafer = WaferManager.Instance.GetWafers(name)[0]; if (waferIDindex == 0) { WaferManager.Instance.UpdateWaferLaserWithScoreAndFileName(name, 0, Aligner.OCRs[ocrindex].LaserMark1, Aligner.OCRs[ocrindex].LaserMark1Score, job, ""); WaferManager.Instance.UpdateWaferHistory(AlignerModulename, 0, SubstAccessType.UpdateLM1); } if (waferIDindex == 1) { WaferManager.Instance.UpdateWaferT7CodeWithScoreAndFileName(name, 0, Aligner.OCRs[ocrindex].LaserMark2, Aligner.OCRs[ocrindex].LaserMark2Score, job, ""); WaferManager.Instance.UpdateWaferHistory(AlignerModulename, 0, SubstAccessType.UpdateLM1); } var destlp = DEVICE.GetDevice(((ModuleName)wafer.DestinationStation).ToString()); string destcarrierID = destlp == null ? "" : destlp.CarrierId; var dvid2 = new SerializableDictionary() { {DVIDName.LOT_ID, wafer.LotId}, {DVIDName.WAFER_ID, wafer.WaferID}, {DVIDName.CarrierID,wafer.OriginCarrierID}, {DVIDName.SOURCE_CAR_ID, wafer.OriginCarrierID}, {DVIDName.SOURCE_SLOT, (wafer.OriginSlot +1)}, {DVIDName.ARRIVE_POS_NAME, Aligner.RobotModuleName.ToString()}, {DVIDName.LASERMARK, Aligner.OCRs[ocrindex].CurrentLaserMark}, {DVIDName.LM_READER_NO,ocrindex+1}, {DVIDName.OCR_SCORE, waferIDindex == 0? Aligner.OCRs[ocrindex].LaserMark1Score: Aligner.OCRs[ocrindex].LaserMark2Score}, {DVIDName.LM_NO, waferIDindex+1}, {"DestCarrier",destcarrierID}, {"DestSlot",wafer.DestinationSlot+1}, { "SourcePort",wafer.OriginStation}, { "DestPort",wafer.DestinationStation}, }; EV.PostInfoLog(Aligner.RobotModuleName.ToString(), $"Wafer:{wafer.WaferID} succeed to read laser mark:" + $"{Aligner.OCRs[ocrindex].CurrentLaserMark ?? ""} with score:{Aligner.OCRs[ocrindex].CurrentLaserMarkScore.ToString() ?? ""} in time:" + $"{Aligner.OCRs[ocrindex].CurrentLaserMarkReadTime ?? ""}."); EV.Notify(EventWaferIdRead, dvid2); if (!Aligner.OCRs[ocrindex].ReadOK || Aligner.OCRs[ocrindex].CurrentLaserMark.Contains("*")) { var dvid3 = new SerializableDictionary() { { "AlarmDescription", $"Read lasermark on wafer:{wafer.WaferID} failed:{Aligner.OCRs[ocrindex].CurrentLaserMark}" } }; EV.Notify(AlarmID.ReadWaferLaserMarkFailed, dvid3); EV.Notify(EventWaferIdReadFail, dvid2); } return true; }); } private void RtSetRetryLaserMarkFlag(int id, int lasermarkIndex, int ocrindex,Action notify) { var ret = Execute(id, () => { notify($"Start set laser mark reader{ocrindex} retry flag to {Aligner.OCRs[ocrindex].ReadOK}"); if(lasermarkIndex ==0) IsNeedRetryLaserMark1 = !Aligner.OCRs[ocrindex].ReadOK; else IsNeedRetryLaserMark2 = !Aligner.OCRs[ocrindex].ReadOK; return true; }); } private void RtWaitReaderReady(int id, int time, int ocrindex, Action notify, Action error) { var ret = ExecuteAndWait(id, () => { notify($"Wait reader index:{ocrindex} to be ready."); var reason = string.Empty; return true; }, () => { if (Aligner.OCRs[ocrindex].IsReady()) { return Result.DONE; } if(Aligner.OCRs[ocrindex].DeviceState == OCRReaderStateEnum.Error) { return Result.FAIL; } return Result.RUN; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { } else if (ret.Item2 == Result.TIMEOUT) //timeout { EV.PostAlarmLog(Aligner.RobotModuleName.ToString(), $"Wait reader index:{ocrindex} to be ready timeout."); var wafer = WaferManager.Instance.GetWafer(Aligner.RobotModuleName,0); var destlp = DEVICE.GetDevice(((ModuleName)wafer.DestinationStation).ToString()); string destcarrierID = destlp == null ? "" : destlp.CarrierId; var dvid = new SerializableDictionary() { {DVIDName.LOT_ID, wafer.LotId}, {DVIDName.WAFER_ID, wafer.WaferID}, {DVIDName.CarrierID,wafer.OriginCarrierID}, {DVIDName.SOURCE_CAR_ID, wafer.OriginCarrierID}, {DVIDName.SOURCE_SLOT, (wafer.OriginSlot +1)}, {DVIDName.ARRIVE_POS_NAME, Aligner.RobotModuleName.ToString()}, {DVIDName.LASERMARK, Aligner.OCRs[ocrindex].CurrentLaserMark}, {DVIDName.LM_READER_NO,ocrindex+1}, {DVIDName.OCR_SCORE, ocrindex == 0? Aligner.OCRs[ocrindex].LaserMark1Score: Aligner.OCRs[ocrindex].LaserMark2Score}, {DVIDName.LM_NO, ocrindex+1}, {"DestCarrier",destcarrierID}, {"DestSlot",wafer.DestinationSlot+1}, { "SourcePort",wafer.OriginStation}, { "DestPort",wafer.DestinationStation}, }; EV.Notify(EventWaferIdReadFail, dvid); EV.Notify(AlarmID.ReadWaferLaserMarkFailed); } else { } } } public void RtSaveOcrPicture(int id, int ocrindex, Action notify) { var ret = Execute(id, () => { notify($"Start to save image for the ocr reader index:{ocrindex}."); return Aligner.OCRs[ocrindex].SavePicture(); }); } private void RtVerifyWaferIDWithHostDefine(int id, ModuleName name, int ocrindex, int waferIDindex, Action notify, Action error) { var ret = Execute(id, () => { var aligner = DEVICE.GetDevice(name.ToString()); var wafer = WaferManager.Instance.GetWafer(name, 0); string lasermark = aligner.OCRs[ocrindex].CurrentLaserMark; string hostdefineMark = wafer.HostLaserMark1; if (waferIDindex == 1) hostdefineMark = wafer.HostLaserMark2; notify($"Start verifying waferID:{wafer.WaferID},lasermark:{lasermark} with host define:{hostdefineMark}."); var reason = string.Empty; WaferManager.Instance.UpdateWaferLMVerifyResult(Aligner.RobotModuleName, 0, true); if ((waferIDindex == 0 && lasermark != wafer.HostLaserMark1) || (waferIDindex == 1 && lasermark != wafer.HostLaserMark2)) { WaferManager.Instance.UpdateWaferLMVerifyResult(Aligner.RobotModuleName, 0, false); EV.Notify(Aligner.AlarmVerifyLaserMarkFailed); notify($"Verify waferID:{wafer.WaferID},lasermark:{lasermark} failed with host define:{hostdefineMark}," + $"action is:{Singleton.Instance.MisMatchHandler}"); if (Singleton.Instance.MisMatchHandler == VerifyFailHandlerEnum.Stop) //Stop return false; if (Singleton.Instance.MisMatchHandler == VerifyFailHandlerEnum.Continue) //Continue return true;// throw new RoutineBreakException(); ; if (Singleton.Instance.MisMatchHandler == VerifyFailHandlerEnum.ReturnCurrentWafer || Singleton.Instance.MisMatchHandler == VerifyFailHandlerEnum.ReturnAllWafer || Singleton.Instance.MisMatchHandler == VerifyFailHandlerEnum.ReturnAllWaferExcpetComplete) { if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.DispatchingToPort) Singleton.Instance.ReleaseLastSlotOnDispatch((ModuleName)wafer.DestinationStation); else Singleton.Instance.ReleaseToBePresentModuleSlot((ModuleName)wafer.DestinationStation, wafer.DestinationSlot); wafer.DestinationStation = wafer.OriginStation; wafer.DestinationSlot = wafer.OriginSlot; wafer.NextStation = wafer.OriginStation; wafer.NextStationSlot = wafer.OriginSlot; } if (Singleton.Instance.MisMatchHandler == VerifyFailHandlerEnum.Transfer) { if (Singleton.Instance.MisMatchCollectPort == ModuleName.System) { EV.PostAlarmLog("System", $"The mismatch collection port setting is wrong."); return false; } if (Singleton.Instance.CurrentSorterRTStateEnum == SorterRTStateEnum.DispatchingToPort) { Singleton.Instance.ReleaseLastSlotOnDispatch((ModuleName)wafer.DestinationStation); wafer.DestinationStation = (int)Singleton.Instance.MisMatchCollectPort; wafer.DestinationSlot = -1; wafer.NextStation = (int)Singleton.Instance.MisMatchCollectPort; wafer.NextStationSlot = -1; } else { Singleton.Instance.ReleaseToBePresentModuleSlot((ModuleName)wafer.DestinationStation, wafer.DestinationSlot); wafer.DestinationStation = (int)Singleton.Instance.MisMatchCollectPort; int collectSlot; if (!Singleton.Instance.BidCollectionSlot(out collectSlot)) return false; wafer.DestinationSlot = collectSlot; wafer.NextStation = (int)Singleton.Instance.MisMatchCollectPort; wafer.NextStationSlot = collectSlot; } } Singleton.Instance.AutoAbortCurrentPJ(); Thread.Sleep(2000); } return true; }); } private void RtVerifyWaferIDAndWaitManualInput(int id, ModuleName name, int time, int ocrindex, int waferIDindex, Action notify, Action error) { var ret = ExecuteAndWait(id, () => { notify("Start verifying waferID"); var reason = string.Empty; _trigAlarmVerifyLMLengthFail.RST = true; _trigAlarmReadInvalidSlotFail.RST = true; _trigAlarmVerifyLMLengthFail.RST = true; _trigAlarmVerifyWithHostDefineFail.RST = true; _trigAlarmVerifyChecksumFail.RST = true; if (!VerifyWaferIDWithAlarm(name, ocrindex, waferIDindex)) { EV.Notify(Aligner.AlarmVerifyLaserMarkFailed); Singleton.Instance.IsVerifyLaserMarkAlarm = true; if (_trigAlarmDestinationOccuppiedFail.Q) EV.Notify(Aligner.AlarmSlotInLaserMarkIsOccuppied); if (_trigAlarmReadInvalidSlotFail.Q) EV.Notify(Aligner.AlarmVerifyLaserMarkSlotNoFailed); if (_trigAlarmVerifyLMLengthFail.Q) EV.Notify(Aligner.AlarmVerifyLaserMarkLengthFailed); if (_trigAlarmVerifyChecksumFail.Q) EV.Notify(Aligner.AlarmVerifyLaserMarkChecksumFailed); } return true; }, () => { if (!VerifyWaferIDWithAlarm(name, ocrindex, waferIDindex)) { Singleton.Instance.IsVerifyLaserMarkAlarm = true; if (_trigAlarmDestinationOccuppiedFail.Q) EV.Notify(Aligner.AlarmSlotInLaserMarkIsOccuppied); if (_trigAlarmReadInvalidSlotFail.Q) EV.Notify(Aligner.AlarmVerifyLaserMarkSlotNoFailed); if (_trigAlarmVerifyLMLengthFail.Q) EV.Notify(Aligner.AlarmVerifyLaserMarkLengthFailed); if (_trigAlarmVerifyChecksumFail.Q) EV.Notify(Aligner.AlarmVerifyLaserMarkChecksumFailed); WaferManager.Instance.UpdateWaferLMVerifyResult(Aligner.RobotModuleName, 0, false); return Result.RUN; } WaferManager.Instance.UpdateWaferLMVerifyResult(Aligner.RobotModuleName, 0, true); Singleton.Instance.IsVerifyLaserMarkAlarm = false; _trigAlarmVerifyLMLengthFail.RST = true; _trigAlarmReadInvalidSlotFail.RST = true; _trigAlarmVerifyLMLengthFail.RST = true; _trigAlarmVerifyWithHostDefineFail.RST = true; _trigAlarmVerifyChecksumFail.RST = true; return Result.DONE; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { } else if (ret.Item2 == Result.TIMEOUT) //timeout { EV.Notify(Aligner.AlarmVerifyLaserMarkTimeout); error($"verify WaferID timeout after {time} seconds"); } else { } } } private string _previousLasermark; private bool VerifyWaferIDWithAlarm(ModuleName alignername,int ocrindex, int waferIDindex) { var aligner = DEVICE.GetDevice(alignername.ToString()); var wafer = WaferManager.Instance.GetWafer(alignername, 0); string lasermark = aligner.OCRs[ocrindex].CurrentLaserMark; if(_previousLasermark != lasermark) { _previousLasermark = lasermark; _trigAlarmVerifyLMLengthFail.RST = true; _trigAlarmReadInvalidSlotFail.RST = true; _trigAlarmVerifyLMLengthFail.RST = true; _trigAlarmVerifyWithHostDefineFail.RST = true; _trigAlarmVerifyChecksumFail.RST = true; } int slot; if ((_aligneRecipe.IsVerifyLaserMarkLength && lasermark.Length != AlignerRecipe.LaserMarkLength)||lasermark.Contains("*")) { _trigAlarmVerifyLMLengthFail.CLK = true; return false; } if(_aligneRecipe.IsVerifyLaserMarkSlotForNCD) { if (lasermark.Length < _aligneRecipe.SlotStartPositionForNCD +1) { _trigAlarmVerifyLMLengthFail.CLK = true; return false; } if(!int.TryParse(lasermark.Substring(_aligneRecipe.SlotStartPositionForNCD-1,2),out slot)) { _trigAlarmReadInvalidSlotFail.CLK = true; return false; } if(slot<1 || slot >25) { _trigAlarmReadInvalidSlotFail.CLK = true; return false; } } if (_aligneRecipe.IsVerifyChecksumLaserMarker1) { if(!VerifyCheckCharater(lasermark)) { _trigAlarmVerifyChecksumFail.CLK = true; return false; } } //if (_aligneRecipe.IsVerifyWithHostDefine) //{ // if (waferIDindex == 0 && lasermark != wafer.HostLaserMark1) // { // _trigAlarmVerifyWithHostDefineFail.CLK = true; // return false; // } // if (waferIDindex == 1 && lasermark != wafer.HostLaserMark2) // { // _trigAlarmVerifyWithHostDefineFail.CLK = true; // return false; // } //} if (wafer.DestinationSlot == 99) { if (_aligneRecipe.SlotStartPositionForNCD < 1) _aligneRecipe.SlotStartPositionForNCD = 1; if (!int.TryParse(lasermark.Substring(_aligneRecipe.SlotStartPositionForNCD - 1, 2), out slot)) { _trigAlarmReadInvalidSlotFail.CLK = true; return false; } //if (slot < 1 || slot > 25) //{ // _trigAlarmReadInvalidSlotFail.CLK = true; // return false; //} if (WaferManager.Instance.CheckHasWafer((ModuleName)wafer.DestinationStation, slot - 1)) { if (wafer.OriginStation != wafer.DestinationStation) { _trigAlarmDestinationOccuppiedFail.CLK = true; return false; } } var lp = DEVICE.GetDevice($"{(ModuleName)wafer.DestinationStation}"); if ((slot - 1) < lp.ValidStartSlotIndex || (slot - 1) > lp.ValidEndSlotIndex) { _trigAlarmReadInvalidSlotFail.CLK = true; return false; } wafer.DestinationSlot = slot - 1; } if (wafer.DestinationSlot == 100) { if (_aligneRecipe.SlotStartPositionForNCD < 1) _aligneRecipe.SlotStartPositionForNCD = 1; if (!int.TryParse(lasermark.Substring(_aligneRecipe.SlotStartPositionForNCD - 1, 2), out slot)) { _trigAlarmReadInvalidSlotFail.CLK = true; return false; } var lp = DEVICE.GetDevice($"{(ModuleName)wafer.DestinationStation}"); int destslot = lp.ValidEndSlotIndex - slot + 1; if (destslot < lp.ValidStartSlotIndex || destslot > lp.ValidEndSlotIndex) { _trigAlarmReadInvalidSlotFail.CLK = true; return false; } if (WaferManager.Instance.CheckHasWafer((ModuleName)wafer.DestinationStation, destslot)) { if (wafer.OriginStation != wafer.DestinationStation) { _trigAlarmDestinationOccuppiedFail.CLK = true; return false; } } wafer.DestinationSlot = destslot; } return true; } private R_TRIG _trigAlarmVerifyLMLengthFail = new R_TRIG(); private R_TRIG _trigAlarmReadInvalidSlotFail = new R_TRIG(); private R_TRIG _trigAlarmVerifyChecksumFail = new R_TRIG(); private R_TRIG _trigAlarmDestinationOccuppiedFail = new R_TRIG(); private R_TRIG _trigAlarmVerifyWithHostDefineFail = new R_TRIG(); private bool VerifyCheckCharater(string lasermark) { UInt64 checksum = 0; for(int i=0;i Convert.ToInt32('H') || Convert.ToInt32(lasermark[lasermark.Length - 2]) < Convert.ToInt32('A')) return false; if (Convert.ToInt32(lasermark[lasermark.Length - 1]) > Convert.ToInt32('7') || Convert.ToInt32(lasermark[lasermark.Length - 1]) < Convert.ToInt32('0')) return false; return checksum % 59 == 0; } } }