| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766 | using Aitex.Core.Common;using Aitex.Core.RT.DataCenter;using Aitex.Core.RT.Device;using Aitex.Core.RT.Event;using Aitex.Core.RT.Log;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using MECF.Framework.Common.Communications;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.SubstrateTrackings;using MECF.Framework.RT.ModuleLibrary.VceModules;using System;using System.Collections.Generic;using System.IO.Ports;using System.Linq;using System.Text;using System.Text.RegularExpressions;using System.Threading.Tasks;using Venus_Core;using Venus_RT.Devices.EFEM;using Venus_RT.Devices.TM;namespace Venus_RT.Devices.VCE{    //定义Vce动作    public enum VceCommand    {        Home,        DoorClose,        DoorOpen,        CheckGoto,        Goto,        GotoLP,        CheckStatus,        Load,        UnLoad,        Map,        ReadMap,        ClearError,    }    public enum VceMessageHead    {        Action,        Read,        Set,        Petrify    }    public sealed class VceMessage    {        private Dictionary<VceCommand, string> _Command2Msg = new Dictionary<VceCommand, string>()        {            //Action            {VceCommand.Home,       "HM"    },            {VceCommand.Load,       "LOAD"  },            {VceCommand.UnLoad,     "UNLOAD"},            {VceCommand.Map,        "MP"    },            {VceCommand.CheckGoto,  "GC"    },            {VceCommand.Goto,       "GO"    },            {VceCommand.GotoLP,     "LP"    },            {VceCommand.DoorOpen,   "DO"    },            {VceCommand.DoorClose,  "DC"    },            {VceCommand.CheckStatus,"OS"    },            //Read            {VceCommand.ReadMap,    "MI"    },            //Set            {VceCommand.ClearError, "ER" },        };        private Dictionary<VceMessageHead, string> _Type2Head = new Dictionary<VceMessageHead, string>()        {            {VceMessageHead.Action,  "A"},            {VceMessageHead.Read,    "R"},            {VceMessageHead.Set,     "S"},            {VceMessageHead.Petrify, "P"},        };        public VceMessageHead Head { get; set; }        public VceCommand Command { get; set; }        public string Param { get; set; }        public string toString()        {            if (string.IsNullOrEmpty(Param))//含尾参                return $"00,{_Type2Head[Head]},{_Command2Msg[Command]}";            else//不含尾参 目前只允许一个                return $"00,{_Type2Head[Head]},{_Command2Msg[Command]},{Param}";        }    }    /// <summary>    /// 泓浒Vce驱动 下发指令等    /// </summary>    public class HongHuVce : VCEModuleBase    {        #region 私有变量        private AsyncSerialPort _serialport;        private string _portname;        private string _newline = "\r";//终止符 0D        private object _locker = new object();        private bool _IsAsciiMode;        private LinkedList<string> _lstAsciiMsgs = new LinkedList<string>();        private PeriodicJob _thread;        private Regex _match_ReadMsg = new Regex(@"\d\d,X,.*");        private Regex _matchErrorCode = new Regex(@"(?<=_BKGERR )(.*)");        private ModuleName _moduleName;        private RState _status;        private string _currentMsg;        private VceMessage _currentVceMessage;        private bool _HasReceiveMsg;        private bool _IsDashWaferError;        private int _currentSlot = 0;        public override int CurrentSlot => _currentSlot;        private ModuleName _baseLPIndex => _moduleName == ModuleName.VCEA ? ModuleName.LP1 : ModuleName.LP2;         private Loadport[] _LPMs = new Loadport[1];        public override ILoadport this[ModuleName mod]        {            get            {                if (!ModuleHelper.IsLoadPort(mod))                    throw new ApplicationException($"{mod} is NOT Loadport");                return _LPMs[mod - _baseLPIndex];            }        }        //待补充        private Dictionary<string, string> _ErrorCode2Reason = new Dictionary<string, string>()        {            {"A1","Action Timeout" },            {"A3","Hardware (CAN or VCN) or configuration failed" },            {"A4","Open Door Prevented Motion" },            {"A5","Platform Action Time-out" },            {"A6","Door Action Timeout" },            {"A7","由于动作连锁导致的异常" },            {"A8","Wafer Slideout" },            {"A9","Door safety LED is blocked" },            {"A11","载台上没有料盒,看一下载台上是否有料盒" },            {"A12","Cassette present prior PICK" },            {"A13","Cassette NOT present during PICK" },            {"A14","Cassette NOT present prior PLACE" },            {"A15","Cassette present after PLACE" },            {"A16","Cassette Present on VCE platform (Servo Arm)" },            {"A17","No new cassette at station after Load" },            {"A18","Proximity sensor blocked but Cassette A not present" },            {"A19","载台上料盒没有取走,请把料盒取走" },            {"A20","Proximity sensor A is blocked (Fixed Buffer)" },            {"A21","Cassette NOT at station A" },            {"A34","Door Clamped sensor is not ON after clamp (only VCE4!)" },            {"A36","Door Not Covered (sensor)" },            {"C0","Illegal Slot Number" },            {"C1","设备收到非法的操作指令" },            {"C2","Illegal pitch value (too big)" },            {"C3","Illegal Cassette type offset" },            {"C4","Illegal number of Slots" },            {"C5","Illegal Partial step size" },            {"C7","Illegal Find Bias" },            {"C8","Unknown Configuration" },            {"C9","Bad command: command cannot be executed with current HW configuration" },            {"C10","VCE is busy" },            {"C12","Bad Fixture Thickness" },            {"C13","Command is NOT executable (file's operation exception)" },            {"C19","VCEConfig.xml is corrupted" },            {"C20","VCEDefaultSettting.xml is corrupted" },            {"CAN1","CAN Error,Replace the board (MCC2B or MCC-GEN5 or MCC-GEN5 EN)" },            {"CAN2","CAN Abort,Replace the board (MCC2B or MCC-GEN5 or MCC-GEN5 EN)" },            {"CAN3","CAN Timeout,Replace the board (MCC2B or MCC-GEN5 or MCC-GEN5 EN)" },            {"H1","Two hand safety switch are not OFF before R-axis motion" },            {"H2","Two hands safety switch timeout" },            {"H3","One or both safety switches are release before R-axis motion is complete" },            {"M0","VCE is NOT Referenced" },            {"M1","Motion Timeout" },            {"M4","Door over speed" },            {"M10","设备中断,设备被外部停止" },            {"M11","FET over Temperature" },            {"M12","FET over Current" },            {"M13","Torque Limit" },            {"M14","Hard Track Error Codes" },            {"M16","Hardware (servo) Motion Error Codes" },            {"M17","Safety Motion Button was Pushed" },            {"M20","Z-brake request before ENABLE_Z_MOVE" },            {"M21","CPLD Detected a difference from the Dual Up Sensors" },            {"M22","Door Closed Error" },            {"M23","Z-brake chip U8 has an output fault" },            {"M24","Unsafe to move: See a safety node (ENABLE_Z_MOVE) or servo following error" },            {"M25","Servo Following Error" },            {"NO_ACT","No actions" },            {"P2","Map NOT Available" },            {"P3","SPS Excessive Offset" },            {"P4","SPS Excessive Thickness" },            {"P12","FB is too large to map" },            {"P13","FB is too small to map" },            {"R1","R-axis is not referenced" },            {"R2","Extended position is NOT defined" },            {"R3","Door NOT Opened" },            {"R4","Wrong Z-axis position: platform must be between UP and DOWN position" },            {"R5","R-axis Limit is exceeded" },            {"R6","R-axis is NOT Homed (it is not IN)" },            {"R7","R-axis Orientation is NOT set" },            {"R9","R-axis is NOT Extended" },            {"S0","Cannot configure Main VCN" },            {"S1","Cannot configure R-axis VCN" },            {"S4","Command String Error: Bad command or parameter, invalid value, etc." },            {"S5","Illegal data entry" },            {"S10","VCEDefaultSetting.XML file is corrupted. Configuration stop" },            {"S11","Not valid for current configuration" },            {"S20","MiscOutput is already in use" },            {"S21","MiscOutput is used by current configuration" },            {"S22","MiscOutput was deleted: it is used by current configuration" },            {"T5","VCN timeout" },            {"U1","USB not found or ‘Upgrade’ directory doesn’t exist" },            {"U2","Script file couldn't be opened" },            {"U3","Script file not found" },            {"U4","File from the list is not found" },            {"U5","Couldn’t create ‘Upgrade’ directory" },            {"U6","Couldn’t copy files" },            {"U10"," upgrade.txt  file is missing" },            {"V2","Cannot disable VCN" },            {"230","Robot Extended" },            {"231","Front buffer extended" },            {"232","Valve drive fault" },            {"236","Door Safety LED is broken" },            {"250","FET Q10 is open circuit" },            {"251","FET Q10 is shorted" },            {"260","Atmospheric Robot is Extended" },            {"261","ERGO Obstructs the Door" },            {"262","Door drive fault" },            {"263","Vacuum Robot is Extended" },            {"264","User Misc Output Drive Fault" },            {"265","Safety Hub Output Fault" },            {"306","Illegal command ID number" },            {"309","Command ID is not supported in thatCOMM FLOW" },            {"390","Invalid Checksum" },            {"414","Command ID in use" },            {"673","GEN5 EN: inputs are in ERROR state" },            {"674","GEN5 EN: inputs are in HALT state" },            {"675","GEN5 EN: inputs are in illegal transition" },            {"L13","由于检测到突片,动作被禁止" },            {"L14","防夹光栅报警,检查舱门关闭路径上是否存在遮挡" },            {"K114","防夹光栅报警" },            {"K115","舱门上限报警" },            {"K116","舱门下限报警 " },            {"K117","急停报警 " },            {"K118","位置未被引用,对设备进行初始化" },            {"K119","Z 轴报警" },            {"K120","R 轴报警 " },            {"K121","Z 轴超限位报警" },            {"K122","机械手不在安全位" },            {"K123","Z 轴未使能" },            {"K124","R 轴未使能" },            {"K125","盒子状态互锁报警" },            {"K158","左凸片" },            {"K159","右凸片" },            {"K160","门没有关好" },            {"K161","盖板缺失" },            {"K162","R轴不在原位" },            {"K163","Z轴不在上下料位" },            {"K164","门未打开" },        };        //                #endregion        #region 暴露变量        public override bool IsConnected => _serialport.IsOpen();        public override RState Status => _status;        public override bool IsReady => _status == RState.Init || _status == RState.End;        public override bool IsError => _status == RState.Failed || _status == RState.Timeout;        public override bool IsInit => _status == RState.Init;        public override bool IsDashWaferError => _IsDashWaferError;        private string[] _slotMap = new string[25];        public string SlotMap        {            get            {                WaferInfo[] wafers = WaferManager.Instance.GetWafers(ModuleHelper.Converter(Name));                string slot = "";                for (int i = 0; i < 25; i++)                {                    slot += wafers[i].IsEmpty ? "0" : "1";                }                return slot;            }        }        private bool _OutDoorIsOpen        {            get             {                switch (_moduleName)                {                    case ModuleName.VCE1:                        //2024-05-20 16:35:34 泓浒四边形硬件还未实现                        //DEVICE.GetDevice<HongHuTM>("SETM").VCEACassPresent                        return true;                    case ModuleName.VCEA:                        if (DEVICE.GetDevice<HongHuDETM>("DETM").VCEACassPresent)                        {                            _LPMs[0].HasCassette = true;                        }                        else                        {                            _LPMs[0].HasCassette = false;                            WaferManager.Instance.DeleteWafer(_LPMs[0].Module, 0, 25);                        }                        return !DEVICE.GetDevice<HongHuDETM>("DETM").VCEALOCKED;                    case ModuleName.VCEB:                        if (DEVICE.GetDevice<HongHuDETM>("DETM").VCEBCassPresent)                        {                            _LPMs[0].HasCassette = true;                        }                        else                        {                            _LPMs[0].HasCassette = false;                            WaferManager.Instance.DeleteWafer(_LPMs[0].Module, 0, 25);                        }                        return !DEVICE.GetDevice<HongHuDETM>("DETM").VCEBLOCKED;                    default:                        return false;                }            }        }        public override bool OutDoorIsOpen => _OutDoorIsOpen;        private bool _hasProtrusion        {            get            {                switch (_moduleName)                {                    case ModuleName.VCE1:                        //2024-05-20 16:35:34 泓浒四边形硬件还未实现                        //DEVICE.GetDevice<HongHuTM>("SETM").VCEProtrusion                        return true;                    case ModuleName.VCEA:                        if (DEVICE.GetDevice<HongHuDETM>("DETM").VCEAProtrusion)                        {                            _LPMs[0].Protrusion = true;                            return true;                        }                        else                        {                            _LPMs[0].Protrusion = false;                            return false;                        }                    case ModuleName.VCEB:                        if (DEVICE.GetDevice<HongHuDETM>("DETM").VCEBProtrusion)                        {                            _LPMs[0].Protrusion = true;                            return true;                        }                        else                        {                            _LPMs[0].Protrusion = false;                            return false;                        }                    default:                        return false;                }            }        }        #endregion        //传入slot数量        public HongHuVce(int slot, ModuleName moduleName) : base(slot, moduleName)        {            _moduleName = moduleName;            _IsAsciiMode = true;            _portname = SC.GetStringValue($"{moduleName}.Port");            _serialport = new AsyncSerialPort(_portname, 9600, 8, Parity.None, StopBits.One, _newline, _IsAsciiMode);            _serialport.Open();            _status = RState.Init;            _serialport.OnDataChanged += onDataChange;            _thread = new PeriodicJob(50, fnTimer, _moduleName.ToString(), true);            if(moduleName == ModuleName.VCE1)                _LPMs[0] = new Loadport(ModuleName.LP1);            else                _LPMs[0] = new Loadport((moduleName - ModuleName.VCEA) + ModuleName.LP1);            CarrierManager.Instance.DeleteCarrier(_LPMs[0].Module.ToString());            WaferManager.Instance.DeleteWafer(_LPMs[0].Module, 0, 25);            CarrierManager.Instance.SubscribeLocation(_LPMs[0].Module.ToString(), 1);            Action<ModuleName, int> _subscribeLoc = (ModuleName module, int waferCount) => {                if (ModuleHelper.IsInstalled(module))                {                    WaferManager.Instance.SubscribeLocation(module, waferCount);                }            };            _subscribeLoc(_LPMs[0].Module, slot);        }        /// <summary>        /// 对处理过的数据list进行处理        /// 将每条数据进行解析        /// </summary>        /// <returns></returns>        private bool fnTimer()        {            lock (_locker)            {                //采用ascii传输                if (_IsAsciiMode)                {                    //有数据尚未处理                    while (_lstAsciiMsgs.Count > 0)                    {                        string _needHandle = _lstAsciiMsgs.First.Value;                        HandleSingleMsg(_needHandle);                        _lstAsciiMsgs.RemoveFirst();                    }                }                //采用binary                else                {                }            }            return true;        }        /// <summary>        /// 处理单条信息的函数        /// 1、判断结束 2、判断错误        /// </summary>        /// <param name="msg">需要处理的单条回复</param>        private void HandleSingleMsg(string rawmsgs)        {            string[] msgs = rawmsgs.Split('\r');            foreach (var Msg in msgs)            {                string msg = Msg.Trim();                LOG.Write(eEvent.EV_VCE_COMMON_INFO, _moduleName, $"{_moduleName} Receive msg=>{msg}");                if (!string.IsNullOrEmpty(msg))                {                    //action set petrify _BKGRDY结束                    switch (_currentVceMessage.Head)                    {                        case VceMessageHead.Action:                        case VceMessageHead.Set:                        case VceMessageHead.Petrify:                            switch (msg)                            {                                //设备收到 开始运行 目前状态在下发                                case "_RDY":                                    LOG.Write(eEvent.EV_VCE_COMMON_INFO, _moduleName, $"vce start {_currentVceMessage.Head}");                                    break;                                //设备执行完毕                                case "_BKGRDY":                                    LOG.Write(eEvent.EV_VCE_COMMON_INFO, _moduleName, $"vce {_currentVceMessage.Head} over");                                    switch (_currentVceMessage.Command)                                    {                                        case VceCommand.Home:                                        case VceCommand.Map:                                        case VceCommand.GotoLP:                                            _currentSlot = 0;                                            break;                                    }                                    _status = RState.End;                                    break;                                //异常处理                                default:                                    _status = RState.Failed;                                    string reason;                                    Errorhandle(msg, out reason);                                    LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _moduleName, reason);                                    break;                            }                            break;                        case VceMessageHead.Read:                            //如果收到的信息符合                            if (_match_ReadMsg.IsMatch(msg))                            {                                //收到消息 用于结束                                _HasReceiveMsg = true;                                switch (_currentVceMessage.Command)                                {                                    //处理wafer 信息为map数据                                    case VceCommand.ReadMap:                                        ReadMapData(msg);                                        break;                                    case VceCommand.CheckStatus:                                        ReadStatus(msg);                                        break;                                }                            }                            //_RDY查询结束                            else                            {                                if (msg == "_RDY")                                {                                    if (_HasReceiveMsg)                                    {                                        _status = RState.End;                                    }                                    else                                    {                                        LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _moduleName, $"Read Message is over but not receive msg! raw message:{_currentMsg}");                                        _status = RState.Failed;                                    }                                }                                else                                {                                    _status = RState.Failed;                                    LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _moduleName, $"Read Message is invalid: receive message {msg} and send message {_currentMsg}");                                }                            }                            break;                    }                }            }        }        private void ReadStatus(string msg)        {            try            {                //BRa,SLbb,CPc,WPd,ERe                string[] status = msg.Split(',');                _currentSlot = Convert.ToInt32(status[4].Substring(2, 2));            }            catch (Exception ex)            {                LOG.Write(eEvent.ERR_VCE_COMMON_Failed,_moduleName, $"illegal msg:{msg}, {ex.Message}");            }        }        private void ReadMapData(string msg)        {            string waferinfo = "";            string[] waferitems = msg.Split(',');            //智能模式 可以识别叠片            for (int i = 3; i < waferitems.Length - 1; ++i)            {                //如果包含只需要逐个检查                if (waferitems[i].Contains('?'))                {                    foreach (char j in waferitems[i])                    {                        if (waferinfo.Length >= 25)                            break;                        else                            waferinfo += j;                    }                }                else                    waferinfo += waferitems[i];            }            for (int i = 0; i < waferinfo.Length; ++i)            {                int slotnum = i;                if (slotnum < 25)                {                    switch (waferinfo[i])                    {                        case '0':                            WaferManager.Instance.DeleteWafer(_LPMs[0].Module, slotnum);                            break;                        case 'X':                            WaferManager.Instance.CreateWafer(_LPMs[0].Module, slotnum, WaferStatus.Normal);                            break;                        case 'C':                            LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _moduleName, $"Slot {i+1}:double or dummy wafer.");                            WaferManager.Instance.CreateWafer(_LPMs[0].Module, slotnum, WaferStatus.Double);                            break;                        case '?':                            LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _moduleName, $"Slot {i + 1}:Crossed wafer.");                            WaferManager.Instance.CreateWafer(_LPMs[0].Module, slotnum, WaferStatus.Crossed);                            break;                    }                }            }            _LPMs[0].IsMapped = true;        }        private void Errorhandle(string msg,out string reason)        {            if (_matchErrorCode.IsMatch(msg))            {                //若是匹配                //包含原因                string errorcode = _matchErrorCode.Match(msg).Value;                if (_ErrorCode2Reason.ContainsKey(errorcode))                {                    if(errorcode == "L13")                        _IsDashWaferError = true;                    reason = _ErrorCode2Reason[errorcode];                }                else                {                    reason = "未找到相关Error Code";                }            }            else            {                //若不匹配                reason = "回复消息不符合标准格式";            }        }        /// <summary>        /// 处理新到的数据        /// 利用linkedlist处理拆包 粘包情况        /// </summary>        /// <param name="newline">新到数据</param>        private void onDataChange(string oneLineMessage)        {            lock (_locker)            {                if (string.IsNullOrEmpty(_newline))//没有CR                {                    _lstAsciiMsgs.AddLast(oneLineMessage);//将消息添加到最后                    return;                }                string[] array = oneLineMessage.Split(_newline.ToCharArray());//按照cr分开通讯数据                foreach (string text in array)                {                    if (!string.IsNullOrEmpty(text))                    {                        _lstAsciiMsgs.AddLast(text + _newline);//存进list中等待处理                    }                }            }        }        public override bool HomeALL()        {            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.Home ,Param = "ALL" };            _currentMsg = _currentVceMessage.toString() + _newline ;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool Home(string axis)        {            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.Home, Param = axis };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool CheckStatus()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Read, Command = VceCommand.CheckStatus };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool CloseDoor()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.DoorClose };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        /// <summary>        /// 开门提示        /// 在honghuVCE中没有ATM信号的内部卡控 可能会导致开门的压差        /// 因此每一次都要增加判断,只要引用此处功能的,前面都需要有判断        ///         /// </summary>        /// <returns></returns>        public override bool OpenDoor()        {            //如果其他指令正在执行 且              //if (!CheckVceStatus())            //    return false;            if (_IsDashWaferError)                _IsDashWaferError = false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.DoorOpen };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool Load()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.Load };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool UnLoad()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.UnLoad };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool Map()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.Map };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool ReadMap()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Read, Command = VceCommand.ReadMap, Param = "S" };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            _HasReceiveMsg = false;            return _serialport.Write(_currentMsg);        }        public override bool Goto(int Targetslot)        {            if (!CheckVceStatus())                return false;            LOG.Write(eEvent.EV_VCE_COMMON_INFO,_moduleName, $"SlotNum:{Targetslot}");            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.Goto, Param = (Targetslot+1).ToString().PadLeft(2,'0') };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool GotoLP()        {            if (!CheckVceStatus())                return false;            _currentVceMessage = new VceMessage { Head = VceMessageHead.Action, Command = VceCommand.GotoLP };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }        public override bool ClearError()        {            _currentVceMessage = new VceMessage { Head = VceMessageHead.Set, Command = VceCommand.ClearError };            _currentMsg = _currentVceMessage.toString() + _newline;            _status = RState.Running;            return _serialport.Write(_currentMsg);        }    }}
 |