using System.Windows.Forms;

namespace TUSB0214DAMSampleApp
{
    public partial class Form1 : Form
    {
        // 動作モードenum
        enum OMode : byte { DC, GATE, TRIGGER };

        // 装置シリアル番号文字列
        string DevSerialStr;

        // 設定値類

        // SYNC OUT
        uint SyncOutClkN;           // 現在の要求クロック周波数から生成された設定値
        double SyncOutFreqD;        // SyncOutClkNから算出されたクロック周波数
        // GROUP A
        SetMode Ch1Mode = SetMode.DC;    // 現在の動作モード
        uint Ch1ClkN;               // 現在の要求クロック周波数から生成された設定値
        double Ch1FreqD;            // Ch1ClkNから算出されたクロック周波数
        decimal WavFreqA = 100.0M;  // 波形生成設定の周波数を設定するNumericUpDownの値保存用
        decimal WavLenA = 100M;     // 波形生成設定の波形データ数を設定するNumericUpDownの値保存用
        // GROUP B
        SetMode Ch2Mode = SetMode.DC;   // 現在の動作モード
        uint Ch2ClkN;               // 現在の要求クロック周波数から生成された設定値
        double Ch2FreqD;            // Ch2ClkNから算出されたクロック周波数
        decimal WavFreqB = 100.0M;  // 波形生成設定の周波数を設定するNumericUpDownの値保存用
        decimal WavLenB = 100M;     // 波形生成設定の波形データ数を設定するNumericUpDownの値保存用

        // コンボボックスの設定値定義 /////////////////////////////
        const int SEL_NONE = -1;// 何も選択されていない
        // DIO設定 index
        const int DIO_IN = 0;
        const int DIO_HIGH = 1;
        const int DIO_LOW = 2;
        // Sync Out 0 index
        const int SYNC0_HIGH = 0;
        const int SYNC0_LOW = 1;
        const int SYNC0_GATE_TRG = 2;
        const int SYNC0_SYNCA = 3;
        const int CYNC0_SYNCB = 4;
        // Sync Out 1 index
        const int SYNC1_HIGH = 0;
        const int SYNC1_LOW = 1;
        const int SYNC1_CLOCK = 2;
        const int SYNC1_SYNCA = 3;
        const int CYNC1_SYNCB = 4;

        //EXIO0 index
        const int EXIO0_IN = 0;
        const int EXIO0_GATE_TRG_IN = 1;
        const int EXIO0_HIGH = 2;
        const int EXIO0_LOW = 3;
        const int EXIO0_GATE_TRG_OUT = 4;
        const int EXIO0_SYNCA = 5;
        const int EXIO0_SYNCB = 6;

        //EXIO1 index
        const int EXIO1_IN = 0;
        const int EXIO1_HIGH = 1;
        const int EXIO1_LOW = 2;
        const int EXIO1_CLOCK_OUT = 3;
        const int EXIO1_SYNCA = 4;
        const int EXIO1_SYNCB = 5;

        bool isVoltageCodeSyncing = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            OpenBtn.Enabled = true;//オープンボタンイネーブル
            CloseBtn.Enabled = false;// クローズボタンディセーブル

            // 起動時は機能操作をディセーブルにする
            DIO_G.Enabled = false;
            SYNCOUT_G.Enabled = false;
            CH1_G.Enabled = false;
            CH2_G.Enabled = false;
            EXIO_G.Enabled = false;

            // コンボボックスのインデックスを初期化
            DIO_SEL0.SelectedIndex = 0;
            DIO_SEL1.SelectedIndex = 0;
            DIO_SEL2.SelectedIndex = 0;
            DIO_SEL3.SelectedIndex = 0;
            DIO_SEL4.SelectedIndex = 0;
            DIO_SEL5.SelectedIndex = 0;
            DIO_SEL6.SelectedIndex = 0;
            DIO_SEL7.SelectedIndex = 0;
            Ch1RangeCh.SelectedIndex = 0;
            Ch2RangeCh.SelectedIndex = 0;
            SyncOutSel0.SelectedIndex = 0;
            SyncOutSel1.SelectedIndex = 0;
            EXIO_SEL0.SelectedIndex = 0;
            EXIO_SEL1.SelectedIndex = 0;

            // ラジオボタンの初期値を設定
            SyncOutFreq_kHz.Checked = true;
            Ch1ModeDC.Checked = true;
            Ch1ClkInt.Checked = true;
            Ch1GTInt.Checked = true;
            Ch1Freq_kHz.Checked = true;
            Ch1WavSin.Checked = true;
            Ch2WavSin.Checked = true;
            Ch1WavFreq_kHz.Checked = true;
            Ch2ModeDC.Checked = true;
            Ch2ClkInt.Checked = true;
            Ch2GTInt.Checked = true;
            Ch2Freq_kHz.Checked = true;
            Ch2WavFreq_kHz.Checked = true;

            // 数値入力の初期値を設定
            SyncOutClkFreq.Value = 100M;
            SyncOutClkFreq.Minimum = 0.001M;
            SyncOutClkFreq.Maximum = 1000M;

            Ch1TrgModeCnt.Value = 1M;
            Ch1TrgModeCnt.Minimum = 1M;
            Ch1TrgModeCnt.Maximum = 65535M;
            Ch1ClkFreq.Value = 100.0M;
            Ch1ClkFreq.Minimum = 0.001M;
            Ch1ClkFreq.Maximum = 1000.0M;
            Ch1StopStSpVol.Value = 0M;
            Ch1StopStSpVol.Minimum = -10M;
            Ch1StopStSpVol.Maximum = 9.9998M;
            Ch2StopStSpVol.Value = 0M;
            Ch2StopStSpVol.Minimum = -10M;
            Ch2StopStSpVol.Maximum = 9.9998M;
            Ch1WavAmp.Value = 1M;
            Ch1WavAmp.Maximum = 9.9998M;
            Ch1WavAmp.Minimum = -10M;
            Ch2WavAmp.Value = 1M;
            Ch2WavAmp.Maximum = 9.9998M;
            Ch2WavAmp.Minimum = -10M;
            Ch1WavFreq.Value = 1M;
            Ch1WavFreq.Minimum = 0.001M;
            Ch1WavFreq.Maximum = 1000M;

            Ch2TrgModeCnt.Value = 1M;
            Ch2TrgModeCnt.Minimum = 1M;
            Ch2TrgModeCnt.Maximum = 65535M;
            Ch2ClkFreq.Value = 100.0M;
            Ch2ClkFreq.Minimum = 0.001M;
            Ch2ClkFreq.Maximum = 1000.0M;
            Ch1StopStSpVol.Value = 0M;
            Ch1StopStSpVol.Minimum = -10M;
            Ch1StopStSpVol.Maximum = 9.9998M;
            Ch2StopStSpVol.Value = 0M;
            Ch2StopStSpVol.Minimum = -10M;
            Ch2StopStSpVol.Maximum = 9.9998M;
            Ch2WavFreq.Value = 1M;
            Ch2WavFreq.Minimum = 0.001M;
            Ch2WavFreq.Maximum = 1000M;
        }

