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,
|
/// <summary>
|
/// Key teach mode
|
/// </summary>
|
Teach,
|
}
|
|
public enum EquipmentStatus
|
{
|
/// <summary>
|
/// 장비 이상 없음.
|
/// </summary>
|
Nomal,
|
/// <summary>
|
/// 장비 Heavy 알람 상태.
|
/// </summary>
|
Fault,
|
/// <summary>
|
/// 장비 Light 알람 상태.
|
/// </summary>
|
Warning,
|
/// <summary>
|
/// 장비 PM 상태
|
/// </summary>
|
PM,
|
}
|
|
public enum ProcessStatus
|
{
|
/// <summary>
|
/// 대기상태, (sequence 대기)
|
/// </summary>
|
Idle,
|
/// <summary>
|
/// 동작상태, (sequence 동작중)
|
/// </summary>
|
Execute,
|
/// <summary>
|
/// 정지 상태, (sequence 일시정지)
|
/// </summary>
|
Pause,
|
/// <summary>
|
/// 정지 대기 상태, (sequence 일시정지, Step 진행 중.)
|
/// </summary>
|
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 // 완
|
=============================================
|
|
*/
|
|
/// <summary>
|
/// 설정 파일 저장 / parameter, alarm 등.
|
/// </summary>
|
public const string settingFilePath = @"C:\SA_LTT\Config\";
|
|
/// <summary>
|
/// 정보 파일 저장 / user, recipe 등.
|
/// </summary>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 마지막 Wafer 진행 후 종료.
|
/// </summary>
|
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;
|
}
|
}
|
}
|