using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.Utilities; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.ModuleLibrary.VceModules; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using Venus_Core; using Venus_RT.Devices; using Venus_RT.Devices.SMIF; using Venus_RT.Devices.TM; using Venus_RT.Devices.VCE; using Venus_RT.Modules.PMs; using Venus_RT.Modules.TM; using Venus_RT.Modules.TM.VenusEntity; namespace Venus_RT.Modules.VCE { #region 状态和消息 public enum VceMSG { Home, Error, DoorOpen, DoorClose, Map, ReadMap, Load, UnLoad, LoadPrepare, LoadWithSMIF, UnLoadWithSMIF, Reset, Goto, GotoLP, CheckStatus, SafeLoad, SafeUnload, Pump, Vent, LeakCheck, Abort, None, ClearError } #endregion public static class VCE2LP { public static Dictionary dVce2LP = new Dictionary() { {ModuleName.LP1,ModuleName.VCEA}, {ModuleName.LP2,ModuleName.VCEB}, }; public static Dictionary sVce2LP = new Dictionary() { {ModuleName.LP1,ModuleName.VCE1}, }; public static Dictionary LP2Vce = new Dictionary(); public static ModuleName QueryLP2VCE(ModuleName lpname) { switch (Singleton.Instance.seTM.Module) { case ModuleName.SETM: if (sVce2LP.ContainsKey(lpname)) { return sVce2LP[lpname]; } else return ModuleName.System; case ModuleName.DETM: if (dVce2LP.ContainsKey(lpname)) { return dVce2LP[lpname]; } else return ModuleName.System; default: return ModuleName.System; } } } public class VceEntity : Entity, IEntity, IModuleEntity { private ModuleName _modulename; private readonly VCEModuleBase _vce; private readonly ISMIF _smif; private bool _CassetteArrive; private bool _IsOnline = false; public bool IsOnline => _IsOnline; public bool IsIdle => fsm.State == (int)VceSTATE.Idle; public bool IsInit => fsm.State == (int)VceSTATE.Init || fsm.State == (int)VceSTATE.Unknown; public bool IsBusy => !IsInit && !IsError && !IsIdle; public bool IsError => fsm.State == (int)VceSTATE.Error; public bool VCEOutDoorClosed => !_vce.OutDoorIsOpen; public bool CassetteArrive => _CassetteArrive; public int CurrentSlot => _vce.CurrentSlot; public int MoveSlot => moveSlot; public VCEModuleBase VCEDevice => _vce; //public int CurrentSlot => currentSlot; private int targetSlot = -1; private int moveSlot = -1; private VCEHomeRoutine _homeRoutine; private LoadRoutine _loadRoutine; private LoadPrepareRoutine _prepareRoutine; private UnloadRoutine _unloadRoutine; private LoadWithSMIFRoutine _loadwithSMIFRoutine; private UnloadWithSMIFRoutine _unloadwithSMIFRoutine; private readonly SEMFPumpRoutine _pumpRoutine; private readonly SEMFVentRoutine _ventRoutine; private readonly SEMFLeakCheckRoutine _leakcheckRoutine; public VceEntity(ModuleName moduleName) { _modulename = moduleName; _vce = new HongHuVce(25, _modulename); _smif = new FortrendPLUS500(_modulename); _homeRoutine = new VCEHomeRoutine(_modulename, _vce); _loadRoutine = new LoadRoutine(_modulename, _vce); _unloadRoutine = new UnloadRoutine(_modulename, _vce); _loadwithSMIFRoutine = new LoadWithSMIFRoutine(_modulename, _vce, _smif); _unloadwithSMIFRoutine = new UnloadWithSMIFRoutine(_modulename, _vce, _smif); if (moduleName == ModuleName.VCE1) { _pumpRoutine = new SEMFPumpRoutine(DEVICE.GetDevice("SETM"), _modulename); _ventRoutine = new SEMFVentRoutine(DEVICE.GetDevice("SETM"), _modulename); _leakcheckRoutine = new SEMFLeakCheckRoutine(DEVICE.GetDevice("SETM"),_modulename); _prepareRoutine = new LoadPrepareRoutine(_modulename, _vce, DEVICE.GetDevice("SETM")); } else { _pumpRoutine = new SEMFPumpRoutine(DEVICE.GetDevice("DETM"), _modulename); _ventRoutine = new SEMFVentRoutine(DEVICE.GetDevice("DETM"), _modulename); _leakcheckRoutine = new SEMFLeakCheckRoutine(DEVICE.GetDevice("DETM"), _modulename); _prepareRoutine = new LoadPrepareRoutine(_modulename, _vce, DEVICE.GetDevice("DETM")); } InitFsmMap(); } protected override bool Init() { DATA.Subscribe($"{_modulename}.VCEOutDoorClosed", () => !VCEOutDoorClosed); DATA.Subscribe($"{_modulename}.CurrentSlot", () => CurrentSlot); DATA.Subscribe($"{_modulename}.FsmState", () => ((VceSTATE)fsm.State).ToString()); DATA.Subscribe($"{_modulename}.CassetteArrive", () => CassetteArrive); DATA.Subscribe($"{_modulename}.IsOnline", () => IsOnline, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{_modulename}.IsOffline", () => !IsOnline, SubscriptionAttribute.FLAG.IgnoreSaveDB); OP.Subscribe($"{_modulename}.HOME", (cmd, args) => { PostMsg(VceMSG.Home); return true; }); OP.Subscribe($"{_modulename}.DoorOpen", (cmd, args) => { PostMsg(VceMSG.DoorOpen); return true; }); OP.Subscribe($"{_modulename}.DoorClose", (cmd, args) => { PostMsg(VceMSG.DoorClose); return true; }); OP.Subscribe($"{_modulename}.Map", (cmd, args) => { PostMsg(VceMSG.Map); return true; }); OP.Subscribe($"{_modulename}.ReadMap", (cmd, args) => { PostMsg(VceMSG.ReadMap); return true; }); OP.Subscribe($"{_modulename}.Load", (cmd, args) => { PostMsg(VceMSG.Load); return true; }); OP.Subscribe($"{_modulename}.UnLoad", (cmd, args) => { PostMsg(VceMSG.UnLoad); return true; }); OP.Subscribe($"{_modulename}.Reset", (cmd, args) => { PostMsg(VceMSG.Reset); return true; }); OP.Subscribe($"{_modulename}.Goto", (cmd, args) => { PostMsg(VceMSG.Goto, args[0]); return true; }); OP.Subscribe($"{_modulename}.GotoLP", (cmd, args) => { PostMsg(VceMSG.GotoLP); return true; }); OP.Subscribe($"{_modulename}.Abort", (cmd, args) => { PostMsg(VceMSG.Abort); return true; }); OP.Subscribe($"{_modulename}.PumpDown", (cmd, args) => { PostMsg(VceMSG.Pump); return true; }); OP.Subscribe($"{_modulename}.Vent", (cmd, args) => { PostMsg(VceMSG.Vent); return true; }); OP.Subscribe($"{_modulename}.LeakCheck", (cmd, args) => { PostMsg(VceMSG.LeakCheck); return true; }); OP.Subscribe($"{_modulename}.ClearError", (cmd, args) => { PostMsg(VceMSG.ClearError); return true; }); OP.Subscribe($"{_modulename}.LoadPrepare", (cmd, args) => { PostMsg(VceMSG.LoadPrepare); return true; }); OP.Subscribe($"{_modulename}.SafeLoad", (cmd, args) => { PostMsg(VceMSG.SafeLoad); return true; }); OP.Subscribe($"{_modulename}.SafeUnload", (cmd, args) => { PostMsg(VceMSG.SafeUnload); return true; }); OP.Subscribe($"{_modulename}.LoadWithSMIF", (cmd, args) => { PostMsg(VceMSG.LoadWithSMIF); return true; }); OP.Subscribe($"{_modulename}.UnLoadWithSMIF", (cmd, args) => { PostMsg(VceMSG.UnLoadWithSMIF); return true; }); OP.Subscribe($"{_modulename}.Online", (cmd, args) => { if (IsIdle) _IsOnline = true; else LOG.Write(eEvent.WARN_TM, _modulename, $"cannot Set Online as {_modulename} is not idle"); return true; }); OP.Subscribe($"{_modulename}.Offline", (cmd, args) => { _IsOnline = false; return true; }); return true; } /// /// 定义状态机的迁移表 /// private void InitFsmMap() { fsm = new StateMachine(_modulename.ToString(), (int)VceSTATE.Init, 50); fsm.EnableRepeatedMsg(true); AnyStateTransition(VceMSG.Error, fnError, VceSTATE.Error); //AnyStateTransition(VceMSG.Abort, fnAbort, VceSTATE.Init); AnyStateTransition(VceMSG.Home, fnStartHome, VceSTATE.Homing); AnyStateTransition(VceMSG.DoorOpen, fnStartOpenDoor, VceSTATE.DoorOpenning); //HOME init->homing idle->homing Transition(VceSTATE.Init, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Idle, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Error, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Homing, FSM_MSG.TIMER, fnHomeTimeout, VceSTATE.Idle); Transition(VceSTATE.Homing, VceMSG.Abort, fnAbort, VceSTATE.Init); //clear Error Transition(VceSTATE.Error, VceMSG.ClearError, fnStartClearError,VceSTATE.ClearError); Transition(VceSTATE.ClearError, FSM_MSG.TIMER, fnClearErrorTimeout, VceSTATE.Idle); //Open Door 开门 Transition(VceSTATE.Idle, VceMSG.DoorOpen, fnStartOpenDoor, VceSTATE.DoorOpenning); Transition(VceSTATE.DoorOpenning, FSM_MSG.TIMER, fnOpenDoorTimeout, VceSTATE.Idle); Transition(VceSTATE.DoorOpenning, VceMSG.Abort, fnAbort, VceSTATE.Idle); //Close Door 关门 Transition(VceSTATE.Idle, VceMSG.DoorClose, fnStartCloseDoor, VceSTATE.DoorClosing); Transition(VceSTATE.DoorClosing, FSM_MSG.TIMER, fnCloseDoorTimeout, VceSTATE.Idle); Transition(VceSTATE.DoorClosing, VceMSG.Abort, fnAbort, VceSTATE.Idle); //Map 扫片 Transition(VceSTATE.Idle, VceMSG.Map, fnStartMapping, VceSTATE.Mapping); Transition(VceSTATE.Mapping, FSM_MSG.TIMER, fnMappingTimeout, VceSTATE.Idle); Transition(VceSTATE.Mapping, VceMSG.Abort, fnAbort, VceSTATE.Idle); //Load 取cassette Transition(VceSTATE.Idle, VceMSG.Load, fnStartLoading, VceSTATE.Loading); Transition(VceSTATE.Loading, FSM_MSG.TIMER, fnLoadingTimeout, VceSTATE.Idle); Transition(VceSTATE.Loading, VceMSG.Abort, fnAbort, VceSTATE.Idle); //UnLoad 放cassette Transition(VceSTATE.Idle, VceMSG.UnLoad, fnStartUnLoading, VceSTATE.UnLoading); Transition(VceSTATE.UnLoading, FSM_MSG.TIMER, fnUnLoadingTimeout, VceSTATE.Idle); Transition(VceSTATE.UnLoading, VceMSG.Abort, fnAbort, VceSTATE.Idle); //Goto 指定槽对准窗口 Transition(VceSTATE.Idle, VceMSG.Goto, fnStartGoto, VceSTATE.Goting); Transition(VceSTATE.Goting, FSM_MSG.TIMER, fnGotingTimeout, VceSTATE.Idle); Transition(VceSTATE.Goting, VceMSG.Abort, fnAbort, VceSTATE.Idle); //ReadMap Transition(VceSTATE.Idle, VceMSG.ReadMap, fnStartReadingMap, VceSTATE.ReadingMap); Transition(VceSTATE.ReadingMap, FSM_MSG.TIMER, fnReadingMapTimeout, VceSTATE.Idle); Transition(VceSTATE.ReadingMap, VceMSG.Abort, fnAbort, VceSTATE.Idle); //Load Prepare Transition(VceSTATE.Idle, VceMSG.LoadPrepare, fnStartLoadPrepare, VceSTATE.LoadPreparing); Transition(VceSTATE.LoadPreparing, FSM_MSG.TIMER, fnLoadingPrepareTimeout, VceSTATE.Idle); Transition(VceSTATE.LoadPreparing, VceMSG.Abort, fnLoadingPrepareAbort, VceSTATE.Idle); //Safe Load Transition(VceSTATE.Idle, VceMSG.SafeLoad, fnStartSafeLoad, VceSTATE.SafeLoading); Transition(VceSTATE.SafeLoading, FSM_MSG.TIMER, fnSafeLoadTimeout, VceSTATE.Idle); Transition(VceSTATE.SafeLoading, VceMSG.Abort, fnSafeLoadAbort, VceSTATE.Idle); //LoadWithSMIF => LoadPrepare & SMIF Load & Load Transition(VceSTATE.Idle, VceMSG.LoadWithSMIF, fnStartLoadWithSMIF, VceSTATE.LoadingWithSMIF); Transition(VceSTATE.LoadingWithSMIF, FSM_MSG.TIMER, fnLoadWithSMIFTimeout, VceSTATE.Idle); Transition(VceSTATE.LoadingWithSMIF, VceMSG.Abort, fnLoadWithSMIFAbort, VceSTATE.Idle); //Safe UnLoad Transition(VceSTATE.Idle, VceMSG.SafeUnload, fnStartSafeUnLoad, VceSTATE.SafeUnloading); Transition(VceSTATE.SafeUnloading, FSM_MSG.TIMER, fnSafeUnLoadTimeout, VceSTATE.Idle); Transition(VceSTATE.SafeUnloading, VceMSG.Abort, fnSafeUnLoadAbort, VceSTATE.Idle); //UnLoad With SMIF => UnLoad with smif Transition(VceSTATE.Idle, VceMSG.UnLoadWithSMIF, fnStartUnLoadWithSMIF, VceSTATE.UnLoadingWithSMIF); Transition(VceSTATE.UnLoadingWithSMIF, FSM_MSG.TIMER, fnUnLoadWithSMIFTimeout, VceSTATE.Idle); Transition(VceSTATE.UnLoadingWithSMIF, VceMSG.Abort, fnUnLoadWithSMIFAbort, VceSTATE.Idle); //Goto LP Transition(VceSTATE.Idle, VceMSG.GotoLP, fnStartGotoLP, VceSTATE.GotingLP); Transition(VceSTATE.GotingLP, FSM_MSG.TIMER, fnGotoLPTimeout, VceSTATE.Idle); Transition(VceSTATE.GotingLP, VceMSG.Abort, fnAbort, VceSTATE.Idle); //CheckStatus Transition(VceSTATE.Idle, VceMSG.CheckStatus, fnStartCheckStatus, VceSTATE.CheckStatus); Transition(VceSTATE.CheckStatus, FSM_MSG.TIMER, fnCheckStatusTimeout, VceSTATE.Idle); Transition(VceSTATE.CheckStatus, VceMSG.Abort, fnAbort, VceSTATE.Idle); //Pump Transition(VceSTATE.Idle, VceMSG.Pump, fnStartPump, VceSTATE.Pumping); Transition(VceSTATE.Pumping, FSM_MSG.TIMER, fnPumpTimeout, VceSTATE.Idle); Transition(VceSTATE.Pumping, VceMSG.Abort, fnAbortPump, VceSTATE.Idle); //Vent Transition(VceSTATE.Idle, VceMSG.Vent, fnStartVent, VceSTATE.Venting); Transition(VceSTATE.Venting, FSM_MSG.TIMER, fnVentTimeout, VceSTATE.Idle); Transition(VceSTATE.Venting, VceMSG.Abort, fnAbortVent, VceSTATE.Idle); //LeakCheck Transition(VceSTATE.Idle, VceMSG.LeakCheck, FnStartLeakCheck, VceSTATE.LeakChecking); Transition(VceSTATE.LeakChecking, FSM_MSG.TIMER, FnLeakCheckTimeout, VceSTATE.Idle); Transition(VceSTATE.LeakChecking, VceMSG.Abort, FnAbortLeakCheck, VceSTATE.Idle); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); Running = true; } private bool fnAbortVent(object[] param) { _ventRoutine.Abort(); return true; } private bool fnVentTimeout(object[] param) { RState ret = _ventRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartVent(object[] param) { return _ventRoutine.Start(param) == RState.Running; } private bool FnStartLeakCheck(object[] param) { return _leakcheckRoutine.Start(param) == RState.Running; } private bool FnLeakCheckTimeout(object[] param) { RState ret = _leakcheckRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool FnAbortLeakCheck(object[] param) { _leakcheckRoutine.Abort(); return true; } private bool fnAbortPump(object[] param) { _pumpRoutine.Abort(); return true; } private bool fnPumpTimeout(object[] param) { RState ret = _pumpRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartPump(object[] param) { return _pumpRoutine.Start(param) == RState.Running; } private bool fnGotoLPTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (_vce.Status == RState.End) { moveSlot = -1; } return _vce.Status == RState.End; } private bool fnStartCheckStatus(object[] param) { return _vce.CheckStatus(); } private bool fnCheckStatusTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartGotoLP(object[] param) { if (_vce.GotoLP()) { targetSlot = -1; return true; } else return false; } private bool fnSafeUnLoadAbort(object[] param) { _unloadRoutine.Abort(); return true; } private bool fnSafeUnLoadTimeout(object[] param) { RState ret = _unloadRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = false; WaferManager.Instance.DeleteWafer(_modulename, 0, 25); } return ret == RState.End; } private bool fnStartClearError(object[] param) { if (_vce.ClearError()) { return true; } else return false; } private bool fnClearErrorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartSafeUnLoad(object[] param) { return _unloadRoutine.Start(param) == RState.Running; } private bool fnSafeLoadTimeout(object[] param) { RState ret = _loadRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = true; } return ret == RState.End; } private bool fnStartLoadWithSMIF(object[] param) { return _loadwithSMIFRoutine.Start(param) == RState.Running; } private bool fnLoadWithSMIFAbort(object[] param) { _loadwithSMIFRoutine.Abort(); return true; } private bool fnLoadWithSMIFTimeout(object[] param) { RState ret = _loadwithSMIFRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = true; } return ret == RState.End; } private bool fnStartUnLoadWithSMIF(object[] param) { return _unloadwithSMIFRoutine.Start(param) == RState.Running; } private bool fnUnLoadWithSMIFAbort(object[] param) { _unloadwithSMIFRoutine.Abort(); return true; } private bool fnUnLoadWithSMIFTimeout(object[] param) { RState ret = _unloadwithSMIFRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = false; WaferManager.Instance.DeleteWafer(_modulename, 0, 25); } return ret == RState.End; } private bool fnStartSafeLoad(object[] param) { return _loadRoutine.Start(param) == RState.Running; } private bool fnSafeLoadAbort(object[] param) { _loadRoutine.Abort(); return true; } private bool fnLoadingPrepareAbort(object[] param) { _prepareRoutine.Abort(); return true; } private bool fnLoadingPrepareTimeout(object[] param) { RState ret = _prepareRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartLoadPrepare(object[] param) { return _prepareRoutine.Start(param) == RState.Running; } private bool fnReadingMapTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartReadingMap(object[] param) { return _vce.ReadMap(); } //急停 private bool fnAbort(object[] param) { return true; } //升降到槽位 private bool fnStartGoto(object[] param) { if (_vce.Goto(Convert.ToInt32(param[0].ToString()))) { targetSlot = Convert.ToInt32(param[0]); return true; } else return false; } private bool fnGotingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (_vce.Status == RState.End) { moveSlot = targetSlot; } return _vce.Status == RState.End; } private bool fnError(object[] param) { return true; } private bool fnStartHome(object[] param) { return _homeRoutine.Start(param) == RState.Running; } private bool fnHomeTimeout(object[] param) { RState ret = _homeRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { moveSlot = -1; } return ret == RState.End; } private bool fnStartOpenDoor(object[] param) { //卡压差 if (Singleton.Instance.seTM.VCEIsATM(_modulename) && Singleton.Instance.seTM.VCEPressure(_modulename) >= SC.GetValue($"{_modulename}.OutDoorOpenPressure")) { //卡状态 if (IsIdle || IsError && _vce.IsDashWaferError) return _vce.OpenDoor(); else { LOG.Write(eEvent.WARN_VCE_COMMON_WARN,_modulename,$"Current Status is {(VceSTATE)fsm.State} && not Dash Wafer Error Cannot Open Door."); return false; } } else { LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _modulename, $"{_modulename} is not ATM or Pressure not arrive {SC.GetValue($"{_modulename}.OutDoorOpenPressure")}"); return false; } } private bool fnOpenDoorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartCloseDoor(object[] param) { return _vce.CloseDoor(); } private bool fnCloseDoorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartMapping(object[] param) { return _vce.Map(); } private bool fnMappingTimeout(object[] param) { if(_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartLoading(object[] param) { return _vce.Load(); } private bool fnLoadingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartUnLoading(object[] param) { return _vce.UnLoad(); } private bool fnUnLoadingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } public bool Check(int msg, out string reason, params object[] args) { reason = ""; return true; } public int Invoke(string function, params object[] args) { switch (function) { case "Home": CheckToPostMessage((int)VceMSG.Home); return (int)VceMSG.Home; } return (int)VceMSG.None; } public bool CheckToPostMessage(int msg, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { LOG.Write(eEvent.WARN_FSM_WARN, _modulename, $"{_modulename} is in {(VceSTATE)fsm.State} state,can not do {(VceMSG)msg}"); return false; } Running = true; fsm.PostMsg(msg, args); return true; } public bool CheckAcked(int msg) { return fsm.CheckExecuted(msg); } public bool IsPrepareTransferReady(ModuleName module, EnumTransferType transferType, int slot) { return false; } } }