PMEntity.cs 57 KB

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