using System;
using System.Runtime.InteropServices;
using System.Text;

namespace ltrModulesNet
{
    public class ltr35api 
    {
        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_Init(ref TLTR35 hnd);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_Open(ref TLTR35 hnd, uint net_addr, ushort net_port,
                                                     string crate_sn, int slot_num);
        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_Close(ref TLTR35 hnd);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_IsOpened(ref TLTR35 hnd);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FillOutFreq(ref CONFIG cfg, double freq, out double fnd_freq);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FillDIAcqFreq(ref CONFIG cfg, double freq, out double fnd_freq);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FillArithPhaseDegree(ref ARITH_PHASE cfg, double degree, out double res_degree);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_Configure(ref TLTR35 hnd);

        [DllImport("ltr35api.dll")]
        static extern int LTR35_Send(ref TLTR35 hnd, uint[] data, uint size, uint timeout);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_PrepareData(ref TLTR35 hnd, double[] dac_data, ref uint dac_size, 
            uint[] dout_data, ref uint dout_size, PrepFlags flags,
            uint[] result, ref uint snd_size);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_PrepareDacData(ref TLTR35 hnd, double[] dac_data, uint size, PrepFlags flags,
            uint[] result, out uint snd_size);
        
        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_SwitchCyclePage(ref TLTR35 hnd, uint flags, uint tout);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_SwitchCyclePageRequest(ref TLTR35 hnd, uint flags);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_SwitchCyclePageWaitDone(ref TLTR35 hnd, uint tout);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_StreamStart(ref TLTR35 hnd, uint flags);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_StreamStartRequest(ref TLTR35 hnd, uint flags);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_StreamStartWaitSlaveReady(ref TLTR35 hnd, uint tout);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_StreamStartWaitDone(ref TLTR35 hnd, uint tout);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_Stop(ref TLTR35 hnd, uint flags);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_StopWithTout(ref TLTR35 hnd, uint flags, uint tout);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_SetArithSrcDelta(ref TLTR35 hnd, byte gen_num, ref ARITH_PHASE delta);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_SetArithAmp(ref TLTR35 hnd, byte ch_num, double amp, double offset);

        [DllImport("ltr35api.dll")]
        static extern int LTR35_RecvInStreamData(ref TLTR35 hnd, uint[] data, uint[] tmark, uint size, uint timeout);

        [DllImport("ltr35api.dll")]
        public static extern IntPtr LTR35_GetErrorString(int err);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FPGAIsEnabled(ref TLTR35 hnd, out bool enabled);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FPGAEnable(ref TLTR35 hnd, bool enable);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_GetStatus(ref TLTR35 hnd, out StatusFlags status);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_GetConfig(ref TLTR35 hnd);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_DacReset(ref TLTR35 hnd);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_DIAsyncIn(ref TLTR35 hnd, out byte di_state);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FlashRead(ref TLTR35 hnd, uint addr, byte[] data, uint size);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FlashWrite(ref TLTR35 hnd, uint addr, byte[] data, uint size, FlashWriteFlags flags);

        [DllImport("ltr35api.dll")]
        static extern _LTRNative.LTRERROR LTR35_FlashErase(ref TLTR35 hnd, uint addr, uint size);


        public const int LTR35_NAME_SIZE = 8;
        public const int LTR35_SERIAL_SIZE = 16;
        public const int LTR35_DAC_CHANNEL_CNT = 8;
        public const int LTR35_DAC_CH_OUTPUT_CNT = 2;
        public const int LTR35_DOUT_MAX_CNT = 16;
        public const int LTR35_DIN_CNT = 2;
        public const int LTR35_MAX_POINTS_PER_PAGE = (4*1024*1024);
        public const int LTR35_ARITH_SRC_CNT = 4;
        public const double LTR35_DAC_FREQ_MAX = 192000;
        public const double LTR35_DAC_FREQ_MIN = 36000;
        public const double LTR35_DAC_SINGLE_RATE_FREQ_MAX = 54000;
        public const double LTR35_DAC_DOUBLE_RATE_FREQ_MAX = 108000;
        public const double LTR35_DAC_QUAD_RATE_FREQ_STD   = 192000;
        public const double LTR35_DAC_DOUBLE_RATE_FREQ_STD = 96000;
        public const double LTR35_DAC_SINGLE_RATE_FREQ_STD = 48000;
        public const double LTR35_SYNT_FREQ_STD            = 36864000;

