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.CommonData;
using MECF.Framework.Common.SubstrateTrackings;
using System;
using System.Collections;
using System.Collections.Generic;
using Venus_Core;
using Venus_RT.Devices.YASKAWA;
using Venus_RT.Modules;
using Venus_RT.Modules.LPs;
namespace Venus_RT.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 RobotMoveInfo _robotMoveInfo = new RobotMoveInfo();
private LidState _CassetteDoor;
private LidState _SideDoor;
private F_TRIG _bSysVacPressure1 = new F_TRIG();
private F_TRIG _bSysCompressedAirPressure = new F_TRIG();
private R_TRIG _bFlowGaugeSensor = new R_TRIG();
private R_TRIG _bLeakageSensor = new R_TRIG();
private F_TRIG _bDiffPressureSensorSetting1 = new F_TRIG();
private F_TRIG _bDiffPressureSensorSetting2 = new F_TRIG();
private F_TRIG _bIonizerAlarm = new F_TRIG();
private F_TRIG _bFFuAlarm = new F_TRIG();
private F_TRIG _bAreaSensor = new F_TRIG();
private F_TRIG _bModeSwitch = new F_TRIG();
private RD_TRIG _bCassetteDoorTrig = new RD_TRIG();
private RD_TRIG _bSideDoorTrig = new RD_TRIG();
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");
}
}
}
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;
_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;
//if ((EfemEntity.EfemType)SC.GetValue($"EFEM.EfemType") == EfemEntity.EfemType.BrooksEFEM)
//{
// BrooksProxy = new BrooksEFEMProxy();
// BrooksProxy.CommandUpdated += MsgOnCommandUpdated;
// BrooksProxy.EventUpdated += MsgOnEventUpdated;
// BrooksProxy.ErrorOccurred += MsgOnErrorOccurred;
//}
_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);
Action _subscribeLoc = (ModuleName module, int waferCount) => {
if (ModuleHelper.IsInstalled(module))
{
WaferManager.Instance.SubscribeLocation(module, waferCount);
}
};
_subscribeLoc(ModuleName.EfemRobot, 2);
_subscribeLoc(ModuleName.Aligner1, 1);
_subscribeLoc(ModuleName.Aligner2, 1);
_subscribeLoc(ModuleName.Cooling1, 1);
_subscribeLoc(ModuleName.Cooling2, 1);
_subscribeLoc(ModuleName.LP1, SC.GetValue("EFEM.LoadPort.SlotNumber"));
_subscribeLoc(ModuleName.LP2, SC.GetValue("EFEM.LoadPort.SlotNumber"));
//_subscribeLoc(ModuleName.Flipper, 1);
_subscribeLoc(ModuleName.Buffer, 10);
DATA.Subscribe("EfemRobot.RobotMoveAction", () => _robotMoveInfo);
DATA.Subscribe("LP1.JobDone", () =>
{
return _LPMs[0].JobDone;
});
DATA.Subscribe("LP1.NotifyJobDone", () =>
{
if (!_LPMs[0].JobDone || !_LPMs[0].HasCassette)
return false;
if (SC.GetValue("System.Job.BuzzerTimeWhenJobDone") >= 0
&& _LPMs[0].TimerNotifyJobDone.ElapsedMilliseconds > SC.GetValue("System.Job.BuzzerTimeWhenJobDone") * 1000)
return false;
return _LPMs[0].JobDone;
});
DATA.Subscribe("LP2.JobDone", () =>
{
return _LPMs[1].JobDone;
});
DATA.Subscribe("LP2.NotifyJobDone", () =>
{
if (!_LPMs[1].JobDone || !_LPMs[1].HasCassette)
return false;
if (SC.GetValue("System.Job.BuzzerTimeWhenJobDone") >= 0
&& _LPMs[1].TimerNotifyJobDone.ElapsedMilliseconds > SC.GetValue("System.Job.BuzzerTimeWhenJobDone") * 1000)
return false;
return _LPMs[1].JobDone;
});
Func _waferSize = (ModuleName module, int slot) => {
string sSize = WaferSize.WS12.ToString();
if (ModuleHelper.IsInstalled(module))
{
sSize = WaferManager.Instance.GetWafer(module, slot).Size.ToString();
}
else
{
sSize = WaferSize.WS12.ToString();
}
return sSize;
};
DATA.Subscribe("Aligner1.WaferSize", () => _waferSize(ModuleName.Aligner1, 0));
DATA.Subscribe("Aligner2.WaferSize", () => _waferSize(ModuleName.Aligner2, 0));
DATA.Subscribe("Cooling1.WaferSize", () => _waferSize(ModuleName.Cooling1, 0));
DATA.Subscribe("Cooling2.WaferSize", () => _waferSize(ModuleName.Cooling2, 0));
DATA.Subscribe("EfemRobot.WaferSize", () => _waferSize(ModuleName.EfemRobot, 0));
DATA.Subscribe("Buffer.WaferSize", () => _waferSize(ModuleName.Buffer, 0));
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 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 void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
{
_robotMoveInfo.Action = action;
_robotMoveInfo.ArmTarget = hand == Hand.Blade1 ? RobotArm.ArmA : (hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
_robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{target}";
}
public bool Pick(MoveParam mp)
{
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 (ModuleHelper.IsPm(mp.SrcModule))
{
JetPM pM = GetPM(mp.SrcModule);
if (pM.IsSlitDoorClosed)
{
EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
return false;
}
AddAction(new PinAction(mp.SrcModule, pM, MovementPosition.Up, false, mp.Arm, true));
AddAction(new ExtendAction(this, new ExtendParam { Module = mp.SrcModule, Arm = mp.Arm, Pos = ExtendPos.GB }));
AddAction(new PinAction(mp.SrcModule, pM, MovementPosition.Down, true, mp.Arm, true));
AddAction(new ExtendAction(this, new ExtendParam { Module = mp.SrcModule, Arm = mp.Arm, Pos = ExtendPos.G4 }));
}
else
{
SetRobotMovingInfo(RobotAction.Picking, mp.Arm, mp.SrcModule);
AddAction(new PickAction(this, mp));
}
return true;
}
public bool Place(MoveParam mp)
{
if (ModuleHelper.IsPm(mp.DestModule))
{
JetPM pM = GetPM(mp.DestModule);
if (pM.IsSlitDoorClosed)
{
EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
return false;
}
AddAction(new ExtendAction(this, new ExtendParam { Module = mp.DestModule, Arm = mp.Arm, Pos = ExtendPos.PB }));
AddAction(new PinAction(mp.DestModule, pM, MovementPosition.Up, true, mp.Arm, false));
AddAction(new ExtendAction(this, new ExtendParam { Module = mp.DestModule, Arm = mp.Arm, Pos = ExtendPos.P4 }));
AddAction(new PinAction(mp.DestModule, pM, MovementPosition.Up, false, mp.Arm, false));
}
else
{
SetRobotMovingInfo(RobotAction.Placing, mp.Arm, mp.DestModule);
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);
if (pM.IsSlitDoorClosed)
{
EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
return;
}
AddAction(new PinAction(pickParam.SrcModule, pM, MovementPosition.Up, false, pickParam.Arm, true));
AddAction(new ExtendAction(this, new ExtendParam { Module = pickParam.SrcModule, Arm = pickParam.Arm, Pos = ExtendPos.GB }));
AddAction(new PinAction(pickParam.SrcModule, pM, MovementPosition.Down, true, pickParam.Arm, true));
AddAction(new ExtendAction(this, new ExtendParam { Module = pickParam.SrcModule, Arm = pickParam.Arm, Pos = ExtendPos.G4 }));
AddAction(new ExtendAction(this, new ExtendParam { Module = placeParam.DestModule, Arm = placeParam.Arm, Pos = ExtendPos.PB }));
AddAction(new PinAction(placeParam.DestModule, pM, MovementPosition.Up, true, placeParam.Arm, false));
AddAction(new ExtendAction(this, new ExtendParam { Module = placeParam.DestModule, Arm = placeParam.Arm, Pos = ExtendPos.P4 }));
AddAction(new PinAction(placeParam.DestModule, pM, MovementPosition.Up, false, placeParam.Arm, false));
}
else
{
SetRobotMovingInfo(RobotAction.Picking, pickParam.Arm, pickParam.SrcModule);
AddAction(new PickAction(this, pickParam));
SetRobotMovingInfo(RobotAction.Placing, placeParam.Arm, placeParam.DestModule);
AddAction(new PlaceAction(this, placeParam));
}
}
public bool Extend(ExtendParam ep)
{
AddAction(new ExtendAction(this, 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, 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;
}
_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)
{
if ((EfemEntity.EfemType)SC.GetValue($"EFEM.EfemType") == EfemEntity.EfemType.BrooksEFEM)
return true;
AddAction(new LiftAction(this, mod, false));
return true;
}
public bool Align(ModuleName mod, float delayTime, Aitex.Core.Common.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
_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[15] ? LidState.Close : LidState.Open; // bit 15
// 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
{
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
{
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)
{
//EV.PostAlarmLog(arg.Module.ToString(), $"NO activated {arg.CommandType} in the queue");
LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"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.PostMsg(EfemEntity.MSG.LiftActionDone, arg.CommandType);
}
}
else if (ModuleHelper.IsLoadPort(mod))
{
Singleton.Instance.EFEM.NotifyLP(mod, LoadportEntity.MSG.ActionDone);
}
if(arg.CommandType == EfemOperation.Pick || arg.CommandType == EfemOperation.Place)
SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.System);
action.OnPostWork(arg.Data);
LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"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(eEvent.EV_EFEM_COMMON_INFO, Module, $"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.ActionDone, arg.CommandType);
}
}
else if (ModuleHelper.IsLoadPort(mod))
{
Singleton.Instance.EFEM.NotifyLPError(mod );
}
LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"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}]");
}
}
}