TDKB200LoadPort.cs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Device.Unit;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.Log;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Core.Util;
  8. using Aitex.Sorter.Common;
  9. using MECF.Framework.Common.Communications;
  10. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.CarrierIdReaders.CarrierIDReaderBase;
  11. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  12. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.IO.Ports;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading;
  20. using System.Threading.Tasks;
  21. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDKB
  22. {
  23. public class TDKB200LoadPort : LoadPortBaseDevice, IConnection
  24. {
  25. public TDKB200LoadPort(string module, string name, string scRoot, IoTrigger[] dos = null, IoSensor[] dis = null, RobotBaseDevice robot = null, bool IsTCPconnection = false, IE84CallBack e84 =null) : base(module, name, robot,e84)
  26. {
  27. _scRoot = scRoot;
  28. _isTcpConnection = IsTCPconnection;
  29. LoadPortType = "TDK200LoadPort";
  30. if (dos != null && dos.Length >= 1)
  31. {
  32. _doLoadPortOK = dos[0];
  33. }
  34. if (dis != null && dis.Length >= 1)
  35. {
  36. _diInfoPadA = dis[0];
  37. _diInfoPadA.OnSignalChanged += _diInfoPad_OnSignalChanged;
  38. }
  39. if (dis != null && dis.Length >= 2)
  40. {
  41. _diInfoPadB = dis[1];
  42. _diInfoPadB.OnSignalChanged += _diInfoPad_OnSignalChanged;
  43. }
  44. if (dis != null && dis.Length >= 3)
  45. {
  46. _diInfoPadC = dis[2];
  47. _diInfoPadC.OnSignalChanged += _diInfoPad_OnSignalChanged;
  48. }
  49. if (dis != null && dis.Length >= 4)
  50. {
  51. _diInfoPadD = dis[3];
  52. _diInfoPadB.OnSignalChanged += _diInfoPad_OnSignalChanged;
  53. }
  54. InitializeLP();
  55. SubscribeLPData();
  56. SubscribeLPAlarm();
  57. }
  58. private void SubscribeLPData()
  59. {
  60. DATA.Subscribe($"{Module}.{Name}.SystemStatus", () => SystemStatus.ToString());
  61. DATA.Subscribe($"{Module}.{Name}.Mode", () => Mode.ToString());
  62. DATA.Subscribe($"{Module}.{Name}.InitPosMovement", () => InitPosMovement.ToString());
  63. DATA.Subscribe($"{Module}.{Name}.OperationStatus", () => OperationStatus.ToString());
  64. DATA.Subscribe($"{Module}.{Name}.ErrorCode", () => ErrorCode.ToString());
  65. DATA.Subscribe($"{Module}.{Name}.ContainerStatus", () => ContainerStatus.ToString());
  66. DATA.Subscribe($"{Module}.{Name}.ClampPosition", () => ClampPosition.ToString());
  67. DATA.Subscribe($"{Module}.{Name}.LPDoorLatchPosition", () => LPDoorLatchPosition.ToString());
  68. DATA.Subscribe($"{Module}.{Name}.VacuumStatus", () => VacuumStatus.ToString());
  69. DATA.Subscribe($"{Module}.{Name}.LPDoorState", () => LPDoorState.ToString());
  70. DATA.Subscribe($"{Module}.{Name}.WaferProtrusion", () => WaferProtrusion.ToString());
  71. DATA.Subscribe($"{Module}.{Name}.ElevatorAxisPosition", () => ElevatorAxisPosition.ToString());
  72. DATA.Subscribe($"{Module}.{Name}.MapperPostion", () => MapperPostion.ToString());
  73. DATA.Subscribe($"{Module}.{Name}.MappingStatus", () => MappingStatus.ToString());
  74. DATA.Subscribe($"{Module}.{Name}.Model", () => Model.ToString());
  75. DATA.Subscribe($"{Module}.{Name}.IsFosbModeActual", () => IsFosbModeActual.ToString());
  76. DATA.Subscribe($"{Module}.{Name}.DockPosition", () => DockPosition.ToString());
  77. }
  78. private void SubscribeLPAlarm()
  79. {
  80. EV.Subscribe(new EventItem("Alarm", AlarmTdkZLMIT, $"Load Port {Name} Z-axis position: NG", EventLevel.Alarm, EventType.EventUI_Notify));
  81. EV.Subscribe(new EventItem("Alarm", AlarmTdkYLMIT, $"Load Port {Name} Y-axis position: NG", EventLevel.Alarm, EventType.EventUI_Notify));
  82. EV.Subscribe(new EventItem("Alarm", AlarmTdkPROTS, $"Load Port {Name} Wafer protrusion", EventLevel.Alarm, EventType.EventUI_Notify));
  83. EV.Subscribe(new EventItem("Alarm", AlarmTdkDLMIT, $"Load Port {Name} Door forward/backward position: NG", EventLevel.Alarm, EventType.EventUI_Notify));
  84. EV.Subscribe(new EventItem("Alarm", AlarmTdkMPBAR, $"Load Port {Name} Mapper arm position: NG", EventLevel.Alarm, EventType.EventUI_Notify));
  85. EV.Subscribe(new EventItem("Alarm", AlarmTdkMPSTP, $"Load Port {Name} Mapper stopper position: NG", EventLevel.Alarm, EventType.EventUI_Notify));
  86. EV.Subscribe(new EventItem("Alarm", AlarmTdkMPEDL, $"Load Port {Name} Mapping end position: NG", EventLevel.Alarm, EventType.EventUI_Notify));
  87. EV.Subscribe(new EventItem("Alarm", AlarmTdkCLOPS, $"Load Port {Name} FOUP clamp open error", EventLevel.Alarm, EventType.EventUI_Notify));
  88. EV.Subscribe(new EventItem("Alarm", AlarmTdkCLCLS, $"Load Port {Name} FOUP clamp close error", EventLevel.Alarm, EventType.EventUI_Notify));
  89. EV.Subscribe(new EventItem("Alarm", AlarmTdkDROPS, $"Load Port {Name} Latch key open error", EventLevel.Alarm, EventType.EventUI_Notify));
  90. EV.Subscribe(new EventItem("Alarm", AlarmTdkDRCLS, $"Load Port {Name} Latch key close error", EventLevel.Alarm, EventType.EventUI_Notify));
  91. EV.Subscribe(new EventItem("Alarm", AlarmTdkVACCS, $"Load Port {Name} Vacuum on error", EventLevel.Alarm, EventType.EventUI_Notify));
  92. EV.Subscribe(new EventItem("Alarm", AlarmTdkVACOS, $"Load Port {Name} Vacuum off error", EventLevel.Alarm, EventType.EventUI_Notify));
  93. EV.Subscribe(new EventItem("Alarm", AlarmTdkAIRSN, $"Load Port {Name} Main air error", EventLevel.Alarm, EventType.EventUI_Notify));
  94. EV.Subscribe(new EventItem("Alarm", AlarmTdkINTOP, $"Load Port {Name} Normal position error at FOUP open", EventLevel.Alarm, EventType.EventUI_Notify));
  95. EV.Subscribe(new EventItem("Alarm", AlarmTdkINTCL, $"Load Port {Name} Normal position error at FOUP close", EventLevel.Alarm, EventType.EventUI_Notify));
  96. EV.Subscribe(new EventItem("Alarm", AlarmTdkINTMP, $"Load Port {Name} Mapper storage error when Z-axis lowered", EventLevel.Alarm, EventType.EventUI_Notify));
  97. EV.Subscribe(new EventItem("Alarm", AlarmTdkINTPI, $"Load Port {Name} Parallel signal error from upper machine", EventLevel.Alarm, EventType.EventUI_Notify));
  98. EV.Subscribe(new EventItem("Alarm", AlarmTdkSAFTY, $"Load Port {Name} Interlock relay failure", EventLevel.Alarm, EventType.EventUI_Notify));
  99. EV.Subscribe(new EventItem("Alarm", AlarmTdkFANST, $"Load Port {Name} Fan operation error", EventLevel.Alarm, EventType.EventUI_Notify));
  100. EV.Subscribe(new EventItem("Alarm", AlarmTdkMPDOG, $"Load Port {Name} Mapping mechanical(Adjustment) error", EventLevel.Alarm, EventType.EventUI_Notify));
  101. EV.Subscribe(new EventItem("Alarm", AlarmTdkDRDKE, $"Load Port {Name} Door detection error during dock.", EventLevel.Alarm, EventType.EventUI_Notify));
  102. EV.Subscribe(new EventItem("Alarm", AlarmTdkDRSWE, $"Load Port {Name} Door detection error except dock", EventLevel.Alarm, EventType.EventUI_Notify));
  103. EV.Subscribe(new EventItem("Alarm", AlarmTdkNoOperation, $"Load Port {Name} No action when foup is present", EventLevel.Alarm, EventType.EventUI_Notify));
  104. }
  105. private string AlarmTdkZLMIT { get => LPModuleName.ToString() + "ZLMIT"; }
  106. private string AlarmTdkYLMIT { get => LPModuleName.ToString() + "YLMIT"; }
  107. private string AlarmTdkPROTS { get => LPModuleName.ToString() + "PROTS"; }
  108. private string AlarmTdkDLMIT { get => LPModuleName.ToString() + "DLMIT"; }
  109. private string AlarmTdkMPBAR { get => LPModuleName.ToString() + "MPBAR"; }
  110. private string AlarmTdkMPSTP { get => LPModuleName.ToString() + "MPSTP"; }
  111. private string AlarmTdkMPEDL { get => LPModuleName.ToString() + "MPEDL"; }
  112. private string AlarmTdkCLOPS { get => LPModuleName.ToString() + "CLOPS"; }
  113. private string AlarmTdkCLCLS { get => LPModuleName.ToString() + "CLCLS"; }
  114. private string AlarmTdkDROPS { get => LPModuleName.ToString() + "DROPS"; }
  115. private string AlarmTdkDRCLS { get => LPModuleName.ToString() + "DRCLS"; }
  116. private string AlarmTdkVACCS { get => LPModuleName.ToString() + "VACCS"; }
  117. private string AlarmTdkVACOS { get => LPModuleName.ToString() + "VACOS"; }
  118. private string AlarmTdkAIRSN { get => LPModuleName.ToString() + "AIRSN"; }
  119. private string AlarmTdkINTOP { get => LPModuleName.ToString() + "INTOP"; }
  120. private string AlarmTdkINTCL { get => LPModuleName.ToString() + "INTCL"; }
  121. private string AlarmTdkINTMP { get => LPModuleName.ToString() + "INTMP"; }
  122. private string AlarmTdkINTPI { get => LPModuleName.ToString() + "INTPI"; }
  123. private string AlarmTdkSAFTY { get => LPModuleName.ToString() + "SAFTY"; }
  124. private string AlarmTdkFANST { get => LPModuleName.ToString() + "FANST"; }
  125. private string AlarmTdkMPDOG { get => LPModuleName.ToString() + "MPDOG"; }
  126. private string AlarmTdkDRDKE { get => LPModuleName.ToString() + "DRDKE"; }
  127. private string AlarmTdkDRSWE { get => LPModuleName.ToString() + "DRSWE"; }
  128. private string AlarmTdkNoOperation { get => LPModuleName.ToString() + "NoOperation"; }
  129. private void _diInfoPad_OnSignalChanged(IoSensor arg1, bool arg2)
  130. {
  131. //if (_infoPadType == 1)
  132. // InfoPadCarrierIndex = (_diInfoPadA == null || !_diInfoPadA.Value ? 0 : 1) +
  133. // (_diInfoPadB == null || !_diInfoPadB.Value ? 0 : 2) +
  134. // (_diInfoPadC == null || !_diInfoPadC.Value ? 0 : 4) +
  135. // (_diInfoPadD == null || !_diInfoPadD.Value ? 0 : 8);
  136. }
  137. public override int InfoPadCarrierIndex
  138. {
  139. get { return base.InfoPadCarrierIndex; }
  140. set
  141. {
  142. if (base.InfoPadCarrierIndex != value)
  143. {
  144. base.InfoPadCarrierIndex = value;
  145. EV.PostInfoLog("LoadPort", $"{LPModuleName} infopad index change to {value}");
  146. //if (CIDReaders != null && CIDReaders.Length > 1)
  147. //{
  148. // int cidindex = SC.GetValue<int>($"CarrierInfo.{LPModuleName}CIDReaderIndex{InfoPadCarrierIndex}");
  149. // if (CIDReaders.Length <= cidindex)
  150. // {
  151. // EV.PostAlarmLog("System", $"The carrier info configuration for CIDReaderIndex{cidindex} is invalid.");
  152. // }
  153. // else
  154. // {
  155. // CarrierIDReaderCallBack = CIDReaders[cidindex];
  156. // }
  157. //}
  158. }
  159. }
  160. }
  161. public override bool IsEnableDualTransfer(out string reason)
  162. {
  163. reason = "";
  164. if(SC.ContainsItem($"CarrierInfo.EnableDualTransfer{InfoPadCarrierIndex}") &&
  165. SC.GetValue<bool>($"CarrierInfo.EnableDualTransfer{InfoPadCarrierIndex}"))
  166. {
  167. return true;
  168. }
  169. return base.IsEnableDualTransfer(out reason);
  170. }
  171. public override CIDReaderBaseDevice[] CIDReaders
  172. {
  173. get { return base.CIDReaders; }
  174. set
  175. {
  176. base.CIDReaders = value;
  177. //if (CIDReaders != null && CIDReaders.Length > 1)
  178. //{
  179. // int cidindex = SC.GetValue<int>($"CarrierInfo.{LPModuleName}CIDReaderIndex{InfoPadCarrierIndex}");
  180. // if (CIDReaders.Length <= cidindex)
  181. // {
  182. // EV.PostAlarmLog("System", $"The carrier info configuration for CIDReaderIndex{cidindex} is invalid.");
  183. // }
  184. // else
  185. // {
  186. // CarrierIDReaderCallBack = CIDReaders[cidindex];
  187. // }
  188. //}
  189. }
  190. }
  191. private void InitializeLP()
  192. {
  193. IsMapWaferByLoadPort = false;
  194. if (_doLoadPortOK != null)
  195. _doLoadPortOK.SetTrigger(true, out _);
  196. //_deviceAddress = SC.GetValue<int>($"{Name}.DeviceAddress");
  197. //InfoPadType,0=TDK,1=Ext,2=FixedbySC
  198. if (IsAutoDetectCarrierType)
  199. {
  200. _infoPadType = SC.ContainsItem($"LoadPort.{Name}.InfoPadType") ? SC.GetValue<int>($"LoadPort.{Name}.InfoPadType") : 2;
  201. if (_infoPadType == 1)
  202. {
  203. InfoPadCarrierIndex = (_diInfoPadA == null || !_diInfoPadA.Value ? 0 : 1) +
  204. (_diInfoPadB == null || !_diInfoPadB.Value ? 0 : 2) +
  205. (_diInfoPadC == null || !_diInfoPadC.Value ? 0 : 4) +
  206. (_diInfoPadD == null || !_diInfoPadD.Value ? 0 : 8);
  207. }
  208. if (_infoPadType == 2)
  209. {
  210. InfoPadCarrierIndex = SC.GetValue<int>($"LoadPort.{Name}.CarrierIndex");
  211. }
  212. }
  213. _enableLog = SC.GetValue<bool>($"LoadPort.{Name}.EnableLogMessage");
  214. if (_isTcpConnection)
  215. {
  216. Address = SC.GetStringValue($"LoadPort.{Name}.Address");
  217. _tcpConnection = new TDKB200LoadPortTCPConnection(this, Address);
  218. _tcpConnection.EnableLog(_enableLog);
  219. if (_tcpConnection.Connect())
  220. {
  221. //LOG.Write($"Connected with {Module}.{Name} .");
  222. EV.PostInfoLog(Module, $"Connected with {Module}.{Name} .");
  223. }
  224. else
  225. {
  226. EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
  227. }
  228. }
  229. else
  230. {
  231. string portName = SC.GetStringValue($"LoadPort.{Name}.PortName");
  232. int bautRate = SC.GetValue<int>($"LoadPort.{Name}.BaudRate");
  233. int dataBits = SC.GetValue<int>($"LoadPort.{Name}.DataBits");
  234. Enum.TryParse(SC.GetStringValue($"LoadPort.{Name}.Parity"), out Parity parity);
  235. Enum.TryParse(SC.GetStringValue($"LoadPort.{Name}.StopBits"), out StopBits stopBits);
  236. Address = portName;
  237. _connection = new TDKB200LoadPortConnection(this, portName, bautRate, dataBits, parity, stopBits);
  238. _connection.EnableLog(_enableLog);
  239. _connection.IsEnableHandlerRetry = true;
  240. int count = SC.ContainsItem("System.ComPortRetryCount") ? SC.GetValue<int>("System.ComPortRetryCount") : 5;
  241. int sleep = SC.ContainsItem("System.ComPortRetryDelayTime") ? SC.GetValue<int>("System.ComPortRetryDelayTime") : 2;
  242. if (sleep <= 0 || sleep > 10)
  243. sleep = 2;
  244. int retry = 0;
  245. do
  246. {
  247. _connection.Disconnect();
  248. Thread.Sleep(sleep * 1000);
  249. if (_connection.Connect())
  250. {
  251. //LOG.Write($"Connected with {Module}.{Name} .");
  252. EV.PostInfoLog(Module, $"Connected with {Module}.{Name} .");
  253. break;
  254. }
  255. if (count > 0 && retry++ > count)
  256. {
  257. EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
  258. break;
  259. }
  260. } while (true);
  261. }
  262. ConnectionManager.Instance.Subscribe($"{Name}", this);
  263. _thread = new PeriodicJob(50, OnTimer, $"{Module}.{Name} MonitorHandler", true);
  264. }
  265. private bool OnTimer()
  266. {
  267. try
  268. {
  269. MonitorFoupState();
  270. if (_isTcpConnection)
  271. {
  272. _tcpConnection.EnableLog(_enableLog);
  273. _trigCommunicationError.CLK = _tcpConnection.IsCommunicationError;
  274. if (_trigCommunicationError.Q)
  275. {
  276. EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_tcpConnection.LastCommunicationError}");
  277. OnError("Communicartion Error");
  278. }
  279. }
  280. else
  281. {
  282. _connection.EnableLog(_enableLog);
  283. _trigCommunicationError.CLK = _connection.IsCommunicationError;
  284. if (_trigCommunicationError.Q)
  285. {
  286. EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
  287. OnError("Communicartion Error");
  288. }
  289. }
  290. if (_isTcpConnection)
  291. {
  292. _tcpConnection.MonitorTimeout();
  293. if (!_tcpConnection.IsConnected || _tcpConnection.IsCommunicationError)
  294. {
  295. lock (_locker)
  296. {
  297. _lstHandler.Clear();
  298. }
  299. _trigRetryConnect.CLK = !_tcpConnection.IsConnected;
  300. if (_trigRetryConnect.Q)
  301. {
  302. Address = SC.GetStringValue($"LoadPort.{Name}.Address");
  303. _tcpConnection = new TDKB200LoadPortTCPConnection(this, Address);
  304. _tcpConnection.EnableLog(_enableLog);
  305. if (!_tcpConnection.Connect())
  306. {
  307. EV.PostAlarmLog(Module, $"Can not connect with {_tcpConnection.Address}, {Module}.{Name}");
  308. }
  309. }
  310. return true;
  311. }
  312. _trigActionDone.CLK = (_lstHandler.Count == 0 && !_tcpConnection.IsBusy);
  313. if (_trigActionDone.Q)
  314. OnActionDone(null);
  315. HandlerBase handler = null;
  316. if (!_tcpConnection.IsBusy)
  317. {
  318. lock (_locker)
  319. {
  320. if (_lstHandler.Count == 0)
  321. {
  322. }
  323. if (_lstHandler.Count > 0)
  324. {
  325. handler = _lstHandler.First.Value;
  326. if (handler != null) _tcpConnection.Execute(handler);
  327. _lstHandler.RemoveFirst();
  328. }
  329. }
  330. }
  331. }
  332. else
  333. {
  334. _connection.MonitorTimeout();
  335. if (!_connection.IsConnected || _connection.IsCommunicationError)
  336. {
  337. lock (_locker)
  338. {
  339. _lstHandler.Clear();
  340. }
  341. _trigRetryConnect.CLK = !_connection.IsConnected;
  342. if (_trigRetryConnect.Q)
  343. {
  344. _connection.SetPortAddress(SC.GetStringValue($"{Name}.Address"));
  345. if (!_connection.Connect())
  346. {
  347. EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
  348. }
  349. }
  350. return true;
  351. }
  352. _trigActionDone.CLK = (_lstHandler.Count == 0 && !_connection.IsBusy);
  353. if (_trigActionDone.Q)
  354. OnActionDone(null);
  355. HandlerBase handler = null;
  356. if (!_connection.IsBusy)
  357. {
  358. lock (_locker)
  359. {
  360. if (_lstHandler.Count == 0)
  361. {
  362. }
  363. if (_lstHandler.Count > 0)
  364. {
  365. handler = _lstHandler.First.Value;
  366. if (handler != null) _connection.Execute(handler);
  367. _lstHandler.RemoveFirst();
  368. }
  369. }
  370. }
  371. }
  372. if (IsAutoDetectCarrierType)
  373. {
  374. _infoPadType = SC.ContainsItem($"LoadPort.{Name}.InfoPadType") ? SC.GetValue<int>($"LoadPort.{Name}.InfoPadType") : 2;
  375. if (_infoPadType == 2)
  376. {
  377. InfoPadCarrierIndex = SC.GetValue<int>($"LoadPort.{Name}.CarrierIndex");
  378. }
  379. if (_infoPadType == 1)
  380. {
  381. InfoPadCarrierIndex = (_diInfoPadA == null || !_diInfoPadA.Value ? 0 : 1) +
  382. (_diInfoPadB == null || !_diInfoPadB.Value ? 0 : 2) +
  383. (_diInfoPadC == null || !_diInfoPadC.Value ? 0 : 4) +
  384. (_diInfoPadD == null || !_diInfoPadD.Value ? 0 : 8);
  385. }
  386. }
  387. else
  388. {
  389. InfoPadCarrierIndex = SC.GetValue<int>($"LoadPort.{Name}.CarrierIndex");
  390. }
  391. }
  392. catch (Exception ex)
  393. {
  394. LOG.Write(ex);
  395. }
  396. return true;
  397. }
  398. public override void Monitor()
  399. {
  400. base.Monitor();
  401. try
  402. {
  403. }
  404. catch (Exception ex)
  405. {
  406. LOG.Write(ex);
  407. }
  408. }
  409. private void MonitorFoupState()
  410. {
  411. if (IsPlacement)
  412. {
  413. int currentfoupstatecode = (ClampPosition == TDKPosition.Close ? 0 : 1) +
  414. (DockPosition == TDKDockPosition.Dock ? 0 : 2) +
  415. (DoorState == FoupDoorState.Close ? 0 : 4) +
  416. (DoorPosition == FoupDoorPostionEnum.Down ? 0 : 8);
  417. if(currentfoupstatecode!= _foupstatecode)
  418. {
  419. _dtFoupStateStart = DateTime.Now;
  420. _foupstatecode = currentfoupstatecode;
  421. }
  422. int timeoutNoOperation = SC.ContainsItem($"{_scRoot}.{Name}.TimeLimitNoOperation") ?
  423. SC.GetValue<int>($"{_scRoot}.{Name}.TimeLimitNoOperation") : 3600000;
  424. if(DateTime.Now - _dtFoupStateStart > TimeSpan.FromSeconds(timeoutNoOperation))
  425. {
  426. EV.Notify(AlarmTdkNoOperation);
  427. _dtFoupStateStart = DateTime.Now;
  428. }
  429. }
  430. }
  431. private DateTime _dtFoupStateStart = DateTime.Now;
  432. private int _foupstatecode = -1;
  433. private R_TRIG _trigActionDone = new R_TRIG();
  434. private string _scRoot;
  435. private bool _isTcpConnection;
  436. private TDKB200LoadPortConnection _connection;
  437. private TDKB200LoadPortTCPConnection _tcpConnection;
  438. private IoTrigger _doLoadPortOK;
  439. private IoSensor _diInfoPadA;
  440. private IoSensor _diInfoPadB;
  441. private IoSensor _diInfoPadC;
  442. private IoSensor _diInfoPadD;
  443. private int _infoPadType=0;
  444. public int InfoPadType => _infoPadType;
  445. public TDKB200LoadPortConnection Connection
  446. {
  447. get => _connection;
  448. }
  449. public TDKB200LoadPortTCPConnection TCPConnection => _tcpConnection;
  450. private PeriodicJob _thread;
  451. private static Object _locker = new Object();
  452. private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
  453. private bool _enableLog = true;
  454. //private bool _commErr = false;
  455. private R_TRIG _trigError = new R_TRIG();
  456. private R_TRIG _trigWarningMessage = new R_TRIG();
  457. private R_TRIG _trigCommunicationError = new R_TRIG();
  458. private R_TRIG _trigRetryConnect = new R_TRIG();
  459. public TDKSystemStatus SystemStatus { get; set; }
  460. public TDKMode Mode { get; set; }
  461. public TDKInitPosMovement InitPosMovement { get; set; }
  462. public TDKOperationStatus OperationStatus { get; set; }
  463. public TDKContainerStatus ContainerStatus { get; set; }
  464. public TDKPosition ClampPosition { get; set; }
  465. public TDKPosition LPDoorLatchPosition { get; set; }
  466. public TDKVacummStatus VacuumStatus { get; set; }
  467. public TDKPosition LPDoorState { get; set; }
  468. public TDKWaferProtrusion WaferProtrusion { get; set; }
  469. public TDKElevatorAxisPosition ElevatorAxisPosition { get; set; }
  470. public TDKDockPosition DockPosition { get; set; }
  471. public TDKMapPosition MapperPostion { get; set; }
  472. public TDKMappingStatus MappingStatus { get; set; }
  473. public TDKModel Model { get; set; }
  474. public string Address { get; set; }
  475. public bool IsConnected => _connection.IsConnected;
  476. public override bool IsEnableTransferWafer(out string reason)
  477. {
  478. if(LPDoorState != TDKPosition.Open)
  479. {
  480. reason = "Door is not open";
  481. return false;
  482. }
  483. if(DockPosition != TDKDockPosition.Dock)
  484. {
  485. reason = "Foup is not dock";
  486. return false;
  487. }
  488. return base.IsEnableTransferWafer(out reason);
  489. }
  490. public bool Disconnect()
  491. {
  492. if (_isTcpConnection)
  493. return _tcpConnection.Disconnect();
  494. return _connection.Disconnect();
  495. }
  496. public void OnCarrierNotPlaced()
  497. {
  498. _isPlaced = false;
  499. ConfirmRemoveCarrier();
  500. }
  501. public void OnCarrierNotPresent()
  502. {
  503. _isPresent = false;
  504. //ConfirmRemoveCarrier();
  505. }
  506. public void OnCarrierPlaced()
  507. {
  508. _isPlaced = true;
  509. ConfirmAddCarrier();
  510. }
  511. public void OnCarrierPresent()
  512. {
  513. _isPresent = true;
  514. //ConfirmAddCarrier();
  515. }
  516. public void OnSwitchKey1()
  517. {
  518. _isAccessSwPressed = true;
  519. }
  520. public void OnSwitchKey2()
  521. {
  522. }
  523. public void OffSwitchKey1()
  524. {
  525. _isAccessSwPressed = false;
  526. }
  527. public void OffSwitchKey2()
  528. {
  529. }
  530. public bool OnEvent(out string reason)
  531. {
  532. reason = string.Empty;
  533. lock (_locker)
  534. {
  535. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  536. //_lstHandler.AddLast(new TDKB200GetHandler(this, "FSBxx", null));
  537. _lstHandler.AddLast(new TDKB200GetHandler(this, "LEDST", null));
  538. }
  539. return true;
  540. }
  541. private LoadportCassetteState _cassetteState = LoadportCassetteState.None;
  542. public override LoadportCassetteState CassetteState
  543. {
  544. get { return _cassetteState; }
  545. set
  546. {
  547. _cassetteState = value;
  548. }
  549. }
  550. public void SetCassetteState(LoadportCassetteState state)
  551. {
  552. _cassetteState = state;
  553. if (state == LoadportCassetteState.Normal)
  554. {
  555. OnCarrierPresent();
  556. OnCarrierPlaced();
  557. }
  558. if (state == LoadportCassetteState.Absent)
  559. {
  560. OnCarrierNotPlaced();
  561. OnCarrierNotPresent();
  562. }
  563. }
  564. public override WaferSize GetCurrentWaferSize()
  565. {
  566. int intwz = SC.GetValue<int>($"CarrierInfo.CarrierWaferSize{InfoPadCarrierIndex}");
  567. switch(intwz)
  568. {
  569. case 0:
  570. return WaferSize.WS0;
  571. case 1:
  572. return WaferSize.WS0;
  573. case 2:
  574. return WaferSize.WS2;
  575. case 3:
  576. return WaferSize.WS3;
  577. case 4:
  578. return WaferSize.WS4;
  579. case 5:
  580. return WaferSize.WS5;
  581. case 6:
  582. return WaferSize.WS6;
  583. case 7:
  584. case 8:
  585. return WaferSize.WS8;
  586. case 12:
  587. return WaferSize.WS12;
  588. default:
  589. return WaferSize.WS0;
  590. }
  591. }
  592. public override string SpecCarrierType
  593. {
  594. get
  595. {
  596. if(SC.ContainsItem($"CarrierInfo.CarrierName{InfoPadCarrierIndex}"))
  597. return SC.GetStringValue($"CarrierInfo.CarrierName{InfoPadCarrierIndex}");
  598. return "";
  599. }
  600. set => base.SpecCarrierType = value;
  601. }
  602. protected override bool fStartWrite(object[] param)
  603. {
  604. return true;
  605. }
  606. protected override bool fStartRead(object[] param)
  607. {
  608. return true;
  609. }
  610. protected override bool fStartExecute(object[] param)
  611. {
  612. try
  613. {
  614. switch (param[0].ToString())
  615. {
  616. case "SetIndicator":
  617. Indicator light = (Indicator)param[1];
  618. if (light != Indicator.LOAD && light != Indicator.UNLOAD)
  619. {
  620. IsBusy = false;
  621. return true;
  622. }
  623. IndicatorState state = (IndicatorState)param[2];
  624. string[] statestr = new string[] { "", "LON", "LBL", "LOF" };
  625. lock (_locker)
  626. {
  627. _lstHandler.AddLast(new TDKB200SetHandler(this, statestr[(int)state]+ $"{(int)light:D2}",null));
  628. _lstHandler.AddLast(new TDKB200GetHandler(this, "LEDST", null));
  629. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  630. IsBusy = false;
  631. }
  632. break;
  633. case "QueryIndicator":
  634. lock (_locker)
  635. {
  636. _lstHandler.AddLast(new TDKB200GetHandler(this, "LEDST", null));
  637. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  638. }
  639. break;
  640. case "QueryState":
  641. lock (_locker)
  642. {
  643. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  644. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  645. }
  646. break;
  647. case "Undock":
  648. lock (_locker)
  649. {
  650. _lstHandler.AddLast(new TDKB200MoveHandler(this, "YWAIT", null));
  651. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  652. }
  653. break;
  654. case "Dock":
  655. lock (_locker)
  656. {
  657. _lstHandler.AddLast(new TDKB200MoveHandler(this, "YDOOR", null));
  658. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  659. }
  660. break;
  661. case "CloseDoor":
  662. lock (_locker)
  663. {
  664. _lstHandler.AddLast(new TDKB200MoveHandler(this, "DORFW", null));
  665. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  666. }
  667. break;
  668. case "OpenDoor":
  669. lock (_locker)
  670. {
  671. _lstHandler.AddLast(new TDKB200MoveHandler(this, "DORBK", null));
  672. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  673. }
  674. break;
  675. case "Unclamp":
  676. lock (_locker)
  677. {
  678. _lstHandler.AddLast(new TDKB200MoveHandler(this, "PODOP", null));
  679. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  680. }
  681. break;
  682. case "Clamp":
  683. lock (_locker)
  684. {
  685. _lstHandler.AddLast(new TDKB200MoveHandler(this, "PODCL", null));
  686. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  687. }
  688. break;
  689. case "DoorUp":
  690. lock (_locker)
  691. {
  692. _lstHandler.AddLast(new TDKB200MoveHandler(this, "ZDRUP", null));
  693. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  694. }
  695. break;
  696. case "DoorDown":
  697. lock (_locker)
  698. {
  699. _lstHandler.AddLast(new TDKB200MoveHandler(this, "ZDRDW", null));
  700. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  701. }
  702. break;
  703. case "OpenDoorNoMap":
  704. lock (_locker)
  705. {
  706. //_lstHandler.AddLast(new TDKMoveHandler(this, "YDOOR", null));
  707. }
  708. break;
  709. case "OpenDoorAndMap":
  710. lock (_locker)
  711. {
  712. //_lstHandler.AddLast(new TDKMoveHandler(this, "YDOOR", null));
  713. }
  714. break;
  715. case "MapWafer":
  716. lock (_locker)
  717. {
  718. if (!IsMapWaferByLoadPort)
  719. {
  720. if (MapRobot != null)
  721. return MapRobot.WaferMapping(LPModuleName, out _);
  722. return false;
  723. }
  724. if (DockPosition != TDKDockPosition.Dock)
  725. _lstHandler.AddLast(new TDKB200MoveHandler(this, "YDOOR", null));
  726. if (DoorState != FoupDoorState.Open)
  727. _lstHandler.AddLast(new TDKB200MoveHandler(this, "DORBK", null));
  728. _lstHandler.AddLast(new TDKB200MoveHandler(this, "MAPDO", null));
  729. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  730. _lstHandler.AddLast(new TDKB200GetHandler(this, "MAPRD", null));
  731. }
  732. break;
  733. case "DoorUpAndClose":
  734. lock (_locker)
  735. {
  736. _lstHandler.AddLast(new TDKB200MoveHandler(this, "ZDRUP", null));
  737. _lstHandler.AddLast(new TDKB200MoveHandler(this, "DORFW", null));
  738. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  739. }
  740. break;
  741. case "OpenDoorAndDown":
  742. lock (_locker)
  743. {
  744. _lstHandler.AddLast(new TDKB200MoveHandler(this, "DORBK", null));
  745. _lstHandler.AddLast(new TDKB200MoveHandler(this, "ZDRDW", null));
  746. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  747. }
  748. break;
  749. case "Move":
  750. lock (_locker)
  751. {
  752. _lstHandler.AddLast(new TDKB200MoveHandler(this, param[1].ToString(), null));
  753. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  754. }
  755. break;
  756. case "Set":
  757. lock (_locker)
  758. {
  759. _lstHandler.AddLast(new TDKB200SetHandler(this, param[1].ToString(), null));
  760. }
  761. break;
  762. case "Get":
  763. lock (_locker)
  764. {
  765. _lstHandler.AddLast(new TDKB200GetHandler(this, param[1].ToString(), null));
  766. }
  767. break;
  768. }
  769. return true;
  770. }
  771. catch (Exception ex)
  772. {
  773. LOG.Write(ex);
  774. EV.PostAlarmLog(Name, $"Parameter invalid");
  775. return false;
  776. }
  777. }
  778. protected override bool fStartUnload(object[] param)
  779. {
  780. if (!_isPlaced)
  781. {
  782. EV.PostAlarmLog(Name, $"No carrier on {Name},can't unload.");
  783. return false;
  784. }
  785. if (!_isDocked)
  786. {
  787. EV.PostAlarmLog(Name, $"Carrier is not docked on {Name},can't unload.");
  788. return false;
  789. }
  790. lock (_locker)
  791. {
  792. _lstHandler.AddLast(new TDKB200MoveHandler(this, "CULOD", null));
  793. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  794. }
  795. return true;
  796. }
  797. protected override bool fStartLoad(object[] param)
  798. {
  799. if (!_isPlaced)
  800. {
  801. EV.PostAlarmLog(Name, $"No carrier on {Name},can't load.");
  802. return false;
  803. }
  804. if (_isDocked)
  805. {
  806. EV.PostAlarmLog(Name, $"Carrier is docked on {Name},can't load.");
  807. return false;
  808. }
  809. lock (_locker)
  810. {
  811. _lstHandler.AddLast(new TDKB200MoveHandler(this, "CLOAD", null));
  812. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  813. }
  814. return true;
  815. }
  816. protected override bool fStartInit(object[] param)
  817. {
  818. lock (_locker)
  819. {
  820. if (param.Length >= 1 && param[0].ToString() == "ForceHome")
  821. _lstHandler.AddLast(new TDKB200MoveHandler(this, "ABORG", null));
  822. else
  823. _lstHandler.AddLast(new TDKB200MoveHandler(this, "ORGSH", null));
  824. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  825. _lstHandler.AddLast(new TDKB200GetHandler(this, "FSBxx", null));
  826. _lstHandler.AddLast(new TDKB200GetHandler(this, "LEDST", null));
  827. }
  828. return true;
  829. }
  830. public override bool SetIndicator(Indicator light, IndicatorState state, out string reason)
  831. {
  832. reason = "";
  833. return fStartExecute(new object[] { "SetIndicator", light, state });
  834. }
  835. protected override bool fStartReset(object[] param)
  836. {
  837. _lstHandler.Clear();
  838. if (_isTcpConnection)
  839. {
  840. if (!_tcpConnection.IsConnected)
  841. _tcpConnection.Connect();
  842. _tcpConnection.ForceClear();
  843. }
  844. else
  845. {
  846. if (!_connection.IsConnected)
  847. _connection.Connect();
  848. _connection.ForceClear();
  849. }
  850. lock (_locker)
  851. {
  852. _lstHandler.AddLast(new TDKB200SetHandler(this, "RESET", null));
  853. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  854. _lstHandler.AddLast(new TDKB200GetHandler(this, "FSBxx", null));
  855. _lstHandler.AddLast(new TDKB200GetHandler(this, "LEDST", null));
  856. }
  857. return true;
  858. }
  859. public override void OnError(string error = "")
  860. {
  861. lock (_locker)
  862. {
  863. _lstHandler.Clear();
  864. if (_isTcpConnection)
  865. _tcpConnection.ForceClear();
  866. else
  867. _connection.ForceClear();
  868. _lstHandler.AddLast(new TDKB200GetHandler(this, "STATE", null));
  869. _lstHandler.AddLast(new TDKB200GetHandler(this, "FSBxx", null));
  870. _lstHandler.AddLast(new TDKB200GetHandler(this, "LEDST", null));
  871. }
  872. base.OnError(error);
  873. }
  874. public void OnAbs(string absMsg)
  875. {
  876. try
  877. {
  878. string absContext = absMsg.Split('/')[1].Replace(";", "").Replace("\r","");
  879. EV.Notify($"{Name}{absContext}");
  880. }
  881. catch(Exception ex)
  882. {
  883. LOG.Write(ex);
  884. }
  885. OnError("Recieve ABS Message:" + absMsg);
  886. }
  887. public override void Terminate()
  888. {
  889. _thread.Stop();
  890. Thread.Sleep(100);
  891. if (!SC.ContainsItem($"{_scRoot}.{Name}.CloseConnectionOnShutDown") || SC.GetValue<bool>($"{_scRoot}.{Name}.CloseConnectionOnShutDown"))
  892. {
  893. LOG.Write($"Close {Address} for connection of {LPModuleName}");
  894. _connection.Disconnect();
  895. _connection.TerminateCom();
  896. }
  897. base.Terminate();
  898. }
  899. public override bool IsForbidAccessSlotAboveWafer()
  900. {
  901. if (SC.ContainsItem($"CarrierInfo.ForbidAccessAboveWaferCarrier{InfoPadCarrierIndex}"))
  902. return SC.GetValue<bool>($"CarrierInfo.ForbidAccessAboveWaferCarrier{InfoPadCarrierIndex}");
  903. return false;
  904. }
  905. }
  906. }