        private void OpenBtn_Click(object sender, EventArgs e)
        {
            DevSerialStr = SerialNum.Value.ToUShort().ToString("D4");
            uint retcode = TUSB0214DAM.TUSB0214DAM_Connect(DevSerialStr);   // デバイスの接続処理
            if (retcode == 0)   // 接続が出来たらコントロールの表示状態を変える
            {
                DIO_G.Enabled = true;
                SYNCOUT_G.Enabled = true;
                CH1_G.Enabled = true;
                CH2_G.Enabled = true;
                OpenBtn.Enabled = false;
                CloseBtn.Enabled = true;
                SerialNum.Enabled = false;
                this.ControlBox = false;
                IOCheckTimer.Enabled = true;
                Ch1CheckTimer.Enabled = true;
                Ch2CheckTimer.Enabled = true;
                DigitalIOGroupInit();           // Digial I/O関係の初期化
                SyncOutGroupInit();             // SyncOut関係の初期化
                CH1GroupInit();              // CH1 Control関係の初期化
                CH2GroupInit();              // CH2 Control関係の初期化
                EXIO_G.Enabled = true;
            }
            else
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void CloseBtn_Click(object sender, EventArgs e)
        {
            // 切断時コントロールの表示状態を変える
            IOCheckTimer.Enabled = false;
            Ch1CheckTimer.Enabled = false;
            Ch2CheckTimer.Enabled = false;

            DIO_G.Enabled = false;
            SYNCOUT_G.Enabled = false;
            CH1_G.Enabled = false;
            CH2_G.Enabled = false;
            OpenBtn.Enabled = true;
            CloseBtn.Enabled = false;
            SerialNum.Enabled = true;
            EXIO_G.Enabled = false;
            this.ControlBox = true;
            TUSB0214DAM.TUSB0214DAM_DisConnect(DevSerialStr);   // 接続解除
        }

        // Digital I/O 関連処理
        // ディレクションビットと出力ビットを装置から読み出してから現在の
        // 値として表示に反映させる
        // 接続時の処理
        private void ChkDIO_State()
        {
            uint retcode;
            byte IO_Dir;
            byte IO_Out;
            retcode = TUSB0214DAM.TUSB0214DAM_Dio_Dir_R(DevSerialStr, out IO_Dir);  // 入出力方向の読み込み
            if (retcode != 0)
            {
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                return;
            }
            retcode = TUSB0214DAM.TUSB0214DAM_Dio_Out_R(DevSerialStr, out IO_Out);  // 出力設定ビットの読み込み
            if (retcode != 0)
            {
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                return;
            }

            // 画面コントロールに反映させる
            DIO_SEL0.SelectedIndex = (!IO_Dir.IsBitSet0()) ? DIO_IN : (IO_Out.IsBitSet0() ? DIO_HIGH : DIO_LOW);
            DIO_SEL1.SelectedIndex = (!IO_Dir.IsBitSet1()) ? DIO_IN : (IO_Out.IsBitSet1() ? DIO_HIGH : DIO_LOW);
            DIO_SEL2.SelectedIndex = (!IO_Dir.IsBitSet2()) ? DIO_IN : (IO_Out.IsBitSet2() ? DIO_HIGH : DIO_LOW);
            DIO_SEL3.SelectedIndex = (!IO_Dir.IsBitSet3()) ? DIO_IN : (IO_Out.IsBitSet3() ? DIO_HIGH : DIO_LOW);
            DIO_SEL4.SelectedIndex = (!IO_Dir.IsBitSet4()) ? DIO_IN : (IO_Out.IsBitSet4() ? DIO_HIGH : DIO_LOW);
            DIO_SEL5.SelectedIndex = (!IO_Dir.IsBitSet5()) ? DIO_IN : (IO_Out.IsBitSet5() ? DIO_HIGH : DIO_LOW);
            DIO_SEL6.SelectedIndex = (!IO_Dir.IsBitSet6()) ? DIO_IN : (IO_Out.IsBitSet6() ? DIO_HIGH : DIO_LOW);
            DIO_SEL7.SelectedIndex = (!IO_Dir.IsBitSet7()) ? DIO_IN : (IO_Out.IsBitSet7() ? DIO_HIGH : DIO_LOW);
        }

        // Digital I/O 関連処理
        // 入力状態をチェックして表示する
        private void ChkDIO_In()
        {
            byte IO_In;
            uint retcode = TUSB0214DAM.TUSB0214DAM_Dio_In(DevSerialStr, out IO_In);   // 入力状態を読み込む
            if (retcode != 0)
            {
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                return;
            }

            // 画面への反映　Highなら明るい緑、Lowなら暗い緑にする
            DIO_IN0.BackColor = IO_In.IsBitSet0() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN1.BackColor = IO_In.IsBitSet1() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN2.BackColor = IO_In.IsBitSet2() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN3.BackColor = IO_In.IsBitSet3() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN4.BackColor = IO_In.IsBitSet4() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN5.BackColor = IO_In.IsBitSet5() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN6.BackColor = IO_In.IsBitSet6() ? Color.LightGreen : Color.DarkGreen;
            DIO_IN7.BackColor = IO_In.IsBitSet7() ? Color.LightGreen : Color.DarkGreen;


            //EXIO の入力状態チェック、反映
            retcode = TUSB0214DAM.TUSB0214DAM_EXIO_In(DevSerialStr, out IO_In);   // 入力状態を読み込む
            if (retcode != 0)
            {
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                return;
            }

            // 画面への反映　Highなら明るい緑、Lowなら暗い緑にする
            EXIO_IN0.BackColor = IO_In.IsBitSet0() ? Color.LightGreen : Color.DarkGreen;
            EXIO_IN1.BackColor = IO_In.IsBitSet1() ? Color.LightGreen : Color.DarkGreen;
        }

        // Didital I/O 関連処理
        // 現在のIO設定を出力に反映する
        private void SetDIO_Out()
        {
            if (!DIO_G.Enabled)
                return;

            byte IO_Dir = 0;    // 入出力方向設定      0が入力
            byte IO_Out = 0;    // 出力High Low設定    0がLow

            // 画面コントロールから読み込む

            if (DIO_SEL0.SelectedIndex != DIO_IN) IO_Dir.BitSet0();
            if (DIO_SEL1.SelectedIndex != DIO_IN) IO_Dir.BitSet1();
            if (DIO_SEL2.SelectedIndex != DIO_IN) IO_Dir.BitSet2();
            if (DIO_SEL3.SelectedIndex != DIO_IN) IO_Dir.BitSet3();
            if (DIO_SEL4.SelectedIndex != DIO_IN) IO_Dir.BitSet4();
            if (DIO_SEL5.SelectedIndex != DIO_IN) IO_Dir.BitSet5();
            if (DIO_SEL6.SelectedIndex != DIO_IN) IO_Dir.BitSet6();
            if (DIO_SEL7.SelectedIndex != DIO_IN) IO_Dir.BitSet7();

            if (DIO_SEL0.SelectedIndex == DIO_HIGH) IO_Out.BitSet0();
            if (DIO_SEL1.SelectedIndex == DIO_HIGH) IO_Out.BitSet1();
            if (DIO_SEL2.SelectedIndex == DIO_HIGH) IO_Out.BitSet2();
            if (DIO_SEL3.SelectedIndex == DIO_HIGH) IO_Out.BitSet3();
            if (DIO_SEL4.SelectedIndex == DIO_HIGH) IO_Out.BitSet4();
            if (DIO_SEL5.SelectedIndex == DIO_HIGH) IO_Out.BitSet5();
            if (DIO_SEL6.SelectedIndex == DIO_HIGH) IO_Out.BitSet6();
            if (DIO_SEL7.SelectedIndex == DIO_HIGH) IO_Out.BitSet7();

            uint retcode;
            retcode = TUSB0214DAM.TUSB0214DAM_Dio_Dir(DevSerialStr, IO_Dir);    // 入出力を設定
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            retcode = TUSB0214DAM.TUSB0214DAM_Dio_Out(DevSerialStr, IO_Out);    // High Low を設定
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        // Digital I/O コントロールグループの初期化をする
        private void DigitalIOGroupInit()
        {
            ChkDIO_State();
            ChkDIO_In();
        }

        // Sync Out 関連処理
        // コントロールグループの表示状態を設定する
        // 要求周波数から実際に設定される周波数を算出したり
        // 設定値に応じて各コントロールのイネーブル設定を変更する
        private void SyncOutGroupEnControls()
        {
            if (!SYNCOUT_G.Enabled)
                return;

            // 表示のイネーブルコントロール
            SyncOutClkFreq.Enabled = (SyncOutSel1.SelectedIndex == SYNC1_CLOCK ||
                EXIO_SEL1.SelectedIndex == EXIO1_CLOCK_OUT);
            SyncOutFreq_kHz.Enabled = SyncOutClkFreq.Enabled;
            SyncOutFreq_Hz.Enabled = SyncOutClkFreq.Enabled;
            SYNCOUT_GTCONT_P.Enabled = ((SyncOutSel0.SelectedIndex == SYNC0_GATE_TRG) ||
                (EXIO_SEL0.SelectedIndex == EXIO1_CLOCK_OUT));
            if (SyncOutSelGOff.Checked)
                SyncOutTrgBtn.Enabled = true;
            else
                SyncOutTrgBtn.Enabled = false;

            // クロック周波数の表示
            if (Etc.GetClockSetting((double)SyncOutClkFreq.Value, SyncOutFreq_kHz.Checked, out SyncOutClkN))// クロック設定値の算出
            {
                SyncOutFreqD = Etc.GetActualFrequency(SyncOutClkN);         // 設定値から周波数の算出
                SyncOutActFreq.Text = Etc.GetFrequencyStr(SyncOutFreqD);    // 周波数から周波数を表す文字列の生成
                SyncOutSetBtn.Enabled = true;
            }
            else
            {
                SyncOutClkFreq.AlartColor(true);
                SyncOutSetBtn.Enabled = false;
            }

            // ボタンの色
            SyncOutSetBtn.BackColor = Color.Salmon;
        }

        // Sync Out 関連処理
        // コントロールグループの初期化をする
        private void SyncOutGroupInit()
        {
            if (SyncOutSel0.SelectedIndex == SEL_NONE) SyncOutSel0.SelectedIndex = SYNC0_HIGH;
            if (SyncOutSel1.SelectedIndex == SEL_NONE) SyncOutSel1.SelectedIndex = SYNC1_HIGH;

            GateSt GateEn;
            uint retcode = TUSB0214DAM.TUSB0214DAM_GateSet_R(DevSerialStr, ModuleN.Ext, out GateEn); // ゲート出力の状態を読み出す
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                if (GateEn == GateSt.GOn)
                    SyncOutSelGOn.Checked = true;
                else
                    SyncOutSelGOff.Checked = true;
            }

            byte OutSel0;
            byte OutSel1;
            retcode = TUSB0214DAM.TUSB0214DAM_Exs_Sel_R(DevSerialStr, out OutSel0, out OutSel1);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                SyncOutSel0.SelectedIndex = OutSel0;
                SyncOutSel1.SelectedIndex = OutSel1;
            }

            byte ExIOSel0;
            byte ExIOSel1;
            retcode = TUSB0214DAM.TUSB0214DAM_EXIO_Sel_R(DevSerialStr,out ExIOSel0, out ExIOSel1);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                EXIO_SEL0.SelectedIndex = ExIOSel0;
                EXIO_SEL1.SelectedIndex = ExIOSel1;
            }

