using Aitex.Core.Common;
using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using System;
using System.Collections;
using System.Collections.Generic;
using MECF.Framework.Common.CommonData;
using VirgoCommon;
using VirgoRT.Device;
using VirgoRT.Device.YASKAWA;
using VirgoRT.Devices.YASKAWA;
using VirgoRT.Modules;
using VirgoRT.Modules.LPs;
namespace VirgoRT.Devices.EFEM
{
///
/// EFEM object class
///
sealed class Efem : EfemBase, IEfem
{
//---------------------------------Fields----------------------------------------
//
private readonly JetPM[] _pm = new JetPM[2];
private readonly Loadport[] _LPMs = new Loadport[2];
private readonly SignalTower _signalT = new SignalTower();
//private readonly CoolingStage[] _aligner = new CoolingStage[2];
//private string _robotMoveAction;
private LidState _CassetteDoor;
private LidState _SideDoor;
private RD_TRIG _bSysVacPressure1 = new RD_TRIG(); //Bit[0] System vacuum source pressure 1
private RD_TRIG _bIonizerCompressedAir = new RD_TRIG(); //Bit[1] Ionizer compressed air
private RD_TRIG _bSysCompressedAirPressure = new RD_TRIG(); //Bit[2] System compressed air pressure 1
private RD_TRIG _bFlowGaugeSensor = new RD_TRIG(); //Bit[4] Flow gauge sensor
private RD_TRIG _bLeakageSensor = new RD_TRIG(); //Bit[5] Leakage sensor
private RD_TRIG _bDiffPressureSensorSetting1 = new RD_TRIG(); //Bit[8] Differential pressure sensor setting 1
private RD_TRIG _bDiffPressureSensorSetting2 = new RD_TRIG(); //Bit[9] Differential pressure sensor setting 2
private RD_TRIG _bIonizerAlarm = new RD_TRIG(); //Bit[10] Ionizer alarm
private RD_TRIG _bFFuAlarm = new RD_TRIG();
private RD_TRIG _bAreaSensor = new RD_TRIG();
private RD_TRIG _bModeSwitch = new RD_TRIG();
private RD_TRIG _bCassetteDoorTrig = new RD_TRIG();
private RD_TRIG _bSideDoorTrig = new RD_TRIG();
private RobotMoveInfo _moveInfo;
public Dictionary IsBufferPinUp = new Dictionary();
public override ILoadport this[ModuleName mod]
{
get
{
if (!ModuleHelper.IsLoadPort(mod))
throw new ApplicationException($"{mod} is NOT Loadport");
return _LPMs[mod - ModuleName.LP1];
}
}
//---------------------------------Properties------------------------------------
//
public LidState CassetteDoor
{
get => _CassetteDoor;
set
{
_CassetteDoor = value;
_bCassetteDoorTrig.CLK = _CassetteDoor == LidState.Close;
if (_bCassetteDoorTrig.T)
{
EV.Notify(CassetteDoorOpen);
EV.PostWarningLog(Module.ToString(), "Cassette door opened");
}
if (_bCassetteDoorTrig.R)
{
EV.Notify(CassetteDoorClose);
EV.PostInfoLog(Module.ToString(), "Cassette door closed");
}
}
}
public LidState DoorSwitch
{
get => _SideDoor;
set
{
_SideDoor = value;
_bSideDoorTrig.CLK = _SideDoor == LidState.Close;
if (_bSideDoorTrig.T)
{
EV.Notify(EFEMSideDoorOpen);
EV.PostAlarmLog(Module.ToString(), "EFEM Side door open");
}
if (_bSideDoorTrig.R)
{
EV.PostInfoLog(Module.ToString(), "EFEM Side door close");
}
}
}
public RobotMoveInfo MoveInfo
{
get => _moveInfo;
set
{
_moveInfo = value;
}
}
private string CassetteDoorOpen = "CassetteDoorOpen";
private string CassetteDoorClose = "CassetteDoorClose";
private string EFEMSideDoorOpen = "EFEMSideDoorOpen";
private string EFEMVacuumPressureError = "EFEMVacuumPressureError";
private string EFEMCDAError = "EFEMCDAError";
private string EFEMFlowGaugeSensorError = "EFEMFlowGaugeSensorError";
private string EFEMLeakageAlarm = "EFEMLeakageAlarm";
private string EFEMIonizerAlarm = "EFEMIonizerAlarm";
private string EFEMFFUAlarm = "EFEMFFUAlarm";
private string EFEMOffline = "EFEMOffline";
private string EFEMCommunicationError = "EFEMCommunicationError";
private string WaferTransferFailed = "WaferTransferFailed";
private string EFEMError = "EFEMError";
// Constructor
//
public Efem()
{
Module = ModuleName.EfemRobot;
_moveInfo = new RobotMoveInfo()
{
Action = RobotAction.Moving,
BladeTarget = ModuleName.System.ToString(),
};
_pm[0] = DEVICE.GetDevice(ModuleName.PMA.ToString());
_pm[1] = DEVICE.GetDevice(ModuleName.PMB.ToString());
_comm = new EfemComm();
_LPMs[0] = new Loadport(ModuleName.LP1, this);
_LPMs[1] = new Loadport(ModuleName.LP2, this);
IsBufferPinUp[ModuleName.Aligner1] = false;
IsBufferPinUp[ModuleName.Aligner2] = false;
IsBufferPinUp[ModuleName.Cooling1] = false;
IsBufferPinUp[ModuleName.Cooling2] = false;
_msgHandler = new MessageHandler(this);
_msgHandler.CommandUpdated += MsgOnCommandUpdated;
_msgHandler.EventUpdated += MsgOnEventUpdated;
_msgHandler.ErrorOccurred += MsgOnErrorOccurred;
CarrierManager.Instance.SubscribeLocation(ModuleName.LP1.ToString(), 1);
CarrierManager.Instance.SubscribeLocation(ModuleName.LP2.ToString(), 1);
WaferManager.Instance.SubscribeLocation(ModuleName.EfemRobot, 2);
WaferManager.Instance.SubscribeLocation(ModuleName.Aligner1, 1);
WaferManager.Instance.SubscribeLocation(ModuleName.Aligner2, 1);
WaferManager.Instance.SubscribeLocation(ModuleName.Cooling1, 1);
WaferManager.Instance.SubscribeLocation(ModuleName.Cooling2, 1);
WaferManager.Instance.SubscribeLocation(ModuleName.LP1, 25);
WaferManager.Instance.SubscribeLocation(ModuleName.LP2, 25);
//DATA.Subscribe("EfemRobot.RobotMoveAction", () => _robotMoveAction);
DATA.Subscribe("EfemRobot.RobotMoveInfo", () => _moveInfo);
DATA.Subscribe("Aligner1.WaferSize", () => WaferManager.Instance.GetWafer(ModuleName.Aligner1, 0).Size.ToString());
DATA.Subscribe("Aligner2.WaferSize", () => WaferManager.Instance.GetWafer(ModuleName.Aligner2, 0).Size.ToString());
DATA.Subscribe("Cooling1.WaferSize", () => WaferManager.Instance.GetWafer(ModuleName.Cooling1, 0).Size.ToString());
DATA.Subscribe("Cooling2.WaferSize", () => WaferManager.Instance.GetWafer(ModuleName.Cooling2, 0).Size.ToString());
DATA.Subscribe("EfemRobot.WaferSize", () => WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).Size.ToString());
DATA.Subscribe("EFEM.CassetteDoor", () => CassetteDoor);
DATA.Subscribe("EfemRobot.GripStateBlade1", () => GripStateBlade1);
DATA.Subscribe("EfemRobot.GripStateBlade2", () => GripStateBlade2);
GripStateBlade1 = "Unknown";
GripStateBlade2 = "Unknown";
_bCassetteDoorTrig.CLK = true;
_bSideDoorTrig.CLK = true;
EV.Subscribe(new EventItem("Event", CassetteDoorOpen, "Cassette Door Open"));
EV.Subscribe(new EventItem("Event", CassetteDoorClose, "Cassette Door Close"));
EV.Subscribe(new EventItem("Event", EFEMSideDoorOpen, "EFEM Side Door Open", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMVacuumPressureError, "EFEM Vacuum pressure error", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMCDAError, "EFEM CDA error", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMFlowGaugeSensorError, "EFEM flow gauge sensor error", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMLeakageAlarm, "EFEM leakage alarm", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMIonizerAlarm, "EFEM Ionizer alarm", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMFFUAlarm, "EFEM FFU alarm", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMOffline, "EFEM offline", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMCommunicationError, "EFEM Communication error", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", WaferTransferFailed, "Wafer Transfer Failed", EventLevel.Alarm, EventType.HostNotification));
EV.Subscribe(new EventItem("Event", EFEMError, "EFEM Error", EventLevel.Alarm, EventType.HostNotification));
}
// Methods
//
public bool HomeAll()
{
AddAction(new HomeAllAction(this, ModuleName.EFEM));
AddAction(new OrgshAction(this, ModuleName.EFEM));
AddAction(new TrackAction(this, ModuleName.EFEM));
return true;
}
public bool Home(ModuleName mod)
{
AddAction(new HomeModuleAction(this, mod));
return true;
}
public bool LPReset(ModuleName mod)
{
AddAction(new LoadPortClearErrorAction(this, mod));
return true;
}
public bool Load(ModuleName mod)
{
AddAction(new LoadModuleAction(this, mod));
return true;
}
public bool Unload(ModuleName mod)
{
AddAction(new UnloadModuleAction(this, mod));
return true;
}
public bool ReadCarrierId(ModuleName mod)
{
AddAction(new ReadCarrierIdModuleAction(this, mod));
return true;
}
public bool WriteCarrierId(ModuleName mod, string id)
{
AddAction(new WriteCarrierIdModuleAction(this, mod, id));
return true;
}
public bool ReadTagData(ModuleName mod)
{
AddAction(new ReadTagDataModuleAction(this, mod));
return true;
}
public bool WriteTagData(ModuleName mod, string tagData)
{
AddAction(new WriteTagDataModuleAction(this, mod, tagData));
return true;
}
public bool Dock(ModuleName mod)
{
AddAction(new DockModuleAction(this, mod));
return true;
}
public bool Undock(ModuleName mod)
{
AddAction(new UndockModuleAction(this, mod));
return true;
}
public bool Clamp(ModuleName mod, bool isUnloadClamp)
{
AddAction(new ClampModuleAction(this, mod, isUnloadClamp));
return true;
}
public bool Unclamp(ModuleName mod)
{
AddAction(new UnclampModuleAction(this, mod));
return true;
}
public bool SetThick(ModuleName mod)
{
AddAction(new SetThicknessModuleAction(this, mod, "Thick"));
return true;
}
public bool SetThin(ModuleName mod)
{
AddAction(new SetThicknessModuleAction(this, mod, "Thin"));
return true;
}
public bool ClearError()
{
AddAction(new ClearErrorAction(this));
return true;
}
public void AbortRobot()
{
AddAction(new AbortAction(this));
}
public bool Pick(MoveParam mp)
{
int arm = mp.Arm == Hand.Blade1 ? 0 : 1;
var _ws = WaferManager.Instance.GetWafer(mp.DestModule, arm).Size;
if (!WaferManager.Instance.CheckWafer(mp.SrcModule, mp.SrcSlot, WaferStatus.Normal))
{
EV.PostAlarmLog("System", $"{mp.SrcModule} slot {mp.SrcSlot + 1} wafer is not normal");
return false;
}
if ((mp.Arm == Hand.Blade1 || mp.Arm == Hand.Both) && !SC.GetValue("EFEM.EfemRobot.LowerBladeEnable"))
{
EV.PostWarningLog("System", $"Lower Blade 已被禁用");
return false;
}
if ((mp.Arm == Hand.Blade2 || mp.Arm == Hand.Both) && !SC.GetValue("EFEM.EfemRobot.UpperBladeEnable"))
{
EV.PostWarningLog("System", $"Upper Blade 已被禁用");
return false;
}
if (ModuleHelper.IsPm(mp.SrcModule))
{
JetPM pM = GetPM(mp.SrcModule);
AddAction(new SlitDoorAction(mp.SrcModule, pM, true));
//if (pM.IsSlitDoorClosed)
//{
// EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
// return false;
//}
AddAction(new PinAction(mp.SrcModule, pM, MovementPosition.Up, false, mp.Arm, true, false));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = mp.SrcModule, Arm = mp.Arm, Pos = ExtendPos.GB, ws = _ws }));
//_robotMoveAction = string.Format($"{mp.SrcModule}.Picking");
_moveInfo.Action = RobotAction.Picking;
_moveInfo.BladeTarget = mp.SrcModule.ToString();
AddAction(new PinAction(mp.SrcModule, pM, MovementPosition.Down, true, mp.Arm, true, true));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = mp.SrcModule, Arm = mp.Arm, Pos = ExtendPos.G4, ws = _ws }));
}
else
{
//_robotMoveAction = string.Format($"{mp.SrcModule}.Picking");
_moveInfo.Action = RobotAction.Picking;
_moveInfo.BladeTarget = mp.SrcModule.ToString();
AddAction(new PickAction(this, mp));
}
return true;
}
public bool Place(MoveParam mp)
{
int arm = mp.Arm == Hand.Blade1 ? 0 : 1;
var _ws = WaferManager.Instance.GetWafer(mp.SrcModule, arm).Size;
if (mp.Arm == Hand.Blade1 && !SC.GetValue("EFEM.EfemRobot.LowerBladeEnable"))
{
EV.PostWarningLog("System", $"Lower Blade 已被禁用");
return false;
}
if (mp.Arm == Hand.Blade2 && !SC.GetValue("EFEM.EfemRobot.UpperBladeEnable"))
{
EV.PostWarningLog("System", $"Upper Blade 已被禁用");
return false;
}
if (ModuleHelper.IsPm(mp.DestModule))
{
JetPM pM = GetPM(mp.DestModule);
AddAction(new SlitDoorAction(mp.DestModule, pM, true));
//if (pM.IsSlitDoorClosed)
//{
// EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
// return false;
//}
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = mp.DestModule, Arm = mp.Arm, Pos = ExtendPos.PB, ws = _ws }));
//_robotMoveAction = string.Format($"{mp.DestModule}.Placing");
_moveInfo.Action = RobotAction.Placing;
_moveInfo.BladeTarget = mp.DestModule.ToString();
AddAction(new PinAction(mp.DestModule, pM, MovementPosition.Up, true, mp.Arm, false, false));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = mp.DestModule, Arm = mp.Arm, Pos = ExtendPos.P4, ws = _ws }));
AddAction(new PinAction(mp.DestModule, pM, MovementPosition.Up, false, mp.Arm, false, true));
}
else
{
//_robotMoveAction = string.Format($"{mp.DestModule}.Placing");
_moveInfo.Action = RobotAction.Placing;
_moveInfo.BladeTarget = mp.DestModule.ToString();
AddAction(new PlaceAction(this, mp));
}
return true;
}
public void PickAndPlace(MoveParam pickParam, MoveParam placeParam)
{
if (!WaferManager.Instance.CheckWafer(pickParam.SrcModule, pickParam.SrcSlot, WaferStatus.Normal))
{
EV.PostAlarmLog("System", $"{pickParam.SrcModule} slot {pickParam.SrcSlot + 1} wafer is not normal");
return;
}
if (ModuleHelper.IsPm(pickParam.SrcModule))
{
JetPM pM = GetPM(pickParam.SrcModule);
var _ws = WaferManager.Instance.GetWafer(pickParam.SrcModule, 0).Size;
AddAction(new SlitDoorAction(pickParam.SrcModule, pM, true));
AddAction(new PinAction(pickParam.SrcModule, pM, MovementPosition.Up, false, pickParam.Arm, true, false));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = pickParam.SrcModule, Arm = pickParam.Arm, Pos = ExtendPos.GB, ws = _ws }));
_moveInfo.Action = RobotAction.Picking;
_moveInfo.BladeTarget = pickParam.SrcModule.ToString();
//_robotMoveAction = string.Format($"{pickParam.SrcModule}.Picking");
AddAction(new PinAction(pickParam.SrcModule, pM, MovementPosition.Down, true, pickParam.Arm, true, true));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = pickParam.SrcModule, Arm = pickParam.Arm, Pos = ExtendPos.G4, ws = _ws }));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = placeParam.DestModule, Arm = placeParam.Arm, Pos = ExtendPos.PB, ws = _ws }));
//_robotMoveAction = string.Format($"{placeParam.DestModule}.Placing");
_moveInfo.Action = RobotAction.Placing;
_moveInfo.BladeTarget = placeParam.DestModule.ToString();
AddAction(new PinAction(placeParam.DestModule, pM, MovementPosition.Up, true, placeParam.Arm, false, false));
AddAction(new ExtendAction(this, pM, new ExtendParam { Module = placeParam.DestModule, Arm = placeParam.Arm, Pos = ExtendPos.P4, ws = _ws }));
AddAction(new PinAction(placeParam.DestModule, pM, MovementPosition.Up, false, placeParam.Arm, false, false));
}
else
{
//_robotMoveAction = string.Format($"{pickParam.SrcModule}.Picking");
_moveInfo.Action = RobotAction.Picking;
_moveInfo.BladeTarget = pickParam.SrcModule.ToString();
AddAction(new PickAction(this, pickParam));
//_robotMoveAction = string.Format($"{placeParam.DestModule}.Placing");
_moveInfo.Action = RobotAction.Placing;
_moveInfo.BladeTarget = placeParam.DestModule.ToString();
AddAction(new PlaceAction(this, placeParam));
}
}
public bool Extend(ExtendParam ep)
{
AddAction(new ExtendAction(this, null, ep));
return true;
}
public void Goto(MoveParam ep)
{
//_robotMoveAction = string.Format($"{ep.SrcModule}.Goto");
AddAction(new GotoAction(this, ep));
}
public bool Retract(ExtendParam ep)
{
AddAction(new ExtendAction(this, null, ep));
return true;
}
public bool Map(ModuleName mod)
{
if (_LPMs[mod - ModuleName.LP1].Protrusion)
{
EV.PostAlarmLog(mod.ToString(), $"{mod} wafer protrusion, can not do Map");
return false;
}
if (SC.GetValue("EFEM.EfemType") == 1)
{
AddAction(new MapAction(this, mod));
return true;
}
_LPMs[mod - ModuleName.LP1].Map();
return true;
}
public bool Grip(Hand blade, bool isGrip)
{
AddAction(new GripAction(this, blade, isGrip));
return true;
}
public bool SetPinUp(ModuleName mod)
{
AddAction(new LiftAction(this, mod, true));
return true;
}
public bool SetPinDown(ModuleName mod)
{
AddAction(new LiftAction(this, mod, false));
return true;
}
public bool Align(ModuleName mod, float delayTime, WaferSize size)
{
AddAction(new AlignAction(this, mod, size));
return true;
}
public bool SetLamp(LightType light, LightStatus status)
{
AddAction(new LedAction(this, light, status));
return true;
}
public void TurnOffBuzzer()
{
AddAction(new LedAction(this, LightType.BUZZER1, LightStatus.OFF));
}
//public void SwitchOnBuzzerAndRed()
//{
// AddAction(new LedAction(this, LightType.RED, LightStatus.ON));
// AddAction(new LedAction(this, LightType.YELLOW, LightStatus.OFF));
// AddAction(new LedAction(this, LightType.GREEN, LightStatus.OFF));
// AddAction(new LedAction(this, LightType.BUZZER1, LightStatus.ON));
//}
public override void ReceiveMessage(string sRec)
{
_msgHandler.ReceiveMessage(sRec);
}
public override void SetOnline(ModuleName mod, bool online)
{
this[mod].SetOnline(online);
}
public override void SetBusy(ModuleName mod, bool busy)
{
this[mod].Status = DeviceState.Busy;
}
//--------------------------------Constructor------------------------------------
//
private JetPM GetPM(ModuleName mod)
{
if (!ModuleHelper.IsPm(mod))
throw new ArgumentException("Module argument error");
return _pm[mod - ModuleName.PMA];
}
//----------------------------------Private Method-------------------------------
//
private void MsgOnEventUpdated(object sender, EventArgs e)
{
if (!(e is EfemEventArgs))
return;
EfemEventArgs eArg = e as EfemEventArgs;
switch (eArg.CommandType)
{
case EfemOperation.SigStatus:
// EVT:SIGSTAT/Parameter/DATA1/DATA2;
string sParam = eArg.DataList[0]; // "SYSTEM" or "Pn"
// DATA1 & DATA2
int nData1 = Convert.ToInt32(eArg.DataList[1], 16);
int nData2 = Convert.ToInt32(eArg.DataList[2], 16);
BitArray baData1 = new BitArray(new int[] { nData1 });
BitArray baData2 = new BitArray(new int[] { nData2 });
if (0 == string.Compare(sParam, Constant.SYS, true))
{
// EVT:SIGSTAT/System/00000000/00000004;
// DATA1
_bSysVacPressure1.CLK = baData1[0]; // bit 0
_bIonizerCompressedAir.CLK = baData1[1]; // bit 1
_bSysCompressedAirPressure.CLK = baData1[2]; // bit 2
_bFlowGaugeSensor.CLK = baData1[4]; // bit 4
_bLeakageSensor.CLK = baData1[5]; // bit 5
this.DoorSwitch = baData1[6] ? LidState.Close : LidState.Open; // bit 6
//bDrivePower = baData1[7]; // bit 7
_bDiffPressureSensorSetting1.CLK = baData1[8]; // bit 8
_bDiffPressureSensorSetting2.CLK = baData1[9]; // bit 9
_bIonizerAlarm.CLK = baData1[10]; // bit 10
_bFFuAlarm.CLK = baData1[11]; // bit 11
_bAreaSensor.CLK = baData1[12]; // bit 12
_bModeSwitch.CLK = baData1[13]; // bit 13
this.CassetteDoor = baData1[19] ? LidState.Close : LidState.Open; // bit 19
// Post warning and alarm
if (!baData1[0]) // Bit[0] ON=Normal, OFF=Abnormal
{
EV.Notify(EFEMVacuumPressureError);
EV.PostAlarmLog(Module.ToString(), "EFEM System vacuum source pressure low");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
if (!baData1[1]) // Bit[1] ON=Normal, OFF=Abnormal
{
if (!SC.ContainsItem("EFEM.IgnoreIonizerError") ||
!SC.GetValue("EFEM.IgnoreIonizerError"))
{
EV.Notify(EFEMIonizerAlarm);
EV.PostAlarmLog(Module.ToString(), "EFEM Ionizer compressed air error");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
}
if (!baData1[2]) // Bit[2] ON=Normal, OFF=Abnormal
{
EV.Notify(EFEMCDAError);
EV.PostAlarmLog(Module.ToString(), "EFEM System compressed air pressure low");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
if (!baData1[4]) // Bit[4] ON=Normal, OFF=Abnormal
{
if (!SC.ContainsItem("EFEM.IgnoreWaterFlowError") ||
!SC.GetValue("EFEM.IgnoreWaterFlowError"))
{
EV.Notify(EFEMFlowGaugeSensorError);
EV.PostAlarmLog(Module.ToString(), "EFEM Flow gauge sensor error");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
}
if (!baData1[5]) // Bit[5] ON=Normal, OFF=Abnormal
{
EV.Notify(EFEMLeakageAlarm);
EV.PostAlarmLog(Module.ToString(), "EFEM Leakage alarm");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
if (!baData1[10]) // Bit[10] ON=Normal, OFF=Abnormal
{
EV.Notify(EFEMIonizerAlarm);
EV.PostAlarmLog(Module.ToString(), "EFEM Ionizer alarm");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
if (!baData1[11]) // Bit[11] ON=Normal, OFF=Abnormal
{
EV.Notify(EFEMFFUAlarm);
EV.PostAlarmLog(Module.ToString(), "FFU alarm");
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
if (!baData1[13]) // Bit[13] ON=RUN, OFF=Maintain
{
EV.Notify(EFEMOffline);
EV.PostAlarmLog(Module.ToString(), "EFEM switch to Maintain mode, HomeAll to recover");
//Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.ToInit);
}
// DATA2
_signalT.ChangeLightStatus(LightType.RED, baData2[0] ? LightStatus.ON : baData2[5] ? LightStatus.BLINK : LightStatus.OFF);
_signalT.ChangeLightStatus(LightType.GREEN, baData2[1] ? LightStatus.ON : baData2[6] ? LightStatus.BLINK : LightStatus.OFF);
_signalT.ChangeLightStatus(LightType.YELLOW, baData2[2] ? LightStatus.ON : baData2[7] ? LightStatus.BLINK : LightStatus.OFF);
_signalT.ChangeLightStatus(LightType.BLUE, baData2[3] ? LightStatus.ON : baData2[8] ? LightStatus.BLINK : LightStatus.OFF);
_signalT.ChangeLightStatus(LightType.WHITE, baData2[4] ? LightStatus.ON : baData2[9] ? LightStatus.BLINK : LightStatus.OFF);
_signalT.ChangeLightStatus(LightType.BUZZER1, baData2[10] ? LightStatus.ON : LightStatus.OFF);
/* EFEM 程序中目前没有实现
_RobotErr.CLK = baData2[27]; // bit 27
bool bArmNotExtendLLA = baData2[30]; // bit 30
bool bArmNotExtendLLB = baData2[31]; // bit 31
*/
} // system event
else
{
_LPMs[eArg.Module - ModuleName.LP1].HandleEvent(eArg);
} // FOUP EVENT
break;
case EfemOperation.GetWaferInfo:
_LPMs[eArg.Module - ModuleName.LP1].HandleEvent(eArg);
break;
default:
break;
}
}
private void MsgOnCommandUpdated(object sender, EventArgs e)
{
EfemActionArgs arg = e as EfemActionArgs;
if (arg == null) throw new ArgumentNullException("Argument is Null");
if (arg.CommandType == EfemOperation.Ready)
{
this.CommunicationConnected = true;
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.CommReady);
return;
}
EfemActionBase action = null;
lock (_lockerAction)
{
foreach (var item in _actions)
{
if (item is EfemActionBase a1)
{
if (a1.Type == arg.CommandType && item.Status != ActionStatus.Completed)
{
action = a1;
break;
}
}
}
if (action == null)
{
LOG.Write($"NO activated [{arg.ID}] [{arg.CommandType}] in the queue");
return;
}
// 更新 action 状态
action.Status = arg.Status;
if (arg.Status == ActionStatus.Completed)
{
ModuleName mod = action.Module;
// Map 命令比较特别, module 是LPX但是用robot做mapping
if (mod == ModuleName.EFEM || mod == ModuleName.EfemRobot || ModuleHelper.IsAligner(mod) || ModuleHelper.IsCooling(mod) || arg.CommandType == EfemOperation.Map)
{
if ((action.Type != EfemOperation.Light) && (action.Type != EfemOperation.Lift))
{
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.ActionDone, arg.CommandType);
}
if (action.Type == EfemOperation.Lift)
{
Singleton.Instance.EFEM.SetLiftDownDone();
}
}
else if (ModuleHelper.IsLoadPort(mod))
{
Singleton.Instance.EFEM.NotifyLP(mod, LoadPortModule.MSG.ActionDone);
}
//_robotMoveAction = string.Format($"System.None");
//_moveInfo.Action = RobotAction.None;
action.OnPostWork(arg.Data);
LOG.Write($"efem action [{action.GetType().Name}] [{action.ID}][{action.Type}] removed from queue");
_actions.Remove(action);
}
}
}
private void MsgOnErrorOccurred(object sender, EventArgs e)
{
if (!(e is EfemErrorArgs arg))
return;
this.Status = DeviceState.Error;
EfemActionBase action = null;
lock (_lockerAction)
{
foreach (var item in _actions)
{
if (item is EfemActionBase a1)
{
if (a1.Type == arg.CommandType && item.Status != ActionStatus.Completed)
{
action = a1;
break;
}
}
}
if (action == null)
{
LOG.Write($"NO activated [{arg.ID}] [{arg.Module}] [{arg.CommandType}] in the queue");
return;
}
ModuleName mod = action.Module;
if (mod == ModuleName.EFEM || mod == ModuleName.EfemRobot || ModuleHelper.IsAligner(mod) || ModuleHelper.IsCooling(mod) || arg.CommandType == EfemOperation.Map)
{
if (action.Type != EfemOperation.Light)
{
Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
}
}
else if (ModuleHelper.IsLoadPort(mod))
{
Singleton.Instance.EFEM.NotifyLPError(mod);
}
LOG.Write($"efem action [{action.GetType().Name}] [{action.ID}][{action.Module}][{action.Type}] removed from queue");
_actions.Remove(action);
}
EV.Notify(EFEMError);
EV.PostAlarmLog(Module.ToString(), $"{arg.Description}, [{arg.Message}], [{arg.Factor}]");
}
}
}