using SA_LTT.Info.AttenuatorCalInfo;
|
using SA_LTT.Info.RecipeInfo;
|
using SA_LTT.Info.WaferInfo;
|
using SA_LTT.Module;
|
using System;
|
using System.Collections.Generic;
|
using System.IO;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace SA_LTT
|
{
|
public delegate void RecipeExcuteEvent(Recipe recipe);
|
public delegate void ProcessInfoExcuteEvent(ProcessInfo _processInfo, int processInfoIndex);
|
|
public class Sequence
|
{
|
/*
|
Port Get
|
Pre Aligner Flip Put
|
Align
|
Pre Align Get
|
Chamber Put
|
|
Melting
|
|
Chamber Get
|
Pre Aligner Flip Put
|
Align
|
Pre Aligner Flip Get
|
Port Put
|
*/
|
|
public enum TmcSteps
|
{
|
Wait,
|
|
StatusCheck,
|
|
LoadPortMapping,
|
CheckMappingData,
|
|
ProcessDataCheck,
|
|
GetLoadPort,
|
CheckGetLoadPort,
|
|
BeforePutPreAlignerFlip,
|
CheckBeforePutPreAlignerFlip,
|
BeforeGetWaitPreAligner, //GetWait 명령 날려 놓고 Align 진행. (TactTime 감소)
|
BeforeAlign,
|
BeforeAlignWait,
|
BeforeGetPreAligner,
|
CheckBeforeGetPreAligner,
|
AlignHomeStart,
|
|
ChamberStatusCheck,
|
PutChamber,
|
CheckPutChamber,
|
|
MeltingWait, // 가공 완료 대기.
|
|
GetChamber,
|
CheckGetChamber,
|
|
AlignHomeCheck,
|
AfterPutPreAlignerFlip,
|
CheckAfterPutPreAlignerFlip,
|
AfterGetWaitPreAligner, //GetWait 명령 날려 놓고 Align 진행. (TactTime 감소)
|
AfterAlign,
|
AfterAlignWait,
|
AfterGetPreAligner,
|
CheckAfterGetPreAligner,
|
|
PutLoadPort,
|
CheckPutLoadPort,
|
|
End,
|
}
|
|
public enum PmcSteps
|
{
|
Wait,
|
|
//Wafer 받기 대기
|
StatusCheck,
|
BeforeMoveLoadPosition,
|
CheckBeforeLoadPosition,
|
BeforeGateOpen,
|
BeforePinUp,
|
WaferPutWait,
|
|
//Wafer 받은 후 이동
|
BeforeVacuumOn,
|
BeforePinDown,
|
BeforeGateClose,
|
|
Melting,
|
|
// Manual 가공 ->
|
MoveCenterPosition,
|
CheckCenterPosition,
|
GetRecipeData,
|
|
// =============================
|
|
//===Wafer Align 진행
|
MoveAlignPosition,
|
CheckAlignPosition,
|
VisionReady,
|
VisionReadyCheck,
|
WaferDetectionReady,
|
WaferDetectionReadyCheck,
|
WaferDetection,
|
WaferDetectionCheck,
|
MoveOffsetPosition,
|
CheckOffsetPositon,
|
|
//====================
|
|
//===전체 가공 영역 다 종료 될때 까지 반복 구간===
|
GetProcessInfoData, //레시피에 있는 가공 좌표 가져오기
|
CoordTransform, //가공 좌표를 Scanner, Stage에 맞게 변환 하는 작업.
|
|
// Todo. Power 측정 기능 넣기.=== Attenuator Set 대신
|
CalDataAttenuatorSet, // 추후 명칭 변경
|
CalDataCheckAttenuator, // 추후 명칭 변경
|
MovePowerMeterPosition,
|
CheckPowerMeterPosition,
|
PowerMeterInitialize,
|
PowerMeterInitializeCheck,
|
LaserOn,
|
MeasurementStart,
|
Measurement,
|
MeasurementEnd,
|
MeasurrmentDataCheck,
|
AttenuatorSet,
|
CheckAttenuator,
|
// ============================
|
|
MoveProcessStartPosition,
|
CheckProcessStartPosition,
|
|
ProcessStart,
|
ProcessRunning,
|
ProcessEnd,
|
//========================================
|
|
//가공 종료
|
AfterMoveLoadPosition,
|
CheckAfterLoadPosition,
|
AfterGateOpen,
|
AfterVacuumOff,
|
AfterPinUp,
|
WaferEmptyWait,
|
PinDown,
|
GateClose,
|
End,
|
|
//Energy drop check
|
EnergyDropCheckStart,
|
EdcPowerMeterInitialize,
|
EdcPowerMeterInitializeCheck,
|
EdcMoveCenterPosition,
|
EdcCheckCenterPosition,
|
EdcMovePowerMeterPosition,
|
EdcCheckPowerMeterPosition,
|
EdcAttenuatorSet,
|
EdcCheckAttenuator,
|
EdcLaserOn,
|
EdcMeasurementStart,
|
EdcMeasurement,
|
EdcMeasurementLaserOff,
|
EdcMeasurementLaserOffCheck,
|
EdcMeasurementEnd,
|
EdcMeasurementDataCheck,
|
EdcLaserOff,
|
EdcLaserOffCheck,
|
EnergyDropCheckEnd,
|
|
//Attenuator Cal
|
AttenuatorCalStart,
|
AcPowerMeterInitialize,
|
AcPowerMeterInitializeCheck,
|
AcMoveCenterPosition,
|
AcCheckCenterPosition,
|
AcMovePowerMeterPosition,
|
AcCheckPowerMeterPosition,
|
AcAttenuatorSet,
|
AcCheckAttenuator,
|
AcCoolingTimeWait,
|
AcLaserOn,
|
AcMeasurementStart,
|
AcMeasurement,
|
AcMeasurementLaserOff,
|
AcMeasurementLaserOffCheck,
|
AcMeasurementEnd,
|
AcMeasurementDataCheck,
|
AcLaserOff,
|
AcLaserOffCheck,
|
AttenuatorCalEnd,
|
}
|
|
private Equipment _equipment;
|
|
private SequenceTimer _processTimer = new SequenceTimer();
|
private SequenceTimer _pmcSequenceTimer = new SequenceTimer();
|
private SequenceTimer _tmcSequenceTimer = new SequenceTimer();
|
private SequenceTimer _measurementTimer = new SequenceTimer();
|
|
private PmcSteps _pmcStep = PmcSteps.Wait;
|
private PmcSteps _pmcStepOld = PmcSteps.Wait;
|
|
private TmcSteps _tmcStep = TmcSteps.Wait;
|
private TmcSteps _tmcStepOld = TmcSteps.Wait;
|
|
private List<TmcSteps> _pauseDisableTmcSteps;
|
private List<PmcSteps> _pauseDisablePmcSteps;
|
|
private Recipe _currentRecipe;
|
private ProcessInfo _oldProcessInfo;
|
private ProcessInfo _processInfo;
|
private int _processNum;
|
|
private double _centerPositionX;
|
private double _centerPositionY;
|
private double _centerPositionT;
|
|
private double _alignOffsetX;
|
private double _alignOffsetY;
|
private double _alignOffsetT;
|
|
private double _processStartPositionX; // 가공 시작 X 축 위치
|
private double _processStartPositionY; // 가공 시작 Y 축 위치
|
private double _processEndPositionX; // 가공 종료 X축 위치
|
private double _stageVelocity; // Stage 가공 속도
|
|
private float _currentAttenuatorCalAngle;
|
|
private Info.FoupInfo.Foup currentFoup;
|
|
private float _setAttenuatorAngle;
|
private int _processNumber;
|
private bool _processStartBit;
|
private bool _processEndBit;
|
private bool _chamberWaferEmptyBit;
|
private int _measurementCount;
|
private int _waferProcessCountAfterMeasurement;
|
private DateTime _lastMeasurementTime = DateTime.Now;
|
|
private List<AttenuatorCalData> _attenuatorCalData = new List<AttenuatorCalData>();
|
public PmcSteps PmcStep
|
{
|
get
|
{
|
return _pmcStep;
|
}
|
|
private set
|
{
|
_pmcStep = value;
|
}
|
}
|
|
public TmcSteps TmcStep
|
{
|
get
|
{
|
return _tmcStep;
|
}
|
|
private set
|
{
|
_tmcStep = value;
|
}
|
}
|
|
//가공 시간 TactTime
|
public double ProcessTactTimeSeconds
|
{
|
get
|
{
|
return _processTimer.Seconds;
|
}
|
}
|
|
public bool IsTmcStepPauseEnable
|
{
|
get
|
{
|
return _pauseDisableTmcSteps.Contains(TmcStep) == false;
|
}
|
}
|
|
public bool IsPmcStepPauseEnable
|
{
|
get
|
{
|
return _pauseDisablePmcSteps.Contains(PmcStep) == false;
|
}
|
}
|
|
// Recipe 등록, 이벤트 하나만 등록해서 사용할 것. begin invoke 사용.
|
public event RecipeExcuteEvent RecipeExcuted;
|
|
// Recipe의 ProcessInfo 등록, 이벤트 하나만 등록해서 사용할 것. begin invoke 사용.
|
public event ProcessInfoExcuteEvent ProcessInfoExcuted;
|
|
public Sequence(Equipment equipment)
|
{
|
_equipment = equipment;
|
_pauseDisableTmcSteps = new List<TmcSteps>();
|
_pauseDisablePmcSteps = new List<PmcSteps>();
|
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckMappingData);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckGetLoadPort);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckBeforePutPreAlignerFlip);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckBeforeGetPreAligner);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckPutChamber);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckAfterPutPreAlignerFlip);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckAfterGetPreAligner);
|
_pauseDisableTmcSteps.Add(TmcSteps.CheckPutLoadPort);
|
_pauseDisableTmcSteps.Add(TmcSteps.End);
|
|
_pauseDisablePmcSteps.Add(PmcSteps.CheckBeforeLoadPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.CheckCenterPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.CheckAttenuator);
|
_pauseDisablePmcSteps.Add(PmcSteps.Measurement);
|
_pauseDisablePmcSteps.Add(PmcSteps.MeasurementEnd);
|
_pauseDisablePmcSteps.Add(PmcSteps.CheckProcessStartPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.ProcessRunning);
|
_pauseDisablePmcSteps.Add(PmcSteps.ProcessEnd);
|
_pauseDisablePmcSteps.Add(PmcSteps.CheckAfterLoadPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.AfterPinUp);
|
_pauseDisablePmcSteps.Add(PmcSteps.End);
|
|
//Energy drop check
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcCheckCenterPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcCheckPowerMeterPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcCheckAttenuator);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcMeasurement);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcMeasurementEnd);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcMeasurementLaserOff);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcMeasurementLaserOffCheck);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcLaserOff);
|
_pauseDisablePmcSteps.Add(PmcSteps.EdcLaserOffCheck);
|
_pauseDisablePmcSteps.Add(PmcSteps.EnergyDropCheckEnd);
|
|
//AttenuatorCal
|
_pauseDisablePmcSteps.Add(PmcSteps.AcCheckCenterPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.AcCheckPowerMeterPosition);
|
_pauseDisablePmcSteps.Add(PmcSteps.AcCheckAttenuator);
|
_pauseDisablePmcSteps.Add(PmcSteps.AcMeasurement);
|
_pauseDisablePmcSteps.Add(PmcSteps.AcMeasurementEnd);
|
_pauseDisablePmcSteps.Add(PmcSteps.AcLaserOff);
|
_pauseDisablePmcSteps.Add(PmcSteps.AcLaserOffCheck);
|
_pauseDisablePmcSteps.Add(PmcSteps.AttenuatorCalEnd);
|
}
|
|
public void TmcSequence()
|
{
|
if (TmcStep != _tmcStepOld)
|
{
|
EquipmentLogManager.Instance.WriteTmcSequenceLog(TmcStep.ToString());
|
_tmcStepOld = TmcStep;
|
_tmcSequenceTimer.ReStart();
|
}
|
|
switch (TmcStep)
|
{
|
case TmcSteps.Wait:
|
{
|
break;
|
}
|
case TmcSteps.StatusCheck:
|
{
|
if (_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_1] || _equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_2])
|
{
|
if (_equipment.port1Foup.status == Info.FoupInfo.FoupStatus.Ready || _equipment.port1Foup.status == Info.FoupInfo.FoupStatus.Ready)
|
{
|
if (_equipment.port1Foup.status == Info.FoupInfo.FoupStatus.Ready)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog("Foup 1 Process start !!");
|
currentFoup = _equipment.port1Foup;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteProcessLog("Foup 2 Process start !!");
|
currentFoup = _equipment.port2Foup;
|
}
|
|
_processNumber = 0;
|
currentFoup.status = Info.FoupInfo.FoupStatus.Process;
|
TmcStep = TmcSteps.LoadPortMapping;
|
}
|
else
|
{
|
TmcStep = TmcSteps.End;
|
}
|
}
|
else
|
{
|
TmcStep = TmcSteps.End;
|
}
|
break;
|
}
|
case TmcSteps.LoadPortMapping:
|
{
|
if (_equipment.robot.MappingSeq(currentFoup.portNumber))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Port {currentFoup.portNumber} mapping");
|
TmcStep = TmcSteps.CheckMappingData;
|
}
|
else
|
{
|
//MappingSeq 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.CheckMappingData:
|
{
|
if (_equipment.robot.IsRunEnable) // Mapping 완료 확인.
|
{
|
if (_equipment.robot.IsMappingError)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Mapping {currentFoup.portNumber} Error Restart.");
|
TmcStep = TmcSteps.LoadPortMapping;
|
}
|
else
|
{
|
TmcStep = TmcSteps.ProcessDataCheck;
|
}
|
}
|
break;
|
}
|
case TmcSteps.ProcessDataCheck:
|
{
|
for (; _processNumber < 25; _processNumber++)
|
{
|
if (currentFoup.foupRecipe.RecipeNames[_processNumber] != null)
|
{
|
if (currentFoup.portNumber == 1)
|
{
|
if (_equipment.waferInfoManager.GetWaferInfo(Info.WaferInfo.WaferInfoManager.WaferNumbers.A1 + _processNumber).IsStatus == Info.WaferInfo.WaferInfo.WaferStatus.Exist)
|
{
|
break;
|
}
|
}
|
else
|
{
|
if (_equipment.waferInfoManager.GetWaferInfo(Info.WaferInfo.WaferInfoManager.WaferNumbers.B1 + _processNumber).IsStatus == Info.WaferInfo.WaferInfo.WaferStatus.Exist)
|
{
|
break;
|
}
|
}
|
}
|
}
|
|
if(_equipment.IsRunStop) // 마지막 웨이퍼 끝난 후 종료.
|
{
|
currentFoup.status = Info.FoupInfo.FoupStatus.Complete;
|
TmcStep = TmcSteps.End;
|
}
|
else
|
{
|
if (_processNumber == 25)
|
{
|
currentFoup.status = Info.FoupInfo.FoupStatus.Complete;
|
TmcStep = TmcSteps.StatusCheck;
|
}
|
else
|
{
|
if(PmcStep == PmcSteps.Wait)
|
{
|
PmcStep = PmcSteps.StatusCheck;
|
}
|
|
TmcStep = TmcSteps.GetLoadPort;
|
}
|
}
|
break;
|
}
|
case TmcSteps.GetLoadPort:
|
{
|
if (currentFoup.portNumber == 1)
|
{
|
if (_equipment.robot.Get(Robot.StageList.Port1, _processNumber + 1))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Get port : {currentFoup.portNumber} lot {_processNumber + 1}");
|
TmcStep = TmcSteps.CheckGetLoadPort;
|
}
|
else
|
{
|
//Get 내부에 alarm 발생 됨.
|
}
|
}
|
else
|
{
|
if (_equipment.robot.Get(Robot.StageList.Port2, _processNumber + 1))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Get port : {currentFoup.portNumber} lot {_processNumber + 1}");
|
TmcStep = TmcSteps.CheckGetLoadPort;
|
}
|
else
|
{
|
//Get 내부에 alarm 발생 됨.
|
}
|
}
|
|
break;
|
}
|
case TmcSteps.CheckGetLoadPort:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist)
|
{
|
TmcStep = TmcSteps.BeforePutPreAlignerFlip;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0074_ROBOT_HAS_NOT_WAFER);
|
TmcStep = TmcSteps.GetLoadPort;
|
}
|
}
|
break;
|
}
|
case TmcSteps.BeforePutPreAlignerFlip:
|
{
|
if (_equipment.robot.Put(Robot.StageList.AlignFlip))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Put align flip");
|
TmcStep = TmcSteps.CheckBeforePutPreAlignerFlip;
|
}
|
else
|
{
|
//Put 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.CheckBeforePutPreAlignerFlip:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist == false)
|
{
|
TmcStep = TmcSteps.BeforeGetWaitPreAligner;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0077_ROBOT_HAS_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.BeforeGetWaitPreAligner:
|
{
|
if (_equipment.robot.GetReady(Robot.StageList.Align))
|
{
|
TmcStep = TmcSteps.BeforeAlign;
|
}
|
else
|
{
|
//Get Ready 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.BeforeAlign:
|
{
|
_equipment.preAligner.Align(180);
|
EquipmentLogManager.Instance.WriteProcessLog($"Pre align start");
|
|
TmcStep = TmcSteps.BeforeAlignWait;
|
break;
|
}
|
case TmcSteps.BeforeAlignWait:
|
{
|
if (_equipment.preAligner.IsRunEnable)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Pre align end");
|
TmcStep = TmcSteps.BeforeGetPreAligner;
|
}
|
break;
|
}
|
case TmcSteps.BeforeGetPreAligner:
|
{
|
if (_equipment.robot.Get(Robot.StageList.Align))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Get align");
|
TmcStep = TmcSteps.CheckBeforeGetPreAligner;
|
}
|
else
|
{
|
//Get 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.CheckBeforeGetPreAligner:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist)
|
{
|
TmcStep = TmcSteps.ChamberStatusCheck;
|
//TmcStep = TmcSteps.AlignHomeStart; //23.05.11 Align 교체 후 테스트
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0074_ROBOT_HAS_NOT_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.AlignHomeStart:
|
{
|
if(_equipment.preAligner.IsRunEnable)
|
{
|
_equipment.preAligner.Home();
|
TmcStep = TmcSteps.ChamberStatusCheck;
|
}
|
break;
|
}
|
case TmcSteps.ChamberStatusCheck:
|
{
|
if (_equipment.chamber.IsGateOpen && _equipment.chamber.IsLiftPinUp && _equipment.chamber.IsLoadPosition)
|
{
|
if(PmcStep == PmcSteps.WaferPutWait)
|
{
|
TmcStep = TmcSteps.PutChamber;
|
}
|
}
|
else
|
{
|
if(_equipment.IsAttenuatorCalTime() == false && _equipment.IsAttenuatorCalRun == false && _equipment.IsEnergyDropCheckTime() == false&& _equipment.IsEnergyDropCheckRun == false)
|
{
|
if (PmcStep == PmcSteps.Wait)
|
{
|
PmcStep = PmcSteps.StatusCheck;
|
}
|
}
|
}
|
break;
|
}
|
case TmcSteps.PutChamber:
|
{
|
if (_equipment.chamber.IsGateOpen && _equipment.chamber.IsLiftPinUp && _equipment.chamber.IsLoadPosition)
|
{
|
if (PmcStep == PmcSteps.WaferPutWait)
|
{
|
if (_equipment.robot.Put(Robot.StageList.Chamber))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Put chamber");
|
TmcStep = TmcSteps.CheckPutChamber;
|
}
|
else
|
{
|
//Put 내부에 alarm 발생 됨.
|
}
|
}
|
}
|
break;
|
}
|
case TmcSteps.CheckPutChamber:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist == false)
|
{
|
_chamberWaferEmptyBit = false;
|
_processStartBit = true;
|
TmcStep = TmcSteps.MeltingWait;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0077_ROBOT_HAS_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.MeltingWait:
|
{
|
if (_processEndBit == true)
|
{
|
if (_equipment.chamber.IsGateOpen && _equipment.chamber.IsLiftPinUp && _equipment.chamber.IsLoadPosition)
|
{
|
if (PmcStep == PmcSteps.WaferEmptyWait)
|
{
|
_processEndBit = false;
|
TmcStep = TmcSteps.GetChamber;
|
}
|
}
|
}
|
break;
|
}
|
case TmcSteps.GetChamber:
|
{
|
if (_equipment.chamber.IsGateOpen && _equipment.chamber.IsLiftPinUp && _equipment.chamber.IsLoadPosition)
|
{
|
if (PmcStep == PmcSteps.WaferEmptyWait)
|
{
|
if (_equipment.robot.Get(Robot.StageList.Chamber))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Get chamber");
|
TmcStep = TmcSteps.CheckGetChamber;
|
}
|
else
|
{
|
//Get 내부에 alarm 발생 됨.
|
}
|
}
|
}
|
break;
|
}
|
case TmcSteps.CheckGetChamber:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist)
|
{
|
_chamberWaferEmptyBit = true;
|
TmcStep = TmcSteps.AlignHomeCheck;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0074_ROBOT_HAS_NOT_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.AlignHomeCheck:
|
{
|
if(_equipment.preAligner.IsRunEnable)
|
{
|
TmcStep = TmcSteps.AfterPutPreAlignerFlip;
|
break;
|
}
|
break;
|
}
|
case TmcSteps.AfterPutPreAlignerFlip:
|
{
|
if (_equipment.robot.Put(Robot.StageList.AlignFlip))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Put align flip");
|
TmcStep = TmcSteps.CheckAfterPutPreAlignerFlip;
|
}
|
else
|
{
|
//Put 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.CheckAfterPutPreAlignerFlip:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist == false)
|
{
|
TmcStep = TmcSteps.AfterGetWaitPreAligner;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0077_ROBOT_HAS_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.AfterGetWaitPreAligner:
|
{
|
if (_equipment.robot.GetReady(Robot.StageList.Align))
|
{
|
TmcStep = TmcSteps.AfterAlign;
|
}
|
else
|
{
|
//Get Ready 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.AfterAlign:
|
{
|
_equipment.preAligner.Align(0);
|
EquipmentLogManager.Instance.WriteProcessLog($"Pre algin start");
|
|
TmcStep = TmcSteps.AfterAlignWait;
|
break;
|
}
|
case TmcSteps.AfterAlignWait:
|
{
|
if (_equipment.preAligner.IsRunEnable)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Pre algin end");
|
TmcStep = TmcSteps.AfterGetPreAligner;
|
}
|
|
break;
|
}
|
case TmcSteps.AfterGetPreAligner:
|
{
|
if (_equipment.robot.Get(Robot.StageList.Align))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Get align");
|
TmcStep = TmcSteps.CheckAfterGetPreAligner;
|
}
|
else
|
{
|
//Get 내부에 alarm 발생 됨.
|
}
|
break;
|
}
|
case TmcSteps.CheckAfterGetPreAligner:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist)
|
{
|
TmcStep = TmcSteps.PutLoadPort;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0074_ROBOT_HAS_NOT_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.PutLoadPort:
|
{
|
if (currentFoup.portNumber == 1)
|
{
|
if (_equipment.robot.Put(Robot.StageList.Port1, _processNumber + 1))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Put port : {currentFoup.portNumber} lot {_processNumber + 1}");
|
TmcStep = TmcSteps.CheckPutLoadPort;
|
}
|
else
|
{
|
//Put 내부에 alarm 발생 됨.
|
}
|
}
|
else
|
{
|
if (_equipment.robot.Put(Robot.StageList.Port2, _processNumber + 1))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Put port : {currentFoup.portNumber} lot {_processNumber + 1}");
|
TmcStep = TmcSteps.CheckPutLoadPort;
|
}
|
else
|
{
|
//Put 내부에 alarm 발생 됨.
|
}
|
}
|
break;
|
}
|
case TmcSteps.CheckPutLoadPort:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_equipment.robot.IsWaferExist == false)
|
{
|
_processNumber++;
|
TmcStep = TmcSteps.ProcessDataCheck;
|
}
|
else
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0077_ROBOT_HAS_WAFER);
|
}
|
}
|
break;
|
}
|
case TmcSteps.End:
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Process end !!");
|
|
if (_equipment.IsAutoRun)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Auto run checked !!");
|
|
if (_equipment.port1Foup.status == Info.FoupInfo.FoupStatus.Complete)
|
{
|
_equipment.port1Foup.status = Info.FoupInfo.FoupStatus.Ready;
|
}
|
|
if (_equipment.port2Foup.status == Info.FoupInfo.FoupStatus.Complete)
|
{
|
_equipment.port2Foup.status = Info.FoupInfo.FoupStatus.Ready;
|
}
|
|
TmcStep = TmcSteps.StatusCheck;
|
}
|
else
|
{
|
TmcStep = TmcSteps.Wait;
|
}
|
|
break;
|
}
|
}
|
}
|
|
public void PmcSequence()
|
{
|
if(PmcStep != _pmcStepOld)
|
{
|
EquipmentLogManager.Instance.WritePmcSequenceLog(PmcStep.ToString());
|
_pmcStepOld = PmcStep;
|
_pmcSequenceTimer.ReStart();
|
}
|
|
switch(PmcStep)
|
{
|
case PmcSteps.Wait:
|
{
|
break;
|
}
|
case PmcSteps.StatusCheck:
|
{
|
_processEndBit = false;
|
PmcStep = PmcSteps.BeforeMoveLoadPosition;
|
break;
|
}
|
case PmcSteps.BeforeMoveLoadPosition:
|
{
|
if(_equipment.chamber.MoveLoadPosition())
|
{
|
PmcStep = PmcSteps.CheckBeforeLoadPosition;
|
}
|
break;
|
}
|
case PmcSteps.CheckBeforeLoadPosition:
|
{
|
if(_equipment.chamber.IsInposition)
|
{
|
if(_equipment.chamber.IsLoadPosition)
|
{
|
PmcStep = PmcSteps.BeforeGateOpen;
|
}
|
else
|
{
|
PmcStep = PmcSteps.BeforeMoveLoadPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.BeforeGateOpen:
|
{
|
if (_equipment.chamber.IsGateOpen)
|
{
|
PmcStep = PmcSteps.BeforePinUp;
|
}
|
else
|
{
|
_equipment.chamber.GateOpen();
|
}
|
|
break;
|
}
|
case PmcSteps.BeforePinUp:
|
{
|
if (_equipment.chamber.IsLiftPinUp)
|
{
|
PmcStep = PmcSteps.WaferPutWait;
|
}
|
else
|
{
|
_equipment.chamber.LiftPinUp();
|
}
|
|
break;
|
}
|
case PmcSteps.WaferPutWait:
|
{
|
if(_processStartBit == true)
|
{
|
if (_equipment.robot.IsRunEnable && _equipment.chamber.WaferInfo.IsStatus == Info.WaferInfo.WaferInfo.WaferStatus.Exist)
|
{
|
_processStartBit = false;
|
PmcStep = PmcSteps.BeforeVacuumOn;
|
}
|
}
|
break;
|
}
|
case PmcSteps.BeforeVacuumOn:
|
{
|
if (_equipment.chamber.IsChuckVacuumOn)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Before vaccum on");
|
PmcStep = PmcSteps.BeforePinDown;
|
}
|
else
|
{
|
_equipment.chamber.ChuckVacuumOn();
|
}
|
break;
|
}
|
case PmcSteps.BeforePinDown:
|
{
|
if (_equipment.chamber.IsLiftPinDown)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Before lift pin down");
|
PmcStep = PmcSteps.BeforeGateClose;
|
}
|
else
|
{
|
_equipment.chamber.LiftPinDown();
|
}
|
break;
|
}
|
case PmcSteps.BeforeGateClose:
|
{
|
if(_equipment.chamber.IsGateClose)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Before gate close");
|
PmcStep = PmcSteps.Melting;
|
}
|
else
|
{
|
_equipment.chamber.GateClose();
|
}
|
break;
|
}
|
case PmcSteps.Melting:
|
{
|
double[] CenterDataX = _equipment.powerPmac.GetAxisTeachData(PmacAxis.X_Axis, EnTeachData.CenterPosX);
|
double[] CenterDataY = _equipment.powerPmac.GetAxisTeachData(PmacAxis.Y_Axis, EnTeachData.CenterPosY);
|
double[] CenterDataT = _equipment.powerPmac.GetAxisTeachData(PmacAxis.X_Axis, EnTeachData.CenterPosT);
|
|
_centerPositionX = CenterDataX[0];
|
_centerPositionY = CenterDataY[0];
|
_centerPositionT = CenterDataT[0];
|
|
PmcStep = PmcSteps.MoveCenterPosition;
|
break;
|
}
|
case PmcSteps.MoveCenterPosition:
|
{
|
if(_equipment.chamber.MoveCenterPosition())
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Move center position");
|
PmcStep = PmcSteps.CheckCenterPosition;
|
}
|
break;
|
}
|
case PmcSteps.CheckCenterPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsCenterPosition)
|
{
|
PmcStep = PmcSteps.GetRecipeData;
|
}
|
else
|
{
|
PmcStep = PmcSteps.MoveCenterPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.GetRecipeData:
|
{
|
string recipeName = _equipment.chamber.WaferInfo.RecipeName;
|
|
if (_equipment.recipeManager.ExistsRecipe(recipeName))
|
{
|
_currentRecipe = _equipment.recipeManager.GetRecipe(recipeName);
|
RecipeExcuted?.BeginInvoke(_currentRecipe, null, null);
|
|
if (_currentRecipe.ProcessInfoList.Count > 0)
|
{
|
_processNum = 0;
|
_processTimer.ReStart();
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Recipe ('{recipeName}') total process count : {_currentRecipe.ProcessInfoList.Count} start ");
|
if (_equipment.modeParameterManager.ModeParameter.AlignUse)
|
{
|
PmcStep = PmcSteps.MoveAlignPosition;
|
}
|
else
|
{
|
PmcStep = PmcSteps.GetProcessInfoData;
|
}
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Recipe ('{recipeName}') process data count is 0");
|
|
if (TmcStep == TmcSteps.Wait)
|
{
|
_equipment.SetMessageBox("Manual 가공이 완료 되었습니다.");
|
PmcStep = PmcSteps.End;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AfterMoveLoadPosition;
|
}
|
}
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Recipe ('{recipeName}') is not exist");
|
|
if (TmcStep == TmcSteps.Wait)
|
{
|
_equipment.SetMessageBox("Manual 가공이 완료 되었습니다.");
|
PmcStep = PmcSteps.End;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AfterMoveLoadPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.MoveAlignPosition:
|
{
|
if (_equipment.chamber.MoveAlignPosition())
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Move align position");
|
PmcStep = PmcSteps.CheckAlignPosition;
|
}
|
break;
|
}
|
case PmcSteps.CheckAlignPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsAlignPosition)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Align start");
|
PmcStep = PmcSteps.VisionReady;
|
}
|
else
|
{
|
PmcStep = PmcSteps.MoveAlignPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.VisionReady:
|
{
|
_alignOffsetX = 0;
|
_alignOffsetY = 0;
|
_alignOffsetT = 0;
|
|
_equipment.visionControl.SendVisionReady("Default");
|
PmcStep = PmcSteps.VisionReadyCheck;
|
break;
|
}
|
case PmcSteps.VisionReadyCheck:
|
{
|
if(_equipment.visionControl.CommnadAcks[VisionToControlCommand.VisionReadyAck] && _equipment.visionControl.CommnadAcks[VisionToControlCommand.InspReadyEnd])
|
{
|
PmcStep = PmcSteps.WaferDetectionReady;
|
}
|
else
|
{
|
if(_pmcSequenceTimer.Seconds > _equipment.settingParameterManager.SettingParameter.VisionTimeOut)
|
{
|
|
}
|
}
|
break;
|
}
|
case PmcSteps.WaferDetectionReady:
|
{
|
_equipment.visionControl.SendWaferDetectionReady();
|
PmcStep = PmcSteps.WaferDetection;
|
break;
|
}
|
case PmcSteps.WaferDetectionReadyCheck:
|
{
|
if (_equipment.visionControl.CommnadAcks[VisionToControlCommand.WaferDetectionReadyAck] && _equipment.visionControl.CommnadAcks[VisionToControlCommand.WaferDetectionReadyEnd])
|
{
|
PmcStep = PmcSteps.WaferDetection;
|
}
|
else
|
{
|
if (_pmcSequenceTimer.Seconds > _equipment.settingParameterManager.SettingParameter.VisionTimeOut)
|
{
|
|
}
|
}
|
break;
|
}
|
case PmcSteps.WaferDetection:
|
{
|
_equipment.visionControl.SendWaferDetectionStart();
|
PmcStep = PmcSteps.WaferDetectionCheck;
|
break;
|
}
|
case PmcSteps.WaferDetectionCheck:
|
{
|
if (_equipment.visionControl.CommnadAcks[VisionToControlCommand.WaferDetectionStartAck] && _equipment.visionControl.CommnadAcks[VisionToControlCommand.WaferDetectionResult])
|
{
|
if(_equipment.visionControl.WaferDetectionResultValue.Result == 0)
|
{
|
_alignOffsetX += _equipment.visionControl.WaferDetectionResultValue.ResultX;
|
_alignOffsetY += _equipment.visionControl.WaferDetectionResultValue.ResultY;
|
_alignOffsetT += _equipment.visionControl.WaferDetectionResultValue.ResultT;
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Align result ->");
|
EquipmentLogManager.Instance.WriteProcessLog($"X: {_equipment.visionControl.WaferDetectionResultValue.ResultX}, Y: {_equipment.visionControl.WaferDetectionResultValue.ResultY}, T: {_equipment.visionControl.WaferDetectionResultValue.ResultT}");
|
PmcStep = PmcSteps.MoveOffsetPosition;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Align complete");
|
PmcStep = PmcSteps.GetProcessInfoData;
|
}
|
}
|
else
|
{
|
if (_pmcSequenceTimer.Seconds > _equipment.settingParameterManager.SettingParameter.VisionTimeOut)
|
{
|
|
}
|
}
|
break;
|
}
|
|
case PmcSteps.MoveOffsetPosition:
|
{
|
double posX = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.AlignX].Position;
|
double posY = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.AlignY].Position;
|
double posT = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.AlignT].Position;
|
|
double speedX = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.AlignX].Speed;
|
double speedY = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.AlignY].Speed;
|
double speedT = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.AlignT].Speed;
|
|
double accX = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.AlignX].Accel;
|
double accY = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.AlignY].Accel;
|
double accT = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.AlignT].Accel;
|
|
_equipment.powerPmac.MoveAbs(PmacAxis.X_Axis, posX + _alignOffsetX, speedX, accX);
|
_equipment.powerPmac.MoveAbs(PmacAxis.Y_Axis, posY + _alignOffsetY, speedY, accY);
|
_equipment.powerPmac.MoveAbs(PmacAxis.T_Axis, posT + _alignOffsetT, speedT, accT);
|
|
PmcStep = PmcSteps.CheckOffsetPositon;
|
break;
|
}
|
case PmcSteps.CheckOffsetPositon:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
double posX = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.AlignX].Position;
|
double posY = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.AlignY].Position;
|
double posT = _equipment.powerPmac.m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.AlignT].Position;
|
|
if (_equipment.powerPmac.InpositionCheck(posX + _alignOffsetX, _equipment.powerPmac.GetAxisActualPos(PmacAxis.X_Axis))
|
&& _equipment.powerPmac.InpositionCheck(posY + _alignOffsetY, _equipment.powerPmac.GetAxisActualPos(PmacAxis.Y_Axis))
|
&& _equipment.powerPmac.InpositionCheck(posT + _alignOffsetT, _equipment.powerPmac.GetAxisActualPos(PmacAxis.T_Axis)))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Offset move.");
|
PmcStep = PmcSteps.WaferDetectionReady;
|
}
|
else
|
{
|
|
}
|
}
|
break;
|
}
|
case PmcSteps.GetProcessInfoData:
|
{
|
if(_processInfo != null)
|
{
|
_oldProcessInfo = _processInfo.Clone();
|
}
|
|
_processInfo = _currentRecipe.ProcessInfoList[_processNum];
|
_processInfo.SetProcessData();
|
|
if (_processInfo.IsProcessEnable)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Process {_processNum + 1} start !!");
|
PmcStep = PmcSteps.CoordTransform;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Process {_processNum + 1} is not enable");
|
PmcStep = PmcSteps.ProcessEnd;
|
}
|
break;
|
}
|
case PmcSteps.CoordTransform:
|
{
|
_equipment.scanner.ClearScanList();
|
|
double middlePosition = (_processInfo.ProcessStartY + _processInfo.ProcessEndY) / 2;
|
|
if(_processNum % 2 == 0) // 짝수 진행방향 ->
|
{
|
foreach (Info.RecipeInfo.Coord coord in _processInfo.ProcessList)
|
{
|
_equipment.scanner.AddScanList(coord.ScanMode, coord.Y - middlePosition, (_processInfo.ProcessStartX - coord.X));
|
}
|
}
|
else // 홀수 진행방향 <-
|
{
|
_processInfo.ProcessList.Reverse();
|
|
for (int i = 0; i < _processInfo.ProcessList.Count; i += 2)
|
{
|
Info.RecipeInfo.Coord coordMark= _processInfo.ProcessList[i];
|
Info.RecipeInfo.Coord coordJump = _processInfo.ProcessList[i + 1];
|
|
_equipment.scanner.AddScanList(coordJump.ScanMode, coordJump.Y - middlePosition, _processInfo.ProcessEndX - coordJump.X); // 짝수
|
_equipment.scanner.AddScanList(coordMark.ScanMode, coordMark.Y - middlePosition, _processInfo.ProcessEndX - coordMark.X); // 짝수
|
}
|
|
}
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Recipe energy is {_processInfo.Energy}");
|
//_equipment.crevis.WriteOutput(Crevis.DigitalOutput.LASER_SHUTTER_OPEN_SOL, true);
|
|
// 측정 energy가 0이면 shutter 닫는거로..?
|
// -> 그냥 Energy 측정 0되면 갠춘할듯.
|
//if(_processInfo.Energy == 0)
|
//{
|
// EquipmentLogManager.Instance.WriteProcessLog($"Measurement energy is 0");
|
// _equipment.crevis.WriteOutput(Crevis.DigitalOutput.LASER_SHUTTER_OPEN_SOL, false);
|
// PmcStep = PmcSteps.MoveProcessStartPosition;
|
// return;
|
//}
|
//else
|
//{
|
// EquipmentLogManager.Instance.WriteProcessLog($"Measurement energy is {_processInfo.Energy}");
|
// _equipment.crevis.WriteOutput(Crevis.DigitalOutput.LASER_SHUTTER_OPEN_SOL, true);
|
//}
|
|
if (_equipment.modeParameterManager.ModeParameter.EnergyMeasurementUse)
|
{
|
// Measurement 진행
|
if (_oldProcessInfo == null || _oldProcessInfo.Energy != _processInfo.Energy)
|
{
|
// 서로 Energy가 다를 때
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy deffrent : energy measure start !");
|
PmcStep = PmcSteps.CalDataAttenuatorSet;
|
}
|
else if ((DateTime.Now - _lastMeasurementTime).TotalSeconds > _equipment.settingParameterManager.SettingParameter.EnergyMeasurementCycle)
|
{
|
// 마지막 Measurement 시간이 setting 값보다 클 때
|
EquipmentLogManager.Instance.WriteProcessLog($"Measure time ({ _equipment.settingParameterManager.SettingParameter.EnergyMeasurementCycle} sec) over : energy measure start !");
|
PmcStep = PmcSteps.CalDataAttenuatorSet;
|
}
|
else if (_waferProcessCountAfterMeasurement > _equipment.settingParameterManager.SettingParameter.EnergyMeasurementWaferCountCycle)
|
{
|
// 마지막 Measurement 한 후 n개의 wafer가 진행 되었을 때
|
EquipmentLogManager.Instance.WriteProcessLog($"Wafer count over({_equipment.settingParameterManager.SettingParameter.EnergyMeasurementWaferCountCycle}) : energy measure start !");
|
PmcStep = PmcSteps.CalDataAttenuatorSet;
|
}
|
else
|
{
|
//Measurement 진행 안함.
|
PmcStep = PmcSteps.MoveProcessStartPosition;
|
}
|
}
|
else
|
{
|
//Measurement 진행 안함.
|
PmcStep = PmcSteps.MoveProcessStartPosition;
|
}
|
|
break;
|
}
|
case PmcSteps.CalDataAttenuatorSet:
|
{
|
_measurementCount = 0;
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy measurement start count : {_measurementCount}");
|
double energy = _processInfo.Energy * (_equipment.settingParameterManager.SettingParameter.BeamWidth * _equipment.settingParameterManager.SettingParameter.BeamHeight / 100);
|
energy = double.Parse($"{energy:F7}");
|
|
_setAttenuatorAngle = _equipment.attenuatorCalInfo.GetAttenuatorAngleForEnergy(energy);
|
|
_equipment.attenuator.MoveAbsolute(_setAttenuatorAngle);
|
|
PmcStep = PmcSteps.CalDataCheckAttenuator;
|
break;
|
}
|
case PmcSteps.CalDataCheckAttenuator:
|
{
|
if (_equipment.attenuator.MotorState == Attenuator.MotorRunState.Stopped)
|
{
|
if (_equipment.attenuator.IsAttenuatorAngleCorrect(_setAttenuatorAngle))
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Attenuator setting {_setAttenuatorAngle} degree");
|
PmcStep = PmcSteps.MovePowerMeterPosition;
|
}
|
else
|
{
|
PmcStep = PmcSteps.CalDataAttenuatorSet;
|
}
|
}
|
break;
|
}
|
case PmcSteps.MovePowerMeterPosition:
|
{
|
if (_equipment.chamber.MovePowerMeterPosition())
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Move power meter position.");
|
PmcStep = PmcSteps.CheckPowerMeterPosition;
|
}
|
break;
|
}
|
case PmcSteps.CheckPowerMeterPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
PmcStep = PmcSteps.PowerMeterInitialize;
|
}
|
else
|
{
|
PmcStep = PmcSteps.MovePowerMeterPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.PowerMeterInitialize:
|
{
|
_equipment.powerMeter.ResetEnergyMeter();
|
_measurementTimer.ReStart();
|
PmcStep = PmcSteps.PowerMeterInitializeCheck;
|
break;
|
}
|
case PmcSteps.PowerMeterInitializeCheck:
|
{
|
if (_equipment.powerMeter.Enable && _equipment.powerMeter.CurrentMeasurementMode == PowerMeter.MeasurementMode.Energy)
|
{
|
PmcStep = PmcSteps.LaserOn;
|
}
|
else
|
{
|
if (_measurementTimer.Seconds > 20)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Measurement 초기화가 되지 않았습니다. energy meter를 확인 해 주세요.");
|
_equipment.SetMessageBox("Measurement 초기화가 되지 않았습니다. energy meter를 확인 해 주세요.");
|
PmcStep = PmcSteps.PowerMeterInitialize;
|
}
|
}
|
break;
|
}
|
case PmcSteps.LaserOn:
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
_equipment.scanner.LaserOn();
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Laser on.");
|
PmcStep = PmcSteps.MeasurementStart;
|
}
|
else
|
{
|
PmcStep = PmcSteps.MovePowerMeterPosition;
|
}
|
break;
|
}
|
case PmcSteps.MeasurementStart:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > _equipment.settingParameterManager.SettingParameter.EnergyMeterHeatingTime)
|
{
|
_equipment.powerMeter.ResetMeasurementsEnergy();
|
_measurementTimer.ReStart();
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy measurement start.");
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Energy measurement start.");
|
PmcStep = PmcSteps.Measurement;
|
}
|
}
|
else if(_pmcSequenceTimer.Seconds > 2)
|
{
|
PmcStep = PmcSteps.LaserOn;
|
}
|
|
break;
|
}
|
case PmcSteps.Measurement:
|
{
|
if (_equipment.settingParameterManager.SettingParameter.EnergyMeasurementTime < _measurementTimer.Seconds || _equipment.chamber.IsPowerMeterPosition == false)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition == false)
|
{
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.MeasurementEnd;
|
}
|
else
|
{
|
if (_equipment.settingParameterManager.SettingParameter.EnergyMeasurementTime < _measurementTimer.Seconds)
|
{
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.MeasurementEnd;
|
}
|
}
|
}
|
break;
|
}
|
case PmcSteps.MeasurementEnd:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > 3)
|
{
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
|
_equipment.scanner.LaserOff();
|
}
|
return;
|
}
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy measurement end.");
|
PmcStep = PmcSteps.MeasurrmentDataCheck;
|
break;
|
}
|
case PmcSteps.MeasurrmentDataCheck:
|
{
|
double energyAverage = _equipment.powerMeter.MeasurementAverageEnergyPerUnitArea;
|
double limitRange = _processInfo.Energy * (_equipment.settingParameterManager.SettingParameter.EnergyMeasurementErrorOccuredRange / 100);
|
double maxLimits = _processInfo.Energy + limitRange;
|
double minLimits = _processInfo.Energy - limitRange;
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Target energy : { _processInfo.Energy}");
|
EquipmentLogManager.Instance.WriteProcessLog($"Everage energy : {energyAverage}");
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy range : {minLimits} ~ {maxLimits}");
|
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Target energy : { _processInfo.Energy}");
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Everage energy : {energyAverage}");
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Energy range : {minLimits} ~ {maxLimits}");
|
|
if (minLimits <= energyAverage && energyAverage <= maxLimits)
|
{
|
_lastMeasurementTime = DateTime.Now;
|
_waferProcessCountAfterMeasurement = 0;
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy measurement success ");
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Energy measurement success ");
|
PmcStep = PmcSteps.MoveProcessStartPosition;
|
}
|
else
|
{
|
if(_measurementCount > _equipment.settingParameterManager.SettingParameter.EnergyMeasurementRetryCount)
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0081_ENERGY_MEASUREMENT_FAIL);
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Energy measurement fail");
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Energy measurement fail");
|
_equipment.SetMessageBox("Power measurement 실패 !");
|
|
if (TmcStep == TmcSteps.Wait)
|
{
|
PmcStep = PmcSteps.End;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AfterMoveLoadPosition;
|
}
|
return;
|
}
|
|
double energyPer1Degree = _equipment.attenuatorCalInfo.GetEnergyPer1Degree();
|
energyPer1Degree *= 100;
|
energyPer1Degree = double.Parse($"{energyPer1Degree / (_equipment.settingParameterManager.SettingParameter.BeamWidth * _equipment.settingParameterManager.SettingParameter.BeamHeight):F4}");
|
|
double settingEnergy = _processInfo.Energy;
|
|
float measurementStepAngle = _equipment.settingParameterManager.SettingParameter.EnergyMeasurmentStepAngle;
|
|
if (energyAverage < minLimits)
|
{
|
if (settingEnergy - energyAverage < energyPer1Degree * measurementStepAngle)
|
{
|
if(energyPer1Degree == 0)
|
{
|
_setAttenuatorAngle += measurementStepAngle / 10;
|
}
|
else
|
{
|
_setAttenuatorAngle += float.Parse($"{(settingEnergy - energyAverage) / energyPer1Degree:F3}");
|
}
|
}
|
else
|
{
|
_setAttenuatorAngle += measurementStepAngle;
|
}
|
}
|
else if(energyAverage > maxLimits)
|
{
|
if (energyAverage - settingEnergy < (energyPer1Degree * measurementStepAngle))
|
{
|
if (energyPer1Degree == 0)
|
{
|
_setAttenuatorAngle -= measurementStepAngle / 10;
|
}
|
else
|
{
|
_setAttenuatorAngle -= float.Parse($"{(energyAverage - settingEnergy) / energyPer1Degree:F3}");
|
}
|
}
|
else
|
{
|
_setAttenuatorAngle -= measurementStepAngle;
|
}
|
}
|
|
_measurementCount++;
|
PmcStep = PmcSteps.AttenuatorSet;
|
}
|
break;
|
}
|
case PmcSteps.AttenuatorSet:
|
{
|
_equipment.attenuator.MoveAbsolute(_setAttenuatorAngle);
|
EquipmentLogManager.Instance.WriteProcessLog($"Attenuator setting {_setAttenuatorAngle} degree");
|
EquipmentLogManager.Instance.WriteEnergyMeasureLog($"Attenuator setting {_setAttenuatorAngle} degree");
|
PmcStep = PmcSteps.CheckAttenuator;
|
break;
|
}
|
case PmcSteps.CheckAttenuator:
|
{
|
if(_equipment.attenuator.MotorState == Attenuator.MotorRunState.Stopped)
|
{
|
if (_equipment.attenuator.IsAttenuatorAngleCorrect(_setAttenuatorAngle))
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
PmcStep = PmcSteps.MeasurementStart;
|
}
|
else
|
{
|
PmcStep = PmcSteps.MovePowerMeterPosition;
|
}
|
}
|
}
|
else
|
{
|
PmcStep = PmcSteps.AttenuatorSet;
|
}
|
}
|
break;
|
}
|
case PmcSteps.MoveProcessStartPosition:
|
{
|
double[] CenterDataY = _equipment.powerPmac.GetAxisTeachData(PmacAxis.Y_Axis, EnTeachData.CenterPosY);
|
double[] CenterDataX = _equipment.powerPmac.GetAxisTeachData(PmacAxis.X_Axis, EnTeachData.CenterPosX);
|
|
double processTime = (_processInfo.ProcessLength / _processInfo.ScannerProcessSpeed); // 차이값
|
|
_processStartPositionY = double.Parse($"{_centerPositionY + _alignOffsetY + (_processInfo.ProcessStartY - (Math.Abs(_processInfo.ProcessStartY - _processInfo.ProcessEndY) / 2)):f4}");
|
|
|
if (_processNum % 2 == 0) // 짝수 진행방향 ->
|
{
|
_processStartPositionX = double.Parse($"{_centerPositionX + _alignOffsetX + (_processInfo.ProcessStartX):f4}");
|
_processEndPositionX = double.Parse($"{_centerPositionX + _alignOffsetX + (_processInfo.ProcessEndX):f4}");
|
_stageVelocity = double.Parse($"{((_processEndPositionX - _processStartPositionX) / processTime):F3}");
|
}
|
else // 홀수 진행방향 <-
|
{
|
_processStartPositionX = double.Parse($"{_centerPositionX + _alignOffsetX + (_processInfo.ProcessEndX):f4}");
|
_processEndPositionX = double.Parse($"{_centerPositionX + _alignOffsetX + (_processInfo.ProcessStartX):f4}");
|
_stageVelocity = double.Parse($"{((_processStartPositionX - _processEndPositionX) / processTime):F3}");
|
}
|
|
bool check = true;
|
check = _equipment.powerPmac.MoveAbs(PmacAxis.Y_Axis, _processStartPositionY, CenterDataY[1], CenterDataY[2]);
|
check = _equipment.powerPmac.MoveAbs(PmacAxis.X_Axis, _processStartPositionX, CenterDataX[1], CenterDataX[2]);
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Move process start position");
|
PmcStep = PmcSteps.CheckProcessStartPosition;
|
break;
|
}
|
case PmcSteps.CheckProcessStartPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
bool isMotorXProcessPosition = _processStartPositionX == _equipment.powerPmac.GetAxisActualPos(PmacAxis.X_Axis);
|
bool isMotorYProcessPosition = _processStartPositionY == _equipment.powerPmac.GetAxisActualPos(PmacAxis.Y_Axis);
|
|
if (isMotorXProcessPosition && isMotorYProcessPosition)
|
{
|
PmcStep = PmcSteps.ProcessStart;
|
}
|
else if (_pmcSequenceTimer.Seconds > 3)
|
{
|
PmcStep = PmcSteps.MoveProcessStartPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.ProcessStart:
|
{
|
//Scanner Setting.
|
if (_equipment.scanner.Initialize())
|
{
|
_equipment.scanner.SetScannerDelay();
|
_equipment.scanner.SetLaserTiming();
|
_equipment.scanner.SetLaserDelays();
|
|
_equipment.scanner.SetJumpMarkSpeed(_processInfo.ScannerProcessSpeed, _processInfo.ScannerProcessSpeed);
|
|
if(_equipment.powerPmac.MoveAbs(PmacAxis.X_Axis, _processEndPositionX, _stageVelocity, _processInfo.AccTime * 100))
|
{
|
_equipment.scanner.ExcuteScanList(true);
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Process ({_processNum + 1}) start");
|
PmcStep = PmcSteps.ProcessRunning;
|
}
|
}
|
break;
|
}
|
case PmcSteps.ProcessRunning:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
double processTime = (_processInfo.ProcessLength / _processInfo.ScannerProcessSpeed); // 차이값
|
|
bool isMotorXProcessPosition = _processEndPositionX == _equipment.powerPmac.GetAxisActualPos(PmacAxis.X_Axis);
|
|
if (isMotorXProcessPosition && _equipment.scanner.IsBusy == false)
|
{
|
PmcStep = PmcSteps.ProcessEnd;
|
}
|
else if (_pmcSequenceTimer.Seconds > processTime + 10)
|
{
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
|
_equipment.scanner.LaserOff();
|
|
EquipmentLogManager.Instance.WriteProcessLog($"가공 Error 가능성 있음.");
|
PmcStep = PmcSteps.ProcessEnd;
|
}
|
}
|
break;
|
}
|
case PmcSteps.ProcessEnd:
|
{
|
ProcessInfoExcuted?.BeginInvoke(_processInfo, _processNum, null, null);
|
|
EquipmentLogManager.Instance.WriteProcessLog($"Process ({_processNum + 1}) end");
|
_processNum++;
|
|
if (_currentRecipe.ProcessInfoList.Count == _processNum)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Recipe ({_currentRecipe.Name}) Process complete !!");
|
_processTimer.Stop();
|
|
WaferInfo waferInfo = _equipment.chamber.WaferInfo.Clone();
|
waferInfo.IsProcessComplete = true;
|
_equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.Chamber, waferInfo);
|
|
if (TmcStep == TmcSteps.Wait)
|
{
|
_equipment.SetMessageBox("Manual 가공이 완료 되었습니다.");
|
PmcStep = PmcSteps.End;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AfterMoveLoadPosition;
|
}
|
}
|
else
|
{
|
PmcStep = PmcSteps.GetProcessInfoData;
|
}
|
|
break;
|
}
|
case PmcSteps.AfterMoveLoadPosition:
|
{
|
if (_equipment.chamber.MoveLoadPosition())
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"Move load position");
|
PmcStep = PmcSteps.CheckAfterLoadPosition;
|
}
|
break;
|
}
|
case PmcSteps.CheckAfterLoadPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsLoadPosition)
|
{
|
PmcStep = PmcSteps.AfterGateOpen;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AfterMoveLoadPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.AfterGateOpen:
|
{
|
if (_equipment.chamber.IsGateOpen)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"After gate open");
|
PmcStep = PmcSteps.AfterVacuumOff;
|
}
|
else
|
{
|
_equipment.chamber.GateOpen();
|
}
|
break;
|
}
|
case PmcSteps.AfterVacuumOff:
|
{
|
if (_equipment.chamber.IsChuckVacuumOn == false)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"After vaccum off");
|
PmcStep = PmcSteps.AfterPinUp;
|
}
|
else
|
{
|
_equipment.chamber.ChuckVacuumOff();
|
}
|
break;
|
}
|
case PmcSteps.AfterPinUp:
|
{
|
if(_pmcSequenceTimer.Seconds > 2) // Vacuum Off 대기 시간.
|
{
|
if (_equipment.chamber.IsLiftPinUp)
|
{
|
_processEndBit = true;
|
EquipmentLogManager.Instance.WriteProcessLog($"After lift pin up");
|
PmcStep = PmcSteps.WaferEmptyWait;
|
}
|
else
|
{
|
_equipment.chamber.LiftPinUp();
|
}
|
}
|
break;
|
}
|
case PmcSteps.WaferEmptyWait:
|
{
|
if (_equipment.robot.IsRunEnable)
|
{
|
if (_chamberWaferEmptyBit && _equipment.chamber.WaferInfo.IsStatus == Info.WaferInfo.WaferInfo.WaferStatus.Empty)
|
{
|
PmcStep = PmcSteps.PinDown;
|
}
|
}
|
break;
|
}
|
case PmcSteps.PinDown:
|
{
|
if (_equipment.chamber.IsLiftPinDown)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"After Lift pin down");
|
PmcStep = PmcSteps.GateClose;
|
}
|
else
|
{
|
_equipment.chamber.LiftPinDown();
|
}
|
break;
|
}
|
case PmcSteps.GateClose:
|
{
|
if (_equipment.chamber.IsGateClose)
|
{
|
EquipmentLogManager.Instance.WriteProcessLog($"After Gate close");
|
PmcStep = PmcSteps.End;
|
}
|
else
|
{
|
_equipment.chamber.GateClose();
|
}
|
break;
|
}
|
case PmcSteps.End:
|
{
|
_processTimer.Stop();
|
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
|
_equipment.scanner.LaserOff();
|
|
_equipment.powerPmac.MoveStop(PmacAxis.X_Axis);
|
|
PmcStep = PmcSteps.Wait;
|
break;
|
}
|
|
// ==================== Energy Drop Check Start =======================
|
case PmcSteps.EnergyDropCheckStart:
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog("Energy drop check start !!");
|
PmcStep = PmcSteps.EdcPowerMeterInitialize;
|
break;
|
}
|
case PmcSteps.EdcPowerMeterInitialize:
|
{
|
_equipment.powerMeter.ResetEnergyMeter();
|
_measurementTimer.ReStart();
|
PmcStep = PmcSteps.EdcPowerMeterInitializeCheck;
|
break;
|
}
|
case PmcSteps.EdcPowerMeterInitializeCheck:
|
{
|
if (_equipment.powerMeter.Enable && _equipment.powerMeter.CurrentMeasurementMode == PowerMeter.MeasurementMode.Energy)
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog("Power meter reset.");
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
PmcStep = PmcSteps.EdcAttenuatorSet;
|
}
|
else
|
{
|
PmcStep = PmcSteps.EdcMoveCenterPosition;
|
}
|
}
|
else
|
{
|
if (_measurementTimer.Seconds > 20)
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog("Measurement 초기화가 되지 않았습니다. energy meter를 확인 해 주세요.");
|
_equipment.SetMessageBox("Measurement 초기화가 되지 않았습니다. energy meter를 확인 해 주세요.");
|
PmcStep = PmcSteps.EdcPowerMeterInitialize;
|
}
|
}
|
break;
|
}
|
case PmcSteps.EdcMoveCenterPosition:
|
{
|
if (_equipment.chamber.MoveCenterPosition())
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog("Move center position.");
|
PmcStep = PmcSteps.EdcCheckCenterPosition;
|
}
|
break;
|
}
|
case PmcSteps.EdcCheckCenterPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsCenterPosition)
|
{
|
PmcStep = PmcSteps.EdcMovePowerMeterPosition;
|
}
|
else
|
{
|
PmcStep = PmcSteps.EdcMoveCenterPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.EdcMovePowerMeterPosition:
|
{
|
if (_equipment.chamber.MovePowerMeterPosition())
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog("Move power meter position.");
|
PmcStep = PmcSteps.EdcCheckPowerMeterPosition;
|
}
|
break;
|
}
|
case PmcSteps.EdcCheckPowerMeterPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
PmcStep = PmcSteps.EdcAttenuatorSet;
|
}
|
else
|
{
|
PmcStep = PmcSteps.EdcMovePowerMeterPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.EdcAttenuatorSet:
|
{
|
_equipment.attenuator.MoveAbsolute(_equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetAngle);
|
PmcStep = PmcSteps.EdcCheckAttenuator;
|
break;
|
}
|
case PmcSteps.EdcCheckAttenuator:
|
{
|
if (_equipment.attenuator.MotorState == Attenuator.MotorRunState.Stopped)
|
{
|
if (_equipment.attenuator.IsAttenuatorAngleCorrect(_equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetAngle))
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Attenuator setting {_equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetAngle} degree");
|
PmcStep = PmcSteps.EdcLaserOn;
|
}
|
else
|
{
|
PmcStep = PmcSteps.EdcAttenuatorSet;
|
}
|
}
|
break;
|
}
|
case PmcSteps.EdcLaserOn:
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Laser on !!");
|
_equipment.scanner.LaserOn();
|
|
PmcStep = PmcSteps.EdcMeasurementStart;
|
}
|
else
|
{
|
PmcStep = PmcSteps.EdcMovePowerMeterPosition;
|
}
|
break;
|
}
|
case PmcSteps.EdcMeasurementStart:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > _equipment.settingParameterManager.SettingParameter.EnergyMeterHeatingTime)
|
{
|
_equipment.powerMeter.ResetMeasurementsEnergy();
|
_measurementTimer.ReStart();
|
PmcStep = PmcSteps.EdcMeasurement;
|
}
|
}
|
else if (_pmcSequenceTimer.Seconds > 2)
|
{
|
PmcStep = PmcSteps.EdcLaserOn;
|
}
|
|
break;
|
}
|
case PmcSteps.EdcMeasurement:
|
{
|
if (_equipment.settingParameterManager.SettingParameter.EnergyDropCheckMeasurementTime < _measurementTimer.Seconds || _equipment.chamber.IsPowerMeterPosition == false)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition == false)
|
{
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.EdcLaserOff;
|
}
|
else
|
{
|
if(_equipment.settingParameterManager.SettingParameter.EnergyDropCheckMeasurementTime < _measurementTimer.Seconds)
|
{
|
PmcStep = PmcSteps.EdcMeasurementLaserOff;
|
}
|
}
|
}
|
break;
|
}
|
|
case PmcSteps.EdcMeasurementLaserOff:
|
{
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.EdcMeasurementLaserOffCheck;
|
break;
|
}
|
case PmcSteps.EdcMeasurementLaserOffCheck:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > 3)
|
{
|
PmcStep = PmcSteps.EdcMeasurementLaserOff;
|
}
|
return;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Laser off !!");
|
PmcStep = PmcSteps.EdcMeasurementEnd;
|
}
|
break;
|
}
|
case PmcSteps.EdcMeasurementEnd:
|
{
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.EdcMeasurementDataCheck;
|
break;
|
}
|
case PmcSteps.EdcMeasurementDataCheck:
|
{
|
double energyAverage = _equipment.powerMeter.MeasurementAverageEnergyPerUnitArea;
|
double limitRange = _equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetEnergy * (_equipment.settingParameterManager.SettingParameter.EnergyDropCheckErrorOccuredRange / 100);
|
double maxLimits = _equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetEnergy + limitRange;
|
double minLimits = _equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetEnergy - limitRange;
|
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Target energy : {_equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetEnergy}");
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Everage energy : {energyAverage}");
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Energy range : {minLimits} ~ {maxLimits}");
|
|
if (minLimits < energyAverage && energyAverage < maxLimits)
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Energy is ok !!");
|
_equipment.equipmentInfo.SetEnergyDropCheckDate();
|
PmcStep = PmcSteps.EdcLaserOff;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Energy drop !!");
|
_equipment.alarmManager.Occur(AlarmCode.AL_1100_ENERGY_DROP_CHECK_WRONG);
|
PmcStep = PmcSteps.EdcLaserOff;
|
}
|
break;
|
}
|
case PmcSteps.EdcLaserOff:
|
{
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.EdcLaserOffCheck;
|
break;
|
}
|
case PmcSteps.EdcLaserOffCheck:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > 3)
|
{
|
PmcStep = PmcSteps.EdcLaserOff;
|
}
|
}
|
else
|
{
|
PmcStep = PmcSteps.EnergyDropCheckEnd;
|
}
|
|
break;
|
}
|
case PmcSteps.EnergyDropCheckEnd:
|
{
|
EquipmentLogManager.Instance.WriteEnergyDropCheckLog($"Energy drop check end !!");
|
PmcStep = PmcSteps.Wait;
|
break;
|
}
|
|
// ==================== Attenuator Cal Start =======================
|
case PmcSteps.AttenuatorCalStart:
|
{
|
_attenuatorCalData.Clear();
|
_currentAttenuatorCalAngle = _equipment.settingParameterManager.SettingParameter.AttenuatorCalStartAngle;
|
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Attenuator cal start !!");
|
PmcStep = PmcSteps.AcPowerMeterInitialize;
|
break;
|
}
|
case PmcSteps.AcPowerMeterInitialize:
|
{
|
_equipment.powerMeter.ResetEnergyMeter();
|
_measurementTimer.ReStart();
|
PmcStep = PmcSteps.AcPowerMeterInitializeCheck;
|
|
break;
|
}
|
case PmcSteps.AcPowerMeterInitializeCheck:
|
{
|
if (_equipment.powerMeter.Enable && _equipment.powerMeter.CurrentMeasurementMode == PowerMeter.MeasurementMode.Energy)
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog("Power meter reset.");
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
PmcStep = PmcSteps.AcAttenuatorSet;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AcMoveCenterPosition;
|
}
|
}
|
}
|
else
|
{
|
if (_measurementTimer.Seconds > 20)
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog("Measurement 초기화가 되지 않았습니다. energy meter를 확인 해 주세요.");
|
_equipment.SetMessageBox("Measurement 초기화가 되지 않았습니다. energy meter를 확인 해 주세요.");
|
PmcStep = PmcSteps.AcPowerMeterInitialize;
|
}
|
}
|
break;
|
}
|
case PmcSteps.AcMoveCenterPosition:
|
{
|
if (_equipment.chamber.MoveCenterPosition())
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog("Move center position.");
|
PmcStep = PmcSteps.AcCheckCenterPosition;
|
}
|
break;
|
}
|
case PmcSteps.AcCheckCenterPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsCenterPosition)
|
{
|
PmcStep = PmcSteps.AcMovePowerMeterPosition;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AcMoveCenterPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.AcMovePowerMeterPosition:
|
{
|
if (_equipment.chamber.MovePowerMeterPosition())
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog("Move power meter position.");
|
PmcStep = PmcSteps.AcCheckPowerMeterPosition;
|
}
|
break;
|
}
|
case PmcSteps.AcCheckPowerMeterPosition:
|
{
|
if (_equipment.chamber.IsInposition)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
PmcStep = PmcSteps.AcAttenuatorSet;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AcMovePowerMeterPosition;
|
}
|
}
|
break;
|
}
|
case PmcSteps.AcAttenuatorSet:
|
{
|
_equipment.attenuator.MoveAbsolute(_currentAttenuatorCalAngle);
|
PmcStep = PmcSteps.AcCheckAttenuator;
|
break;
|
}
|
case PmcSteps.AcCheckAttenuator:
|
{
|
if (_equipment.attenuator.MotorState == Attenuator.MotorRunState.Stopped)
|
{
|
if (_equipment.attenuator.IsAttenuatorAngleCorrect(_currentAttenuatorCalAngle))
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Attenuator setting {_equipment.settingParameterManager.SettingParameter.EnergyDropCheckTargetAngle} degree");
|
PmcStep = PmcSteps.AcCoolingTimeWait;
|
}
|
else
|
{
|
PmcStep = PmcSteps.AcAttenuatorSet;
|
}
|
}
|
break;
|
}
|
case PmcSteps.AcCoolingTimeWait:
|
{
|
if (_measurementTimer.Seconds > _equipment.settingParameterManager.SettingParameter.AttenuatorCalCoolingTime)
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Cooling time wait !");
|
PmcStep = PmcSteps.AcLaserOn;
|
}
|
break;
|
}
|
case PmcSteps.AcLaserOn:
|
{
|
if (_equipment.chamber.IsPowerMeterPosition)
|
{
|
_equipment.scanner.LaserOn();
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Laser on !!");
|
|
PmcStep = PmcSteps.AcMeasurementStart;
|
}
|
break;
|
}
|
case PmcSteps.AcMeasurementStart:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > _equipment.settingParameterManager.SettingParameter.EnergyMeterHeatingTime)
|
{
|
_equipment.powerMeter.ResetMeasurementsEnergy();
|
_measurementTimer.ReStart();
|
PmcStep = PmcSteps.AcMeasurement;
|
}
|
}
|
else if (_pmcSequenceTimer.Seconds > 2)
|
{
|
PmcStep = PmcSteps.AcLaserOn;
|
}
|
break;
|
}
|
case PmcSteps.AcMeasurement:
|
{
|
if (_equipment.settingParameterManager.SettingParameter.AttenuatorCalMeasurementTime < _measurementTimer.Seconds || _equipment.chamber.IsPowerMeterPosition == false)
|
{
|
if (_equipment.chamber.IsPowerMeterPosition == false)
|
{
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.AcLaserOff;
|
}
|
else
|
{
|
if(_equipment.settingParameterManager.SettingParameter.AttenuatorCalMeasurementTime < _measurementTimer.Seconds)
|
{
|
PmcStep = PmcSteps.AcMeasurementLaserOff;
|
}
|
}
|
}
|
break;
|
}
|
case PmcSteps.AcMeasurementLaserOff:
|
{
|
_measurementTimer.ReStart();
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.AcMeasurementLaserOffCheck;
|
break;
|
}
|
case PmcSteps.AcMeasurementLaserOffCheck:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > 3)
|
{
|
PmcStep = PmcSteps.AcMeasurementLaserOff;
|
}
|
return;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Laser off !!");
|
PmcStep = PmcSteps.AcMeasurementEnd;
|
}
|
break;
|
}
|
case PmcSteps.AcMeasurementEnd:
|
{
|
PmcStep = PmcSteps.AcMeasurementDataCheck;
|
break;
|
}
|
case PmcSteps.AcMeasurementDataCheck:
|
{
|
AttenuatorCalData attenuatorCalData = new AttenuatorCalData();
|
attenuatorCalData.AttenuatorAngle = _currentAttenuatorCalAngle;
|
attenuatorCalData.Energy = _equipment.powerMeter.MeasurementAverageEnergy;
|
|
_attenuatorCalData.Add(attenuatorCalData);
|
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Attenuator angle : {attenuatorCalData.AttenuatorAngle} energy : {attenuatorCalData.Energy}");
|
|
//종료
|
if (_currentAttenuatorCalAngle >= _equipment.settingParameterManager.SettingParameter.AttenuatorCalEndAngle)
|
{
|
_equipment.attenuatorCalInfo.SetAttenuatorCalData(_attenuatorCalData.ToArray());
|
|
_equipment.equipmentInfo.SetAttenuatorCalDate();
|
PmcStep = PmcSteps.AcLaserOff;
|
}
|
// 마지막
|
else if (_currentAttenuatorCalAngle < _equipment.settingParameterManager.SettingParameter.AttenuatorCalEndAngle && _currentAttenuatorCalAngle + _equipment.settingParameterManager.SettingParameter.AttenuatorCalAngleStep > _equipment.settingParameterManager.SettingParameter.AttenuatorCalEndAngle)
|
{
|
_currentAttenuatorCalAngle = _equipment.settingParameterManager.SettingParameter.AttenuatorCalEndAngle;
|
PmcStep = PmcSteps.AcPowerMeterInitialize;
|
}
|
// 계속 진행
|
else
|
{
|
_currentAttenuatorCalAngle += _equipment.settingParameterManager.SettingParameter.AttenuatorCalAngleStep;
|
PmcStep = PmcSteps.AcPowerMeterInitialize;
|
}
|
break;
|
}
|
case PmcSteps.AcLaserOff:
|
{
|
if (_equipment.scanner.IsBusy)
|
{
|
_equipment.scanner.Stop();
|
}
|
_equipment.scanner.LaserOff();
|
PmcStep = PmcSteps.AcLaserOffCheck;
|
break;
|
}
|
case PmcSteps.AcLaserOffCheck:
|
{
|
if (_equipment.scanner.IsLaserOn)
|
{
|
if (_pmcSequenceTimer.Seconds > 3)
|
{
|
PmcStep = PmcSteps.AcLaserOff;
|
}
|
return;
|
}
|
else
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Laser off !!");
|
PmcStep = PmcSteps.AttenuatorCalEnd;
|
}
|
break;
|
}
|
case PmcSteps.AttenuatorCalEnd:
|
{
|
EquipmentLogManager.Instance.WriteAttenuatorCalLog($"Attenuator Cal end !!");
|
PmcStep = PmcSteps.Wait;
|
break;
|
}
|
}
|
}
|
|
public bool ProcessStart()
|
{
|
if (TmcStep == TmcSteps.Wait && PmcStep == PmcSteps.Wait)
|
{
|
TmcStep = Sequence.TmcSteps.StatusCheck;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool ManualProcessStart()
|
{
|
if (PmcStep == PmcSteps.Wait)
|
{
|
PmcStep = Sequence.PmcSteps.MoveCenterPosition;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool ProcessStop()
|
{
|
TmcStep = TmcSteps.End;
|
PmcStep = PmcSteps.End;
|
return true;
|
}
|
|
public bool EnergyDropCheckStart()
|
{
|
if(PmcStep == PmcSteps.Wait)
|
{
|
PmcStep = PmcSteps.EnergyDropCheckStart;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool AttenuatorCalStart()
|
{
|
if (PmcStep == PmcSteps.Wait)
|
{
|
PmcStep = PmcSteps.AttenuatorCalStart;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool EnergyDropCheckStop()
|
{
|
if(PmcSteps.EnergyDropCheckStart <= PmcStep && PmcStep <= PmcSteps.EnergyDropCheckEnd)
|
{
|
PmcStep = PmcSteps.EdcLaserOff;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool AttenuatorCalStop()
|
{
|
if (PmcSteps.AttenuatorCalStart <= PmcStep && PmcStep <= PmcSteps.AttenuatorCalEnd)
|
{
|
PmcStep = PmcSteps.AcLaserOff;
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
}
|
}
|