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;
}
}
}