        public const int LTR35_DAC_CODE_MAX = 0x7FFFFF;
        public const int LTR35_DAC_SCALE_CODE_MAX = 0x600000;

        public const ushort LTR35_STREAM_STATUS_PERIOD_DEFAULT = 1024;
        public const ushort LTR35_STREAM_STATUS_PERIOD_MAX = 1024;
        public const ushort LTR35_STREAM_STATUS_PERIOD_MIN = 8;
        public const uint LTR35_DIN_SYNT_FREQ_DIV            = 4;
        public const byte LTR35_DI_STREAM_FREQ_DIV_POW_MAX   = 5;

        public const uint LTR35_FLASH_USERDATA_ADDR   = 0x100000;
        public const uint LTR35_FLASH_USERDATA_SIZE   = 0x700000;
        public const uint LTR35_FLASH_ERASE_BLOCK_SIZE = 1024;


        public enum Modification : byte
        {
            Unknown = 0, /**< Неизвестная (не поддерживаемая библиотекой) модификация */
            Mod1 = 1,  /**< LTR35-1 */
            Mod2 = 2,  /**< LTR35-2 */
            Mod3 = 3   /**< LTR35-3 */
        }

        [Flags]
        public enum DoutsWordFlags : uint
        {
            DisH = 0x00020000,
            DisL = 0x00010000
        }

        [Flags]
        public enum PrepFlags : uint
        {
            Volt = 0x00000001,
        }

        public enum OutDataFormat  : byte
        {
            Format24 = 0,
            Format20 = 1
        }

        public enum OutMode : byte
        {
            Cycle = 0,
            Stream = 1
        }

        public enum DacOutput : byte
        {
            FullRange = 0,
            DivRange = 1
        }

        public enum ChSrc : byte
        {
            SDRAM = 0,
            Sin1 = 1,
            Cos1 = 2,
            Sin2 = 3,
            Cos2 = 4,
            Sin3 = 5,
            Cos3 = 6,
            Sin4 = 7,
            Cos4 = 8 
        }

        public enum Rate : byte
        {
            Single = 0,
            Double = 1,
            Quad = 2
        }

        public enum InStreamMode : byte
        {
            Off = 0,
            ChEcho = 1,
            DI = 2
        }

        [Flags]
        public enum InStreamDIChs : byte
        {
            DI1 = 0x01,
            DI2 = 0x02
        }

        public enum SyncMode : byte
        {
            Internal = 0,
            Master = 1,
            Slave = 2
        }

        public enum SyncSlaveSrc : byte
        {
            DI2_Risze = 0,
            DI2_Fall = 1
        }

        [Flags]
        public enum CfgFlags : uint
        {
            DisableAfcCor = 0x00000001,
            DisablePeriodicStatus = 0x00000100,
        }

        [Flags]
        public enum FlashWriteFlags : uint
        {
            AlreadyErased = 0x00000001,
        }

        [Flags]
        public enum StatusFlags : uint
        {
            PLL_Lock = 0x0001,
            PLL_LockHold = 0x0002,
            SyncMode = 0x0030,
            DI1_State = 0x0040,
            DI2_State = 0x0080,
        }

        public enum RunState : byte
        {
            Stopped = 0,
            SlaveRdyWaiting = 1,
            StartAckWaiting = 2,
            Running = 3
        }

        /** Калибровочные коэффициенты */
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct CBR_COEF
        {
            float _offset;
            float _scale;

            public float Offset { get { return _offset; } } /**< Код смещения */
            public float Scale { get { return _scale; } }  /**< Коэффициент шкалы */
        }

