PMEntity.cs 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Diagnostics;
  5. using Aitex.Core.Common;
  6. using Aitex.Core.RT.DataCenter;
  7. using Aitex.Core.RT.Device;
  8. using Aitex.Core.RT.Event;
  9. using Aitex.Core.RT.Fsm;
  10. using Aitex.Core.RT.OperationCenter;
  11. using Aitex.Core.RT.Routine;
  12. using Aitex.Core.RT.SCCore;
  13. using Aitex.Core.Util;
  14. using Aitex.RT.Device.Custom;
  15. using Aitex.Sorter.Common;
  16. using MECF.Framework.Common.DataCenter;
  17. using MECF.Framework.Common.Equipment;
  18. using MECF.Framework.Common.Schedulers;
  19. using MECF.Framework.Common.SubstrateTrackings;
  20. using VirgoCommon;
  21. using VirgoRT.Devices;
  22. using VirgoRT.Modules;
  23. using VirgoRT.Modules.PMs;
  24. namespace VirgoRT.Module
  25. {
  26. public class RecipeRunningInfo
  27. {
  28. public Guid InnerId { get; set; }
  29. public RecipeHead Head { get; set; }
  30. public List<RecipeStep> RecipeStepList { get; set; }
  31. public string RecipeName { get; set; }
  32. public DateTime BeginTime { get; set; }
  33. public DateTime EndTime { get; set; }
  34. public int StepNumber { get; set; }
  35. public string StepName { get; set; }
  36. public double StepTime { get; set; }
  37. public double StepElapseTime { get; set; }
  38. public double TotalTime { get; set; }
  39. public double TotalElapseTime { get; set; }
  40. }
  41. public class PMEntity : Entity, IModuleEntity
  42. {
  43. public enum MSG
  44. {
  45. Home,
  46. Transfer,
  47. PrepareTransfer,
  48. PostTransfer,
  49. Reset,
  50. Abort,
  51. Error,
  52. LaunchPump,
  53. Pump,
  54. Vent,
  55. CyclePurge,
  56. Heat,
  57. TransferHandoff,
  58. StartTransfer,
  59. LeakCheck,
  60. DeleteLeakCheck,
  61. MoveLiftPin,
  62. WaitLiftpin,
  63. MoveGuidePin,
  64. MFCVerification,
  65. AllMFCVerification,
  66. Clean,
  67. CleanReady,
  68. Process,
  69. RunRecipe,
  70. PostProcess,
  71. RecipeSkipStep,
  72. RecipeUpdate,
  73. RecipeResume,
  74. RecipePause,
  75. RecipeAbort,
  76. PreProcess,
  77. AutoMode,
  78. ManualMode,
  79. LockLid,
  80. Online,
  81. Offline,
  82. GasFlow,
  83. StopGasFlow,
  84. RfPower,
  85. MaxMsg
  86. }
  87. // ----------------------------Fields--------------------------
  88. //
  89. private int _bigWafer = 0;
  90. private int _midWafer = 0;
  91. private int _smallWafer = 0;
  92. private bool _enableBias;
  93. private int _liftpinDelayTime = 0;
  94. private StatsDataItem _statProcessedWafer;
  95. private StatsDataItemRFAndPump _statRfOnTime;
  96. private StatsDataItemRFAndPump _statBiasRfOnTime;
  97. private StatsDataItemRFAndPump _statPumpOnTime;
  98. private readonly JetPM _chamber;
  99. private string _processStatus;
  100. private DateTime _recipeStartTime;
  101. //routine
  102. private readonly VentRoutine _ventRoutine;
  103. private readonly PumpDownRoutine _pumpRoutine;
  104. private readonly StartPumpRoutine _startPumpRoutine;
  105. private readonly TemperatureControlRoutine _temperatureControlRoutine;
  106. private readonly GasFlowRoutine _gasFlowRoutine;
  107. private readonly RfPowerRoutine _rfPowerRoutine;
  108. private readonly CyclePurgeRoutine _cyclePurgeRoutine;
  109. private readonly CleanRoutine _cleanRoutine;
  110. private readonly ProcessRoutine _processRoutine;
  111. private readonly PreProcessRoutine _preProcessRoutine;
  112. private readonly PostProcessRoutine _postProcessRoutine;
  113. private readonly LeakCheckRoutine _leakCheckRoutine;
  114. private readonly PMPrepareTransferRoutine _prepareTrans;
  115. private readonly PMPostTransferRoutine _postTrans;
  116. private readonly PMHomeRoutine _home;
  117. private readonly PMMfcVerificationRoutine _mfcVerification;
  118. private readonly PMAllMfcVerificationRoutine _allMfcVerification;
  119. private AutoFlag _AutoMode;
  120. private bool _isOnline;
  121. private bool _isAlarm;
  122. private DateTime _pumpStartTime;
  123. private TimeSpan _pumpElapsedTime;
  124. private DateTime _rfStartTime;
  125. private DateTime _tcStartTime;
  126. private TimeSpan _rfElapsedTime;
  127. private TimeSpan _tcElapsedTime;
  128. private MovementPosition _goalLiftPin;
  129. private ushort _ActivatedActionID;
  130. private Stopwatch _LifpinSleepTimer;
  131. private bool _EnableResetChamberError;
  132. // --------------------------Properties------------------------
  133. //
  134. public ModuleName Module { get; }
  135. public Action<bool, bool> TransferPrepared;
  136. public bool IsIdle
  137. {
  138. get { return fsm.State == (int)PMState.Idle; }
  139. }
  140. public bool IsError
  141. {
  142. get { return fsm.State == (int)PMState.Error; }
  143. }
  144. public bool IsAutoMode => _AutoMode == AutoFlag.Auto;
  145. public RecipeRunningInfo RecipeRunningInfo
  146. {
  147. get
  148. {
  149. return _recipeRunningInfo;
  150. }
  151. }
  152. public int Invoke(string function, params object[] args)
  153. {
  154. switch (function)
  155. {
  156. case "Home":
  157. CheckToPostMessage((int)MSG.Home);
  158. return (int)MSG.Home;
  159. }
  160. return (int)FSM_MSG.NONE;
  161. }
  162. public bool CheckAcked(int msg)
  163. {
  164. return fsm.CheckExecuted(msg);
  165. }
  166. public bool IsInit
  167. {
  168. get { return fsm.State == (int)PMState.Init; }
  169. }
  170. public bool IsBusy
  171. {
  172. get { return !IsInit && !IsError && !IsIdle; }
  173. }
  174. public bool IsProcessing
  175. {
  176. get { return fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess ; }
  177. }
  178. private DateTime _leakCheckStartTime;
  179. private TimeSpan _leakCheckElapsedTime;
  180. private string LeakCheckElapseTime
  181. {
  182. get
  183. {
  184. if ((fsm.State == (int)PMState.LeakCheck))
  185. _leakCheckElapsedTime = DateTime.Now - _leakCheckStartTime;
  186. return string.Format("{0}:{1}:{2}", ((int)_leakCheckElapsedTime.TotalHours).ToString("00"),
  187. _leakCheckElapsedTime.Minutes.ToString("00"), _leakCheckElapsedTime.Seconds.ToString("00"));
  188. }
  189. }
  190. private string PumpTime
  191. {
  192. get
  193. {
  194. if ((fsm.State == (int)PMState.Pumping) || (fsm.State == (int)PMState.PreProcess))
  195. _pumpElapsedTime = DateTime.Now - _pumpStartTime;
  196. return string.Format("{0}:{1}:{2}", ((int)_pumpElapsedTime.TotalHours).ToString("00"),
  197. _pumpElapsedTime.Minutes.ToString("00"), _pumpElapsedTime.Seconds.ToString("00"));
  198. }
  199. }
  200. private int StepNo
  201. {
  202. get
  203. {
  204. if ( (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))
  205. {
  206. return _processRoutine.CurStepNum + 1;
  207. }
  208. return 0;
  209. }
  210. }
  211. private int RecipeSteps
  212. {
  213. get
  214. {
  215. if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))
  216. {
  217. return _preProcessRoutine.CurrentRecipeStepList.Count;
  218. }
  219. return 0;
  220. }
  221. }
  222. private string RecipeStepName
  223. {
  224. get
  225. {
  226. if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))
  227. {
  228. return _processRoutine.CurStepComment;
  229. }
  230. return null;
  231. }
  232. }
  233. private double LeakRate
  234. {
  235. get { return _leakCheckRoutine.LeakRate; }
  236. }
  237. private string RecipeName
  238. {
  239. get
  240. {
  241. if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))
  242. {
  243. return _preProcessRoutine.CurrentRecipeRunningName.Split('\\')[1];
  244. }
  245. return null;
  246. }
  247. }
  248. private string RFTime
  249. {
  250. get
  251. {
  252. if (fsm.State == (int)PMState.RfPowering)
  253. _rfElapsedTime = DateTime.Now - _rfStartTime;
  254. return $"{((int)_rfElapsedTime.TotalHours).ToString("00")}:{_rfElapsedTime.Minutes.ToString("00")}:{_rfElapsedTime.Seconds.ToString("00")}";
  255. }
  256. }
  257. private string TCTime
  258. {
  259. get
  260. {
  261. if (fsm.State == (int)PMState.Heating)
  262. _tcElapsedTime = DateTime.Now - _tcStartTime;
  263. return $"{((int)_tcElapsedTime.TotalHours).ToString("00")}:{_tcElapsedTime.Minutes.ToString("00")}:{_tcElapsedTime.Seconds.ToString("00")}";
  264. }
  265. }
  266. private TimeSpan _recipeElapsedTime;
  267. public string RecipeElapsedTime
  268. {
  269. get
  270. {
  271. if (fsm.State == (int)PMState.LoadProcessRecipe || fsm.State == (int)PMState.PreProcess
  272. || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess)
  273. _recipeElapsedTime = DateTime.Now - _recipeStartTime;
  274. return string.Format("{0}:{1}:{2}", ((int)_recipeElapsedTime.TotalHours).ToString("00"),
  275. _recipeElapsedTime.Minutes.ToString("00"), _recipeElapsedTime.Seconds.ToString("00"));
  276. }
  277. }
  278. public double RecipeTotalElapsedSeconds
  279. {
  280. get
  281. {
  282. if (fsm.State == (int)PMState.LoadProcessRecipe || fsm.State == (int)PMState.PreProcess
  283. || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess)
  284. _recipeElapsedTime = DateTime.Now - _recipeStartTime;
  285. return _recipeElapsedTime.TotalSeconds;
  286. }
  287. }
  288. public bool IsOnline
  289. {
  290. get { return _isOnline; }
  291. }
  292. private RecipeRunningInfo _recipeRunningInfo = new RecipeRunningInfo();
  293. // --------------------------Constructor-----------------------
  294. //
  295. public PMEntity(ModuleName module)
  296. {
  297. this.Module = module;
  298. //_chamber = new JetPM(ModuleHelper.Converter(Name));
  299. _smallWafer = SC.GetValue<int>($"System.SmallWafer");
  300. _midWafer = SC.GetValue<int>($"System.MidWafer");
  301. _bigWafer = SC.GetValue<int>($"System.BigWafer");
  302. _enableBias = SC.GetValue<bool>($"{Module}.BiasRf.EnableBiasRF");
  303. _EnableResetChamberError = SC.GetValue<bool>($"{Module}.EnableResetError");
  304. _chamber = DEVICE.GetDevice<JetPM>(Module.ToString());
  305. _isAlarm = false;
  306. _LifpinSleepTimer = new Stopwatch();
  307. LeakCheckResultManager.Instance.Initialize(Module.ToString());
  308. fsm = new StateMachine<PMEntity>(Module.ToString(), (int)PMState.Init, 50);
  309. _ventRoutine = new VentRoutine(_chamber);
  310. _pumpRoutine = new PumpDownRoutine(_chamber);
  311. _startPumpRoutine = new StartPumpRoutine(_chamber);
  312. _temperatureControlRoutine = new TemperatureControlRoutine(_chamber);
  313. _prepareTrans = new PMPrepareTransferRoutine(_chamber, _ventRoutine);
  314. _postTrans = new PMPostTransferRoutine(_chamber);
  315. _gasFlowRoutine = new GasFlowRoutine(_chamber);
  316. _rfPowerRoutine = new RfPowerRoutine(_chamber, true);
  317. _cyclePurgeRoutine = new CyclePurgeRoutine(_chamber);
  318. _leakCheckRoutine = new LeakCheckRoutine(_chamber, _pumpRoutine);
  319. _cleanRoutine = new CleanRoutine(_chamber);
  320. _preProcessRoutine = new PreProcessRoutine(_chamber, _pumpRoutine);
  321. _processRoutine = new ProcessRoutine(_chamber, this);
  322. _postProcessRoutine = new PostProcessRoutine(_chamber, _ventRoutine);
  323. _home = new PMHomeRoutine(_chamber);
  324. _mfcVerification = new PMMfcVerificationRoutine(_chamber, _pumpRoutine);
  325. _allMfcVerification = new PMAllMfcVerificationRoutine(_chamber, _pumpRoutine);
  326. //Idle
  327. EnterExitTransition((int)PMState.Idle, FnIdle, (int)FSM_MSG.NONE, null);
  328. EnterExitTransition<PMState, FSM_MSG>(PMState.Error, fEnterError, FSM_MSG.NONE, null);
  329. //Error
  330. Transition(PMState.Init, MSG.Error, FnError, PMState.Error);
  331. Transition(PMState.Error, MSG.Reset, FnReset, PMState.Idle);
  332. AnyStateTransition(FSM_MSG.WARNING, fWarning, FSM_STATE.SAME);
  333. AnyStateTransition((int)FSM_MSG.ALARM, fAlarm, (int)PMState.Error);
  334. AnyStateTransition(MSG.AutoMode, FnSetAuto, FSM_STATE.SAME);
  335. AnyStateTransition(MSG.ManualMode, FnSetManual, FSM_STATE.SAME);
  336. AnyStateTransition(MSG.Online, FnSetOnline, FSM_STATE.SAME);
  337. AnyStateTransition(MSG.Offline, FnSetOffline, FSM_STATE.SAME);
  338. //Home
  339. EnterExitTransition((int)PMState.Homing, FnEnterHome, (int)FSM_MSG.NONE, FnExitHome);
  340. Transition(PMState.Init, MSG.Home, FnStartHome, PMState.Homing);
  341. Transition(PMState.Error, MSG.Home, FnStartHome, PMState.Homing);
  342. Transition(PMState.Idle, MSG.Home, FnStartHome, PMState.Homing);
  343. Transition(PMState.Homing, FSM_MSG.TIMER, FnMonitorHome, PMState.Idle);
  344. Transition(PMState.Homing, MSG.Error, null, PMState.Error);
  345. Transition(PMState.Homing, MSG.Abort, FnAbortTask, PMState.Init);
  346. // Gas Flow sequence
  347. Transition(PMState.Idle, MSG.GasFlow, FnStartGasFlow, PMState.GasFlowing);
  348. Transition(PMState.GasFlowing, MSG.GasFlow, FnStartGasFlow, PMState.GasFlowing);
  349. Transition(PMState.GasFlowing, FSM_MSG.TIMER, FnGasFlowTimeout, PMState.Idle);
  350. Transition(PMState.GasFlowing, MSG.StopGasFlow, FnStopGasFlow, PMState.Idle);
  351. Transition(PMState.GasFlowing, MSG.Abort, FnAbortGasFlow, PMState.Idle);
  352. //RF Power sequence
  353. Transition(PMState.Idle, MSG.RfPower, FnStartRfPower, PMState.RfPowering);
  354. Transition(PMState.GasFlowing, MSG.RfPower, FnStartRfPower, PMState.RfPowering);
  355. Transition(PMState.RfPowering, FSM_MSG.TIMER, FnRfPowerTimeout, PMState.Idle);
  356. Transition(PMState.RfPowering, MSG.Abort, FnAbortRfPower, PMState.Idle);
  357. // Heat substrate
  358. Transition(PMState.Idle, MSG.Heat, FnHeat, PMState.Heating);
  359. Transition(PMState.Heating, FSM_MSG.TIMER, FnHeatTimeout, PMState.Idle);
  360. Transition(PMState.Heating, MSG.Abort, FnAbortHeating, PMState.Idle);
  361. //Launch Pump sequence
  362. Transition(PMState.Idle, MSG.LaunchPump, FnLaunchPump, PMState.LaunchingPump);
  363. Transition(PMState.LaunchingPump, FSM_MSG.TIMER, FnLaunchPumpTimeout, PMState.Idle);
  364. Transition(PMState.LaunchingPump, MSG.Abort, FnAbortStartPumping, PMState.Idle);
  365. //Pump sequence
  366. Transition(PMState.Idle, MSG.Pump, FnStartPumpDown, PMState.Pumping);
  367. Transition(PMState.Venting, MSG.Pump, FnVentToPumping, PMState.Pumping);
  368. Transition(PMState.Pumping, FSM_MSG.TIMER, FnPumpDownTimeout, PMState.Idle);
  369. Transition(PMState.Pumping, MSG.Abort, FnAbortPumping, PMState.Idle);
  370. //vent sequence
  371. Transition(PMState.Idle, MSG.Vent, FnStartVent, PMState.Venting);
  372. Transition(PMState.Pumping, MSG.Vent, FnPumpingToVent, PMState.Venting);
  373. Transition(PMState.Venting, FSM_MSG.TIMER, FnVentTimeout, PMState.Idle);
  374. Transition(PMState.Venting, MSG.Abort, FnAbortVent, PMState.Idle);
  375. // Purge sequence
  376. Transition(PMState.Idle, MSG.CyclePurge, FnStartPurge, PMState.Purging);
  377. Transition(PMState.Purging, FSM_MSG.TIMER, FnPurgeTimeout, PMState.Idle);
  378. Transition(PMState.Purging, MSG.Abort, FnAbortPurge, PMState.Idle);
  379. //Leak check sequence
  380. Transition(PMState.Idle, MSG.LeakCheck, FnStartLeakCheck, PMState.LeakCheck);
  381. Transition(PMState.Idle, MSG.DeleteLeakCheck, FnDeleteLeakCheck, PMState.Idle);
  382. Transition(PMState.LeakCheck, FSM_MSG.TIMER, FnLeakCheckTimeout, PMState.Idle);
  383. Transition(PMState.LeakCheck, MSG.Abort, FnAbortLeakCheck, PMState.Idle);
  384. //MFC verification
  385. Transition(PMState.Idle, MSG.MFCVerification, FnStartMFCVerification, PMState.MFCVerification);
  386. Transition(PMState.MFCVerification, FSM_MSG.TIMER, FnMFCVerificationTimeout, PMState.Idle);
  387. Transition(PMState.MFCVerification, MSG.Abort, FnAbortMFCVerification, PMState.Idle);
  388. //MFC verification
  389. Transition(PMState.Idle, MSG.AllMFCVerification, FnStartAllMFCVerification, PMState.AllMFCVerification);
  390. Transition(PMState.AllMFCVerification, FSM_MSG.TIMER, FnAllMFCVerificationTimeout, PMState.Idle);
  391. Transition(PMState.AllMFCVerification, MSG.Abort, FnAbortAllMFCVerification, PMState.Idle);
  392. // Transfer
  393. Transition(PMState.Idle, MSG.PrepareTransfer, FnStartPrepareTransfer, PMState.PrepareTransfer);
  394. Transition(PMState.PrepareTransfer, FSM_MSG.TIMER, FnPreTransferTimeout, PMState.Idle);
  395. Transition(PMState.PrepareTransfer, MSG.Abort, FnAbortTask, PMState.Idle);
  396. Transition(PMState.Idle, MSG.PostTransfer, FnStartPostTransfer, PMState.PostTransfer);
  397. Transition(PMState.PostTransfer, FSM_MSG.TIMER, FnPostTransferTimeout, PMState.Idle);
  398. Transition(PMState.PostTransfer, MSG.Abort, FnAbortTask, PMState.Idle);
  399. // lift pin
  400. Transition(PMState.Idle, MSG.MoveLiftPin, FnSetLiftpin, PMState.LiftpinMoving);
  401. Transition(PMState.Idle, MSG.WaitLiftpin, null, PMState.LiftpinWaiting);
  402. Transition(PMState.LiftpinWaiting, FSM_MSG.TIMER, FnWaitLiftpinTimeout, PMState.LiftpinMoving);
  403. Transition(PMState.LiftpinMoving, FSM_MSG.TIMER, FnLiftpinTimeout, PMState.Idle);
  404. // guide pin
  405. Transition(PMState.Idle, MSG.MoveGuidePin, FnSetGuidePin, PMState.GuidePinMoving);
  406. Transition(PMState.GuidePinMoving, FSM_MSG.TIMER, FnGuidePinTimeout, PMState.Idle);
  407. // PreClean sequence
  408. Transition(PMState.Idle, MSG.Clean, FnPreClean, PMState.PreClean);
  409. Transition(PMState.PreClean, FSM_MSG.TIMER, FnPreCleanTimeout, PMState.LoadProcessRecipe);
  410. // PreProcess sequence
  411. Transition(PMState.Idle, MSG.RunRecipe, FnProcessLoadRecipe, PMState.LoadProcessRecipe);
  412. Transition(PMState.LoadProcessRecipe, MSG.PreProcess, FnStartPreProcess, PMState.PreProcess);
  413. Transition(PMState.LoadProcessRecipe, MSG.Abort, null, PMState.Idle);
  414. Transition(PMState.LoadProcessRecipe, MSG.Error, null, PMState.Idle);
  415. Transition(PMState.PreProcess, FSM_MSG.TIMER, FnPreProcessTimeout, PMState.PreProcess);
  416. Transition(PMState.PreProcess, MSG.Abort, FnAbortPreProcess, PMState.Idle);
  417. Transition(PMState.PreProcess, MSG.RecipeAbort, FnAbortPreProcess, PMState.Idle);
  418. Transition(PMState.PreProcess, MSG.Error, FnAbortPreProcess, PMState.Error);
  419. // Process
  420. Transition(PMState.PreProcess, MSG.Process, FnStartProcess, PMState.Processing);
  421. Transition(PMState.Processing, FSM_MSG.TIMER, FnProcessTimeout, PMState.Processing);
  422. Transition(PMState.Processing, MSG.Error, FnAbortProcess, PMState.Error);
  423. Transition(PMState.Processing, MSG.RecipeAbort, FnAbortProcess, PMState.PostProcess);
  424. Transition(PMState.Processing, MSG.RecipePause, FnPauseProcess, PMState.Processing);
  425. Transition(PMState.Processing, MSG.RecipeResume, FnResumeRecipe, PMState.Processing);
  426. Transition(PMState.Processing, MSG.RecipeUpdate, FnUpdateRecipe, PMState.Processing);
  427. Transition(PMState.Processing, MSG.RecipeSkipStep, FnSkipStep, PMState.Processing);
  428. EnterExitTransition<PMState, FSM_MSG>(PMState.Processing, FnEnterProcess, FSM_MSG.NONE, FnExitProcess);
  429. //PostProcess sequence
  430. Transition(PMState.Processing, MSG.PostProcess, FnStartPostProcess, PMState.PostProcess);
  431. Transition(PMState.PostProcess, FSM_MSG.TIMER, FnPostProcessTimeout, PMState.Idle);
  432. Transition(PMState.PostProcess, MSG.Abort, FnAbortPostProcess, PMState.Idle);
  433. Transition(PMState.PostProcess, MSG.RecipeAbort, FnAbortPostProcess, PMState.Idle);
  434. EnterExitTransition<PMState, FSM_MSG>(PMState.PostProcess, null, FSM_MSG.NONE, fExitPostProcess);
  435. Running = true;
  436. }
  437. protected override bool Init()
  438. {
  439. DATA.Subscribe($"{Module}.FsmState", () => ((PMState)fsm.State).ToString());
  440. DATA.Subscribe($"{Module}.FsmPrevState", () => ((PMState)fsm.PrevState).ToString());
  441. DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage);
  442. DATA.Subscribe($"{Module}.PMState", () => fsm.State);
  443. DATA.Subscribe($"{Module}.IsAutoMode", () => IsAutoMode);
  444. DATA.Subscribe($"{Module}.IsOnline", () => _isOnline);
  445. DATA.Subscribe($"{Module}.IsAlarm", () => _isAlarm);
  446. DATA.Subscribe($"{Module}.ProcessStatus", () => _processStatus);
  447. DATA.Subscribe($"{Module}.PumpTime", () => PumpTime);
  448. DATA.Subscribe($"{Module}.TCTime", () => TCTime);
  449. DATA.Subscribe($"{Module}.StepNo", () => StepNo);
  450. DATA.Subscribe($"{Module}.RecipeStepName", () => RecipeStepName);
  451. DATA.Subscribe($"{Module}.RecipeName", () => RecipeName);
  452. DATA.Subscribe($"{Module}.LeakRate", () => LeakRate);
  453. DATA.Subscribe($"{Module}.LeakCheckElapseTime", () => LeakCheckElapseTime);
  454. DATA.Subscribe($"{Module}.SmallWafer", () => _smallWafer);
  455. DATA.Subscribe($"{Module}.BigWafer", () => _bigWafer);
  456. DATA.Subscribe($"{Module}.MidWafer", () => _midWafer);
  457. DATA.Subscribe($"{Module}.RecipeSteps", () => RecipeSteps);
  458. DATA.Subscribe($"{Module}.RecipeProcessTime", () => RecipeElapsedTime);
  459. DATA.Subscribe($"{Module}.RecipeTotalElapsedSeconds", () => RecipeTotalElapsedSeconds);
  460. DATA.Subscribe($"{Module}.RecipeStepTimeElapsed", () => (_processRoutine.CurStepElpasedTime / 1000).ToString("F0"));
  461. DATA.Subscribe($"{Module}.RecipeStepTimeSetPoint", () => (_processRoutine.CurStepTotalTime / 1000).ToString("F0"));
  462. OP.Subscribe($"{Module}.{RtOperation.GasFlow}", (cmd, args) => CheckToPostMessage((int)MSG.GasFlow, args));
  463. OP.Subscribe($"{Module}.{RtOperation.RfPower}", (cmd, args) => CheckToPostMessage((int)MSG.RfPower, args));
  464. OP.Subscribe($"{Module}.{RtOperation.MoveLiftPin}", (cmd, args) => CheckToPostMessage((int)MSG.MoveLiftPin, args[0], 0, true));
  465. OP.Subscribe($"{Module}.{RtOperation.MoveGuidePin}", (cmd, args) => CheckToPostMessage((int)MSG.MoveGuidePin, args[0], args[1]));
  466. OP.Subscribe($"{Module}.Home", (cmd, args) => CheckToPostMessage((int)MSG.Home));
  467. OP.Subscribe($"{Module}.{RtOperation.Reset}", (cmd, args) => CheckToPostMessage((int)MSG.Reset));
  468. OP.Subscribe($"{Module}.{RtOperation.Abort}", (cmd, args) => CheckToPostMessage((int)MSG.Abort));
  469. OP.Subscribe($"{Module}.PrepareTransfer", (cmd, args) => CheckToPostMessage((int)MSG.PrepareTransfer, args[0]));
  470. OP.Subscribe($"{Module}.TransferHandoff", (cmd, args) => CheckToPostMessage((int)MSG.TransferHandoff, args[0]));
  471. OP.Subscribe($"{Module}.{RtOperation.Pump}", (cmd, args) => CheckToPostMessage((int)MSG.Pump));
  472. OP.Subscribe($"{Module}.{RtOperation.StartPump}", (cmd, args) => CheckToPostMessage((int)MSG.LaunchPump));
  473. OP.Subscribe($"{Module}.{RtOperation.Vent}", (cmd, args) => CheckToPostMessage((int)MSG.Vent));
  474. OP.Subscribe($"{Module}.{RtOperation.Purge}", (cmd, args) => CheckToPostMessage((int)MSG.CyclePurge));
  475. OP.Subscribe($"{Module}.{RtOperation.LeakCheck}", (cmd, args) => CheckToPostMessage((int)MSG.LeakCheck, args));
  476. OP.Subscribe($"{Module}.{RtOperation.DeleteLeakCheck}", (cmd, args) => CheckToPostMessage((int)MSG.DeleteLeakCheck, args));
  477. OP.Subscribe($"{Module}.{RtOperation.LockLid}", (cmd, args) => CheckToPostMessage((int)MSG.LockLid, true));
  478. OP.Subscribe($"{Module}.{RtOperation.UnlockLid}", (cmd, args) => CheckToPostMessage((int)MSG.LockLid, false));
  479. OP.Subscribe($"{Module}.{RtOperation.RunRecipe}", (cmd, args) => CheckToPostMessage((int)MSG.RunRecipe, (string)args[0], "", true));
  480. OP.Subscribe($"{Module}.{RtOperation.SkipCurrentStep}", (cmd, args) => CheckToPostMessage((int)MSG.RecipeSkipStep));
  481. OP.Subscribe($"{Module}.{RtOperation.AbortRecipe}", (cmd, args) => CheckToPostMessage((int)MSG.RecipeAbort));
  482. OP.Subscribe($"{Module}.{RtOperation.PmAuto}", (cmd, args) => CheckToPostMessage((int)MSG.AutoMode));
  483. OP.Subscribe($"{Module}.{RtOperation.PmManual}", (cmd, args) => CheckToPostMessage((int)MSG.ManualMode));
  484. OP.Subscribe($"{Module}.{RtOperation.PmOnline}", (cmd, args) => CheckToPostMessage((int)MSG.Online));
  485. OP.Subscribe($"{Module}.{RtOperation.PmOffline}", (cmd, args) => CheckToPostMessage((int)MSG.Offline));
  486. OP.Subscribe($"{Module}.{RtOperation.Heat}", (cmd, args) => CheckToPostMessage((int)MSG.Heat, args[0]));
  487. OP.Subscribe($"{Module}.{RtOperation.MFCVerification}", (cmd, args) => CheckToPostMessage((int)MSG.MFCVerification, args));
  488. OP.Subscribe($"{Module}.{RtOperation.AllMFCVerification}", (cmd, args) => CheckToPostMessage((int)MSG.AllMFCVerification, args));
  489. StatsDataManager.Instance.Subscribe($"{Module}.ProcessedWaferCount", "Processed Wafer Count", 0);
  490. StatsDataManager.Instance.Subscribe($"{Module}.RfOnTime", "Rf On Time");
  491. if (_enableBias)
  492. StatsDataManager.Instance.Subscribe($"{Module}.BiasRfOnTime", "Bias Rf On Time");
  493. StatsDataManager.Instance.Subscribe($"{Module}.PumpOnTime", "Pump On Time");
  494. _statProcessedWafer = StatsDataManager.Instance.GetItem($"{Module}.ProcessedWaferCount");
  495. _statRfOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.RfOnTime");
  496. if (_enableBias)
  497. _statBiasRfOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.BiasRfOnTime");
  498. _statPumpOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.PumpOnTime");
  499. return true;
  500. }
  501. // Methods
  502. //
  503. private bool CheckToPostMessage(int msg, params object[] args)
  504. {
  505. if (!fsm.FindTransition(fsm.State, msg))
  506. {
  507. EV.PostWarningLog(Module.ToString(), $"{Module} is in { (PMState)fsm.State} state,can not do {(MSG)msg}");
  508. return false;
  509. }
  510. fsm.PostMsg(msg, args);
  511. return true;
  512. }
  513. private bool FnAbortTask(object[] param)
  514. {
  515. //_task.Abort();
  516. return true;
  517. }
  518. private bool FnSetAuto(object[] param)
  519. {
  520. this._AutoMode = AutoFlag.Auto;
  521. return true;
  522. }
  523. private bool FnSetManual(object[] param)
  524. {
  525. if (fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess)
  526. {
  527. EV.PostWarningLog(Module.ToString(), $"{Module} is in {(PMState)fsm.State},can not do SetAutoMode");
  528. return false;
  529. }
  530. this._AutoMode = AutoFlag.Manual;
  531. if (IsOnline)
  532. {
  533. EV.PostWarningLog(Module.ToString(), $"{Module} is online,change to offline due to the chamber change to manual mode");
  534. this._isOnline = false;
  535. }
  536. return true;
  537. }
  538. private bool FnSetOnline(object[] param)
  539. {
  540. if (!IsAutoMode)
  541. {
  542. EV.PostWarningLog(Module.ToString(), $"{Module} in manual mode,can not set online.");
  543. return false;
  544. }
  545. if (!_chamber.CheckSlitDoorClose())
  546. {
  547. EV.PostWarningLog(Module.ToString(), $"{Module} slit door is open,can not set online.");
  548. return false;
  549. }
  550. this._isOnline = true;
  551. return true;
  552. }
  553. private bool FnSetOffline(object[] param)
  554. {
  555. this._isOnline = false;
  556. return true;
  557. }
  558. #region Gas&RF
  559. private bool FnStartGasFlow(object[] objs)
  560. {
  561. Result ret = _gasFlowRoutine.Start(objs);
  562. if (ret == Result.FAIL || ret == Result.TIMEOUT)
  563. {
  564. return false; //do noting
  565. }
  566. return true;
  567. }
  568. private bool FnGasFlowTimeout(object[] objs)
  569. {
  570. Result ret = _gasFlowRoutine.Monitor();
  571. if (ret == Result.FAIL || ret == Result.TIMEOUT)
  572. {
  573. PostMsg(MSG.Abort);
  574. return true;
  575. }
  576. return false;
  577. }
  578. private bool FnAbortGasFlow(object[] objs)
  579. {
  580. _gasFlowRoutine.Abort();
  581. return true;
  582. }
  583. private bool FnStopGasFlow(object[] objs)
  584. {
  585. _gasFlowRoutine.StopFlow2();
  586. return true;
  587. }
  588. private bool FnStartRfPower(object[] objs)
  589. {
  590. _rfStartTime = DateTime.Now;
  591. Result ret = _rfPowerRoutine.Start(objs);
  592. if (ret == Result.DONE)
  593. {
  594. return false;
  595. }
  596. if (ret == Result.FAIL || ret == Result.TIMEOUT)
  597. {
  598. return false; //do noting
  599. }
  600. return true;
  601. }
  602. private bool FnRfPowerTimeout(object[] objs)
  603. {
  604. Result ret = _rfPowerRoutine.Monitor();
  605. if (ret == Result.DONE)
  606. return true;
  607. else if (ret == Result.FAIL || ret == Result.TIMEOUT)
  608. {
  609. //do nothing
  610. return true;
  611. }
  612. return false;
  613. ;
  614. }
  615. private bool FnAbortRfPower(object[] objs)
  616. {
  617. _rfPowerRoutine.Abort();
  618. if (_gasFlowRoutine._gasStatus)
  619. _gasFlowRoutine.Abort();
  620. return true;
  621. }
  622. private bool FnHeat(object[] objs)
  623. {
  624. _tcStartTime = DateTime.Now;
  625. return _temperatureControlRoutine.Start(objs) == Result.RUN;
  626. }
  627. private bool FnHeatTimeout(object[] param)
  628. {
  629. Result ret = _temperatureControlRoutine.Monitor();
  630. if (ret == Result.DONE)
  631. {
  632. return true;
  633. }
  634. if (ret == Result.FAIL || ret == Result.TIMEOUT)
  635. {
  636. //do nothing
  637. return true;
  638. }
  639. return false;
  640. }
  641. private bool FnAbortHeating(object[] param)
  642. {
  643. _temperatureControlRoutine.Abort();
  644. return true;
  645. }
  646. #endregion Gas&RF
  647. #region Subroutine
  648. private bool FnStartLeakCheck(object[] param)
  649. {
  650. _leakCheckStartTime = DateTime.Now;
  651. return _leakCheckRoutine.Start(param) == Result.RUN;
  652. }
  653. private bool FnLeakCheckTimeout(object[] param)
  654. {
  655. Result res = _leakCheckRoutine.Monitor();
  656. return res == Result.DONE || res == Result.FAIL;
  657. }
  658. private bool FnDeleteLeakCheck(object[] param)
  659. {
  660. _leakCheckRoutine.DeleteLeadCheck(param);
  661. return true;
  662. }
  663. private bool FnAbortLeakCheck(object[] param)
  664. {
  665. _leakCheckRoutine.Abort();
  666. return true;
  667. }
  668. private bool FnStartMFCVerification(object[] param)
  669. {
  670. _mfcVerification.Init((string)param[0], (float)param[1], (int)param[2]);
  671. return _mfcVerification.Start(param) == Result.RUN;
  672. }
  673. private bool FnMFCVerificationTimeout(object[] param)
  674. {
  675. Result res = _mfcVerification.Monitor();
  676. return res == Result.DONE || res == Result.FAIL;
  677. }
  678. private bool FnAbortMFCVerification(object[] param)
  679. {
  680. _mfcVerification.Abort();
  681. return true;
  682. }
  683. private bool FnStartAllMFCVerification(object[] param)
  684. {
  685. _allMfcVerification.Init((string[])param[0], (bool[])param[1]);
  686. return _allMfcVerification.Start(param) == Result.RUN;
  687. }
  688. private bool FnAllMFCVerificationTimeout(object[] param)
  689. {
  690. Result res = _allMfcVerification.Monitor();
  691. return res == Result.DONE || res == Result.FAIL;
  692. }
  693. private bool FnAbortAllMFCVerification(object[] param)
  694. {
  695. _allMfcVerification.Abort();
  696. return true;
  697. }
  698. private bool FnStartVent(object[] param)
  699. {
  700. Result ret = _ventRoutine.Start();
  701. if (ret == Result.DONE)
  702. {
  703. return false;
  704. }
  705. else if (ret == Result.FAIL)
  706. {
  707. return false; //do noting
  708. }
  709. return true;
  710. }
  711. private bool FnVentTimeout(object[] param)
  712. {
  713. Result ret = _ventRoutine.Monitor();
  714. if (ret == Result.DONE)
  715. {
  716. return true;
  717. }
  718. if (ret == Result.FAIL)
  719. {
  720. //do nothing
  721. return true;
  722. }
  723. return false;
  724. }
  725. private bool FnVentToPumping(object[] param)
  726. {
  727. _ventRoutine.Abort();
  728. return FnStartPumpDown(param);
  729. }
  730. private bool FnAbortVent(object[] param)
  731. {
  732. _ventRoutine.Abort();
  733. return true;
  734. }
  735. private bool FnLaunchPump(object[] param)
  736. {
  737. _pumpStartTime = DateTime.Now;
  738. return _startPumpRoutine.Start() == Result.RUN;
  739. }
  740. private bool FnLaunchPumpTimeout(object[] param)
  741. {
  742. Result ret = _startPumpRoutine.Monitor();
  743. if (ret == Result.DONE)
  744. {
  745. return true;
  746. }
  747. if (ret == Result.FAIL || ret == Result.TIMEOUT)
  748. {
  749. PostMsg(MSG.Abort);
  750. return false;
  751. }
  752. return false;
  753. }
  754. private bool FnAbortStartPumping(object[] param)
  755. {
  756. _startPumpRoutine.Abort();
  757. return true;
  758. }
  759. private bool FnStartPumpDown(object[] param)
  760. {
  761. _pumpStartTime = DateTime.Now;
  762. return _pumpRoutine.Start() == Result.RUN;
  763. }
  764. private bool FnPumpDownTimeout(object[] param)
  765. {
  766. Result ret = _pumpRoutine.Monitor();
  767. if (ret == Result.DONE)
  768. {
  769. return true;
  770. }
  771. if (ret == Result.FAIL || ret == Result.TIMEOUT)
  772. {
  773. //do nothing
  774. return true;
  775. }
  776. return false;
  777. }
  778. private bool FnPumpingToVent(object[] param)
  779. {
  780. _pumpRoutine.Abort();
  781. return FnStartVent(param);
  782. }
  783. private bool FnAbortPumping(object[] param)
  784. {
  785. _pumpRoutine.Abort();
  786. return true;
  787. }
  788. private bool FnStartPurge(object[] param)
  789. {
  790. return _cyclePurgeRoutine.Start(param) == Result.RUN;
  791. }
  792. private bool FnPurgeTimeout(object[] param)
  793. {
  794. Result ret = _cyclePurgeRoutine.Monitor();
  795. if (ret == Result.DONE)
  796. {
  797. return true;
  798. }
  799. else if (ret == Result.FAIL || ret == Result.TIMEOUT)
  800. {
  801. return true;
  802. }
  803. return false;
  804. }
  805. private bool FnAbortPurge(object[] param)
  806. {
  807. _cyclePurgeRoutine.Abort();
  808. return true;
  809. }
  810. #endregion Subroutine
  811. #region Transfer
  812. private bool FnStartPrepareTransfer(object[] param)
  813. {
  814. if (param.Length > 2)
  815. _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), (float)param[1], (WaferSize)param[2]);
  816. else if (param.Length > 1)
  817. _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), (float)param[1]);
  818. else
  819. _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), 0);
  820. Result ret = _prepareTrans.Start();
  821. if (ret == Result.FAIL || ret == Result.DONE)
  822. return false;
  823. return ret == Result.RUN;
  824. }
  825. private bool FnPreTransferTimeout(object[] param)
  826. {
  827. Result ret = _prepareTrans.Monitor();
  828. if (ret == Result.FAIL)
  829. {
  830. PostMsg(MSG.Abort);
  831. return false;
  832. }
  833. return ret == Result.DONE;
  834. }
  835. private bool FnStartPostTransfer(object[] param)
  836. {
  837. Result ret = _postTrans.Start(param);
  838. if (ret == Result.FAIL)
  839. {
  840. PostMsg(MSG.Error);
  841. return false;
  842. }
  843. return ret == Result.RUN;
  844. }
  845. private bool FnPostTransferTimeout(object[] param)
  846. {
  847. Result ret = _postTrans.Monitor();
  848. if (ret == Result.FAIL)
  849. {
  850. PostMsg(MSG.Abort);
  851. return false;
  852. }
  853. return ret == Result.DONE;
  854. }
  855. private bool FnSetLiftpin(object[] param)
  856. {
  857. MovementPosition pos = (MovementPosition)param[0];
  858. _ActivatedActionID = (ushort)param[1];
  859. bool isPick = (bool)param[2];
  860. _goalLiftPin = pos;
  861. _liftpinDelayTime = SC.GetValue<int>(isPick ? $"{Module}.PinDownDelayTimePick" : $"{Module}.PinDownDelayTimePlace") * 1000;
  862. if (_liftpinDelayTime > 0)
  863. {
  864. _LifpinSleepTimer.Restart();
  865. CheckToPostMessage((int)MSG.WaitLiftpin);
  866. return false;
  867. }
  868. _chamber.SetLiftPin(pos, out _);
  869. EV.PostInfoLog(Module.ToString(), $"Set lift pin {pos}");
  870. return true;
  871. }
  872. private bool FnWaitLiftpinTimeout(object[] param)
  873. {
  874. if (_LifpinSleepTimer.ElapsedMilliseconds > _liftpinDelayTime)
  875. {
  876. _chamber.SetLiftPin(_goalLiftPin, out _);
  877. EV.PostInfoLog(Module.ToString(), $"Set lift pin {_goalLiftPin}");
  878. _LifpinSleepTimer.Reset();
  879. return true;
  880. }
  881. return false;
  882. }
  883. private bool FnLiftpinTimeout(object[] param)
  884. {
  885. if (_chamber.LiftPinPosition == _goalLiftPin)
  886. {
  887. EV.PostInfoLog(Module.ToString(), $"lift pin current value {_chamber.LiftPinPosition}");
  888. Singleton<RouteManager>.Instance.EFEM.PostMsg(
  889. _goalLiftPin == MovementPosition.Up ? EfemEntity.MSG.PMLiftPinUp : EfemEntity.MSG.PMLiftPinDown, _ActivatedActionID);
  890. _goalLiftPin = MovementPosition.Unknown;
  891. _ActivatedActionID = 0;
  892. return true;
  893. }
  894. return false;
  895. }
  896. private bool FnSetGuidePin(object[] param)
  897. {
  898. WaferSize ws = (WaferSize)param[0];
  899. MovementPosition pos = (MovementPosition)param[1];
  900. _chamber.SetGuidePin(ws, pos);
  901. return true;
  902. }
  903. private bool FnGuidePinTimeout(object[] param)
  904. {
  905. return true;
  906. }
  907. private bool FnPreClean(object[] param)
  908. {
  909. _cleanRoutine.param = param;
  910. _chamber.SetSlitDoor(false, out _);
  911. return true;
  912. }
  913. private bool FnPreCleanTimeout(object[] param)
  914. {
  915. if (_chamber.IsSlitDoorClosed)
  916. {
  917. if (!FnProcessLoadRecipe(_cleanRoutine.param))
  918. {
  919. EV.PostAlarmLog(_chamber.Module.ToString(), "Clean recipe read failed");
  920. PostMsg(FSM_MSG.ALARM);
  921. return false;
  922. }
  923. return true;
  924. }
  925. return false;
  926. }
  927. #endregion Transfer
  928. #region Process
  929. private bool FnProcessLoadRecipe(object[] param)
  930. {
  931. _processStatus = "Succeed to load recipe";
  932. _recipeStartTime = DateTime.Now;
  933. Result ret = _preProcessRoutine.LoadRecipe(param);
  934. if (ret == Result.DONE)
  935. {
  936. PostMsg(MSG.PreProcess);
  937. }
  938. else if (ret == Result.FAIL)
  939. {
  940. _processStatus = "Failed to load recipe";
  941. return false;
  942. }
  943. return true;
  944. }
  945. private bool FnStartPreProcess(object[] param)
  946. {
  947. _pumpStartTime = DateTime.Now;
  948. //_processStatus = Resources.PMEntity_fStartPreProcess_PreparingRunningRecipe;
  949. Result ret = _preProcessRoutine.Start(param);
  950. if (ret == Result.DONE)
  951. {
  952. return false;
  953. }
  954. if (ret == Result.FAIL || ret == Result.VERIFYFAIL)
  955. {
  956. //_processStatus = Resources.PMEntity_fStartPreProcess_PreparingRunningRecipeFailed;
  957. PostMsg(MSG.Error);
  958. return false; //do noting
  959. }
  960. WaferManager.Instance.UpdateWaferProcessStatus(this.Module, 0, EnumWaferProcessStatus.InProcess);
  961. return true;
  962. }
  963. private bool FnPreProcessTimeout(object[] param)
  964. {
  965. //_processStatus = Resources.PMEntity_fPreProcess_RunRecipePumpingDown;
  966. Result ret = _preProcessRoutine.Monitor();
  967. if (ret == Result.DONE)
  968. {
  969. PostMsg(MSG.Process,
  970. _preProcessRoutine.CurrentRecipeBaseName,
  971. _preProcessRoutine.CurrentRecipeRunningName,
  972. 0,
  973. _preProcessRoutine.CurrentLotName,
  974. _preProcessRoutine.CurrentRecipeContent,
  975. _preProcessRoutine.CurrentRecipeHead,
  976. _preProcessRoutine.CurrentRecipeStepList);
  977. return true;
  978. }
  979. if (ret == Result.FAIL)
  980. {
  981. //_processStatus = Resources.PMEntity_fPreProcess_RunRecipePumpingDownFailed;
  982. PostMsg(MSG.Error);
  983. return true;
  984. }
  985. return false; ;
  986. }
  987. private bool FnAbortPreProcess(object[] param)
  988. {
  989. //_processStatus = Resources.PMEntity_fAbortPreProcess_RunRecipePumpingDownAborted;
  990. WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);
  991. _preProcessRoutine.Abort();
  992. return true;
  993. }
  994. private bool FnStartProcess(object[] param)
  995. {
  996. //_processStatus = Resources.PMEntity_fStartProcess_StartRunningRecipe;
  997. Result ret = _processRoutine.Start(param);
  998. if (ret == Result.DONE)
  999. {
  1000. return true;
  1001. }
  1002. else if (ret == Result.FAIL || ret == Result.VERIFYFAIL)
  1003. {
  1004. //_processStatus = Resources.PMEntity_fStartProcess_RunRecipeFailed;
  1005. PostMsg(MSG.Error);
  1006. return true; //do noting
  1007. }
  1008. return true;
  1009. }
  1010. private bool FnProcessTimeout(object[] param)
  1011. {
  1012. //_processStatus = Resources.PMEntity_fProcess_RunningRecipe;
  1013. Result ret = _processRoutine.Monitor();
  1014. {
  1015. if (ret == Result.DONE)
  1016. {
  1017. PostMsg(MSG.PostProcess, _processRoutine.CurrentRecipeRunningName, _processRoutine.CurrentRecipeContent);
  1018. return true;
  1019. }
  1020. else if (ret == Result.FAIL)
  1021. {
  1022. //_processStatus = Resources.PMEntity_fStartProcess_RunRecipeFailed;
  1023. PostMsg(MSG.Error);
  1024. return true;
  1025. }
  1026. return false;
  1027. }
  1028. }
  1029. private bool FnAbortProcess(object[] param)
  1030. {
  1031. //_processStatus = Resources.PMEntity_fAbortProcess_RunningRecipeAborted;
  1032. _processRoutine.AbortRecipe();
  1033. WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);
  1034. _processRoutine.Abort();
  1035. Result ret = _postProcessRoutine.Start(new object[] { _processRoutine.CurrentRecipeRunningName, _processRoutine.CurrentRecipeContent });
  1036. if (ret == Result.DONE)
  1037. {
  1038. return false;
  1039. }
  1040. else if (ret == Result.FAIL)
  1041. {
  1042. PostMsg(MSG.Error);
  1043. //_processStatus = Resources.PMEntity_fAbortProcess_RunRecipeAborted;
  1044. return false; //do noting
  1045. }
  1046. return true;
  1047. }
  1048. private bool FnPauseProcess(object[] param)
  1049. {
  1050. return true;
  1051. }
  1052. private bool FnResumeRecipe(object[] param)
  1053. {
  1054. return true;
  1055. }
  1056. private bool FnUpdateRecipe(object[] param)
  1057. {
  1058. return true;
  1059. }
  1060. private bool FnSkipStep(object[] param)
  1061. {
  1062. _processRoutine.SkipCurrentRecipeStep();
  1063. return true;
  1064. }
  1065. private bool FnExitProcess(object[] param)
  1066. {
  1067. //_statProcessedWafer
  1068. StatsDataManager.Instance.Increase(_statProcessedWafer.Name);
  1069. _processRoutine.Exit();
  1070. return true;
  1071. }
  1072. private bool FnEnterProcess(object[] param)
  1073. {
  1074. return true;
  1075. }
  1076. private bool FnStartPostProcess(object[] param)
  1077. {
  1078. //_processStatus = Resources.PMEntity_fStartPostProcess_RunRecipePostProcess;
  1079. Result ret = _postProcessRoutine.Start(param);
  1080. if (ret == Result.DONE)
  1081. {
  1082. return false;
  1083. }
  1084. else if (ret == Result.FAIL)
  1085. {
  1086. PostMsg(MSG.Error);
  1087. return false;
  1088. }
  1089. return true;
  1090. }
  1091. private bool FnPostProcessTimeout(object[] param)
  1092. {
  1093. //_processStatus = Resources.PMEntity_fPostProcess_RunRecipeCyclePurge;
  1094. Result ret = _postProcessRoutine.Monitor();
  1095. if (ret == Result.DONE)
  1096. {
  1097. WaferManager.Instance.UpdateWaferProcessStatus(this.Module, 0, EnumWaferProcessStatus.Completed);
  1098. //_processStatus = Resources.PMEntity_fPostProcess_RecipeCompleted;
  1099. return true;
  1100. }
  1101. else if (ret == Result.FAIL)
  1102. {
  1103. //_processStatus = Resources.PMEntity_fPostProcess_RunRecipeCyclePurgeError;
  1104. PostMsg(MSG.Error);
  1105. return true;
  1106. }
  1107. return false;
  1108. }
  1109. private bool FnAbortPostProcess(object[] param)
  1110. {
  1111. //_processStatus = Resources.PMEntity_fAbortPostProcess_RecipeAborted;
  1112. WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);
  1113. _postProcessRoutine.Abort();
  1114. return true;
  1115. }
  1116. private bool fExitPostProcess(object[] objs)
  1117. {
  1118. _postProcessRoutine.Exit();
  1119. //EV.Notify(EventLotFinished, new SerializableDictionary<string, string>()
  1120. //{
  1121. // {DVIDName.LotId, preProcessRoutine.CurrentLotName},
  1122. // {DVIDName.JobId, preProcessRoutine.CurrentJobName},
  1123. // {DVIDName.RecipeId, preProcessRoutine.CurrentRecipeBaseName }
  1124. //});
  1125. return true;
  1126. }
  1127. #endregion PROCESS
  1128. private string GetFsmLastMessage()
  1129. {
  1130. int msg = fsm.LastMsg;
  1131. if (msg >= (int)MSG.Home && msg <= (int)MSG.MaxMsg)
  1132. return ((MSG)msg).ToString();
  1133. if (msg == (int)FSM_MSG.TIMER)
  1134. return "Timer";
  1135. return msg.ToString();
  1136. }
  1137. protected override void Term()
  1138. {
  1139. }
  1140. private bool FnReset(object[] param)
  1141. {
  1142. if (!_EnableResetChamberError)
  1143. return false;
  1144. _isAlarm = false;
  1145. if ((PMState)fsm.State == PMState.Error)
  1146. return true;
  1147. return false;
  1148. }
  1149. public bool Check(int msg, out string reason, object[] objs)
  1150. {
  1151. reason = "";
  1152. return true;
  1153. }
  1154. public bool IsProcessed()
  1155. {
  1156. return IsIdle;
  1157. }
  1158. public bool IsPrepareTransferReady(ModuleName robot, EnumTransferType type, int slot, Hand blade)
  1159. {
  1160. if (type == EnumTransferType.Pick)
  1161. {
  1162. return _chamber.CheckEnableTransfer(type, WaferManager.Instance.GetWafer(_chamber.Module, 0).Size);
  1163. }
  1164. else if (type == EnumTransferType.Place)
  1165. {
  1166. return _chamber.CheckEnableTransfer(type, WaferManager.Instance.GetWafer(robot, (int)blade).Size);
  1167. }
  1168. return false;
  1169. }
  1170. public void Home()
  1171. {
  1172. CheckToPostMessage((int)MSG.Home);
  1173. }
  1174. private bool FnExitHome(object[] param)
  1175. {
  1176. return true;
  1177. }
  1178. private bool FnEnterHome(object[] param)
  1179. {
  1180. return true;
  1181. }
  1182. private bool FnStartHome(object[] objs)
  1183. {
  1184. Result ret = _home.Start();
  1185. if (ret == Result.FAIL || ret == Result.DONE)
  1186. return false;
  1187. return ret == Result.RUN;
  1188. }
  1189. private bool FnMonitorHome(object[] objs)
  1190. {
  1191. Result ret = _home.Monitor();
  1192. if (ret == Result.FAIL)
  1193. {
  1194. PostMsg(MSG.Error);
  1195. return false;
  1196. }
  1197. if (ret == Result.DONE && _isAlarm)
  1198. _isAlarm = false;
  1199. return ret == Result.DONE;
  1200. }
  1201. private bool fExitTransfer(object[] objs)
  1202. {
  1203. return true;
  1204. }
  1205. private bool fEnterError(object[] objs)
  1206. {
  1207. //if (IsProcessMode)
  1208. //{
  1209. // EV.Notify(EventLotFinished, new SerializableDictionary<string, string>()
  1210. // {
  1211. // {DVIDName.LotId, preProcessRoutine.CurrentLotName},
  1212. // {DVIDName.JobId, preProcessRoutine.CurrentJobName},
  1213. // {DVIDName.RecipeId, preProcessRoutine.CurrentRecipeBaseName }
  1214. // });
  1215. //}
  1216. _chamber.GeneratorPowerOn(false);
  1217. _chamber.GeneratorBiasPowerOn(false);
  1218. _chamber.StopAllGases();
  1219. return true;
  1220. }
  1221. private bool FnError(object[] objs)
  1222. {
  1223. Running = false;
  1224. if (((PMState)fsm.State == PMState.Processing) || ((PMState)fsm.State == PMState.PreProcess)
  1225. || ((PMState)fsm.State == PMState.Homing) || ((PMState)fsm.State == PMState.LoadProcessRecipe))
  1226. return false;
  1227. if (IsProcessing)
  1228. {
  1229. WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);
  1230. }
  1231. return true;
  1232. }
  1233. private bool fWarning(object[] objs)
  1234. {
  1235. //IsWarning = false;
  1236. return true;
  1237. }
  1238. private bool fAlarm(object[] objs)
  1239. {
  1240. _isAlarm = true;
  1241. if (fsm.State == (int)PMState.Init)
  1242. return false;
  1243. if (fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.PostProcess)
  1244. {
  1245. PostMsg(MSG.Error);
  1246. return false;
  1247. }
  1248. //IsAlarm = true;
  1249. return true;
  1250. }
  1251. private bool FnIdle(object[] objs)
  1252. {
  1253. Running = false;
  1254. return true;
  1255. }
  1256. public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot)
  1257. {
  1258. if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString()))
  1259. return (int)MSG.PrepareTransfer;
  1260. return (int)FSM_MSG.NONE;
  1261. }
  1262. public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp)
  1263. {
  1264. if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString(), temp))
  1265. return (int)MSG.PrepareTransfer;
  1266. return (int)FSM_MSG.NONE;
  1267. }
  1268. public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp, WaferSize size)
  1269. {
  1270. if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString(), temp, size))
  1271. return (int)MSG.PrepareTransfer;
  1272. return (int)FSM_MSG.NONE;
  1273. }
  1274. public int InvokePostTransfer(ModuleName robot, EnumTransferType type, int slot)
  1275. {
  1276. if (CheckToPostMessage((int)MSG.PostTransfer, type.ToString()))
  1277. return (int)MSG.PostTransfer;
  1278. return (int)FSM_MSG.NONE;
  1279. }
  1280. public int InvokeClean(string recipeName, string waferID, bool withWafer)
  1281. {
  1282. if (CheckToPostMessage((int)MSG.Clean, recipeName, waferID, withWafer))
  1283. {
  1284. return (int)MSG.Clean;
  1285. }
  1286. return (int)FSM_MSG.NONE;
  1287. }
  1288. public int InvokeProcess(string recipeName, string waferID, bool withWafer)
  1289. {
  1290. if (CheckToPostMessage((int)MSG.RunRecipe, recipeName, waferID, withWafer))
  1291. return (int)MSG.RunRecipe;
  1292. return (int)FSM_MSG.NONE;
  1293. }
  1294. public int InvokePreHeat(float temperature)
  1295. {
  1296. if (CheckToPostMessage((int)MSG.Heat, (double)temperature))
  1297. return (int)MSG.Heat;
  1298. return (int)FSM_MSG.NONE;
  1299. }
  1300. public void InvokeReset()
  1301. {
  1302. PostMsg((int)MSG.Reset);
  1303. }
  1304. public void SetAuto()
  1305. {
  1306. this._AutoMode = AutoFlag.Auto;
  1307. }
  1308. #region EndPoint
  1309. public bool CheckEndPoint()
  1310. {
  1311. EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");
  1312. if (epd == null)
  1313. return false;
  1314. return epd.IsEnd;
  1315. }
  1316. public void StartEndPoint(string config, int index)
  1317. {
  1318. EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");
  1319. if (epd == null)
  1320. return;
  1321. epd.StepStart(config, index);
  1322. }
  1323. public void StopEndPoint()
  1324. {
  1325. EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");
  1326. if (epd == null)
  1327. return;
  1328. epd.StepStop();
  1329. }
  1330. public void EndPointRecipeStop()
  1331. {
  1332. EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");
  1333. if (epd == null)
  1334. return;
  1335. epd.RecipeStop();
  1336. }
  1337. public void EndPointRecipeStart(string recipeName)
  1338. {
  1339. EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");
  1340. if (epd == null)
  1341. return;
  1342. epd.RecipeStart(recipeName);
  1343. }
  1344. #endregion
  1345. }
  1346. }