PMEntity.cs 61 KB

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