        /** Описание выхода ЦАП */
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct DAC_OUT_DESCR 
        {
            double _amp_max;
            double _amp_min;
            int _code_max; 
            int _code_min; 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            uint[] _reserved;

            public double AmpMax { get { return _amp_max; } } /* Максимальное пиковое значение амплитуды сигнала для данного выхода/ */
            public double AmpMin { get { return _amp_min; } } /* Минимальное пиковое значение амплитуды сигнала для данного выхода. */
            public int CodeMax { get { return _code_max; } } /* Код ЦАП, соответствующий максимальной амплитуде. */
            public int CodeMin { get { return _code_min; } } /* Код ЦАП, соответствующий минимальной амплитуде. */
        }

        /* Коэффициенты для калибровки АЧХ */
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct AFC_COEF
        {
            [MarshalAs(UnmanagedType.U1)]
            bool _valid;      
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            uint[] _reserved; 
            double _fd;          
            double _sig_freq;     
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_DAC_CHANNEL_CNT)]
            double[] _k;

            public bool Valid { get { return _valid; } } /* Признак действительности значения остальных полей. */
            public double Fd { get { return _fd; } } /* Частота генерации ЦАП, на которой измерено отношение амплитуд. */
            public double SigFreq { get { return _sig_freq; } } /* Частота сигнала, для которой измерено отношение амплитуд. */
            public double K(int ch) { return _k[ch]; }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct INFO
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_NAME_SIZE)]
            char[] _name;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_SERIAL_SIZE)]
            char[] _serial;
            ushort _verFPGA;
            byte _verPLD;
            Modification _modification;
            byte dac_ch_cnt;
            byte dout_line_cnt;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_DAC_CH_OUTPUT_CNT)]
            DAC_OUT_DESCR[]  _dac_out_descr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
            uint[] _reserved1;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_DAC_CHANNEL_CNT * LTR35_DAC_CH_OUTPUT_CNT)]
            CBR_COEF[] _cbr_coef;
            AFC_COEF _cbr_afc_coef;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64 * LTR35_DAC_CHANNEL_CNT * LTR35_DAC_CH_OUTPUT_CNT - 24)]
            uint[] _reserved2;

            /* Название модуля */
            public string Name { get { return new string(_name).Split('\0')[0]; } }
            /* Серийный номер модуля */
            public string Serial { get { return new string(_serial).Split('\0')[0]; } }
            /* Версия прошивки ПЛИС модуля (действительна только после ее загрузки) */
            public ushort VerFPGA { get { return _verFPGA; } }
            /* Версия прошивки PLD */
            public byte VerPLD { get { return _verPLD; } }
            /* Модификация модуля */
            public Modification Modification { get { return _modification; } }
            /* Количество установленных каналов ЦАП */
            public byte DacChCnt { get { return dac_ch_cnt; } }
            /* Количество линий цифрового вывода */
            public byte DoutLineCnt { get { return dout_line_cnt; } }
            /* Описание параметров выходов ЦАП для данной модификации модуля. */
            public DAC_OUT_DESCR DacOutDescr(int out_num) { return _dac_out_descr[out_num]; }
            /* Заводские калибровочные коэффициенты. */
            public CBR_COEF CbrCoef(int ch_num, int out_num) { return _cbr_coef[ch_num * LTR35_DAC_CH_OUTPUT_CNT + out_num]; }
            /* Заводские коэффициенты для коррекции АЧХ модуля. */
            public AFC_COEF CbrAfcCoef { get { return _cbr_afc_coef; } }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct CHANNEL_CONFIG
        {
            [MarshalAs(UnmanagedType.U1)]
            bool _enabled;      
            DacOutput _output;
            ChSrc _source;
            double _arith_amp;
            double _arith_offs;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            uint[] _reserved;

            /* Разрешение выдачи сигнала для данного канала. */
            public bool Enabled { get { return _enabled; } set { _enabled = value; } }
            /* Используемый выход для данного канала */
            public DacOutput output { get { return _output; } set { _output = value; } }
            /* Источник данных для данного канала */
            public ChSrc Source { get { return _source; } set { _source = value; } }
            /* Амплитуда сигнала в режиме арифметического генератора */
            public double ArithAmp { get { return _arith_amp; } set { _arith_amp = value; } }
            /* Смещение сигнала в режиме арифметического генератора */
            public double ArithOffs { get { return _arith_offs; } set { _arith_offs = value; } }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct ARITH_PHASE
        {
            uint _reserved;
            uint _code_h;
            /* 32-битный код, задающий фазу. Каждый разряд имеет вес (2*pi)/(2^32) */
            public uint CodeH { get { return _code_h; } set { _code_h = value; } }


            public _LTRNative.LTRERROR FillArithPhaseDegree(double degree, out double res_degree)
            {
                return LTR35_FillArithPhaseDegree(ref this, degree, out res_degree);
            }
        }

        /* Настройки арифметического генератора */
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct ARITH_SRC_CONFIG
        {
            ARITH_PHASE _phase;
            ARITH_PHASE _delta;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
            uint[] _reserved;

            /* Начальная фаза сигнала. */
            public ARITH_PHASE Phase { get { return _phase; } set { _phase = value; } }
            /* Приращение фазы сигнала */
            public ARITH_PHASE Delta { get { return _delta; } set { _delta = value; } }
        }

        /* Настройки синтезатора частоты */
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct FREQ_SYNT_CONFIG
        {
            ushort _b;
            ushort _r;
            byte _a;

            public  ushort b { get { return _b; } set { _b = value; } }
            public ushort r { get { return _r; } set { _r = value; } }
            public byte a { get { return _a; } set { _a = value; } }
        }

        /* Настройки синхронного ввода */
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct IN_STREAM_CONFIG
        {
            InStreamMode _mode;
            byte _echo_ch;
            InStreamDIChs _di_ch_en_msk;
            byte _di_freq_div_pow;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            uint[] _reserved;


            public InStreamMode InStreamMode { get { return _mode; } set { _mode = value; } }
            public byte EchoChannel { get { return _echo_ch; } set { _echo_ch = value; } }
            public InStreamDIChs DIChEnMask { get { return _di_ch_en_msk; } set { _di_ch_en_msk = value; } }
            public byte DIFreqDivPow { get { return _di_freq_div_pow; } set { _di_freq_div_pow = value; } }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct SYNC_CONFIG
        {
            SyncMode _mode;
            SyncSlaveSrc _slave_src;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            uint[] _reserved;

            public SyncMode SyncMode { get { return _mode; } set { _mode = value; } }
            public SyncSlaveSrc SlaveSrc { get { return _slave_src; } set { _slave_src = value; } }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct CONFIG
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_DAC_CHANNEL_CNT)]
            CHANNEL_CONFIG[] _ch;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_ARITH_SRC_CNT)]
            ARITH_SRC_CONFIG[] _arith_src;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LTR35_ARITH_SRC_CNT)]
            ARITH_SRC_CONFIG[] _arith_src_reserv;

            OutMode _out_mode;
            OutDataFormat _out_data_fmt;
            Rate _dac_rate;
            FREQ_SYNT_CONFIG _freq_synt;
            ushort _stream_status_period;
            CfgFlags _flags;
            IN_STREAM_CONFIG _in_stream;
            SYNC_CONFIG _sync;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 47)]
            uint[] _reserved;


            public CHANNEL_CONFIG[] Ch { get { return _ch; } set { _ch = value; } }
            public ARITH_SRC_CONFIG[] ArithSrc { get { return _arith_src; } set { _arith_src = value; } }
            public OutMode OutMode { get { return _out_mode; } set { _out_mode = value; } }
            public OutDataFormat OutDataFmt { get { return _out_data_fmt; } set { _out_data_fmt = value; } }
            public Rate DacRate { get { return _dac_rate; } set { _dac_rate = value; } }
            public FREQ_SYNT_CONFIG FreqSynt { get { return _freq_synt; } set { _freq_synt = value; } }
            public ushort StreamStatusPeriod { get { return _stream_status_period; } set { StreamStatusPeriod = value; } }
            public CfgFlags Flags { get { return _flags; } set { _flags = value; } }
            public IN_STREAM_CONFIG InStream { get { return _in_stream; } set { _in_stream = value; } }
            public SYNC_CONFIG Sync { get { return _sync; } set { _sync = value; } }


            public _LTRNative.LTRERROR FillOutFreq(double freq, out double fnd_freq)
            {
                return LTR35_FillOutFreq(ref this, freq, out fnd_freq);
            }


            public _LTRNative.LTRERROR FillDIAcqFreq(double freq, out double fnd_freq)
            {
                return LTR35_FillDIAcqFreq(ref this, freq, out fnd_freq);
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct STATE
        {
            _LTRNative.FpgaState _fpga_state;
            [MarshalAs(UnmanagedType.U1)]
            bool _run;
            [MarshalAs(UnmanagedType.U1)]
            RunState _run_state;
            double _out_freq;
            byte _enabled_ch_cnt;
            byte _sdram_ch_cnt;
            byte _arith_ch_cnt;
            byte _in_stream_di_ch_cnt;
            double _in_stream_di_acq_freq;
            double _in_stream_word_freq;
            double _synt_freq;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
            uint[] _reserved;

            public _LTRNative.FpgaState FpgaState { get { return _fpga_state; } }
            public bool Run { get { return _run; } }
            public RunState RunState { get { return _run_state; } }
            public double OutFreq { get { return _out_freq; } }
            public byte EnabledChCnt { get { return _enabled_ch_cnt; } }
            public byte SDRAMChCnt { get { return _sdram_ch_cnt; } }
            public byte ArithChCnt { get { return _arith_ch_cnt; } }
            public byte InStreamDIChCnt { get { return _in_stream_di_ch_cnt; } }
            public double InStreamDIAcqFreq { get { return _in_stream_di_acq_freq; } }
            public double InStreamWordFreq { get { return _in_stream_word_freq; } }
            public double SyntFreq { get { return _synt_freq; } }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct TLTR35
        {
            int _size;
            public _LTRNative.TLTR Channel;
            IntPtr _internal;
            CONFIG _cfg;
            STATE _stat;
            INFO _info;


            /** Настройки модуля. Заполняются пользователем перед вызовом LTR210_SetADC(). */
            public CONFIG Cfg { get { return _cfg; } set { _cfg = value; } }
            /** Состояние модуля и рассчитанные параметры. Поля изменяются функциями
                библиотеки. Пользовательской программой могут использоваться
                только для чтения. */
            public STATE State { get { return _stat; } }
            /** Информация о модуле */
            public INFO ModuleInfo { get { return _info; } }
        }

        TLTR35 module;

        public CONFIG Cfg { get { return module.Cfg; } set { module.Cfg = value; } }
        public STATE State { get { return module.State; } }
        public INFO ModuleInfo { get { return module.ModuleInfo; } }



        public ltr35api()
        {
            LTR35_Init(ref module);
        }

        /* в финализаторе убеждаемся, что остановили поток и 
         * закрыли модуль */
        ~ltr35api()
        {
            if (IsOpened() == _LTRNative.LTRERROR.OK)
            {              
                Close();
            }
        }

        public _LTRNative.LTRERROR Open(uint saddr, ushort sport, string csn, int slot_num)
        {
            return LTR35_Open(ref module, saddr, sport, csn, slot_num);
        }

        public _LTRNative.LTRERROR Open(string csn, int slot_num)
        {
            return Open(_LTRNative.SADDR_DEFAULT, _LTRNative.SPORT_DEFAULT, csn, slot_num);
        }

        public _LTRNative.LTRERROR Open(int slot_num)
        {
            return Open("", slot_num);
        }

        public _LTRNative.LTRERROR Close()
        {
            return LTR35_Close(ref module);
        }

        public _LTRNative.LTRERROR IsOpened()
        {
            return LTR35_IsOpened(ref module);
        }

        public _LTRNative.LTRERROR Configure()
        {
            return LTR35_Configure(ref module);
        }

        public int Send(uint[] data, uint size, uint timeout)
        {
            return LTR35_Send(ref module, data, size, timeout);
        }


        public _LTRNative.LTRERROR PrepareData(double[] dac_data, ref uint dac_size,
            uint[] dout_data, ref uint dout_size, PrepFlags flags,
            uint[] result, ref uint snd_size)
        {
            return LTR35_PrepareData(ref module, dac_data, ref dac_size, dout_data, ref dout_size, flags, result, ref snd_size);
        }

        public _LTRNative.LTRERROR LTR35_PrepareDacData(double[] dac_data, uint size, PrepFlags flags,
            uint[] result, out uint snd_size)
        {
            return LTR35_PrepareDacData(ref module, dac_data, size, flags, result, out snd_size);
        }

        public _LTRNative.LTRERROR SwitchCyclePage(uint tout)
        {
            return LTR35_SwitchCyclePage(ref module, 0, tout);
        }

        public _LTRNative.LTRERROR SwitchCyclePageRequest()
        {

            return LTR35_SwitchCyclePageRequest(ref module, 0); 
        }

        public _LTRNative.LTRERROR SwitchCyclePageWaitDone(uint tout)
        {
            return LTR35_SwitchCyclePageWaitDone(ref module, tout);
        }

        public _LTRNative.LTRERROR StreamStart()
        {
            return LTR35_StreamStart(ref module, 0);
        }

        public _LTRNative.LTRERROR StreamStartRequest()
        {
            return LTR35_StreamStartRequest(ref module, 0);
        }

        public _LTRNative.LTRERROR StreamStartWaitSlaveReady(uint tout)
        {
            return LTR35_StreamStartWaitSlaveReady(ref module, tout);
        }

        public _LTRNative.LTRERROR StreamStartWaitDone(uint tout)
        {
            return LTR35_StreamStartWaitDone(ref module, tout);
        }

        public _LTRNative.LTRERROR Stop()
        {
            return LTR35_Stop(ref module, 0);
        }

        public _LTRNative.LTRERROR StopWithTout(uint tout)
        {
            return LTR35_StopWithTout(ref module, 0, tout);
        }

        public _LTRNative.LTRERROR SetArithSrcDelta(byte gen_num, ARITH_PHASE delta)
        {
            return LTR35_SetArithSrcDelta(ref module, gen_num, ref delta);
        }

        public _LTRNative.LTRERROR SetArithAmp(byte ch_num, double amp, double offset)
        {
            return LTR35_SetArithAmp(ref module, ch_num, amp, offset);
        }

        public int RecvInStreamData(uint[] data, uint[] tmark, uint size, uint timeout)
        {
            return LTR35_RecvInStreamData(ref module, data, tmark, size, timeout);
        }

        public _LTRNative.LTRERROR FPGAIsEnabled(out bool enabled)
        {
            return LTR35_FPGAIsEnabled(ref module, out enabled);
        }

        public _LTRNative.LTRERROR FPGAEnable(bool enable)
        {
            return LTR35_FPGAEnable(ref module, enable);
        }

        public _LTRNative.LTRERROR GetStatus(out StatusFlags status)
        {
            return LTR35_GetStatus(ref module, out status);
        }
        public _LTRNative.LTRERROR GetConfig()
        {
            return LTR35_GetConfig(ref module);
        }

        public _LTRNative.LTRERROR DacReset()
        {
            return LTR35_DacReset(ref module);
        }

        public _LTRNative.LTRERROR DIAsyncIn(out byte di_state)
        {
            return LTR35_DIAsyncIn(ref module, out di_state);
        }

        public _LTRNative.LTRERROR FlashRead(uint addr, byte[] data, uint size)
        {
            return LTR35_FlashRead(ref module, addr, data, size);
        }

        public _LTRNative.LTRERROR FlashWrite(uint addr, byte[] data, uint size, FlashWriteFlags flags)
        {
            return LTR35_FlashWrite(ref module, addr, data, size, flags);
        }

        public _LTRNative.LTRERROR FlashErase(uint addr, uint size)
        {
            return LTR35_FlashErase(ref module, addr, size);
        }



        public static string GetErrorString(_LTRNative.LTRERROR err)
        {
            IntPtr ptr = LTR35_GetErrorString((int)err);
            string str = Marshal.PtrToStringAnsi(ptr);
            Encoding srcEncodingFormat = Encoding.GetEncoding("windows-1251");
            Encoding dstEncodingFormat = Encoding.UTF8;
            return dstEncodingFormat.GetString(Encoding.Convert(srcEncodingFormat, dstEncodingFormat, srcEncodingFormat.GetBytes(str)));
        }
    }
}
