using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;

// @Name: do_waveform.cs
// @Author: Smacq
// @Copyright: Smacq
// @Date: 2024/12/25
// @Brief:
// This code focuses on the Do functions of the USB - 3000 device, performing digital waveform output.
// It sets the Do output HIGH/LOW 2 times, where 0V is LOW (default) and 3.3V is HIGH.
// The DO channels vary depending on the module, either Do_4 or Do_8.
// You can refer to the user manual for more information about functions or device details.
//
// Execution result when only connecting USB for USB - 3000(DO_4):
// 0
//...
// 0


class Program
{
    static void Main(string[] args)
    {
        // Device index starts from zero
        int DevIndex = 0;

        // Init Do_data_array
        // Data type is uint32, it is not modifiable.
        // Do data point 0 is LOW, 1 is HIGH.
        //
        // For example:
        // Do_channel_4:0xF(1111) Do3~Do0 is HIGH
        // Do_channel_8:0xFF(1111 1111) Do7~Do0 is HIGH.
        // Do_channel_4:0x3(0011) Do3~Do2 is LOW,Do1~Do0 is HIGH.
        // Do_channel_8:0x88(1000 1000) Do7 and Do3 is HIGH, other Do is LOW.
        uint[] Do_data_array = { 0xF, 0, 0xFF, 0, 0xF0, 0 };

        // select digital output wave channel
        // Do_channel_4:0(0000)~0xF(1111) Do3~Do0
        // Do_channel_8:0(0000 0000)~0xFF(1111 1111) Do7~Do0
        // select Do channel for example:
        // Do_0: 0x1(0001), Do_0 and Do_1: 0x3(0011), Do_3 and Do_7: 0x88(1000 1000)
        uint DoWaveChannel = 0xF;

        // Do channel sample mode:
        // 0 = continuous non - loop output to computer buffer
        // 1 = FIFO output loop determined by SetUSB3DoCycle()
        byte DoSampleMode = 1;

        // Do Sampling period, unit ns, steps 10ns:
        // USB - 3000 is synchronous Do, max rate is 10M = 100.
        // sample rate and period:
        // 1M = 1000
        // 100k = 10000
        // 10k = 100000
        // 1k = 1000000
        // 100 = 10000000
        // 10 = 100000000
        // 1 = 1000000000
        uint DoSampleRate = 1000000000;

        // Do acquisition trig source:
        // 0 = SetUSB3AiSoftTrig(), 1 = Ext_Trig_In, 2~5 = Din_0~3,
        // 6 = with AI, 7 = with DI, 9~12 = with AO~3, 255 = GlobalSoftTrig
        // Supported parameters: 0/1/2/3/4/5/6/7/9/11/12/255
        byte DoTrigSource = 0;

        // Do acquisition clock source:
        // 0 = SetUSB3DoSampleRate(), 1 = Conv_In, 2 = Ai, 3 = Di, 5~8 = AO~3
        // Supported parameters: 0/1/2/3/5/6/7/8
        byte DoConvSource = 0;

        // Set waveform output cycle
        // 0 = infinite loop output
        // 1 = 1 time, 2 = 2 times and so on.
        // Supported parameters: 0 ~ 4294967295
        uint DoCycle = 2;

        // Download to Do FIFO data number
        uint Num = (uint)Do_data_array.Length;

        int error_code;

        // Open specific device and print return value.
        error_code = USB3000DLL.USB3OpenDevice(DevIndex);
        Console.WriteLine(error_code);

        // Set digital output wave channel
        error_code = USB3000DLL.SetUSB3DoWaveCtrl(DevIndex, DoWaveChannel);
        Console.WriteLine(error_code);

        // Disable Do software trig, clear flag
        error_code = USB3000DLL.SetUSB3ClrDoTrigger(DevIndex);
        Console.WriteLine(error_code);

        // Clear FIFO
        error_code = USB3000DLL.SetUSB3ClrDoFifo(DevIndex);
        Console.WriteLine(error_code);

        // Set Device Do sample mode
        error_code = USB3000DLL.SetUSB3DoSampleMode(DevIndex, DoSampleMode);
        Console.WriteLine(error_code);

        // Set Device sample rate
        error_code = USB3000DLL.SetUSB3DoSampleRate(DevIndex, DoSampleRate);
        Console.WriteLine(error_code);

        // Set Device trig source
        error_code = USB3000DLL.SetUSB3DoTrigSource(DevIndex, DoTrigSource);
        Console.WriteLine(error_code);

        // Set Device clock source
        error_code = USB3000DLL.SetUSB3DoConvSource(DevIndex, DoConvSource);
        Console.WriteLine(error_code);

        // Set digital output cycle 2 times
        error_code = USB3000DLL.SetUSB3DoCycle(DevIndex, DoCycle);
        Console.WriteLine(error_code);

        // Download array data to Do FIFO
        error_code = USB3000DLL.SetUSB3DoDataFifo(DevIndex, Do_data_array, Num);
        Console.WriteLine(error_code);

        // Enable Do software trig start DO output wave
        error_code = USB3000DLL.SetUSB3DoSoftTrig(DevIndex);
        Console.WriteLine(error_code);

        // Necessary delay for Do wave output
        Thread.Sleep(12000);

        // Disable Do software trig, clear flag
        error_code = USB3000DLL.SetUSB3ClrDoTrigger(DevIndex);
        Console.WriteLine(error_code);

        // Clear FIFO
        error_code = USB3000DLL.SetUSB3ClrDoFifo(DevIndex);
        Console.WriteLine(error_code);

        // Close Device and stop Do wave output
        error_code = USB3000DLL.USB3CloseDevice(DevIndex);
        Console.WriteLine(error_code);
    }
    class USB3000DLL
    {
        [DllImport("USB3000.dll")]
        public static extern int FindUSB3DAQ();
        [DllImport("USB3000.dll")]
        public static extern int USB3OpenDevice(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int USB3CloseDevice(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int USB3ReadDevcieSN(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int USB3ReadDevcieModel(int DevIndex);
        //--------------------------------------------------------------------------
        // Ananlog Input Configuration
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiSampleRate(int DevIndex, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiSampleMode(int DevIndex, byte AiSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiConnectType(int DevIndex, byte AiConnectType);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiRange(int DevIndex, byte Chan, float AiRange);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiChanSel(int DevIndex, byte Chan, byte Sel);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiTrigSource(int DevIndex, byte AiTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiConvSource(int DevIndex, byte AiConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiPreTrigPoints(int DevIndex, uint AiPreTrigPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiOneShotPoints(int DevIndex, uint AiOneShotPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAiFifo(int DevIndex);
        //--------------------------------------------------------------------------
        // Digital I/O Configuration
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiSampleRate(int DevIndex, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiSampleMode(int DevIndex, byte DiSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiTrigSource(int DevIndex, byte DiTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiConvSource(int DevIndex, byte DiConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiPreTrigPoints(int DevIndex, uint DiPreTrigPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiOneShotPoints(int DevIndex, uint DiOneShotPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDiFifo(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoSampleRate(int DevIndex, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoSampleMode(int DevIndex, byte DoSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoTrigSource(int DevIndex, byte DoTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoConvSource(int DevIndex, byte DoConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoCycle(int DevIndex, uint DoCycle);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoDataFifo(int DevIndex, uint[] Value, uint Len);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDoFifo(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoWaveCtrl(int DevIndex, uint Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoImmediately(int DevIndex, uint Chan, uint Value);
        //--------------------------------------------------------------------------
        // Ananlog Output Configuration
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSampleRate(int DevIndex, byte Chan, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSampleMode(int DevIndex, byte Chan, byte AoSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoTrigSource(int DevIndex, byte Chan, byte AoTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoConvSource(int DevIndex, byte Chan, byte AoConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoCycle(int DevIndex, byte Chan, byte AoCycle);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoDataFifo(int DevIndex, byte Chan, float[] Voltage, uint Len);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAoFifo(int DevIndex, byte Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSync(int DevIndex, byte Chans);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoImmediately(int DevIndex, byte Chan, float Voltage);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoImmediately4Chans(int DevIndex, float Volt0, float Volt1, float Volt2, float Volt3);
        //--------------------------------------------------------------------------
        // Trig Control
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSoftTrig(int DevIndex, byte Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3GlobalSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAiTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDiTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDoTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAoTrigger(int DevIndex, byte Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrGlobalSoftTrig(int DevIndex);
        //--------------------------------------------------------------------------
        // Sync Configuration
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ExtTrigOutSource(int DevIndex, byte Source);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ExtConvOutSource(int DevIndex, byte Source);
        //--------------------------------------------------------------------------
        // Get Data Acquired
        [DllImport("USB3000.dll")]
        public static extern int USB3GetAi(int DevIndex, uint Points, float[] Ai, int TimeOut);
        [DllImport("USB3000.dll")]
        public static extern int USB3GetDi(int DevIndex, uint Points, byte[] Di, int TimeOut);
    }

}