            SyncOutGroupEnControls();
            SyncOutSetBtn.AwakeColor(true);
        }

        // Group A 関連処理
        // クロック周波数のチェックと実際に設定される周波数の表示
        // 問題が無ければ trueを返す
        private bool FreqChkA()
        {
            bool clkresult = true;
            bool wavresult = true;

            // クロック設定値のチェック
            if (CH1_CLKGEN_G.Enabled)
            {
                clkresult = Etc.GetClockSetting((double)Ch1ClkFreq.Value, Ch1Freq_kHz.Checked, out Ch1ClkN);// 希望周波数に一番近くなる設定値(整数)を生成
                if (clkresult)
                {
                    Ch1FreqD = Etc.GetActualFrequency(Ch1ClkN);         // 設定値で設定した時に実際に設定される周波数(希望と丁度同じとは限らない)を取得
                    Ch1ActFreq.Text = Etc.GetFrequencyStr(Ch1FreqD);    // その周波数を文字列で取得
                }
                Ch1ClkFreq.AlartColor(!clkresult);
            }
            // 波形周波数のチェック
            if (CH1_IMAGE_GEN_G.Enabled && Ch1ClkInt.Checked)
            {
                int len;
                wavresult = Etc.GetWaveLength((double)Ch1WavFreq.Value, Ch1WavFreq_kHz.Checked, Ch1FreqD, out len);// 波形に必要なデータ長を取得
                if (wavresult)
                {
                    Ch1WavActFreq.Text = Etc.GetFrequencyStr(Ch1FreqD / (double)len); // 設定整数値から再度周波数に計算しなおして周波数文字列を得る
                    Ch1WavFreq.AlartColor(false);
                }
                Ch1WavFreq.AlartColor(!wavresult);
            }
            else
                Ch1WavFreq.AlartColor(false);
            return (clkresult && wavresult);
        }

        // Group B 関連処理
        // クロック周波数のチェックと実際に設定される周波数の表示
        // 問題が無ければ trueを返す
        private bool FreqChkB()
        {
            bool clkresult = true;
            bool wavresult = true;

            // クロック設定値のチェック
            if (CH2_CLKGEN_G.Enabled)
            {
                clkresult = Etc.GetClockSetting((double)Ch2ClkFreq.Value, Ch2Freq_kHz.Checked, out Ch2ClkN);// 希望周波数に一番近くなる設定値(整数)を生成
                if (clkresult)
                {
                    Ch2FreqD = Etc.GetActualFrequency(Ch2ClkN);         // 設定値で設定した時に実際に設定される周波数(希望と丁度同じとは限らない)を取得
                    Ch2ActFreq.Text = Etc.GetFrequencyStr(Ch2FreqD);    // その周波数を文字列で取得
                }
                Ch2ClkFreq.AlartColor(!clkresult);
            }
            // 波形周波数のチェック
            if (CH2_IMAGE_GEN_G.Enabled && Ch2ClkInt.Checked)
            {
                int len;
                wavresult = Etc.GetWaveLength((double)Ch2WavFreq.Value, Ch2WavFreq_kHz.Checked, Ch2FreqD, out len);// 波形に必要なデータ長を取得
                if (wavresult)
                {
                    Ch2WavActFreq.Text = Etc.GetFrequencyStr(Ch2FreqD / (double)len); // 設定整数値から再度周波数に計算しなおして周波数文字列を得る
                    Ch2WavFreq.AlartColor(false);
                }
                Ch2WavFreq.AlartColor(!wavresult);
            }
            else
                Ch2WavFreq.AlartColor(false);
            return (clkresult && wavresult);
        }


        // Group A 関連処理
        // 電圧設定チェック
        // 問題が無ければ trueを返す
        private bool VoltChkA()
        {
            bool err = false;

            RangeSel RangeCh1 = (RangeSel)Ch1RangeCh.SelectedIndex;   // ch1 レンジ
            double DCV1 = (double)Ch1OffsetDC.Value;                 // ch1 直流オフセット電圧
            double AMP1 = (double)Ch1WavAmp.Value;                     // ch1 振幅電圧
            double STPV1 = (double)Ch1StopStSpVol.Value;               // ch1 停止電圧

            // 直流電圧設定値がレンジ内に入っているか確認
            err |= Ch1OffsetDC.AlartColor(!Etc.VoltRangeChk(RangeCh1, DCV1));

            if (!Ch1ModeDC.Checked)// 直流出力ではない場合
            {
                // 波形のピーク電圧がレンジ内に入っているか確認
                err |= Ch1WavAmp.AlartColor((!Etc.VoltRangeChk(RangeCh1, DCV1 + AMP1)) || (!Etc.VoltRangeChk(RangeCh1, DCV1 - AMP1)));

                // 停止電圧の設定が有効ならば、停止電圧がレンジ内に入っているか確認
                if (Ch1StopStSpChk.Checked)
                    err |= Ch1StopStSpVol.AlartColor(!Etc.VoltRangeChk(RangeCh1, STPV1));
            }

            return !err;
        }

        // Group A 関連処理
        // 電圧設定チェック
        // 問題が無ければ trueを返す
        private bool VoltChkB()
        {
            bool err = false;

            RangeSel RangeCh2 = (RangeSel)Ch2RangeCh.SelectedIndex;   // ch2 レンジ
            double DCV2 = (double)Ch2OffsetDC.Value;                 // ch2 直流オフセット電圧
            double AMP2 = (double)Ch2WavAmp.Value;                     // ch2 振幅電圧
            double STPV2 = (double)Ch2StopStSpVol.Value;                // ch2 停止電圧

            // 直流電圧設定値がレンジ内に入っているか確認
            err |= Ch2OffsetDC.AlartColor(!Etc.VoltRangeChk(RangeCh2, DCV2));

            if (!Ch2ModeDC.Checked)// 直流出力ではない場合
            {
                // 波形のピーク電圧がレンジ内に入っているか確認
                err |= Ch2WavAmp.AlartColor((!Etc.VoltRangeChk(RangeCh2, DCV2 + AMP2)) || (!Etc.VoltRangeChk(RangeCh2, DCV2 - AMP2)));

                // 停止電圧の設定が有効ならば、停止電圧がレンジ内に入っているか確認
                if (Ch2StopStSpChk.Checked)
                    err |= Ch2StopStSpVol.AlartColor(!Etc.VoltRangeChk(RangeCh2, STPV2));
            }

            return !err;
        }

        // Group A 関連処理
        // コントロールグループの表示状態を設定する
        private void CH1GroupEnControls()
        {
            if (!CH1_G.Enabled)
                return;

            bool err = false;

            // 表示のイネーブルコントロール
            CH1_CLK_G.Enabled = !Ch1ModeDC.Checked;
            CH1_GT_G.Enabled = !Ch1ModeDC.Checked;
            CH1_GMODE_G.Enabled = Ch1ModeGate.Checked;
            Ch1GModeInv.Enabled = Ch1GTExt.Checked || Ch1GTExtFront.Checked;
            CH1_TMODE_G.Enabled = Ch1ModeTrg.Checked;
            CH1_CLKGEN_G.Enabled = !Ch1ModeDC.Checked & Ch1ClkInt.Checked;
            Ch1TrgModeCnt.Enabled = !Ch1TrgModeInf.Checked;
            CH1_STPST_G.Enabled = !Ch1ModeDC.Checked;
            Ch1StopStSpVol.Enabled = Ch1StopStSpChk.Checked;
            CH1_WGEN_G.Enabled = !Ch1ModeDC.Checked;
            CH1_IMAGE_GEN_G.Enabled = !Ch1ModeDC.Checked;
            CH1_GCONT_G.Enabled = Ch1ModeGate.Checked && Ch1GTInt.Checked;
            Ch1StartTrgBtn.Enabled = Ch1ModeTrg.Checked && Ch1GTInt.Checked;
            Ch1StopBtn.Enabled = Ch1ModeTrg.Checked;

            // クロック周波数のチェックと表示
            err |= !FreqChkA();

            
            // 電圧レベルチェック
            err |= !VoltChkA();

            // ボタンの表示
            Ch1SetBtn.AwakeColor(true);
            Ch1SetBtn.Enabled = !err;
        }

        // Group B 関連処理
        // コントロールグループの表示状態を設定する
        private void CH2GroupEnControls()
        {
            if (!CH2_G.Enabled)
                return;

            bool err = false;

            // 表示のイネーブルコントロール
            CH2_CLK_G.Enabled = !Ch2ModeDC.Checked;
            CH2_GT_G.Enabled = !Ch2ModeDC.Checked;
            CH2_GMODE_G.Enabled = Ch2ModeGate.Checked;
            Ch2GModeInv.Enabled = Ch2GTExt.Checked;
            CH2_TMODE_G.Enabled = Ch2ModeTrg.Checked;
            CH2_CLKGEN_G.Enabled = !Ch2ModeDC.Checked;
            Ch2TrgModeCnt.Enabled = !Ch2TrgModeInf.Checked;
            CH2_STPST_G.Enabled = !Ch2ModeDC.Checked;
            Ch2StopStSpVol.Enabled = Ch2StopStSpChk.Checked;
            CH2_WGEN_G.Enabled = !Ch2ModeDC.Checked;
            CH2_IMAGE_GEN_G.Enabled = !Ch2ModeDC.Checked;
            CH2_GCONT_G.Enabled = Ch2ModeGate.Checked && Ch2GTInt.Checked;
            Ch2StartTrgBtn.Enabled = Ch2ModeTrg.Checked && Ch2GTInt.Checked;
            Ch2StopBtn.Enabled = Ch2ModeTrg.Checked;

            // クロック周波数のチェックと表示
            err |= !FreqChkB();

            // 電圧レベルチェック
            err |= !VoltChkB();

            // ボタンの表示
            Ch2SetBtn.AwakeColor(true);
            Ch2SetBtn.Enabled = !err;
        }

        // Group A
        // 構造体から設定を読み出して画面表示に反映する
        private void SetSettingsA(stSettings sets)
        {
            Ch1Mode = sets.Mode;
            switch (sets.Mode)
            {
                case SetMode.DC:
                    Ch1ModeDC.Checked = true;
                    break;
                case SetMode.Gate:
                    Ch1ModeGate.Checked = true;
                    break;
                case SetMode.Trg:
                    Ch1ModeTrg.Checked = true;
                    break;
            }
            if (sets.ClkSel == SigSrc.Internal) Ch1ClkInt.Checked = true;
            else Ch1ClkExt.Checked = true;
            if (sets.GTSel == SigSrc.Internal) Ch1GTInt.Checked = true;
            else Ch1GTExt.Checked = true;
            if (sets.ExGtInv == SigInv.Invert) Ch1GModeInv.Checked = true;
            else Ch1GModeInv.Checked = false;
            if (sets.Rstc == RestartPos.Zero) Ch1GModeStart.Checked = true;
            else Ch1GModeStart.Checked = false;
            if (sets.FStat == FinState.SpecificValue) Ch1StopStSpChk.Checked = true;
            else Ch1StopStSpChk.Checked = false;
            if (sets.FStat == FinState.SpecificValue) Ch1StopStSpChk.Checked = true;
            else Ch2StopStSpChk.Checked = false;
            Ch1StopStSpVol.Value = (decimal)Etc.DacCodeToVolt(sets.FVal, (RangeSel)Ch1RangeCh.SelectedIndex);
            if (sets.RepCyc == 0) Ch1TrgModeInf.Checked = true;
            else Ch1TrgModeCnt.Value = sets.RepCyc;
        }

        // Group B
        // 構造体から設定を読み出して画面表示に反映する
        private void SetSettingsB(stSettings sets)
        {
            Ch2Mode = sets.Mode;
            switch (sets.Mode)
            {
                case SetMode.DC:
                    Ch2ModeDC.Checked = true;
                    break;
                case SetMode.Gate:
                    Ch2ModeGate.Checked = true;
                    break;
                case SetMode.Trg:
                    Ch2ModeTrg.Checked = true;
                    break;
            }
            if (sets.ClkSel == SigSrc.Internal) Ch2ClkInt.Checked = true;
            else Ch2ClkExt.Checked = true;
            if (sets.GTSel == SigSrc.Internal) Ch2GTInt.Checked = true;
            else Ch2GTExt.Checked = true;
            if (sets.ExGtInv == SigInv.Invert) Ch2GModeInv.Checked = true;
            else Ch2GModeInv.Checked = false;
            if (sets.Rstc == RestartPos.Zero) Ch2GModeStart.Checked = true;
            else Ch2GModeStart.Checked = false;
            if (sets.FStat == FinState.SpecificValue) Ch2StopStSpChk.Checked = true;
            else Ch2StopStSpChk.Checked = false;
            if (sets.FStat == FinState.SpecificValue) Ch2StopStSpChk.Checked = true;
            else Ch2StopStSpChk.Checked = false;
            Ch2StopStSpVol.Value = (decimal)Etc.DacCodeToVolt(sets.FVal, (RangeSel)Ch2RangeCh.SelectedIndex);
            if (sets.RepCyc == 0) Ch2TrgModeInf.Checked = true;
            else Ch2TrgModeCnt.Value = sets.RepCyc;
        }

        // Group A 関連処理
        // コントロールグループの初期化をする
        private void CH1GroupInit()
        {
            uint retcode;

            // 設定されているレンジを読み込んで画面に反映させる
            RangeSel Range;
            // ch1 レンジ
            retcode = TUSB0214DAM.TUSB0214DAM_RangeSet_R(DevSerialStr, ChSel.Ch1, out Range);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                int r = (int)Range;
                Ch1RangeCh.SelectedIndex = r;
            }

            // 設定構造体を読み込む
            stSettings Damset;
            retcode = TUSB0214DAM.TUSB0214DAM_DacChSet_R(DevSerialStr, ModuleN.CH1, out Damset);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                SetSettingsA(Damset);
            }
            

            CH1GroupEnControls();    // コントロールの表示設定
            Ch1SetBtn.AwakeColor(true);

            // ゲートコントロールの設定値を読み込んで画面に反映させる
            GateSt GateEn;
            retcode = TUSB0214DAM.TUSB0214DAM_GateSet_R(DevSerialStr, ModuleN.CH1, out GateEn);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                if (GateEn == GateSt.GOn)
                    Ch1GateOn.Checked = true;
                else
                    Ch1GateOff.Checked = true;
            }
        }

        // Group B 関連処理
        // コントロールグループの初期化をする
        private void CH2GroupInit()
        {
            uint retcode;

            // 設定されているレンジを読み込んで画面に反映させる
            RangeSel Range;
            // ch2 レンジ
            retcode = TUSB0214DAM.TUSB0214DAM_RangeSet_R(DevSerialStr, ChSel.Ch2, out Range);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
                Ch2RangeCh.SelectedIndex = (int)Range;

            // 設定構造体を読み込む
            stSettings Damset;
            retcode = TUSB0214DAM.TUSB0214DAM_DacChSet_R(DevSerialStr, ModuleN.CH2, out Damset);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                SetSettingsB(Damset);
            }

            


            CH2GroupEnControls();    // コントロールの表示設定
            Ch2SetBtn.AwakeColor(true);

            // ゲートコントロールの設定値を読み込んで画面に反映させる
            GateSt GateEn;
            retcode = TUSB0214DAM.TUSB0214DAM_GateSet_R(DevSerialStr, ModuleN.CH2, out GateEn);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            else
            {
                if (GateEn == GateSt.GOn)
                    Ch1GateOn.Checked = true;
                else
                    Ch1GateOff.Checked = true;
            }
        }

        // Group A Group B 関連処理
        // 動作設定
        // 画面の設定を読み出して設定構造体に値を設定して
        // モジュール毎に設定を行う
        private void SetModeSetting(ModuleN mod)
        {
            uint retcode;
            stSettings sets;                   // 設定構造体
            sets.FStat = FinState.LastValue;   // 構造体要素の配列作成
            sets.FVal = 0;      // 構造体要素の配列作成

            // 画面から設定値を構造体要素に設定する
            if (mod == ModuleN.CH1)
            {
                sets.Mode = (Ch1ModeDC.Checked) ? SetMode.DC : (Ch1ModeGate.Checked) ? SetMode.Gate : SetMode.Trg;
                sets.ClkSel = (Ch1ClkInt.Checked ? SigSrc.Internal : (Ch1ClkExt.Checked ? SigSrc.External : SigSrc.EXIO));
                sets.GTSel = (Ch1GTInt.Checked ? SigSrc.Internal : (Ch1GTExt.Checked ? SigSrc.External : SigSrc.EXIO));
                sets.ExGtInv = (Ch1GModeInv.Checked) ? SigInv.Invert : SigInv.NonInvert;
                sets.Rstc = (Ch1GModeStart.Checked) ? RestartPos.Zero : RestartPos.Conti;
                sets.xOption = 0;
                sets.FStat = (Ch1StopStSpChk.Checked) ? FinState.SpecificValue : FinState.LastValue;
                sets.FVal = Etc.DoubleToDacCode(Ch1StopStSpVol.Value.ToDouble(), (RangeSel)Ch1RangeCh.SelectedIndex);
                sets.RepCyc = (Ch1TrgModeInf.Checked) ? (ushort)0 : Ch1TrgModeCnt.Value.ToUShort();

                Ch1Mode = sets.Mode;
            }
            else
            {
                sets.Mode = (Ch2ModeDC.Checked) ? SetMode.DC : (Ch2ModeGate.Checked) ? SetMode.Gate : SetMode.Trg;
                sets.ClkSel = (Ch2ClkInt.Checked) ? SigSrc.Internal : (Ch2ClkExt.Checked ? SigSrc.External : SigSrc.EXIO);
                sets.GTSel = (Ch2GTInt.Checked) ? SigSrc.Internal : (Ch2GTExt.Checked ? SigSrc.External : SigSrc.EXIO);
                sets.ExGtInv = (Ch2GModeInv.Checked) ? SigInv.Invert : SigInv.NonInvert;
                sets.Rstc = (Ch2GModeStart.Checked) ? RestartPos.Zero : RestartPos.Conti;
                sets.xOption = 0;
                sets.FStat = (Ch2StopStSpChk.Checked) ? FinState.SpecificValue : FinState.LastValue;
                sets.FVal = Etc.DoubleToDacCode(Ch2StopStSpVol.Value.ToDouble(), (RangeSel)Ch2RangeCh.SelectedIndex);
                sets.RepCyc = (Ch2TrgModeInf.Checked) ? (ushort)0 : Ch2TrgModeCnt.Value.ToUShort();

                Ch2Mode = sets.Mode;
            }

            // 設定を実行する
            retcode = TUSB0214DAM.TUSB0214DAM_DacChSet(DevSerialStr, mod, ref sets);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        // Group A Group B 関連処理
        // クロック生成器設定
        private void SetClockGen(ModuleN mod)
        {
            uint retcode;
            uint DivideN;
            if (mod == ModuleN.CH1)
                DivideN = Ch1ClkN - 1;  // 除数は1小さい値を設定する
            else
                DivideN = Ch2ClkN - 1;  // 除数は1小さい値を設定する

            retcode = TUSB0214DAM.TUSB0214DAM_Clock_Gen(DevSerialStr, mod, DivideN);// クロックを設定する
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        // Group A Group B 関連処理
        // レンジの設定
        private void SetRange(ChSel ch)
        {
            uint retcode;
            RangeSel range;

            switch (ch)
            {
                case ChSel.Ch1: range = (RangeSel)Ch1RangeCh.SelectedIndex; break;
                case ChSel.Ch2: range = (RangeSel)Ch2RangeCh.SelectedIndex; break;
                default: range = RangeSel.Unipol5; break;
            }
            retcode = TUSB0214DAM.TUSB0214DAM_RangeSet(DevSerialStr, ch, range);//　レンジを設定する
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        // Group A Group B 関連処理
        // 直流電圧設定
        private void SetDCVolt(ChSel ch)
        {
            // 各チャンネルのレンジを直流電圧値から設定すべき値を計算する
            ushort dcv;
            switch (ch)
            {
                case ChSel.Ch1: dcv = Etc.DoubleToDacCode(Ch1OffsetDC.Value.ToDouble(), (RangeSel)Ch1RangeCh.SelectedIndex); break;
                case ChSel.Ch2: dcv = Etc.DoubleToDacCode(Ch2OffsetDC.Value.ToDouble(), (RangeSel)Ch2RangeCh.SelectedIndex); break;
                default: dcv = 0; break;
            }
            uint retcode = TUSB0214DAM.TUSB0214DAM_DacValSet(DevSerialStr, ch, dcv);// 出力値を設定する
                                                                                   //uint retcode = TUSB0214DAMex.TUSB0214DAM_DacValSet_NoCalibed(DevSerialStr, ch, (ushort)(dcv << 2));// 出力値を設定する

            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        // Group A Group B 関連処理
        // 波形設定
        // 周期波形モードの時に波形を設定する
        private void SetWavImage(ModuleN mod)
        {
            uint retcode;
            ushort[] wimage1;       // ch1(or ch3)波形イメージ配列
            ushort[] wimage2;       // ch2(or ch4)波形イメージ配列
            int len;                // 波形長

            if (mod == ModuleN.CH1)
            {
                WShape shape;           // 波形種類
                RangeSel range;         // 電圧レンジ
                double offset;          // オフセット電圧
                double amp;             // 振幅電圧

                if (Ch1ClkInt.Checked)
                    Etc.GetWaveLength((double)Ch1WavFreq.Value, Ch1WavFreq_kHz.Checked, Ch1FreqD, out len);// 波形に必要なデータ長を取得
                else
                    len = Ch1WavFreq.Value.ToInt();

                // ch1 波形イメージ生成
                shape = (Ch1WavSin.Checked) ? WShape.Sin : (Ch1WavRect.Checked) ? WShape.Rectangle : WShape.Triangle;
                range = (RangeSel)Ch1RangeCh.SelectedIndex;
                offset = Ch1OffsetDC.Value.ToDouble();
                amp = Ch1WavAmp.Value.ToDouble();
                wimage1 = new ushort[len];
                Etc.WaveImageGen(shape, range, offset, amp, ref wimage1, len);


                // 波形イメージの書き込み
                retcode = TUSB0214DAM.TUSB0214DAM_WavImgSet(DevSerialStr, mod, wimage1, len);
                if (retcode != 0)
                    MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            }
            else
            {
                WShape shape;           // 波形種類
                RangeSel range;         // 電圧レンジ
                double offset;          // オフセット電圧
                double amp;             // 振幅電圧

                if (Ch2ClkInt.Checked)
                    Etc.GetWaveLength((double)Ch2WavFreq.Value, Ch2WavFreq_kHz.Checked, Ch2FreqD, out len);// 波形に必要なデータ長を取得
                else
                    len = Ch2WavFreq.Value.ToInt();

                // ch2 波形イメージ生成
                shape = (Ch2WavSin.Checked) ? WShape.Sin : (Ch2WavRect.Checked) ? WShape.Rectangle : WShape.Triangle;
                range = (RangeSel)Ch2RangeCh.SelectedIndex;
                offset = Ch2OffsetDC.Value.ToDouble();
                amp = Ch2WavAmp.Value.ToDouble();
                wimage1 = new ushort[len];
                Etc.WaveImageGen(shape, range, offset, amp, ref wimage1, len);


                // 波形イメージの書き込み
                retcode = TUSB0214DAM.TUSB0214DAM_WavImgSet(DevSerialStr, mod, wimage1, len);
                if (retcode != 0)
                    MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            }


        }

        private void DigitalIOChange(object sender, EventArgs e)
        {
            SetDIO_Out();   // Digital I/O 出力を設定する
        }

        private void IOCheckTimer_Tick(object sender, EventArgs e)
        {
            ChkDIO_In();    // Digital I/O 入力状態を確認する
        }

        private void SyncOutChange(object sender, EventArgs e)
        {
            SyncOutGroupEnControls();   // Sync Out 表示状態を更新する
        }

        private void SyncOutSelGOff_CheckedChanged(object sender, EventArgs e)
        {
            // Sync Out ゲート出力をOffに設定する
            uint retcode = TUSB0214DAM.TUSB0214DAM_GateSet(DevSerialStr, ModuleN.Ext, GateSt.GOff);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void SyncOutSelGOn_CheckedChanged(object sender, EventArgs e)
        {
            // Sync Out ゲート出力をOnに設定する
            uint retcode = TUSB0214DAM.TUSB0214DAM_GateSet(DevSerialStr, ModuleN.Ext, GateSt.GOn);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void SyncOutSetBtn_Click(object sender, EventArgs e)
        {
            // Sync Out 出力選択を設定する
            byte OutSel0 = SyncOutSel0.SelectedIndex.ToByte();  // Sync Out 0 設定
            byte OutSel1 = SyncOutSel1.SelectedIndex.ToByte();  // Sync Out 1 設定
            uint retcode = TUSB0214DAM.TUSB0214DAM_Exs_Sel(DevSerialStr, OutSel0, OutSel1);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));

            // EXI/O  選択を設定する
            byte EXIOSel0 = EXIO_SEL0.SelectedIndex.ToByte();  // EXI/O 0 設定
            byte EXIOSel1 = EXIO_SEL1.SelectedIndex.ToByte();  // EXI/O 1 設定
            retcode = TUSB0214DAM.TUSB0214DAM_EXIO_Sel(DevSerialStr, EXIOSel0, EXIOSel1);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));

            // 出力クロックを設定する
            if (SyncOutSel1.SelectedIndex == SYNC1_CLOCK || EXIO_SEL1.SelectedIndex == EXIO1_CLOCK_OUT)
            {
                retcode = TUSB0214DAM.TUSB0214DAM_Clock_Gen(DevSerialStr, ModuleN.Ext, (SyncOutClkN - 1));
                if (retcode != 0)
                    MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
            }

            SyncOutSetBtn.UseVisualStyleBackColor = true;
        }

        private void SyncOutTrgBtn_Click(object sender, EventArgs e)
        {
            // Sync Out 1 トリガ信号を発生させる
            uint retcode = TUSB0214DAM.TUSB0214DAM_Trigger(DevSerialStr, ModuleN.Ext, TrgSel.TStart);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void CH1Change(object sender, EventArgs e)
        {
            //電圧値と電圧コードを連動
            if (!isVoltageCodeSyncing)
            {
                isVoltageCodeSyncing = true;

                NumericUpDown changed = sender as NumericUpDown;

                if (changed == Ch1OffsetDC)
                {
                   UInt16 code = Etc.DoubleToDacCode(Ch1OffsetDC.Value.ToDouble(), (RangeSel)Ch1RangeCh.SelectedIndex);
                    if (0 <= code && code <= 16383)
                    {
                        Ch1OffsetDCCode.Value = code;
                    }
                }
                else if (changed == Ch1OffsetDCCode)
                {
                   Ch1OffsetDC.Value = (decimal)Etc.DacCodeToVolt((UInt16)Ch1OffsetDCCode.Value, (RangeSel)Ch1RangeCh.SelectedIndex); 
                }

                isVoltageCodeSyncing = false;
            }
            CH1GroupEnControls();    // Group A 表示状態を更新する
        }

        private void CH1ClkSrcChange(object sender, EventArgs e)
        {
            // クロックソースが変更された時に実行する

            if (Ch1ClkInt.Checked)// 内部クロックに変更
            {
                Ch1WavGenFreqLbl.Text = "Freq.";
                Ch1WavFreq.DecimalPlaces = 3;
                Ch1WavFreq.Maximum = 1000M;
                Ch1WavFreq.Minimum = 0.001M;
                Ch1WavFreq.Value = WavFreqA;
                Ch1WavGenFreqP.Visible = true;
            }
            else                 //外部クロックに変更  
            {
                Ch1WavGenFreqLbl.Text = "Leng.";
                Ch1WavFreq.DecimalPlaces = 0;
                Ch1WavFreq.Maximum = 262144M;
                Ch1WavFreq.Minimum = 2M;
                Ch1WavFreq.Value = WavLenA;
                Ch1WavGenFreqP.Visible = false;
            }
            CH1GroupEnControls();
        }

        private void Ch1SetBtn_Click(object sender, EventArgs e)
        {
            if (Ch1ClkInt.Checked)// 内部クロック
                WavFreqA = Ch1WavFreq.Value;
            else
                WavLenA = Ch1WavFreq.Value;

            // 動作設定 ////
            SetModeSetting(ModuleN.CH1);

            // クロック生成設定 ////
            if (CH1_CLKGEN_G.Enabled)
            {
                SetClockGen(ModuleN.CH1);
            }

            // レンジ設定　////
            SetRange(ChSel.Ch1);
            //SetRange(ChSel.Ch2);

            // 直流電圧設定 or 波形イメージ  書き込み ////
            if (Ch1ModeDC.Checked)// 直流動作
            {
                SetDCVolt(ChSel.Ch1);
                //SetDCVolt(ChSel.Ch2);
            }
            else
            {
                SetWavImage(ModuleN.CH1);
            }

            Ch1SetBtn.AwakeColor(false);
        }

        private void Ch1GateChange(object sender, EventArgs e)
        {
            // Group A のゲート出力を設定する
            GateSt GateEn = (Ch1GateOn.Checked) ? GateSt.GOn : GateSt.GOff;
            uint retcode = TUSB0214DAM.TUSB0214DAM_GateSet(DevSerialStr, ModuleN.CH1, GateEn);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void Ch1StartTrgBtn_Click(object sender, EventArgs e)
        {
            // Group A のスタートトリガを出力する
            uint retcode = TUSB0214DAM.TUSB0214DAM_Trigger(DevSerialStr, ModuleN.CH1, TrgSel.TStart);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void Ch1StopBtn_Click(object sender, EventArgs e)
        {
            // Group A のトリガ波形出力を停止する
            uint retcode = TUSB0214DAM.TUSB0214DAM_Trigger(DevSerialStr, ModuleN.CH1, TrgSel.TStop);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void Ch1CheckTimer_Tick(object sender, EventArgs e)
        {
            uint retcode;
            // Group A タイマーチェック
            // 周期波形出力時の出力状態(出力中かどうか)を表示する

            switch (Ch1Mode)
            {
                case SetMode.DC:    // 直流出力時
                    Ch1WavGenInd.BackColor = SystemColors.Control;
                    break;
                case SetMode.Gate:  // ゲート出力時
                    GateSt GateEn;  // ゲート出力設定時
                    retcode = TUSB0214DAM.TUSB0214DAM_GateSet_R(DevSerialStr, ModuleN.CH1, out GateEn);
                    if (retcode != 0)
                        MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                    else if (GateEn == GateSt.GOn)
                        Ch1WavGenInd.BackColor = Color.LightBlue;
                    else
                        Ch1WavGenInd.BackColor = SystemColors.Control;
                    break;
                case SetMode.Trg:   // トリガ出力時
                    TrgStat stat;
                    retcode = TUSB0214DAM.TUSB0214DAM_Trigger_Stat(DevSerialStr, ModuleN.CH1, out stat);
                    if (retcode != 0)
                        MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                    else if (stat == TrgStat.TRun)
                        Ch1WavGenInd.BackColor = Color.LightBlue;
                    else
                        Ch1WavGenInd.BackColor = SystemColors.Control;
                    break;
            }
        }

        private void CH2Change(object sender, EventArgs e)
        {
            //電圧値と電圧コードを連動
            if (!isVoltageCodeSyncing)
            {
                isVoltageCodeSyncing = true;

                NumericUpDown changed = sender as NumericUpDown;

                if (changed == Ch2OffsetDC)
                {
                    UInt16 code = Etc.DoubleToDacCode(Ch2OffsetDC.Value.ToDouble(), (RangeSel)Ch2RangeCh.SelectedIndex);
                    if (0 <= code && code <= 16383)
                    {
                        Ch2OffsetDCCode.Value = code;
                    }
                }
                else if (changed == Ch2OffsetDCCode)
                {
                    Ch2OffsetDC.Value = (decimal)Etc.DacCodeToVolt((UInt16)Ch2OffsetDCCode.Value, (RangeSel)Ch2RangeCh.SelectedIndex);
                }

                isVoltageCodeSyncing = false;
            }

            //表示変更
            CH2GroupEnControls();
        }

        private void CH2ClkSrcChange(object sender, EventArgs e)
        {
            if (Ch2ClkInt.Checked)// 内部クロックに変更
            {
                Ch2WavGenFreqLbl.Text = "Freq.";
                Ch2WavFreq.DecimalPlaces = 3;
                Ch2WavFreq.Maximum = 1000M;
                Ch2WavFreq.Minimum = 0.001M;
                Ch2WavFreq.Value = WavFreqB;
                Ch2WavGenFreqP.Visible = true;
            }
            else
            {
                Ch2WavGenFreqLbl.Text = "Leng.";
                Ch2WavFreq.DecimalPlaces = 0;
                Ch2WavFreq.Maximum = 262144M;
                Ch2WavFreq.Minimum = 2M;
                Ch2WavFreq.Value = WavLenB;
                Ch2WavGenFreqP.Visible = false;
            }
            CH2GroupEnControls();
        }

        private void Ch2SetBtn_Click(object sender, EventArgs e)
        {
            if (Ch2ClkInt.Checked)// 内部クロック
                WavFreqB = Ch2WavFreq.Value;
            else
                WavLenB = Ch2WavFreq.Value;

            // 動作設定 ////
            SetModeSetting(ModuleN.CH2);

            // クロック生成設定 ////
            if (CH2_CLKGEN_G.Enabled)
            {
                SetClockGen(ModuleN.CH2);
            }

            // レンジ設定　////
            SetRange(ChSel.Ch2);
            //SetRange(ChSel.Ch4);

            // 直流電圧設定 or 波形イメージ  書き込み ////
            if (Ch2ModeDC.Checked)// 直流動作
            {
                SetDCVolt(ChSel.Ch2);
                //SetDCVolt(ChSel.Ch4);
            }
            else
            {
                SetWavImage(ModuleN.CH2);
            }

            Ch2SetBtn.AwakeColor(false);
        }

        private void Ch2GateChange(object sender, EventArgs e)
        {
            // Group B のゲート出力を設定する
            GateSt GateEn = (Ch2GateOn.Checked) ? GateSt.GOn : GateSt.GOff;
            uint retcode = TUSB0214DAM.TUSB0214DAM_GateSet(DevSerialStr, ModuleN.CH2, GateEn);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void Ch2StartTrgBtn_Click(object sender, EventArgs e)
        {
            // Group B のスタートトリガを出力する
            uint retcode = TUSB0214DAM.TUSB0214DAM_Trigger(DevSerialStr, ModuleN.CH2, TrgSel.TStart);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void Ch2StopBtn_Click(object sender, EventArgs e)
        {
            // Group B のトリガ波形出力を停止する
            uint retcode = TUSB0214DAM.TUSB0214DAM_Trigger(DevSerialStr, ModuleN.CH2, TrgSel.TStop);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
        }

        private void Ch2CheckTimer_Tick(object sender, EventArgs e)
        {
            uint retcode;
            // Group B タイマーチェック
            // 周期波形出力時の出力状態(出力中かどうか)を表示する

            switch (Ch2Mode)
            {
                case SetMode.DC:    // 直流出力時
                    Ch2WavGenInd.BackColor = SystemColors.Control;
                    break;
                case SetMode.Gate:  // ゲート出力時
                    GateSt GateEn;
                    retcode = TUSB0214DAM.TUSB0214DAM_GateSet_R(DevSerialStr, ModuleN.CH2, out GateEn);
                    if (retcode != 0)
                        MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                    else if (GateEn == GateSt.GOn)
                        Ch2WavGenInd.BackColor = Color.LightBlue;
                    else
                        Ch2WavGenInd.BackColor = SystemColors.Control;
                    break;
                case SetMode.Trg:   // トリガ出力時
                    TrgStat stat;
                    retcode = TUSB0214DAM.TUSB0214DAM_Trigger_Stat(DevSerialStr, ModuleN.CH2, out stat);
                    if (retcode != 0)
                        MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));
                    else if (stat == TrgStat.TRun)
                        Ch2WavGenInd.BackColor = Color.LightBlue;
                    else
                        Ch2WavGenInd.BackColor = SystemColors.Control;
                    break;
            }
        }

        private void ExIOSetBtn_Click(object sender, EventArgs e)
        {
            // Sync Out 出力選択を設定する
            byte ExIOSel0 = EXIO_SEL0.SelectedIndex.ToByte();  // Sync Out 0 設定
            byte ExIOSel1 = EXIO_SEL1.SelectedIndex.ToByte();  // Sync Out 1 設定
            uint retcode = TUSB0214DAM.TUSB0214DAM_Exs_Sel(DevSerialStr, ExIOSel0, ExIOSel1);
            if (retcode != 0)
                MessageBox.Show(TUSB0214DAM.GetErrMessage(retcode));

            SyncOutSetBtn.UseVisualStyleBackColor = true;

        }
    }
}