using Agilent.AgM938x.Interop;
using Agilent.AgM9300.Interop;
using Agilent.AgM9018.Interop;
using System;
using System.Windows.Forms;

namespace MIMOTestPlan
{
    public partial class TriggerRouting
    {
        public IAgM938xEx M9381chan1;
        public IAgM938xEx M9381chan2;
        public IAgM938xEx M9381chan3;
        public IAgM938xEx M9381chan4;
        public IAgM9018 M9018;  // chassis

        public string M9381Chan1resource = "M9381Chan1";
        public string M9381Chan2resource = "M9381Chan2";
        public string M9381Chan3resource = "M9381Chan3";
        public string M9381Chan4resource = "M9381Chan4";
        public string M9018resource = "PXI15::0::0::INSTR";

        public void RouteTriggers()
        {
            int errorcode = -1; string message = string.Empty;
            bool idquery = true;
            bool reset = true;
            bool simulateHardware = true;
            string M9381options = string.Format(
                "QueryInstrStatus=true, Simulate={0}, M9381Setup= Model=, Trace=false", (simulateHardware ? "true" : "false"));
            string M9018options = string.Format(
                 "QueryInstrStatus=true, Simulate={0}, M9018Setup= Model=, Trace=false", (simulateHardware ? "true" : "false"));
            try
            {
                M9381chan1 = new AgM938x();
                M9381chan2 = new AgM938x();
                M9381chan3 = new AgM938x();
                M9381chan4 = new AgM938x();
                M9018 = new AgM9018();

                                // Initialize M9018A Chassis
                M9018.Initialize(M9018resource, idquery, reset, M9018options);

                //Initialize M9381 Channel 1
                M9381chan1.Initialize(M9381Chan1resource, idquery, reset, M9381options);

                // Clear startup messages & warnings if any.
                do
                {
                    M9381chan1.Utility.ErrorQuery(ref errorcode, ref message);
                    if (errorcode != 0)
                        Console.WriteLine(message);
                } while (errorcode != 0);

                //Initialize M9381 Channel 2
                M9381chan2.Initialize(M9381Chan2resource, idquery, reset, M9381options);


                // Clear startup messages & warnings if any.
                do
                {
                    M9381chan2.Utility.ErrorQuery(ref errorcode, ref message);
                    if (errorcode != 0)
                        Console.WriteLine(message);
                } while (errorcode != 0);

                //Initialize M9381 Channel 3
                M9381chan3.Initialize(M9381Chan3resource, idquery, reset, M9381options);


                // Clear startup messages & warnings if any.
                do
                {
                    M9381chan3.Utility.ErrorQuery(ref errorcode, ref message);
                    if (errorcode != 0)
                        Console.WriteLine(message);
                } while (errorcode != 0);

                //Initialize M9381 Channel 4
                M9381chan4.Initialize(M9381Chan4resource, idquery, reset, M9381options);


                // Clear startup messages & warnings if any.
                do
                {
                    M9381chan4.Utility.ErrorQuery(ref errorcode, ref message);
                    if (errorcode != 0)
                        Console.WriteLine(message);
                } while (errorcode != 0);


                // This is where we do the work to make sure the triggers that are required for the M9381A
                // are routed properly across backplane segments on the chassis where necessary
                //
                // The M9018A has 3 trigger bus segments:  
                // Bus 1: slots 1-6
                // Bus 2: slots 7-12
                // Bus 3: slots 13-18 
                //
                // For each M9381A in our system, there are three requirements:
                // 1) There must be a PXI trigger from M9311A to M9310A for ALC.  This defaults to trigger 7
                // 2) There must be a PXI trigger from M9301A to M9311A for front panel External Trigger.  This defaults to trigger 6.
                // 3) None of these triggers can conflict with each other.  For example, if there are two VSGs (or portions of a VSG)
                // occupying a single chassis, they cannot both use the default trigger lines.
                //
                // To satisfy these requirements, we have two tools available to us:
                // 1) Routing triggers between bus segments on the chassis
                // 2) redefining the triggers used by the M9381A.
                //
                // For this example, we examine the routings needed for a 4 channel M9381A, with a single M9300A in slot 10.
                // The other VSGs are in the following locations:
                // VSG 1: slots 2-5
                // VSG 2: slots 6-9
                // VSG 3: slots 11-14
                // VSG 4: slots 15-18
                // We can make some observations about this configuration:
                // 1) VSG1 and VSG2 have conflicting backplane trigger requirements, because the M9311A modules will be in slots 
                //    2 and 6, therefore in the same bus segment
                // 2) VSG 2 crosses segment boundary 1-2
                // 3) VSG 2 and 3 have conflicting trigger requirements, because the M9301A module from VSG 2 and M9311A module 
                //    from VSG 3 will be in slots 9 and 11, therefore in the same bus segment
                // 4) VSG 3 crosses segment boundary 2-3
                // 5) VSG 3 and 4 have conflicting trigger requirements, because the M9301A module from VSG 3 and M9311A module 
                //    from VSG 4 will be in slots 14 and 15, therefore in the same bus segment
                // 6) VSG 1 and VSG 4 are contained entirely within one trigger bus segment.  
                // 
                // To come up with a routing, we have to address all 5 of these issues above to satisfy the 3 requirements 
                // outlined earlier.
                //
                // The simplest routing turns out to be the following
                // 1) VSG 1 and VSG 3 use default triggers 6 and 7
                // 2) VSG 2 and VSG 4 use triggers 5 and 8

                // Route triggers on chassis backplane.  Note that these will persist until a power cycle, 
                // so this section could be performed in a separate
                // program that runs at startup, for example as a service
                M9018.TriggerBus.Connect(0, Agilent.AgM9018.Interop.AgM9018TrigBusEnum.AgM9018TrigBus2To1);
                M9018.TriggerBus.Connect(5, Agilent.AgM9018.Interop.AgM9018TrigBusEnum.AgM9018TrigBus1To2);
                M9018.TriggerBus.Connect(6, Agilent.AgM9018.Interop.AgM9018TrigBusEnum.AgM9018TrigBus3To2);
                M9018.TriggerBus.Connect(7, Agilent.AgM9018.Interop.AgM9018TrigBusEnum.AgM9018TrigBus2To3);
                    
                // Redefine triggers for VSG 2 and 4.
                M9381chan2.System.PXIResources.AddHint("M9311A", "M9310A", "ALC TRIGGER", 
                    Agilent.AgM938x.Interop.AgM938xPXIResourceTypeEnum.AgM938xPXIResourceTypeTTL_TRIGGER, 
                    Agilent.AgM938x.Interop.AgM938xPXIResourcesEnum.AgM938xPXIResourcesTTL_TRIGGER_5);
                M9381chan2.System.PXIResources.AddHint("M9301A", "M9311A", "EXTERNAL TRIGGER", 
                    Agilent.AgM938x.Interop.AgM938xPXIResourceTypeEnum.AgM938xPXIResourceTypeTTL_TRIGGER, 
                    Agilent.AgM938x.Interop.AgM938xPXIResourcesEnum.AgM938xPXIResourcesTTL_TRIGGER_0);
                M9381chan4.System.PXIResources.AddHint("M9311A", "M9310A", "ALC TRIGGER", 
                    Agilent.AgM938x.Interop.AgM938xPXIResourceTypeEnum.AgM938xPXIResourceTypeTTL_TRIGGER, 
                    Agilent.AgM938x.Interop.AgM938xPXIResourcesEnum.AgM938xPXIResourcesTTL_TRIGGER_5);
                M9381chan4.System.PXIResources.AddHint("M9301A", "M9311A", "EXTERNAL TRIGGER", 
                    Agilent.AgM938x.Interop.AgM938xPXIResourceTypeEnum.AgM938xPXIResourceTypeTTL_TRIGGER, 
                    Agilent.AgM938x.Interop.AgM938xPXIResourcesEnum.AgM938xPXIResourcesTTL_TRIGGER_0);

  
                // Do other VSG things
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }
    
    }
}