| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671 | using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml;using Aitex.Core.Common.DeviceData;using Aitex.Core.RT.DataCenter;using Aitex.Core.RT.Device;using Aitex.Core.RT.Event;using Aitex.Core.RT.IOCore;using Aitex.Core.RT.Log;using Aitex.Core.RT.OperationCenter;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;namespace Aitex.Core.RT.Device.Unit{    public enum SignalType    {        Acitvie,        Passive,    }    public enum  SignalID    {        CS_0,               CS_1,        AM_AVBL,        VALID,        TR_REQ,        BUSY,        COMPT,        CONT,        L_REQ,        U_REQ,        HO_AVBL,        READY,        ES    }    public class Signal    {        public bool Value        {            get            {                if (_di != null)                    return _di.Value;                if (_do != null)                    return _do.Value;                return false;            }        }        private SignalID _id;        private RD_TRIG _trig = new RD_TRIG();        private DIAccessor _di = null;        private DOAccessor _do = null;        public event Action<SignalID, bool> OnChanged;        public Signal(SignalID id, DIAccessor diAccessor, DOAccessor doAccessor)        {            _id = id;            _di = diAccessor;            _do = doAccessor;                  }                public void Monitor()        {            if (_di != null)                _trig.CLK = _di.Value;            if (_do != null)                _trig.CLK = _do.Value;            if (_trig.R)            {                if (OnChanged != null)                    OnChanged(_id, true);            }            if (_trig.M)            {                if (OnChanged != null)                    OnChanged(_id, false);            }        }        public void Reset()        {            _trig.RST = true;        }            }    public enum LPAccessMode    {        Operator = 0,	    AMHS = 1,    };    public enum LPTransferState    {        OutOfService = 0,        TransferBlocked = 1,        ReadyToLoad = 2,        ReadyToUnload = 3,        InService = 4,        TransferReady = 5,    }    public interface IE84Provider    {        bool ReadyForLoad();        bool ReadyForUnload();        bool FoupArrirved();        bool FoupRemoved();    }    public class E84Passiver : BaseDevice, IDevice    {        public enum E84State        {            Idle,            WaitForTrReqOn,            WaitForBusyOn,            WaitForTransfer,            WaitForBusyOff,            WaitForValidOff,            Error,        }        public enum Timeout        {            TP1,            TP2,            TP3,            TP4,            TP5,        }        public bool LightCurtainBroken { get; set; }   //interlock        public LPAccessMode  Mode{ get; set; }        public LPTransferState TransferState { get; set; }        public IE84Provider Provider { get; set; }        //Active equipment signal        private DIAccessor _diValid;                    private DIAccessor _diCS0;        private DIAccessor _diCS1;        private DIAccessor _diAmAvbl;        private DIAccessor _diTrReq;        private DIAccessor _diBusy;        private DIAccessor _diCompt;        private DIAccessor _diCont;        //Passive         private DOAccessor _doLoadReq;        private DOAccessor _doUnloadReq;        private DOAccessor _doReady;                 private DOAccessor _doHOAvbl;        private DOAccessor _doES;                       private DeviceTimer _timer = new DeviceTimer();        private R_TRIG _trigReset = new R_TRIG();        private List<Signal> _signals = new List<Signal>();        //timeout        private SCConfigItem _scTimeoutTP1;        private SCConfigItem _scTimeoutTP2;        private SCConfigItem _scTimeoutTP3;        private SCConfigItem _scTimeoutTP4;        private SCConfigItem _scTimeoutTP5;        private int reqOnTimeout    = 2;        //L_REQ|U_REQ_ON ON ---> TR REQ ON        private int readyOnTimeout  = 2;        //READY ON ---> BUSY ON          private int busyOnTimeout   = 2;        //BUSYON -- CARRIAGE DETECT|CARRIAGE REMOVE        private int reqOffTimeout   = 2;        //L_REQ|U_REQ off --->BUSY off        private int readyOffTimeout = 2;        //Ready off --->Valid off        private E84State _state;        private Timeout _tp;        public E84Passiver(string module, XmlElement node, string ioModule = "")        {            base.Module = node.GetAttribute("module");            base.Name = node.GetAttribute("id");            base.Display = node.GetAttribute("display");            base.DeviceID = node.GetAttribute("schematicId");            _diValid = ParseDiNode("VALID", node, ioModule);            _signals.Add(new Signal(SignalID.VALID, _diValid, null));            _diCS0 = ParseDiNode("CS_0", node, ioModule);            _signals.Add(new Signal(SignalID.CS_0, _diCS0, null));            _diCS1 = ParseDiNode("CS_1", node, ioModule);            _signals.Add(new Signal(SignalID.CS_1, _diCS1, null));            _diAmAvbl = ParseDiNode("AM_AVBL", node, ioModule);            _signals.Add(new Signal(SignalID.AM_AVBL, _diAmAvbl, null));            _diTrReq = ParseDiNode("TR_REQ", node, ioModule);            _signals.Add(new Signal(SignalID.TR_REQ, _diTrReq, null));            _diBusy = ParseDiNode("BUSY", node, ioModule);            _signals.Add(new Signal(SignalID.BUSY, _diBusy, null));            _diCompt = ParseDiNode("COMPT", node, ioModule);            _signals.Add(new Signal(SignalID.COMPT, _diCompt, null));            _diCont = ParseDiNode("CONT", node, ioModule);            _signals.Add(new Signal(SignalID.CONT, _diCont, null));            _doLoadReq = ParseDoNode("L_REQ", node, ioModule);            _signals.Add(new Signal(SignalID.L_REQ, null, _doLoadReq));            _doUnloadReq = ParseDoNode("U_REQ", node, ioModule);            _signals.Add(new Signal(SignalID.U_REQ, null, _doUnloadReq));            _doReady = ParseDoNode("READY", node, ioModule);            _signals.Add(new Signal(SignalID.READY, null, _doReady));            _doHOAvbl = ParseDoNode("HO_AVBL", node, ioModule);            _signals.Add(new Signal(SignalID.HO_AVBL, null, _doHOAvbl));            _doES = ParseDoNode("ES", node, ioModule);            _signals.Add(new Signal(SignalID.ES, null, _doES));            foreach (var signal in _signals)            {                signal.OnChanged += OnSignalChange;            }            _scTimeoutTP1 = SC.GetConfigItem("Fa.E84.TP1");            _scTimeoutTP2 = SC.GetConfigItem("Fa.E84.TP2");            _scTimeoutTP3 = SC.GetConfigItem("Fa.E84.TP3");            _scTimeoutTP4 = SC.GetConfigItem("Fa.E84.TP4");            _scTimeoutTP5 = SC.GetConfigItem("Fa.E84.TP5");        }        public bool Initialize()        {            reset();            return true;        }        private bool InvokeReset(string arg1, object[] arg2)        {            //string reason;            EV.PostInfoLog(Module, $"E84 reset {Module}.{Name}");            reset();            return true;        }        public void Terminate()        {            reset();        }        private void reset()        {            _doLoadReq.Value = false;            _doUnloadReq.Value = false;            _doReady.Value = false;            _doHOAvbl.Value = false;            _doES.Value = false;            _state = E84State.Idle;            foreach (var signal in _signals)            {                signal.Reset();            }        }        public void Monitor()        {            try            {                foreach (var signal in _signals)                {                    signal.Monitor();                }                if (LightCurtainBroken)                {                    _doES.Value = false;                }                else                {                    _doES.Value = true;                }                if (Mode != LPAccessMode.AMHS)                {                    _doHOAvbl.Value = false;                    return;                }                if (_timer.IsTimeout())                {                    _doHOAvbl.Value    = false;                    _doLoadReq.Value   = false;                    _doUnloadReq.Value = false;                    _doReady.Value = false;                    _doES.Value = false;                    _state = E84State.Error;                    switch (_state)                    {                        case E84State.WaitForTrReqOn:                            _tp = Timeout.TP1;                            break;                        case E84State.WaitForBusyOn:                            _tp = Timeout.TP2;                            break;                        case E84State.WaitForTransfer:                            _tp = Timeout.TP3;                            break;                        case E84State.WaitForBusyOff:                            _tp = Timeout.TP4;                            break;                        case E84State.WaitForValidOff:                            _tp = Timeout.TP5;                            break;                    }                    EV.PostMessage("E84", EventEnum.DefaultAlarm, string.Format("E84 {0} Timeout", _tp));                }                switch (_state)                {                    case E84State.Idle:                        {                            if (waitValidOn())                            {                                _state = E84State.WaitForTrReqOn;                                if (_scTimeoutTP1 != null)                                    reqOnTimeout = _scTimeoutTP1.IntValue;                                _timer.Start(reqOnTimeout);                            }                        }                        break;                    case E84State.WaitForTrReqOn:                        {                            if (wait4TrReqOn())                            {                                _state = E84State.WaitForBusyOn;                                if(_scTimeoutTP2!= null)                                    readyOnTimeout = _scTimeoutTP2.IntValue;                                _timer.Start(readyOnTimeout);                            }                        }                        break;                    case E84State.WaitForBusyOn:                        {                            if (wait4BusyOn())                            {                                _state = E84State.WaitForTransfer;                                if (_scTimeoutTP3 != null)                                    busyOnTimeout = _scTimeoutTP3.IntValue;                                _timer.Start(busyOnTimeout);                            }                        }                        break;                    case E84State.WaitForTransfer:                        {                            if (wait4Transfer())                            {                                _state = E84State.WaitForBusyOff;                                if (_scTimeoutTP4 != null)                                    reqOffTimeout = _scTimeoutTP4.IntValue;                                _timer.Start(reqOffTimeout);                            }                        }                        break;                    case E84State.WaitForBusyOff:                        {                            if (wait4BusyOff())                            {                                _state = E84State.WaitForValidOff;                                if (_scTimeoutTP5 != null)                                    readyOffTimeout = _scTimeoutTP5.IntValue;                                _timer.Start(readyOffTimeout);                            }                        }                        break;                    case E84State.WaitForValidOff:                        {                            if (waitValidOff())                            {                                _state = E84State.Idle;                                _timer.Stop();                            }                        }                        break;                    case E84State.Error:                        {                            if (autoRecovery())                            {                                _state = E84State.Idle;                                _timer.Stop();                            }                        }                        break;                }            }            catch (Exception ex)            {                LOG.WriteExeption(ex);            }        }        public void Reset()        {            _doLoadReq.Value = false;            _doUnloadReq.Value = false;            _doReady.Value = false;            _doHOAvbl.Value = false;            _doES.Value = false;            foreach (var signal in _signals)            {                signal.Reset();            }            if (TransferState != LPTransferState.OutOfService)            {                if (Mode == LPAccessMode.AMHS)                {                    _doHOAvbl.Value = true;                    _doES.Value = true;                }            }        }        private bool waitValidOn()        {            if (_diValid.Value)            {                if (!_diCS0.Value && !_diCS1.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, CS0 or CS1 should be on");                    _doHOAvbl.Value = false;                    return false;                }                if (_diTrReq.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, VALID should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (_diBusy.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, BUSY should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (_diCompt.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, COMPT should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (TransferState == LPTransferState.ReadyToLoad)                {                    _doLoadReq.Value = true;                }                else if (TransferState == LPTransferState.ReadyToUnload)                {                    _doUnloadReq.Value = true;                }            }            return true;        }        private bool wait4TrReqOn()        {            if (_diTrReq.Value)            {                if (!_diCS0.Value && !_diCS1.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, CS0 or CS1 should be on");                    _doHOAvbl.Value = false;                    return false;                }                if (!_diValid.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, TR_REQ should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (_diBusy.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, BUSY should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (_diCompt.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, COMPT should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (TransferState == LPTransferState.ReadyToLoad)                {                    if(Provider.ReadyForLoad())                        _doReady.Value = true;                }                else if (TransferState == LPTransferState.ReadyToUnload)                {                    if(Provider.ReadyForUnload())                        _doReady.Value = true;                 }                return true;            }            return false;        }        private bool wait4BusyOn()        {            if (_diBusy.Value)            {                if (!_diCS0.Value && !_diCS1.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn on, CS0 or CS1 should be on");                    _doHOAvbl.Value = false;                    return false;                }                if (!_diValid.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn on, VALID should be on");                    _doHOAvbl.Value = false;                    return false;                }                if (!_diTrReq.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, TR_REQ should be on");                    _doHOAvbl.Value = false;                    return false;                }                if (_diCompt.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, COMPT should be off");                    _doHOAvbl.Value = false;                    return false;                }                return true;            }            return false;        }        private bool wait4Transfer()        {            if (TransferState == LPTransferState.ReadyToLoad)            {                if (Provider.FoupArrirved())  //FOUP placement                {                    _doLoadReq.Value = false;                    return true;                }                                }            else if (TransferState == LPTransferState.ReadyToUnload)            {                if (Provider.FoupArrirved())  //FOUP placement                {                    _doUnloadReq.Value = false;                    return true;                }            }            return false;        }        private bool wait4BusyOff()        {              if (_diCompt.Value && !_diTrReq.Value && !_diBusy.Value)            {                if (!_diValid.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn off, VALID should be on");                    _doHOAvbl.Value = false;                    return false;                }                if (!_diCS0.Value && !_diCS1.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn off, CS0 or CS1 should be on");                    _doHOAvbl.Value = false;                    return false;                }                _doReady.Value = false;                return true;            }            return false;        }        private bool waitValidOff()        {            if (_diValid.Value  && (_diCS0.Value || _diCS1.Value) && !_diCompt.Value)            {                _doHOAvbl.Value = true;                if (_diBusy.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn off, BUSY should be off");                    _doHOAvbl.Value = false;                    return false;                }                if (_diTrReq.Value)                {                    EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn off, TR REQ should be off");                    _doHOAvbl.Value = false;                    return false;                }                _doLoadReq.Value = false;                _doUnloadReq.Value = false;                _doReady.Value = false;                _doES.Value = false;                return true;            }            return false;        }        private bool autoRecovery()        {            bool ret = false;            switch (_tp)            {                case Timeout.TP1:                case Timeout.TP2:                case Timeout.TP5:                    {                        if (  !_diAmAvbl.Value && !_diValid.Value && !_diCS0.Value && !_diCS1.Value                            &&!_diTrReq.Value && !_diBusy.Value && !_diCompt.Value && !_diCont.Value)                            ret = true;                    }                            break;            }            return ret;        }        private void OnSignalChange(SignalID signal, bool value)        {        }    }}
 |