Exemple #1
0
 public WaferData(EFEM_TYPE efType, WaferType wType, int nSlot)
 {
     this.efemType  = efType;
     this.waferType = wType;
     this.nSlot     = nSlot;
     Init();
 }
Exemple #2
0
        /// <summary>
        /// EFEM의 슬롯에 Wafer가 있는지
        /// </summary>
        /// <param name="efType"></param>
        /// <param name="nSlot"></param>
        /// <returns></returns>
        public bool IsInSlotEFEM(EFEM_TYPE efType, int nSlot)
        {
            WaferData[] wData = GetEfemData(efType);
            if (wData[nSlot] == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #3
0
        private int TimeCoolingEnd;     // 쿨링 끝

        public WaferData()
        {
            efemType     = EFEM_TYPE.A_CARRIER;
            waferType    = WaferType.CARRIER;
            nSlot        = 0;
            bIsPreAlign  = false;
            bIsPostAlign = false;
            bIsLami      = false;
            bIsBond      = false;
            bIsHP        = false;
        }
Exemple #4
0
        /// <summary>
        /// EFEM에서 FM Robot으로 이동
        /// </summary>
        /// <param name="nSlot"></param>
        public bool LoadingEfemToFm(EFEM_TYPE efType, int nSlot, HAND arm)
        {
            WaferData[] wData = GetEfemData(efType);
            if (wData[nSlot] == null || robotFM[(int)arm] != null)
            {
                return(false);
            }

            robotFM[(int)arm] = wData[nSlot];
            wData[nSlot]      = null;

            Save();

            return(true);
        }
Exemple #5
0
        /// <summary>
        /// FM에서 EFEM으로 이동
        /// </summary>
        /// <param name="efType"></param>
        /// <param name="nSlot"></param>
        /// <returns></returns>
        public bool LoadingFmToEfem(EFEM_TYPE efType, int nSlot, HAND arm)
        {
            WaferData[] wData = GetEfemData(efType);
            if (robotFM[(int)arm] == null || wData[nSlot] != null)
            {
                return(false);
            }

            wData[nSlot]      = robotFM[(int)arm];
            robotFM[(int)arm] = null;

            Save();

            return(true);
        }
Exemple #6
0
        WaferData[] GetEfemData(EFEM_TYPE efType)
        {
            switch (efType)
            {
            case EFEM_TYPE.A_CARRIER:
                return(carrierArray1);

            case EFEM_TYPE.B_CARRIER:
                return(carrierArray2);

            case EFEM_TYPE.C_DEVICE:
                return(deviceArray1);

            case EFEM_TYPE.D_DEVICE:
                return(deviceArray2);

            default:
                System.Diagnostics.Debug.Fail("EFEM_TYPE이 이상함");
                break;
            }

            return(null);
        }
Exemple #7
0
        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++;
        }