public bool Initialize(EFEM Lpm) { string Comport = ""; int nBaud = 0; switch (Lpm) { case EFEM.LPMA: Comport = _Main.ConfigMgr.Port1.Comport; nBaud = _Main.ConfigMgr.Port1.Baudrate; break; case EFEM.LPMB: Comport = _Main.ConfigMgr.Port2.Comport; nBaud = _Main.ConfigMgr.Port2.Baudrate; break; case EFEM.LPMC: Comport = _Main.ConfigMgr.Port3.Comport; nBaud = _Main.ConfigMgr.Port3.Baudrate; break; case EFEM.LPMD: Comport = _Main.ConfigMgr.Port4.Comport; nBaud = _Main.ConfigMgr.Port4.Baudrate; break; } _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Open(Comport, nBaud); Thread.Sleep(300); return(_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().IsOpen()); }
public int GetNextWaferSlot(EFEM Lpm, LPMStatus status, int nMaxCnt) { int nRet = -1; for (int i = 0; i < nMaxCnt; i++) { if (status == LPMStatus.Load) { //LPM Load시 Mapping Data if (GetWaferInfo(Lpm, i, ScanMode.Exist)) { nRet = i; break;//현재 Index를 넘기자 } } else { //Unload if (GetUnloadSlot(Lpm, i) == false) //Slot이 비었을 경우 { nRet = i; break; } } } return(nRet); }
public bool IsHomeCheck(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_HOME_COMP] == 1) { return(true); } else { return(false); } }
public bool IsAlarmCheck(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_ALARM_OCCURED] == 1) { return(true); } else { return(false); } }
public bool IsVacuum(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_VACCUM_STATUS] == 1) { return(true); } else { return(false); } }
public bool IsActing(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_ACTING] == 1) { return(true); } else { return(false); } }
public bool IsDoorClose(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_DOOR_CLOSE] == 1 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_DOOR_OPEN] == 0) { return(true); } else { return(false); } }
public bool IsPoupUnDock(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_FOUP_UNDOCKED] == 1 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_FOUP_DOCKED] == 0) { return(true); } else { return(false); } }
public bool IsLatchUnlock(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_LATCH_UNLOCKED] == 1 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_LATCH_LOCKED] == 0) { return(true); } else { return(false); } }
public bool IsArmRetract(EFEM Lpm) { if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_FINGER_ARM_RETRACTED] == 1 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_FINGER_ARM_EXTENDED] == 0) { return(true); } else { return(false); } }
public LPM_Wafer GetLPMWaferStauts(EFEM Lpm, int nIndex) { if (GetUnloadSlot(Lpm, nIndex)) { return(LPM_Wafer.Unload); } else if (GetWaferInfo(Lpm, nIndex, ScanMode.Exist)) { return(LPM_Wafer.Exist); } else { return(LPM_Wafer.Empty); } }
public bool CheckUnload(EFEM Lpm) { #if !_REAL_MC return(true); #endif if (_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_RESERVED] == 0 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_DOOR_OPEN] == 0 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.StatusData[(int)STATUS_DATA.STS_DOOR_CLOSE] == 1 && _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().WorkStatus == WORK_STATUS.IDLE) { return(true); } else { return(false); } }
public bool SetMode(EFEM Lpm, Mode mode, bool bOn) { switch (mode) { case Mode.ModeAuto: _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_AutoMode(bOn); break; case Mode.ModeMaint: _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_MAINT_MODE(bOn); break; case Mode.ModeMapping: _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_MappingMode(bOn); break; } return(true); }
public fn CheckUnload_LPM(EFEM lpm) { if (LpmRoot.CheckUnload(lpm)) { return(fn.success); } else { if (LpmRoot.IsAlarmCheck(lpm)) { return(fn.err); } else { return(fn.busy); } } }
public bool GetWaferInfo(EFEM Lpm, int nIndex, ScanMode Scan) { bool bCheck = false; switch (Scan) { case ScanMode.Exist: bCheck = _Main.GetLoaderData().GetPortData((int)Lpm).WaferData[nIndex].WaferUse; break; case ScanMode.Cross: bCheck = _Main.GetLoaderData().GetPortData((int)Lpm).WaferData[nIndex].WaferCross; break; case ScanMode.Double: bCheck = _Main.GetLoaderData().GetPortData((int)Lpm).WaferData[nIndex].WaferDouble; break; default: break; } return(bCheck); }
public bool CheckWaferSlot(EFEM Lpm, int nMaxCnt, ref int nSlot) { //웨이퍼 스캔 시 Cross, Double 상태인 웨이퍼가 있는지 확인 //있다면 에러 처리 해야 함 bool bCheck = false; for (int i = 0; i < nMaxCnt; i++) { bCheck = GetWaferInfo(Lpm, i, ScanMode.Cross); //Cross Data if (bCheck) { nSlot = i; break; //검색 된 Slot Index } bCheck = GetWaferInfo(Lpm, i, ScanMode.Double); //Double Data if (bCheck) { nSlot = i; break; } } return(bCheck); }
public void Run() { if (!isAcceptRun()) { return; } if (nSeqNo != nPreSeqNo) { resetCmd(); } nPreSeqNo = nSeqNo; CaseFM seqCase = (CaseFM)nSeqNo; //test int nRetV = 0; alwaysCheck(); switch (seqCase) { case CaseFM.Initialze: break; case CaseFM.Check_Interlock: //임시 테스트, 웨이퍼 2장만 진행하기 위함 //if (nWaferCount >= 2) return; //strLog = seqCase.ToString(); //AddMessage(strLog); break; case CaseFM.Start_LPM_Load: if (bLPM_Load[(int)EFEM.LPMA] && bLPM_Load[(int)EFEM.LPMC]) { //이미 LPM 로드 상태면 진행하지 않는다 nextSeq((int)CaseFM.Check_Status); return; } break; case CaseFM.Move_LPM_Load: if (bLPM_Load[(int)EFEM.LPMA] == false) { //로드 전 Flag 초기화 LpmRoot.InitMappingFlag(EFEM.LPMA); LoadLPM(EFEM.LPMA); } if (bLPM_Load[(int)EFEM.LPMC] == false) { LpmRoot.InitMappingFlag(EFEM.LPMC); LoadLPM(EFEM.LPMC); } Thread.Sleep(500); //Load Delay break; case CaseFM.Compl_LPM_Load: if (CheckLoad_LPM(EFEM.LPMA) != fn.success) { return; } break; case CaseFM.End_LPM_Load: if (CheckLoad_LPM(EFEM.LPMC) != fn.success) { return; } break; case CaseFM.LPM_Mapping_Data: //로드 시 Scan한 Map Data 연결 break; case CaseFM.Check_Status_Load_A: //Status를 체크 할 경우 LPM Alarm이 발생함, //테스트 시 제거 후 진행 함 //LpmRoot.GetStatus(EFEM.LPMA); break; case CaseFM.Compl_Status_Load_A: //if (CheckLoad_LPM(EFEM.LPMA) != fn.success) return; break; case CaseFM.End_Status_Load_A: #if _REAL_MC //LPM Load 후 Mapping Flag가 변경되면 완료 if (LpmRoot.GetMappingComplete(EFEM.LPMA) == false) { return; } if (LpmRoot.GetMappingComplete(EFEM.LPMC) == false) { return; } #endif bLPM_Load[(int)EFEM.LPMA] = true; bLPM_Load[(int)EFEM.LPMC] = true; break; case CaseFM.Check_Status: RUN_MODE RunMode = RecipeMgr.Inst.TempRcp.eRunMode; //현재 레시피 if (RunMode == RUN_MODE.FULL || RunMode == RUN_MODE.ONLY_BOND) { //FULL Mode if (nWaferCount % 2 == 0) { Working_LPM = EFEM.LPMA; efemType = EFEM_TYPE.A_CARRIER; } else { Working_LPM = EFEM.LPMC; efemType = EFEM_TYPE.C_DEVICE; } } else if (RunMode == RUN_MODE.ONLY_LAMI) { //Only Lami 일경우 Carrier 고정 사용 Working_LPM = EFEM.LPMA; efemType = EFEM_TYPE.A_CARRIER; } else { return; } //Next Wafer Slot 유/무 확인 GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM] = LpmRoot.GetNextWaferSlot(Working_LPM, LPMStatus.Load, COUNT.MAX_PORT_SLOT); if (GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM] < 0) { //Wafer Empty //더이상 투입할 웨이퍼가 없을경우 언로딩 시퀀스로 보낸다 nextSeq((int)CaseFM.Check_Unload_Wafer); return; } break; case CaseFM.Start_FM_Pickup_LPM: //FM 로봇 상태 확인 //FM 로봇 웨이퍼 상태 확인 //웨이퍼 택타임 측정 시작 시간 if (Working_LPM == EFEM.LPMA) { GlobalVariable.seqShared.carrierArray1[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff"); } else if (Working_LPM == EFEM.LPMB) { GlobalVariable.seqShared.carrierArray2[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff"); } else if (Working_LPM == EFEM.LPMC) { GlobalVariable.seqShared.deviceArray1[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff"); } else if (Working_LPM == EFEM.LPMD) { GlobalVariable.seqShared.deviceArray2[GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM]].strTotalSt = DateTime.Now.ToString("hh:mm:ss.fff"); } break; case CaseFM.Move_FM_Pickup_LPM: fmStatus = FMStatus.LPM_LOAD; Working_Stage = (FMStage)Working_LPM + 1; //현재 LPM을 작업 할 Stage로 변경 nWorking_Slot = GlobalVariable.WaferInfo.nWaferLoadSlot[(int)Working_LPM] + 1; //현재 작업할 Wafer Slot Working_Arm = ARM.UPPER; MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus); strLog = string.Format("FmRobot Pickup Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.Compl_FM_Pickup_LPM: if (CheckCompl_FM() != fn.success) { return; } //nRetV = CheckCompl_FM(); //f(nRetV == err ) strLog = string.Format("FmRobot Pickup Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.End_FM_Pickup_LPM: GlobalSeq.autoRun.prcFM.LpmRoot.SetWaferInfo(Working_LPM, nWorking_Slot - 1, false); //웨이퍼 맵핑 데이터 갱신 GlobalVariable.seqShared.LoadingEfemToFm(efemType, nWorking_Slot - 1, (HAND)Working_Arm); nWaferCount++; break; case CaseFM.Waiting_AL: if (GlobalVariable.seqShared.IsInAligner() || GlobalVariable.interlock.bAlignMoving == true) { //Alinger에 Wafer가 아직 있으면 대기 하도록 하자 return; } break; case CaseFM.Start_FM_Place_AL: break; case CaseFM.Move_FM_Place_AL: fmStatus = FMStatus.BUFFER_LOAD; Working_Stage = FMStage.AL; nWorking_Slot = 1; Working_Arm = ARM.UPPER; MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus); strLog = string.Format("FmRobot Place Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.Compl_FM_Place_AL: if (CheckCompl_FM() != fn.success) { return; } strLog = string.Format("FmRobot Place Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.End_FM_Place_AL: GlobalVariable.seqShared.LoadingFmToAligner((HAND)Working_Arm); GlobalVariable.interlock.bAlignMoving = true; //얼라인 동작 break; case CaseFM.Check_Unload_Wafer: //CP에 언로드 할 웨이퍼가 있는지 확인 if (GlobalVariable.seqShared.IsInCP(0) == false) { nextSeq((int)CaseFM.Initialze); return; } break; ////////////////////////////////////// //Wafer Unload ///////////////////////////////////// case CaseFM.Start_FM_Pickup_CP: //CP 웨이퍼 감지 센서 확인 필요! break; case CaseFM.Move_FM_Pickup_CP: fmStatus = FMStatus.BUFFER_UNLOAD; Working_Stage = FMStage.CP1; nWorking_Slot = 1; Working_Arm = ARM.LOWER; //CP에서 언로딩 시에는 LOW ARM 사용하자 MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus); strLog = string.Format("FmRobot Pickup Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.Compl_FM_Pickup_CP: if (CheckCompl_FM() != fn.success) { return; } strLog = string.Format("FmRobot Pickup Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.End_FM_Pickup_cp: GlobalVariable.seqShared.LoadingCpToFm(0, (HAND)Working_Arm); break; case CaseFM.Start_FM_Place_LPM: //완료 웨이퍼 언로딩 시 LPM A부터 채워넣자 Working_LPM = EFEM.LPMA; //LPM 상태를 확인하자 if (CheckLoad_LPM(Working_LPM) != fn.success) { //로드 상태가 아니면 에러 return; } //Unload Slot Check //Next Wafer Slot 유/무 확인 GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM] = LpmRoot.GetNextWaferSlot(Working_LPM, LPMStatus.Unload, COUNT.MAX_PORT_SLOT); if (GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM] < 0) { //Wafer Empty return; } break; case CaseFM.Move_FM_Place_LPM: fmStatus = FMStatus.LPM_UNLOAD; Working_Stage = (FMStage)Working_LPM + 1; nWorking_Slot = GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM] + 1; //현재 작업할 Wafer Slot Working_Arm = ARM.LOWER; //CP에서 언로딩 시에는 LOW ARM 사용하자 MoveFmRobot(Working_Stage, nWorking_Slot, Working_Arm, fmStatus); strLog = string.Format("FmRobot Place Move Start -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.Compl_FM_Place_LPM: if (CheckCompl_FM() != fn.success) { return; } strLog = string.Format("FmRobot Place Move End -> {0}, {1}, {2}", Working_Stage.ToString(), nWorking_Slot, Working_Arm.ToString()); AddMessage(strLog); break; case CaseFM.End_FM_Place_LPM: GlobalVariable.seqShared.LoadingFmToEfem(EFEM_TYPE.A_CARRIER, nWorking_Slot - 1, (HAND)Working_Arm); //Wafer Unload 후 Data 변경 GlobalSeq.autoRun.prcFM.LpmRoot.SetUnloadSlot(Working_LPM, nWorking_Slot - 1, true); if (Working_LPM == EFEM.LPMA) { GlobalVariable.seqShared.carrierArray1[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff"); } else if (Working_LPM == EFEM.LPMB) { GlobalVariable.seqShared.carrierArray2[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff"); } else if (Working_LPM == EFEM.LPMC) { GlobalVariable.seqShared.deviceArray1[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff"); } else if (Working_LPM == EFEM.LPMD) { GlobalVariable.seqShared.deviceArray2[GlobalVariable.WaferInfo.nWaferUnloadSlot[(int)Working_LPM]].strTotalEnd = DateTime.Now.ToString("hh:mm:ss.fff"); } nextSeq((int)CaseFM.Initialze); return; /////////////////////////////////// //LPM Unload ////////////////////////////////// case CaseFM.Start_LPM_Unload: break; case CaseFM.Move_LPM_Unload: UnloadLPM(Working_LPM); break; case CaseFM.Check_Status_Unload: LpmRoot.GetStatus(Working_LPM); break; case CaseFM.Compl_LPM_Unload: if (CheckUnload_LPM(Working_LPM) != fn.success) { return; } break; case CaseFM.End_LPM_Unload: //처음 case로 nextSeq((int)CaseFM.Initialze); return; } nSeqNo++; }
public bool SetReset(EFEM Lpm) { _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_Reset(); return(true); }
public bool MoveHome(EFEM Lpm) { _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_Home(); return(true); }
public void InitMappingFlag(EFEM Lpm) { _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.bRecvMapping = false; }
public bool GetMappingComplete(EFEM Lpm) { return(_Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().LPM_Data.bRecvMapping); }
public void SetWaferInfo(EFEM Lpm, int nIndex, bool bSet) { //테스트용 함수 _Main.GetLoaderData().GetPortData((int)Lpm).WaferData[nIndex].WaferUse = bSet; }
public void LoadLPM(EFEM Lpm) { LpmRoot.MoveLoad(Lpm); }
public bool GetStatus(EFEM Lpm) { _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_Status(); return(true); }
public void SetUnloadSlot(EFEM Lpm, int nSlot, bool bSet) { GlobalVariable.WaferInfo.bWaferUnloadExist[(int)Lpm, nSlot] = bSet; }
public bool GetErrorCode(EFEM Lpm) { _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_ReadErrorCode(); return(true); }
public void UnloadLPM(EFEM lpm) { LpmRoot.MoveUnload(lpm); }
public bool GetUnloadSlot(EFEM Lpm, int nSlot) { return(GlobalVariable.WaferInfo.bWaferUnloadExist[(int)Lpm, nSlot]); }
public fn FmRobot_Place_LPM() { if (!isAcceptRun()) { return(fn.busy); } nPreSeqNo = nSeqNo; FMStage stage = GlobalVariable.manualInfo.mnlStageFM; //매뉴얼에서 선택한 Stage 연결 int nSlot = GlobalVariable.manualInfo.nSelectSource; FmRobot_Arm = (CJ_Controls.Communication.CybogRobot_HTR.ARM)GlobalVariable.manualInfo.SelArmFM; EFEM Lpm = EFEM.LPMA; FMStatus fmStatus = FMStatus.LPM_UNLOAD; //LPM 구분 switch (stage) { case FMStage.LPMA: Lpm = EFEM.LPMA; break; case FMStage.LPMB: Lpm = EFEM.LPMB; break; case FMStage.LPMC: Lpm = EFEM.LPMC; break; case FMStage.LPMD: Lpm = EFEM.LPMD; break; default: //LPM Index Error return(fn.err); } switch (nSeqNo) { case 0: break; case 10: if (GlobalSeq.autoRun.prcFM.CheckUnload_LPM(Lpm) != fn.success) { return(fn.busy); } break; case 15: //Door Open Check break; case 20: GlobalSeq.autoRun.prcFM.MoveFmRobot(stage, nSlot, FmRobot_Arm, fmStatus); break; case 30: if (GlobalSeq.autoRun.prcFM.CheckCompl_FM() != fn.success) { return(fn.busy); } break; case 35: GlobalSeq.autoRun.prcFM.MoveFmRobot(stage, nSlot, FmRobot_Arm, fmStatus, true); break; case 40: if (GlobalSeq.autoRun.prcFM.CheckCompl_FM() != fn.success) { return(fn.busy); } break; case 50: nSeqNo = 0; return(fn.success); } //wrong seq check if (nSeqNo > 10000) { //error occur return(fn.err); } nSeqNo++; return(fn.busy); }
public bool MoveScanUpDown(EFEM Lpm, bool bUpDown) { _Main.GetLoaderData().GetPortData((int)Lpm).GetNano300().Cmd_Send_ScanUp(bUpDown); return(true); }