| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 | using System;using System.Collections.Generic;using System.Linq;using System.Runtime.InteropServices;using System.Text;using System.Threading.Tasks;namespace MECF.Framework.RT.Core.IoProviders{    public partial class MCProtocol    {        ////        ///        ///        /// Melsec Protocol QnA compatible 3E frame Constant and Message Format Definition        ///        ///        ///        ///         public const int CMD_BATCH_READ = 0x0401;        public const int CMD_BATCH_WRITE = 0x1401;        public const int CMD_RANDOM_READ = 0x0403;        public const int CMD_RANDOM_WRITE = 0x1402;        public const int SUB_CMD_WORD_UNITS = 0;        public const int SUB_CMD_BYTE_UNITS = 1;        public static readonly int JUNK_SIZE = Marshal.SizeOf(typeof(ushort)); // RESERVED        static public readonly int PLCDataSize = Marshal.SizeOf(typeof(ushort));        static public readonly int PLCDataBits = PLCDataSize * 8;        static public readonly int BufDataSize = Marshal.SizeOf(typeof(byte));        static public readonly int BufDataBits = BufDataSize * 8;        static public readonly int IntSize = Marshal.SizeOf(typeof(int));        static public readonly int IntBits = IntSize * 8;        static public readonly int ShortSize = Marshal.SizeOf(typeof(ushort));        // List of Commands and Functions for the QnA Compatible 3E Frame Device Memory Read/Write        // refer to manual 3-62        public const ushort MC_COMMAND_MULTIPLE_BATCH_READ = 0x0406;        public const ushort MC_COMMAND_MULTIPLE_BATCH_WRITE = 0x1406;        public const ushort MC_COMMAND_BATCH_READ = 0x0401;        public const ushort MC_COMMAND_BATCH_WRITE = 0x1401;        public const ushort MC_COMMAND_RANDOM_READ = 0x0403;        public const ushort MC_COMMAND_RANDOM_WRITE = 0x1402;        public const ushort MC_COMMAND_MONITOR_DATA_REGISTRATION = 0x0801;        public const ushort MC_COMMAND_MONITOR = 0x0802;        public const ushort MC_SUBCOMMAND_BIT_UNITS = 0x0001;        public const ushort MC_SUBCOMMAND_WORD_UNITS = 0x0000;        // List of Device code for QnACPU        // refer to manual 3-70        public const byte MC_DEVICE_CODE_INPUT_BIT = 0x9C;        public const byte MC_DEVICE_CODE_OUTPUT_BIT = 0x0D;        public const byte MC_DEVICE_CODE_INTERNAL_RELAY_BIT = 0x90;        public const byte MC_DEVICE_CODE_LATCH_RELAY_BIT = 0x92;        public const byte MC_DEVICE_CODE_ANNUNCIATOR_BIT = 0x93;        public const byte MC_DEVICE_CODE_EDGE_RELAY_BIT = 0x94;        public const byte MC_DEVICE_CODE_LINK_RELAY_BIT = 0xA0;        public const byte MC_DEVICE_CODE_DATA_REGISTER_WORD = 0xA8;        public const byte MC_DEVICE_CODE_LINK_REGISTER_WORD = 0xB4;        // refer to manual 3-4        public const ushort MC_SUBHEADER_COMMAND_MESSAGE = 0x0050;        public const ushort MC_SUBHEADER_RESPONSE_MESSAGE = 0x00D0;        // refer to manual 3-14        public const ushort MC_REQUEST_MODULE_IO_NUMBER = 0x03FF;        public const byte MC_REQUEST_MODULE_STATION_NUMBER = 0x00;        public static readonly ushort MC_CPU_MONITOR_TIMER = 0x0008; // Wait time (Unit: 250ms)        public const ushort MC_COMPLETE_CODE_SUCCESS = 0x0000;        // User Defined Constant        public static readonly ushort MC_NONE_DESIGNATE_DATA_LENGTH = 0x0000;        public static readonly int MC_SUBHEADER_SIZE = Marshal.SizeOf(MC_SUBHEADER_COMMAND_MESSAGE);        public static readonly int MC_QHEADER_COMMAND_SIZE = Marshal.SizeOf(typeof(MC_COMMAND_HEADER));        public static readonly int MC_QHEADER_RESPONSE_SIZE = Marshal.SizeOf(typeof(MC_RESPONSE_HEADER));        public static readonly int MC_BATCH_COMMAND_SIZE = Marshal.SizeOf(typeof(MC_BATCH_COMMAND));        //public static readonly int MC_POINT_BITS = sizeof(ushort) * 8;        //public const int MC_CA_WRITE_SIZE = 1024;        //public const int MC_COMMAND_DATA_SIZE = 1024;        //public const int MC_IO_BUFFER_LENGTH = 1024;        // Command Message Format        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_DATA_FORMAT        //{        //    public MC_HEADER mc_Header;        //    public MC_APPLICATION_DATA mc_ApplicationData;        //};        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_HEADER // Ethernet module adds and deletes the header        //{        //};        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_APPLICATION_DATA        //{        //    public MC_SUBHEADER mc_SubHeader;        //    public MC_TEXT mc_Text;        //};        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_SUBHEADER  // 2 bytes (3E frame)        //{        //    public enum SUBHEADER_TYPE : ushort        //    {        //        MC_COMMAND_MESSAGE = 0x0050,        //        MC_RESPONSE_MESSAGE = 0x00D0        //    };        //    public SUBHEADER_TYPE mc_SubHeaderType;        //}        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_TEXT   // Text Command or Text Response        //{        //}        //public const byte MC_LOCAL_STATION_MCSocket_NUMBER = 0x00;        //public const byte MC_LOCAL_STATION_PC_NUMBER = 0xFF;        // refer to manual 3-7        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_QHEADER_COMMAND        //{        //    public byte nMCSocketNo;        //    public byte nStationNo;        //    public ushort nRequestIONumber;        //    public byte nRequestStationNumber;        //    public ushort nRequestDataLength;        //    public ushort nCPUMonitorTimer;        //}        [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        public struct MC_COMMAND_HEADER        {            public ushort ProtocolID; // MC_COMMAND_MESSAGE or MC_RESPONSE_MESSAGE            public byte NetworkID;            public byte StationID;            public ushort RequestIONumber;            public byte RequestStationNumber;            public ushort RequestDataLen;            public ushort CPUMonitorTimer;        };// MC_COMMAND_HEADER;        [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        public struct MC_RESPONSE_HEADER        {            public ushort ProtocolId; //nSubheader            public byte NetworkId;  //SocketNumber            public byte StationId;            public ushort RequestIoNumber;            public byte RequestStationNumber;            public ushort ResponseDataLen;            public ushort CompleteCode;        };        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_QHEADER_RESPONSE        //{        //    public ushort nSubHeader;        //    public byte nMCSocketNo;        //    public byte nStationNo;        //    public ushort nRequestIONumber;        //    public byte nRequestStationNumber;        //    public ushort nResponseDataLength;        //    public ushort nCompleteCode;        //}        [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        public struct MC_BATCH_COMMAND        {            public ushort Command;            public ushort SubCommand;            public ushort HeadAddr;            public byte Reserved;            public byte DeviceCode;            public ushort DevicePoints;        }        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_HEAD_DEVICE        //{        //    public byte bLow;        //    public byte bMid;        //    public byte bHig;        //    public int HeadDevice        //    {        //        get        //        {        //            return (bLow | bMid << sizeof(byte) | bHig << sizeof(byte) * 2);        //        }        //        set        //        {        //            bLow = (byte)(0x00 | value);        //            bMid = (byte)(0x00 | value >> sizeof(byte));        //            bHig = (byte)(0x00 | value >> sizeof(byte) * 2);        //        }        //    }        //}        //[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //public struct MC_CA_RANDOM_WRITE_BIT        //{        //    public ushort nCommand;        //    public ushort nSubCommand;        //    public byte nBitPoints;        //    public DATA_RANDOM_WRITE_BIT[] data;        //    [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]        //    public struct DATA_RANDOM_WRITE_BIT        //    {        //        public ushort nHeadDeviceAddr;        //        public byte nReserved;        //        public byte nDeviceCode;        //        public byte nSet;        //    }        //    byte[] ToByteArray()    // can serialize with pointer type?        //    {        //        byte[] buffer = new byte[0];        //        return buffer;        //    }        //};        public static byte[] TransBoolArrayToByteData(bool[] value)        {            int length = (value.Length + 1) / 2;            byte[] buffer = new byte[length];            for (int i = 0; i < length; i++)            {                if (value[i * 2 + 0])                    buffer[i] += 0x10;                if ((i * 2 + 1) < value.Length)                {                    if (value[i * 2 + 1])                        buffer[i] += 0x01;                }            }            return buffer;        }        public static bool[] TransByteDataToBoolArray(byte[] value, int offset, int size)        {            int count = size * 2;            bool[] result = new bool[count];            for (int i = 0; i < size; i++)            {                if ((value[i] & 0x10) == 0x10)                {                    result[i * 2 + 0] = true;                }                if ((value[i] & 0x01) == 0x01)                {                    result[i * 2 + 1] = true;                }            }            return result;        }        public static T ToStruct<T>(byte[] by) where T : struct        {            int objectSize = Marshal.SizeOf(typeof(T));            if (objectSize > by.Length) return default(T);            // Allocate some unmanaged memory.            IntPtr buffer = Marshal.AllocHGlobal(objectSize);            // Copy the read byte array (byte[]) into the unmanaged memory block.            Marshal.Copy(by, 0, buffer, objectSize);            // Push the memory into a new struct of type (T).            T returnStruct = (T)Marshal.PtrToStructure(buffer, typeof(T));            // Free the unmanaged memory block.            Marshal.FreeHGlobal(buffer);            return returnStruct;        }        public static object ToStruct(byte[] buffer, Type t)        {            int objectSize = Marshal.SizeOf(t);            if (objectSize > buffer.Length) return null;            // Allocate some unmanaged memory.            IntPtr buf = Marshal.AllocHGlobal(objectSize);            // Copy the read byte array (byte[]) into the unmanaged memory block.            Marshal.Copy(buffer, 0, buf, objectSize);            // Push the memory into a new struct of type (T).            object result = Marshal.PtrToStructure(buf, t);            // Free the unmanaged memory block.            Marshal.FreeHGlobal(buf);            return result;        }        public static byte[] Struct2Bytes(object o)        {            // create a new byte buffer the size of your struct            byte[] buffer = new byte[Marshal.SizeOf(o)];            // pin the buffer so we can copy data into it w/o GC collecting it            GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);            // copy the struct data into the buffer            Marshal.StructureToPtr(o, bufferHandle.AddrOfPinnedObject(), false);            // free the GC handle            bufferHandle.Free();            return buffer;        }        public static byte[] Ushort2Byte(ushort[] data)        {            int sizeofT1 = Marshal.SizeOf(typeof(ushort));            int sizeofT2 = Marshal.SizeOf(typeof(byte));            byte[] by = new byte[sizeofT1 * data.Length / sizeofT2];            for (int i = data.Length; i-- > 0;)            {                BitConverter.GetBytes(data[i]).CopyTo(by, i * 2);            }            return by;        }        public static byte[] Ushort2Byte(ushort[] data, int offset, int length)        {            int sizeofT1 = Marshal.SizeOf(typeof(ushort));            int sizeofT2 = Marshal.SizeOf(typeof(byte));            byte[] by = new byte[sizeofT1 * length / sizeofT2];                        for (int i = offset+length; i-- > offset;)            {                var value = BitConverter.GetBytes(data[i]);                value.CopyTo(by, (i-offset) * 2);            }            return by;        }        public static ushort[] Byte2Ushort(byte[] data)        {            return Byte2Ushort(data, 0, data.Length);        }        public static ushort[] Byte2Ushort(byte[] data, int offset, int length)        {            System.Diagnostics.Debug.Assert(data.Length % 2 == 0);            int sizeofT1 = Marshal.SizeOf(typeof(byte));            int sizeofT2 = Marshal.SizeOf(typeof(ushort));            ushort[] us = new ushort[sizeofT1 * length / sizeofT2];            for (int i = 0; i < us.Length; i++)            {                us[i] = BitConverter.ToUInt16(data, offset + i * 2);            }            return us;        }    }}
 |