using SA_LTT.Alarm; using SA_LTT.Info.AttenuatorCalInfo; using SA_LTT.Info.EquipmentInfo; using SA_LTT.Info.FoupInfo; using SA_LTT.Info.RecipeInfo; using SA_LTT.Info.WaferInfo; using SA_LTT.Module; using SA_LTT.Parameter; using SA_LTT.UserInfo; using System; using System.Reflection; using System.Threading; using static SA_LTT.Info.WaferInfo.WaferInfoManager; using static SA_LTT.Sequence; namespace SA_LTT { //여기서는 안씀 (Auto Key가 없음) ;; 그냥 Maint일 때 Teach로.. public enum EquipmentMode { Auto, /// /// Key teach mode /// Teach, } public enum EquipmentStatus { /// /// 장비 이상 없음. /// Nomal, /// /// 장비 Heavy 알람 상태. /// Fault, /// /// 장비 Light 알람 상태. /// Warning, /// /// 장비 PM 상태 /// PM, } public enum ProcessStatus { /// /// 대기상태, (sequence 대기) /// Idle, /// /// 동작상태, (sequence 동작중) /// Execute, /// /// 정지 상태, (sequence 일시정지) /// Pause, /// /// 정지 대기 상태, (sequence 일시정지, Step 진행 중.) /// PauseWait, } public delegate void UserChangedEvnet(User changedUser); public class Equipment : IDisposable { /* =========== Hardware 목록 ================ Laser PreAligner LED <- ? GR200 Temp EFU Robot // 진 -ing Chiller Scanner // 완 Motor IO Attenuator // 완 ============================================ ============= Software 목록 ================= Alarm // 완 Recipe Mode(Teach/Auto) EquipmentStatus(Nomal/Fault/PM) ProcessStatus(Idle/Execute/Pause) UserParameter -> 미정 SystemParameter -> 미정 InterlockParameter -> 미정 UserInfo // 완 ============================================= */ /// /// 설정 파일 저장 / parameter, alarm 등. /// public const string settingFilePath = @"C:\SA_LTT\Config\"; /// /// 정보 파일 저장 / user, recipe 등. /// public const string infoFilePath = @"C:\SA_LTT\Info\"; public const string Version = "001.000.000"; public static string UpdateDate; private EquipmentStatus _equipmentStatus = EquipmentStatus.Nomal; private ProcessStatus _processStatus = ProcessStatus.Idle; private EquipmentMode _equipmentMode = EquipmentMode.Teach; private bool CheckCST1Removed; private bool CheckCST2Removed; private bool _isRunStop; private bool _isAutoRun; public EquipmentInfo equipmentInfo; public AttenuatorCalInfo attenuatorCalInfo; public ModeParameterManager modeParameterManager; public SettingParameterManager settingParameterManager; public Crevis crevis; public Scanner scanner; public PreAligner preAligner; public Robot robot; public AlarmManager alarmManager; public Attenuator attenuator; public E5CC tempControl; public FFU ffu; public GR200 gr200; public PowerPmacCtrl powerPmac; public PiLaser piLaser; public PowerMeter powerMeter; public Chiller chiller; public Chamber chamber; public UserManager userManager; private User _user; public WaferInfoManager waferInfoManager; public RecipeManager recipeManager; public FoupRecipeManager foupRecipeManager; public VisionControl visionControl; private Sequence _sequence; private Thread t_ModuleUpdate; private Thread t_Sequence; private Thread t_UpdateTowerLamp; public event UserChangedEvnet UserChanged; public Foup port1Foup; public Foup port2Foup; public bool SequencePause { get; private set; } public bool IsDisposed { get; private set; } public PmcSteps PmcStep { get { return _sequence.PmcStep; } } public TmcSteps TmcStep { get { return _sequence.TmcStep; } } public bool IsEnergyDropCheckRun { get { if (PmcSteps.EnergyDropCheckStart <= PmcStep && PmcStep <= PmcSteps.EnergyDropCheckEnd) { return true; } else { return false; } } } public bool IsAttenuatorCalRun { get { if (PmcSteps.AttenuatorCalStart <= PmcStep && PmcStep <= PmcSteps.AttenuatorCalEnd) { return true; } else { return false; } } } public double ProcessTactTimeSeconds { get { return _sequence.ProcessTactTimeSeconds; } } public EquipmentStatus EquipmentStatus { get { return _equipmentStatus; } private set { _equipmentStatus = value; } } public ProcessStatus ProcessStatus { get { return _processStatus; } private set { _processStatus = value; } } public EquipmentMode EquipmentMode { get { return _equipmentMode; } private set { _equipmentMode = value; } } public bool IsLampOn { get { if(crevis.Connected) { return crevis.DigitalOutputs[Crevis.DigitalOutput.FLUORESCENT_LAMP_OFF] ? false : true; } else { return false; } } } public User User { get { return _user; } private set { _user = value; } } /// /// 마지막 Wafer 진행 후 종료. /// public bool IsRunStop { get { return _isRunStop; } set { _isRunStop = value; } } public bool IsAutoRun { get { return _isAutoRun; } set { _isAutoRun = value; } } private bool checkCycle = false; private System.Windows.Forms.Timer t_UiView = new System.Windows.Forms.Timer(); private MessageBoxPad messageBoxPad = new MessageBoxPad(); private string message; bool messageboxPadShowBit; public Equipment() { InitializeParameter(); InitializeData(); InitializeModule(); Assembly assembly = Assembly.GetExecutingAssembly(); DateTime buildTime = System.IO.File.GetLastWriteTime(assembly.Location); UpdateDate = $"{buildTime.Year}-{buildTime.Month:D2}-{buildTime.Day:D2}"; _sequence = new Sequence(this); t_ModuleUpdate = new Thread(ModuleUpdate); t_ModuleUpdate.Start(); t_Sequence = new Thread(SequenceRun); t_Sequence.Start(); t_UpdateTowerLamp = new Thread(UpdateTowerLamp); t_UpdateTowerLamp.Start(); while (checkCycle == false) ; EquipmentLogManager.Instance.WriteProcessLog($"Program start !!"); t_UiView.Tick += T_UiView_Tick; t_UiView.Interval = 2000; t_UiView.Start(); } private void T_UiView_Tick(object sender, EventArgs e) { if(messageboxPadShowBit) { messageboxPadShowBit = false; messageBoxPad.SetMessage(message); messageBoxPad.Show(); } } public void SetMessageBox(string message = "") { this.message = message; messageboxPadShowBit = true; } private void InitializeParameter() { equipmentInfo = new EquipmentInfo(); equipmentInfo.Refresh(); attenuatorCalInfo = new AttenuatorCalInfo(); attenuatorCalInfo.Refresh(); attenuatorCalInfo.SetAttenuatorCalData(attenuatorCalInfo.GetAttenuatorCalData()); modeParameterManager = new ModeParameterManager(); settingParameterManager = new SettingParameterManager(); modeParameterManager.Refresh(); settingParameterManager.Refresh(); } private void InitializeData() { EquipmentMode = EquipmentMode.Auto; EquipmentStatus = EquipmentStatus.Nomal; ProcessStatus = ProcessStatus.Idle; SequencePause = true; User = new User(); alarmManager = new AlarmManager(); alarmManager.Occurred += AlarmManager_Occurred; alarmManager.Cleared += AlarmManager_Cleared; userManager = new UserManager(this); waferInfoManager = new WaferInfoManager(this); recipeManager = new RecipeManager(this); foupRecipeManager = new FoupRecipeManager(this); visionControl = new VisionControl(this); port1Foup = new Foup(this); port1Foup.portNumber = 1; port2Foup = new Foup(this); port2Foup.portNumber = 2; } private void AlarmManager_Cleared() { } private void AlarmManager_Occurred(Alarm.Alarm occurredAlarm) { //임시, 부저 사용 안함. //crevis.WriteOutput(Crevis.DigitalOutput.BUZZER_1, true); } private void InitializeModule() { crevis = new Crevis(this); scanner = new Scanner(this); scanner.Initialize(); preAligner = new PreAligner(this); robot = new Robot(this); attenuator = new Attenuator(this); tempControl = new E5CC(this); ffu = new FFU(this); gr200 = new GR200(this); powerPmac = new PowerPmacCtrl(this); piLaser = new PiLaser(this); chamber = new Chamber(this); powerMeter = new PowerMeter(this); chiller = new Chiller(this); } private void ModuleUpdate() { while (IsDisposed == false) { Thread.Sleep(10); try { ScannerUpdate(); UpdateWaferInfo(); UpdateFoupInfo(); CheckAlarm(); UpdateEquipmentStatus(); if (checkCycle == false) { checkCycle = true; } } catch(Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } } private void CheckAlarm() { bool check = false; if (crevis.DigitalInputs[Crevis.DigitalInput.EMO_SW_1]) { alarmManager.Occur(AlarmCode.AL_0001_EMO_STOP_1); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.EMO_SW_2]) { alarmManager.Occur(AlarmCode.AL_0002_EMO_STOP_2); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.EMO_SW_3]) { alarmManager.Occur(AlarmCode.AL_0003_EMO_STOP_3); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.EMO_SW_4]) { alarmManager.Occur(AlarmCode.AL_0004_EMO_STOP_4); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.SMOKE_DETECTOR_CP_BOX]) { alarmManager.Occur(AlarmCode.AL_0005_SMOKE_DETECTOR_ON); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.SERVO_MC_STATUS] == false) { alarmManager.Occur(AlarmCode.AL_0020_SERVO_MC_OFF); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.VACUUM_MC_STATUS]) { alarmManager.Occur(AlarmCode.AL_0021_VACUUM_MC_OFF); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.WATER_LEAK_LASER] == false) { alarmManager.Occur(AlarmCode.AL_0030_LASER_WATER_LEAK); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.WATER_LEAK_CHILLER] == false) { alarmManager.Occur(AlarmCode.AL_0031_CHILLER_WATER_LEAK); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.MAIN_CDA_PRESSURE] == false) { alarmManager.Occur(AlarmCode.AL_0040_MAIN_CDA_PRESSURE); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.MAIN_VAC_PRESSURE] == false) { alarmManager.Occur(AlarmCode.AL_0041_MAIN_VAC_PRESSURE); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.MAIN_CDA_FLOW]) { alarmManager.Occur(AlarmCode.AL_0042_MAIN_CDA_FLOW); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.CMB_VACUUM_PRESSURE]) { alarmManager.Occur(AlarmCode.AL_0043_CMB_VAC_PRESSURE); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.DOOR_LOCK_OPEN_1]) { alarmManager.Occur(AlarmCode.AL_0010_DOOR_OPEN_1); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.DOOR_LOCK_OPEN_2]) { alarmManager.Occur(AlarmCode.AL_0011_DOOR_OPEN_2); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.DOOR_LOCK_OPEN_3]) { alarmManager.Occur(AlarmCode.AL_0012_DOOR_OPEN_3); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.DOOR_LOCK_OPEN_4]) { alarmManager.Occur(AlarmCode.AL_0013_DOOR_OPEN_4); check = true; } if (crevis.DigitalInputs[Crevis.DigitalInput.CP_BOX_OPEN]) { alarmManager.Occur(AlarmCode.AL_0014_DOOR_OPEN_CP); check = true; } } private void UpdateTowerLamp() { /* * ========== RED (Equipment status)========== * 점등 : Fault 상태 설비 운전 불가. (Heavy Alarm) * 점멸 : Warning 상태 설비 사용 가능. (Light Alarm) * 소등 : 사용 가능 * ========== YELLOW (Equipment Mode)========== * 점등 : Teach Mode * 점멸 : X * 소등 : Atuo Mode * ========== GREEN (Process status)========== * 점등 : Sequence 동작 중 * 점멸 : Sequence 일시 정지 * 소등 : Sequence 정지 상태. */ while (IsDisposed == false) { Thread.Sleep(500); try { // Red if (alarmManager.OccurredAlarms.Count > 0) { if (alarmManager.OccurredAlarms.Exists(x => x.Level == AlarmLevel.Heavy)) { if (crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_RED] == false) crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_RED, true); } else { crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_RED, !crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_RED]); } } else { if (crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_RED]) crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_RED, false); } //Yellow if (EquipmentMode == EquipmentMode.Auto) { if (crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_YELLOW]) crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_YELLOW, false); } else { if (crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_YELLOW] == false) crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_YELLOW, true); } //Green if (ProcessStatus == ProcessStatus.Execute) { if (crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_GREEN] == false) crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_GREEN, true); } else if (ProcessStatus == ProcessStatus.Idle) { if (crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_GREEN]) crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_GREEN, false); } else { crevis.WriteOutput(Crevis.DigitalOutput.SIGNAL_TOWER_GREEN, !crevis.DigitalOutputs[Crevis.DigitalOutput.SIGNAL_TOWER_GREEN]); } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } } private bool IsInterlock() { bool check = false; // Robot 인터락 if(robot.IsError) { check = true; } // Vision Interlock if (modeParameterManager.ModeParameter.AlignUse) { if(crevis.DigitalOutputs[Crevis.DigitalOutput.FLUORESCENT_LAMP_OFF] == false) { SetMessageBox("Align 사용시 Lamp를 꺼주세요."); check = true; } } // PreAligner 인터락 //if(preAligner.IsHome == false) // Home 상태가 계속 off로 들어옴; //{ // check = true; //} // 장비 상태 인터락 if (EquipmentMode == EquipmentMode.Teach) //장비 Mode 확인 { check = true; } if (EquipmentStatus == EquipmentStatus.Fault) //장비 상태 확인 { check = true; } return check; } private void SequenceRun() { while (IsDisposed == false) { Thread.Sleep(50); try { /* * Auto -> Sequence 동작 진행 중. * PauseWait -> Sequence 동작 중 일시정지 대기. * Pause -> Sequence 동작 중 일시 정지. * Idle -> Sequence 대기 상태. */ if (IsInterlock()) // Interlock 발생. { ProcessPause(); if (_sequence.IsTmcStepPauseEnable == false) { _sequence.TmcSequence(); } if (_sequence.IsPmcStepPauseEnable == false) { _sequence.PmcSequence(); } } else // Interlock 발생 안함. { if(SequencePause) // Pause 상태 { if (_sequence.IsTmcStepPauseEnable == false) { _sequence.TmcSequence(); } if(_sequence.IsPmcStepPauseEnable == false) { _sequence.PmcSequence(); } } else // Excute 상태 { //Todo. Shutter always use랑 상관 없이 Energy drop check, attenuator cal 때는 항상 열어놓을까 ..? if (modeParameterManager.ModeParameter.ShutterAlwaysUse) { if (PmcStep != PmcSteps.Wait) { if (crevis.DigitalOutputs[Crevis.DigitalOutput.LASER_SHUTTER_OPEN_SOL] == false) { crevis.WriteOutput(Crevis.DigitalOutput.LASER_SHUTTER_OPEN_SOL, true); } } } if (IsEnergyDropCheckTime()) { //Tmc 진행 중 일 때만 실행. if (_sequence.TmcStep != TmcSteps.Wait) { _sequence.EnergyDropCheckStart(); } } if(IsAttenuatorCalTime()) { //Tmc 진행 중 일 때만 실행. if (_sequence.TmcStep != TmcSteps.Wait) { _sequence.AttenuatorCalStart(); } } _sequence.PmcSequence(); _sequence.TmcSequence(); } } UpdateProcessStatus(); } catch(Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } } public bool IsEnergyDropCheckTime() { if (modeParameterManager.ModeParameter.EnergyDropCheckUse) { if ((DateTime.Now - equipmentInfo.EnergyDropCheckDate).TotalHours > settingParameterManager.SettingParameter.EnergyDropCheckCycle) { return true; } else { return false; } } else { return false; } } public bool IsAttenuatorCalTime() { if (modeParameterManager.ModeParameter.AttenuatorCalUse) { if ((DateTime.Now - equipmentInfo.AttenuatorCalDate).TotalHours > settingParameterManager.SettingParameter.AttenuatorCalCycle) { return true; } else { return false; } } else { return false; } } private void UpdateEquipmentStatus() { if(alarmManager.OccurredAlarms.Count > 0) { if(alarmManager.OccurredAlarms.Exists(x=>x.Level == AlarmLevel.Heavy)) { EquipmentStatus = EquipmentStatus.Fault; } else { EquipmentStatus = EquipmentStatus.Warning; } } else { if (EquipmentMode == EquipmentMode.Teach) { EquipmentStatus = EquipmentStatus.PM; } else { EquipmentStatus = EquipmentStatus.Nomal; } } } private void UpdateProcessStatus() { if (SequencePause == false && _sequence.PmcStep == Sequence.PmcSteps.Wait && _sequence.TmcStep == Sequence.TmcSteps.Wait) { ProcessStatus = ProcessStatus.Idle; ProcessPause(); } else if (SequencePause) { if (_sequence.IsTmcStepPauseEnable && _sequence.IsPmcStepPauseEnable) { if(_sequence.PmcStep == Sequence.PmcSteps.Wait && _sequence.TmcStep == Sequence.TmcSteps.Wait) { ProcessStatus = ProcessStatus.Idle; } else { ProcessStatus = ProcessStatus.Pause; } } else { ProcessStatus = ProcessStatus.PauseWait; } } else { ProcessStatus = ProcessStatus.Execute; } } private void ScannerUpdate() { if(scanner.IsInitialized) { scanner.GetBusy(); scanner.GetLaserOn(); } //Laser On일 때 Board On if(scanner.IsLaserOn) { if (crevis.DigitalOutputs[Crevis.DigitalOutput.LASER_LED_BOARD_ON] == false) crevis.WriteOutput(Crevis.DigitalOutput.LASER_LED_BOARD_ON, true); } else { if (crevis.DigitalOutputs[Crevis.DigitalOutput.LASER_LED_BOARD_ON] == true) crevis.WriteOutput(Crevis.DigitalOutput.LASER_LED_BOARD_ON, false); } } private void UpdateWaferInfo() { //CST 1번 제거 될시 Port1 Wafer Info 초기화. if(crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_1]) { CheckCST1Removed = false; } else { if (CheckCST1Removed == false) { WaferInfo waferInfo = new WaferInfo(); WaferNumbers waferNumber = WaferNumbers.A1; for (int i = 0; i < 25; i++) { waferInfo.SourceNumber = waferNumber + i; waferInfoManager.SetWaferInfo(waferNumber + i, waferInfo.Clone()); } CheckCST1Removed = true; } } //CST 2번 제거 될시 Port2 Wafer Info 초기화. if (crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_2]) { CheckCST2Removed = false; } else { if (CheckCST2Removed == false) { WaferInfo waferInfo = new WaferInfo(); WaferNumbers waferNumber = WaferNumbers.B1; for (int i = 0; i < 25; i++) { waferInfo.SourceNumber = waferNumber + i; waferInfoManager.SetWaferInfo(waferNumber + i, waferInfo.Clone()); } CheckCST2Removed = true; } } //로봇 동작 안할 때 if(robot.IsRunEnable && robot.IsPutGetRun == false) { //Robot Wafer info 동기화, 애매쓰... if (robot.IsWaferExist) { WaferInfo waferInfo = waferInfoManager.GetWaferInfo(WaferNumbers.Robot); if (waferInfo.IsStatus == WaferInfo.WaferStatus.Empty) { //상태 Error 알람? waferInfo.IsStatus = WaferInfo.WaferStatus.Exist; waferInfoManager.SetWaferInfo(WaferNumbers.Robot, waferInfo); } } else { WaferInfo waferInfo = waferInfoManager.GetWaferInfo(WaferNumbers.Robot); if (waferInfo.IsStatus != WaferInfo.WaferStatus.Empty) { //상태 Error 알람? waferInfo.IsStatus = WaferInfo.WaferStatus.Empty; waferInfoManager.SetWaferInfo(WaferNumbers.Robot, waferInfo); } } //Aligner Wafer info 동기화, 애매쓰... if (preAligner.IsWaferExist) { WaferInfo waferInfo = waferInfoManager.GetWaferInfo(WaferNumbers.PreAligner); if (waferInfo.IsStatus == WaferInfo.WaferStatus.Empty) { //상태 Error 알람? waferInfo.IsStatus = WaferInfo.WaferStatus.Exist; waferInfoManager.SetWaferInfo(WaferNumbers.PreAligner, waferInfo); } } else { WaferInfo waferInfo = waferInfoManager.GetWaferInfo(WaferNumbers.PreAligner); if (waferInfo.IsStatus != WaferInfo.WaferStatus.Empty) { //상태 Error 알람? waferInfo.IsStatus = WaferInfo.WaferStatus.Empty; waferInfoManager.SetWaferInfo(WaferNumbers.PreAligner, waferInfo); } } } } private void UpdateFoupInfo() { if (crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_1] == false) { port1Foup.status = FoupStatus.Empty; } else { if(port1Foup.status == FoupStatus.Empty) { port1Foup.status = FoupStatus.Ready; } } if (crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_2] == false) { port2Foup.status = FoupStatus.Empty; } else { if (port2Foup.status == FoupStatus.Empty) { port2Foup.status = FoupStatus.Ready; } } } public void Dispose() { EquipmentLogManager.Instance.WriteProcessLog($"Program end !!"); IsDisposed = true; } public bool ChangeUser(string userName) { if (userManager.ExistsUser(userName)) { User = userManager.GetUser(userName); UserChanged?.Invoke(User.Clone()); return true; } else { return false; } } public void LogOut() { User user = new User(); user.Name = string.Empty; user.Level = UserLevel.Operator; user.Password = "1234"; User = user; UserChanged?.Invoke(User.Clone()); } public void BuzzerStop() { crevis.WriteOutput(Crevis.DigitalOutput.BUZZER_1, false); crevis.WriteOutput(Crevis.DigitalOutput.BUZZER_2, false); crevis.WriteOutput(Crevis.DigitalOutput.BUZZER_3, false); crevis.WriteOutput(Crevis.DigitalOutput.BUZZER_4, false); } public void LampOn() { crevis.WriteOutput(Crevis.DigitalOutput.FLUORESCENT_LAMP_OFF, false); } public void LampOff() { crevis.WriteOutput(Crevis.DigitalOutput.FLUORESCENT_LAMP_OFF, true); } public void EmoStop() { /* Process stop 목록========= process pause Motor 정지. Scanner 정지, laser off IO off 목록====== N2 MFC Valve on sol off N2 CHB valve on sol off CHB bypass on sol on */ if(ProcessStatus == ProcessStatus.Execute) { ProcessPause(); } if(chamber.IsInposition == false) { chamber.AllStop(); } if(scanner.IsBusy) { scanner.Stop(); } if(scanner.IsLaserOn) { scanner.LaserOff(); } if(crevis.DigitalOutputs[Crevis.DigitalOutput.N2_MFC_VALVE_ON_SOL] != false) { crevis.WriteOutput(Crevis.DigitalOutput.N2_MFC_VALVE_ON_SOL, false); } if (crevis.DigitalOutputs[Crevis.DigitalOutput.N2_CHAMBER_VALVE_ON_SOL] != false) { crevis.WriteOutput(Crevis.DigitalOutput.N2_CHAMBER_VALVE_ON_SOL, false); } if (crevis.DigitalOutputs[Crevis.DigitalOutput.CMB_BYPASS_ON_SOL] != true) { crevis.WriteOutput(Crevis.DigitalOutput.CMB_BYPASS_ON_SOL, true); } } public void ProcessStartCheck() { if(User.Level == UserLevel.Operator) { // door close 상태에서 가능. } else if (User.Level == UserLevel.Engineer) { // door close 상태에서 가능. } else if (User.Level == UserLevel.Master) { // Interlock 해제. } } public bool ChangeMode(EquipmentMode mode) { if(EquipmentMode == mode) { return true; } else { //나중에 인터락 걸기; if(ProcessStatus == ProcessStatus.Idle) { EquipmentMode = mode; return true; } else { return false; } } } public bool ChangeEquipementStatus(EquipmentStatus status) { if(EquipmentStatus == status) { return true; } else { if (EquipmentStatus == EquipmentStatus.Nomal) { if (status == EquipmentStatus.Fault || status == EquipmentStatus.Warning) { if (alarmManager.OccurredAlarms.Count == 0) { EquipmentStatus = status; return true; } else { } } } else if (EquipmentStatus == EquipmentStatus.Fault) { if(status == EquipmentStatus.Nomal) { if(alarmManager.OccurredAlarms.Count == 0) { EquipmentStatus = status; return true; } else { } } } else if (EquipmentStatus == EquipmentStatus.Warning) { } else if (EquipmentStatus == EquipmentStatus.PM) { EquipmentStatus = status; return true; } } return false; } public bool ProcessStart() { //Teach or Fault if (EquipmentMode == EquipmentMode.Teach || EquipmentStatus == EquipmentStatus.Fault) { return false; } if(TmcStep == TmcSteps.Wait && PmcStep == PmcSteps.Wait) { for (int i = (int)WaferNumbers.B25 + 1; i < Enum.GetValues(typeof(WaferNumbers)).Length; i++) { if (waferInfoManager.GetWaferInfo((WaferNumbers)i).IsStatus != WaferInfo.WaferStatus.Empty) { SetMessageBox("내부에 Wafer가 존재합니다."); return false; } } } _sequence.ProcessStart(); SequencePause = false; return true; } public bool ProcessStartInterlock() { if (piLaser.CurrentPiLaserStatus.EnableLdd == false) { SetMessageBox("LDD 가 열려있지 않습니다."); return false; } if (piLaser.CurrentPiLaserStatus.EnableShutter == false) { SetMessageBox("Laser shutter가 열려있지 않습니다."); return false; } if (piLaser.CurrentPiLaserStatus.SetCurrent != piLaser.CurrentPiLaserStatus.MaxCurrent) { SetMessageBox("Laser set current가 max값이 아닙니다."); return false; } return true; } public bool ManualProcessStart() { //Teach or Fault if (EquipmentMode == EquipmentMode.Teach || EquipmentStatus == EquipmentStatus.Fault || ProcessStatus != ProcessStatus.Idle) { return false; } if (_sequence.ManualProcessStart()) { SequencePause = false; return true; } else { return false; } } public bool ManualEnergyDropCheckStart() { if (EquipmentMode == EquipmentMode.Teach || EquipmentStatus == EquipmentStatus.Fault || ProcessStatus != ProcessStatus.Idle) { return false; } if (_sequence.EnergyDropCheckStart()) { SequencePause = false; return true; } else { return false; } } public bool EnergyDropCheckStop() { SequencePause = false; return _sequence.EnergyDropCheckStop(); } public bool ManualAttenuatorCalStart() { if (EquipmentMode == EquipmentMode.Teach || EquipmentStatus == EquipmentStatus.Fault || ProcessStatus != ProcessStatus.Idle) { return false; } if (_sequence.AttenuatorCalStart()) { SequencePause = false; return true; } else { return false; } } public bool AttenuatorCalStop() { SequencePause = false; return _sequence.AttenuatorCalStop(); } public void ProcessPause() { if(SequencePause == false) { EquipmentLogManager.Instance.WriteProcessLog($"Process pause"); SequencePause = true; } } public bool ProcessStop() { if(ProcessStatus == ProcessStatus.Execute) { return false; } if(_sequence.ProcessStop()) { SequencePause = false; return true; } else { return false; } } //한번만 사용할 것. BeginInvoke 사용중. public void AddRecipeExcutedEvent(RecipeExcuteEvent recipeExcuteEvent) { _sequence.RecipeExcuted += recipeExcuteEvent; } //한번만 사용할 것. BeginInvoke 사용중. public void AddProcessInfoExcutedEvent(ProcessInfoExcuteEvent processInfoExcuteEvent) { _sequence.ProcessInfoExcuted += processInfoExcuteEvent; } } }