TruPlasmaRF.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Core.RT.Tolerance;
  8. using Aitex.Core.UI.Control;
  9. using Aitex.Core.Util;
  10. using MECF.Framework.Common.Communications;
  11. using MECF.Framework.Common.DataCenter;
  12. using MECF.Framework.Common.Device.Bases;
  13. using MECF.Framework.Common.Equipment;
  14. using System;
  15. using System.Collections;
  16. using System.Collections.Generic;
  17. using System.Diagnostics;
  18. using System.Linq;
  19. using System.Net;
  20. using Venus_Core;
  21. namespace Venus_RT.Devices
  22. {
  23. public class TruPlasmaRF : RfPowerBase
  24. {
  25. private readonly AsyncSerialPort _serial;
  26. private static byte _ACK = 0x06;
  27. private static byte ParamRead = 0x01;
  28. private static byte ParamWrite = 0x02;
  29. private static byte TelegramError = 0xFE;
  30. private static byte MessageRead = 0x04;
  31. private static byte CtllnterfaceAct= 0x05;
  32. // private bool = 0x05;
  33. public TruPlasmaRF(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  34. {
  35. var portNum = SC.GetStringValue(device == VenusDevice.Rf ? $"{mod}.Rf.Port" : $"{mod}.BiasRf.Port");
  36. _serial = new AsyncSerialPort(portNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "\r\r");
  37. }
  38. public override bool Initialize()
  39. {
  40. base.Initialize();
  41. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  42. if (_serial.Open())
  43. {
  44. _serial.OnBinaryDataChanged += SerialPortDataReceived;
  45. _serial.OnErrorHappened += SerialPortErrorOccurred;
  46. }
  47. else
  48. {
  49. LOG.Write(eEvent.ERR_RF, Module, "Tru 射频发生器串口无法打开");
  50. return false;
  51. }
  52. return true;
  53. }
  54. public new AITRfData DeviceData =>
  55. new AITRfData
  56. {
  57. Module = Module,
  58. DeviceName = Name,
  59. ScalePower = ScalePower,
  60. ForwardPower = ForwardPower,
  61. ReflectPower = ReflectPower,
  62. IsRfOn = IsPowerOn,
  63. PowerSetPoint = PowerSetPoint,
  64. };
  65. private void SerialPortDataReceived(byte[] rawMessage)
  66. {
  67. LOG.Write(eEvent.INFO_RF, Module, $"RF byte"+rawMessage.ToString());
  68. try
  69. {
  70. if (rawMessage.Length==1&& rawMessage[1]== 0x06) //ACK 指令
  71. {
  72. }
  73. else if (rawMessage.Length > 1)
  74. {
  75. parsecmd(rawMessage);
  76. }
  77. }
  78. catch (Exception ex)
  79. {
  80. LOG.WriteExeption(ex);
  81. }
  82. }
  83. public void parsecmd(byte[] message)
  84. {
  85. switch (message[4])
  86. {
  87. case 0x01://ParamRead
  88. int DataValue = BitConverter.ToInt32(new byte[] { message[10], message[11], message[12], message[13] }, 0);
  89. ReflectPower = DataValue;
  90. break;
  91. case 0x02://ParamWrite
  92. DataValue = BitConverter.ToInt32(new byte[] { message[10] ,message[11], message[12], message[13] }, 0);
  93. ForwardPower = DataValue;
  94. break;
  95. case 0xFE://TelegramError
  96. LOG.Write(eEvent.ERR_RF, Module, "Telegram structure is not correct");
  97. break;
  98. default:
  99. // 默认代码块
  100. break;
  101. }
  102. }
  103. private void SerialPortErrorOccurred(string obj)
  104. {
  105. LOG.Write(eEvent.ERR_RF, Module, $"Tru 射频串口出错, [{obj}]");
  106. }
  107. public override void SetPower(float val)
  108. {
  109. //var power = !_scEnableCalibration.BoolValue ? val : CalibrationData(val, true);
  110. ForwardPower=val;
  111. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x06, 0x00, 0x01, 0x00, 0x04 };
  112. byte[] valueBytes = BitConverter.GetBytes((int)val);
  113. baseBytes.AddRange(valueBytes);
  114. baseBytes = CRC16(baseBytes.ToArray());
  115. baseBytes.Add(0x55);
  116. _serial.Write(baseBytes.ToArray());
  117. }
  118. public override bool SetPowerOnOff(bool on, out string str)
  119. {
  120. str = "";
  121. var _chamber = DEVICE.GetDevice<JetPMBase>(Module);
  122. if (on && !_chamber.CheckGeneratorAndHVInterlock(VenusDevice.Rf))
  123. {
  124. return false;
  125. }
  126. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6F, 0x00, 0x01, 0x00, 0x07 };
  127. if (on == true)
  128. {
  129. baseBytes.AddRange(new List<byte> { 0x01, 0x00, 0x00, 0x00 });
  130. }
  131. else
  132. {
  133. baseBytes.AddRange(new List<byte> { 0x00, 0x00, 0x00, 0x00 });
  134. }
  135. baseBytes = CRC16(baseBytes.ToArray());
  136. baseBytes.Add(0x55);
  137. _serial.Write(baseBytes.ToArray());
  138. return true;
  139. }
  140. public override void SetPulseMode(bool on)
  141. {
  142. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6A, 0x01, 0x01, 0x00, 0x04 };
  143. if (on == true)
  144. {
  145. baseBytes.AddRange(new List<byte> { 0x01, 0x00, 0x00, 0x00 });
  146. }
  147. else
  148. {
  149. baseBytes.AddRange(new List<byte> { 0x00, 0x00, 0x00, 0x00 });
  150. }
  151. baseBytes = CRC16(baseBytes.ToArray());
  152. baseBytes.Add(0x55);
  153. _serial.Write(baseBytes.ToArray());
  154. }
  155. public override void SetPulseRateFreq(int nFreq)
  156. {
  157. if (nFreq > 0)
  158. {
  159. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6C, 0x01, 0x01, 0x00, 0x04 };
  160. byte[] valueBytes = BitConverter.GetBytes(nFreq);
  161. baseBytes.AddRange(valueBytes);
  162. baseBytes = CRC16(baseBytes.ToArray());
  163. baseBytes.Add(0x55);
  164. _serial.Write(baseBytes.ToArray());
  165. }
  166. else
  167. {
  168. LOG.Write(eEvent.ERR_RF, Module, $"{Name},SetPulseRateFreq() parameter error: {nFreq}");
  169. }
  170. }
  171. public override void SetPulseDutyCycle(int percentage)
  172. {
  173. if (percentage >= 10 && percentage <= 90)
  174. {
  175. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6D, 0x01, 0x01, 0x00, 0x04 };
  176. byte[] valueBytes = BitConverter.GetBytes(percentage);
  177. baseBytes.AddRange(valueBytes);
  178. baseBytes = CRC16(baseBytes.ToArray());
  179. baseBytes.Add(0x55);
  180. _serial.Write(baseBytes.ToArray());
  181. }
  182. else
  183. {
  184. LOG.Write(eEvent.ERR_RF, Module, $"{Name},SetPulseDutyCycle() parameter error: {percentage}");
  185. }
  186. }
  187. #region 霍廷格RF协议crc-16/CCITT-FALSE校验
  188. private bool CRC16(byte[] buffer, ref byte[] ResCRC16) // crc-16/CCITT-FALSE,判断校验
  189. {
  190. bool status = false;
  191. ushort crc = 0xFFFF;
  192. int size = buffer.Length; //计算待计算的数据长度
  193. int i = 0;
  194. if (size > 0)
  195. {
  196. while (size-- > 0)
  197. {
  198. crc = (ushort)((crc >> 8) | (crc << 8));
  199. crc ^= buffer[i++];
  200. crc ^= (ushort)(((byte)crc) >> 4);
  201. crc ^= (ushort)(crc << 12);
  202. crc ^= (ushort)((crc & 0xff) << 5);
  203. }
  204. }
  205. //判断输入的ResCRC16与计算出来的是否一致
  206. if (ResCRC16[0] == (byte)((crc >> 8) & 0xff) && ResCRC16[1] == (byte)(crc & 0xff))
  207. {
  208. status = true;
  209. }
  210. return status;
  211. }
  212. private List<byte> CRC16(byte[] buffer) // crc-16/CCITT-FALSE,补全两个字节
  213. {
  214. ushort crc = 0xFFFF;
  215. int size = buffer.Length; //计算待计算的数据长度
  216. int i = 0;
  217. if (size > 0)
  218. {
  219. while (size-- > 0)
  220. {
  221. crc = (ushort)((crc >> 8) | (crc << 8));
  222. crc ^= buffer[i++];
  223. crc ^= (ushort)(((byte)crc) >> 4);
  224. crc ^= (ushort)(crc << 12);
  225. crc ^= (ushort)((crc & 0xff) << 5);
  226. }
  227. }
  228. var byteList = buffer.ToList();
  229. byteList.Add((byte)(crc & 0xff));
  230. byteList.Add((byte)((crc >> 8) & 0xff));
  231. return byteList;
  232. }
  233. #endregion
  234. }
  235. static class TruPlasmaMatchMessage
  236. {
  237. public const string PRESET = "G";
  238. public const string AUTO = "L";
  239. public const string MANUAL = "M";
  240. public const string PRESET_MEM = "P";
  241. public const string START_QUERY = "S3";
  242. public const string STOP_QUERY = "SP";
  243. public const string WRITE_POS = "$APGR";
  244. public const string READ_POS = "$APRR";
  245. }
  246. class TruPlasmaMatch : RfMatchBase
  247. {
  248. private readonly AsyncSerialPort _serial;
  249. private const ushort S3_HEAD_LENGTH = 2;
  250. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  251. private int QUERY_INTERVAL = 1000;
  252. //private int _scMatchPresetMode;
  253. //private int _scMatchMode;
  254. //private readonly SCConfigItem _scMatchPositionC1;
  255. //private readonly SCConfigItem _scMatchPositionC2;
  256. //private readonly bool _scEnableC1C2Position;
  257. // --------------------------Properties------------------------
  258. //
  259. [Subscription("MatchWorkMode")]
  260. public EnumRfMatchTuneMode WorkMode { get; set; }
  261. public float C1 { get; set; }
  262. public float C2 { get; set; }
  263. //[Subscription("VPP")]
  264. public ushort VPP { get; set; }
  265. public new AITMatchData DeviceData
  266. {
  267. get
  268. {
  269. return new AITMatchData
  270. {
  271. Module = Module,
  272. DeviceName = Name,
  273. WorkMode = WorkMode.ToString(),
  274. C1 = TunePosition1,
  275. C2 = TunePosition2,
  276. VPP = "",
  277. DCBias = DCBias.ToString()
  278. };
  279. }
  280. }
  281. public TruPlasmaMatch(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  282. {
  283. var portNum = SC.GetStringValue($"{mod}.{device}.Port");
  284. _serial = new AsyncSerialPort(portNum, 9600, 8);
  285. //_scMatchPresetMode = SC.GetValue<int>($"{Module}.Rf.PresetMode");
  286. //_scMatchMode = SC.GetValue<int>($"{Module}.Rf.MatchMode");
  287. //_scMatchPositionC1 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1");
  288. //_scMatchPositionC2 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2");
  289. //_scEnableC1C2Position = SC.GetValue<bool>($"{Module}.Rf.EnableC1C2Position");
  290. SerachCommandList = new List<string>()
  291. {
  292. AdTecMatchMessage.READ_POS,
  293. AdTecMatchMessage.START_QUERY
  294. };
  295. intervalTime = 100;
  296. sendDataChangedEvent += TruMatch_sendDataChangedEvent;
  297. baseStopwatch.Start();
  298. baseTimer.Enabled = true;
  299. }
  300. private void TruMatch_sendDataChangedEvent(string obj)
  301. {
  302. this.SendCmd(obj);
  303. }
  304. ~TruPlasmaMatch()
  305. {
  306. _serial?.Close();
  307. }
  308. public override bool Initialize()
  309. {
  310. base.Initialize();
  311. if (_serial.Open())
  312. {
  313. _serial.OnBinaryDataChanged += SerialBinaryPortDataReceived;
  314. _serial.OnErrorHappened += SerialPortErrorOccurred;
  315. }
  316. else
  317. {
  318. LOG.Write(eEvent.ERR_RF, Module, "Match 串口无法打开");
  319. return false;
  320. }
  321. DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
  322. DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
  323. DATA.Subscribe($"{Module}.{Name}.WorkMode", () => WorkMode.ToString());
  324. OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
  325. {
  326. return true;
  327. });
  328. OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
  329. {
  330. return true;
  331. });
  332. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
  333. {
  334. SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
  335. return true;
  336. });
  337. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
  338. {
  339. SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
  340. return true;
  341. });
  342. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
  343. {
  344. SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
  345. return true;
  346. });
  347. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
  348. {
  349. SetMatchMode((string)param[0] == "Auto" ? EnumRfMatchTuneMode.Auto : EnumRfMatchTuneMode.Manual, out reason);
  350. return true;
  351. });
  352. _timerQueryStatus.Start(QUERY_INTERVAL);
  353. this.SendCmd(AdTecMatchMessage.START_QUERY);
  354. //LOG.Write(eEvent.ERR_RF, Module, "Initialize done.");
  355. return true;
  356. }
  357. public override void Monitor()
  358. {
  359. //try
  360. //{
  361. // if (_timerQueryStatus.IsTimeout())
  362. // {
  363. // this.SendCmd(AdTecMatchMessage.READ_POS);
  364. // _timerQueryStatus.Start(QUERY_INTERVAL);
  365. // }
  366. //}
  367. //catch (Exception ex)
  368. //{
  369. // LOG.WriteExeption(ex);
  370. //}
  371. }
  372. public override void Terminate()
  373. {
  374. this.SendCmd(AdTecMatchMessage.STOP_QUERY);
  375. }
  376. public override void Reset()
  377. {
  378. //SendCmd(AdTecMatchMessage.STOP_QUERY);
  379. }
  380. /// <summary>
  381. ///
  382. /// </summary>
  383. /// <param name="c1,c2">百分比数字</param>
  384. /// <param name="c2"></param>
  385. ///
  386. private void executeMatchPostion(float c1, float c2)
  387. {
  388. //SetWorkMode(EnumRfMatchTuneMode.Manual);
  389. ////await Task.Delay(200);
  390. SetPosition(c1, c2);
  391. //await Task.Delay(200);
  392. //SetPresetMemory(0);
  393. //await Task.Delay(200);
  394. // SetWorkMode(EnumRfMatchTuneMode.Auto);
  395. }
  396. public override void SetMatchPosition(float c1, float c2, out string reason)
  397. {
  398. float DataValue = BitConverter.ToSingle(new byte[] { 0x9A, 0x99, 0x19,0x3F }, 0);
  399. byte[] floatAsBytes = BitConverter.GetBytes(DataValue);
  400. float DataValue1= BitConverter.ToSingle(new byte[] { floatAsBytes[0], floatAsBytes[1], floatAsBytes[2], floatAsBytes[3] }, 0);
  401. //LOG.Write(eEvent.WARN_RF, Module, $"AdTec Match error [{c1}, {c2}]");
  402. base.SetMatchPosition(c1, c2, out reason);
  403. executeMatchPostion(c1, c2);
  404. reason = "";
  405. }
  406. public void SetPresetMode(RfMatchPresetMode mode)
  407. {
  408. }
  409. // -----------------------Private Method-------------------------
  410. //
  411. private void SerialBinaryPortDataReceived(byte[] message)
  412. {
  413. if(message.Count()==0)
  414. {
  415. LOG.Write(eEvent.ERR_RF, Module, "收到 Match 数据为空");
  416. return;
  417. }
  418. else
  419. {
  420. if (message[0] ==0x1D && message[6]==0x60 && message[7] == 0x00)
  421. {
  422. this.TunePosition1 = BitConverter.ToSingle(new byte[] { message[10], message[11], message[12], message[13] }, 0) * 10;
  423. this.TunePosition2 = BitConverter.ToSingle(new byte[] { message[14], message[15], message[16], message[17] }, 0) * 10;
  424. switch (message[7])
  425. {
  426. case 0x01:
  427. this.WorkMode = EnumRfMatchTuneMode.Manual;
  428. break;
  429. case 0x02:
  430. this.WorkMode = EnumRfMatchTuneMode.Auto;
  431. break;
  432. case 0x20:
  433. this.WorkMode = EnumRfMatchTuneMode.Undefined;
  434. break;
  435. default:
  436. break;
  437. }
  438. }
  439. }
  440. }
  441. private void SerialPortErrorOccurred(string str)
  442. {
  443. LOG.Write(eEvent.ERR_RF, Module, $"AdTec Match error [{str}]");
  444. }
  445. private void SendCmd(string str)
  446. {
  447. _serial?.Write(str + "\r");
  448. //EV.PostInfoLog(Module.ToString(), $"Match send [{str}]");
  449. }
  450. private void SetPosition(float c1val, float c2val)
  451. {
  452. List<byte> Len = new List<byte>() { 0x16, 0xE9};
  453. List<byte> DstSrc = new List<byte>() { 0x00, 0x0A, 0x00, 0x00};
  454. List<byte> Cmd = new List<byte> { 0x60, 0x40 };
  455. byte[] val1Bytes = BitConverter.GetBytes(c1val / 100);
  456. byte[] val2Bytes = BitConverter.GetBytes(c2val / 100);
  457. List<byte> Act = new List<byte>() { 0x64 };
  458. List<byte> Ctr123 = new List<byte> { 0x08, 0x01, 0x80 };
  459. List<byte> baseBytes = new List<byte>() { };
  460. baseBytes.AddRange(Len);
  461. baseBytes.AddRange(DstSrc);
  462. baseBytes.AddRange(Cmd);
  463. baseBytes.AddRange(val1Bytes);
  464. baseBytes.AddRange(val2Bytes);
  465. baseBytes.AddRange(Act);
  466. baseBytes.AddRange(Ctr123);
  467. byte ack=0x00;
  468. for (int i=2; i< baseBytes.Count;i++)
  469. {
  470. ack += baseBytes[i];
  471. }
  472. baseBytes.Add(ack);
  473. //SetPointCommandQueue.Add(cmd);
  474. _serial.Write(baseBytes.ToArray());
  475. }
  476. public override bool SetMatchMode(EnumRfMatchTuneMode enumRfMatchTuneMode, out string reason)
  477. {
  478. reason = string.Empty;
  479. SetWorkMode(enumRfMatchTuneMode);
  480. return true;
  481. }
  482. private void SetWorkMode(EnumRfMatchTuneMode mode)
  483. {
  484. //string data = mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :
  485. // mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "";
  486. //this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :
  487. // mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "");
  488. //SetPointCommandQueue.Add(data);
  489. }
  490. private void SetPresetMemory(byte gear)
  491. {
  492. //this.SendCmd(AdTecMatchMessage.PRESET_MEM + gear.ToString());
  493. //SetPointCommandQueue.Add(AdTecMatchMessage.PRESET_MEM + gear.ToString());
  494. }
  495. }
  496. }