let Common   = system.getScript("/driverlib/Common.js");
let Pinmux   = system.getScript("/driverlib/pinmux.js");

/* Intro splash on GUI */
let longDescription = `The Enhanced Quadrature Encoder Pulse (eQEP) module is used for direct interface with a linear or rotary
incremental encoder to get position, direction, and speed information from a rotating machine for use in a
high-performance motion and position-control system.
`

let device_driverlib_peripheral =
    system.getScript("/driverlib/device_driverlib_peripherals/" +
        Common.getDeviceName().toLowerCase() + "_eqep.js");

function onChangeUseInterrupts(inst, ui)
{
    if (inst.useInterrupts){
        ui.enableInterrupt.hidden = false
        ui.registerInterrupts.hidden = false
        ui.interruptSources.hidden = false
    }
    else{
        ui.enableInterrupt.hidden = true
        ui.registerInterrupts.hidden = true
        ui.interruptSources.hidden = true
    }
}
var EQEP_INSTANCE = [
    { name: "EQEP1_BASE", displayName: "EQEP1"},
    { name: "EQEP2_BASE", displayName: "EQEP2"},
    { name: "EQEP3_BASE", displayName: "EQEP3"},
    { name: "EQEP4_BASE", displayName: "EQEP4"},
    { name: "EQEP5_BASE", displayName: "EQEP5"},
    { name: "EQEP6_BASE", displayName: "EQEP6"},
]
/* Array of CAN configurables that are common across device families */
let config = [
    {
        name        : "eqepBase",
        displayName : "eqep Instance",
        description : 'Instance of the EQEP used.',
        hidden      : false,
        default     : EQEP_INSTANCE[0].name,
        options     : EQEP_INSTANCE
    },
    {
        //
        // This is needed for locking some options when a HARDWARE is needed
        // Currently we only have NO STROB connection for EQEP on launchpads
        //
        name: "$hardware",
        onChange: (inst, ui) => {
            if (inst.$hardware)
            {
                var useCaseNames = Pinmux.getPeripheralUseCaseNames("EQEP").map((useCaseOpt) => {
                      return useCaseOpt.name
                    }
                );
                useCaseNames = useCaseNames.concat(PinmuxAdditionalUseCases.getAdditionalUseCaseNames("EQEP"));

                if (useCaseNames.includes("NO STROBE"))
                {
                    inst.useCase = "NO STROBE"
                }
            }
        }
    },
    
];
let conditionalConfig = [];
conditionalConfig = conditionalConfig.concat([
    // setInputPolarity
    {
        name         : "inputPolarity",
        displayName  : "Input Polarity",
        description  : "Sets the polarity of the eQEP module's input signals.",
        hidden       : false,
        default      : [],
        minSelections: 0,
        options      :
        [
            {name: "invertQEPA", displayName: "Invert QEPA"},
            {name: "invertQEPB", displayName: "Invert QEPB"},
            {name: "invertIndex", displayName: "Invert Index"},
            {name: "invertStrobe", displayName: "Invert Strobe"},
        ]
    },
    // setDecoderConfig
    {
        name        : "eqepOperationMode",
        displayName : "Position Counter Source (QSRC)",
        description : `Specify if quadrature signals are being provided on QEPA and QEPB,
                        if a direction signal and a clock are being provided, or if the direction
                        should be hard-wired for a single direction with QEPA used for input.`,
        hidden      : false,
        default     : "EQEP_CONFIG_QUADRATURE",
        options     : 
        [
            {name: "EQEP_CONFIG_QUADRATURE",    displayName: "Quadrature-clock mode"},
            {name: "EQEP_CONFIG_CLOCK_DIR",     displayName: "Direction-count mode"},
            {name: "EQEP_CONFIG_UP_COUNT",      displayName: "Up-count mode, QDIR = 1"},
            {name: "EQEP_CONFIG_DOWN_COUNT",    displayName: "Down-count mode, QDIR = 0"},
        ]
    },
    {
        name        : "eqepResolution",
        displayName : "Resolution",
        description : "Specify if both rising and falling edges should be counted or just rising edges",
        hidden      : false,
        default     : "EQEP_CONFIG_2X_RESOLUTION",
        options     : 
        [
            {name: "EQEP_CONFIG_2X_RESOLUTION", displayName: "2X Resolution: Count rising and falling edge"},
            {name: "EQEP_CONFIG_1X_RESOLUTION", displayName: "1X Resolution: Count rising edge only"},
        ]
    },
    {
        name        : "eqepSwap",
        displayName : "Swap QEPA and QEPB",
        description : `Specify if the signals provided on QEPA and QEPB should be swapped 
                        before being processed.`,
        hidden      : false,
        default     : "EQEP_CONFIG_NO_SWAP",
        options     :
        [
            {name: "EQEP_CONFIG_NO_SWAP",   displayName: "Do not swap QEPA and QEPB"},
            {name: "EQEP_CONFIG_SWAP",      displayName: "Swap QEPA and QEPB"},
        ]
    },
    {
        name        : "eqepIGATE",
        displayName : "Index Pulse Gating",
        description : `Specify if the gating of the index pulse should be enabled or disabled.`,
        hidden      : false,
        default     : "EQEP_CONFIG_IGATE_DISABLE",
        options     :
        [
            {name: "EQEP_CONFIG_IGATE_DISABLE", displayName: "Disable gating of Index pulse"},
            {name: "EQEP_CONFIG_IGATE_ENABLE",  displayName: "Gate the index pin with strobe"},
        ]
    },
])

conditionalConfig = conditionalConfig.concat([
    // enableDirectionChangeDuringIndex /disableDirectionChangeDuringIndex
    {
        name        : "enableDirectionChange",
        displayName : "Enable Direction Change During Index",
        description : 'Enables the index direction enhancement mode of the eQEP module.',
        hidden      : false,
        default     : false
    },
])

//config = config.concat([
    // {
    //     name            : "GROUP_DECODER",
    //     displayName     : "Quadrature Decoder Unit",
    //     description     : "",
    //     longDescription : "",
    //     config          : conditionalConfig
    // },
    // {
    //     name            : "GROUP_POSITION",
    //     displayName     : "Position Counter and Control Unit",
    //     description     : "",
    //     longDescription : "",
    //     config          : [
    //         // setPositionCounterConfig
    //         {
    //             name        : "positionCounterMode",
    //             displayName : "Position Counter Mode",
    //             description : "Configuration for the eQEP module position counter.",
    //             hidden      : false,
    //             default     : device_driverlib_peripheral.EQEP_PositionResetMode[0].name,
    //             options     : device_driverlib_peripheral.EQEP_PositionResetMode
    //         },
    //         {
    //             name        : "positionCounterMax",
    //             displayName : "Maximum Position",
    //             description : "Specifies the maximum position value.",
    //             hidden      : false,
    //             default     : 0
    //         },
    //         // setPosition
    //         {
    //             name        : "setPosition",
    //             displayName : "Position Counter (QPOSCNT)",
    //             description : "Sets the current encoder position.",
    //             hidden      : false,
    //             default     : 0
    //         },
    //         {
    //             name: "GROUP_LATCH",
    //             displayName: "Latch Mode",
    //             description: "",
    //             longDescription: "",
    //             collapsed: false,
    //             config: [
    //                 // setLatchMode
    //                 {
    //                     name        : "latchPositionCounter",
    //                     displayName : "QEP Capture Latch Mode (QCLM)",
    //                     description : "Specify the event that latches the position counter.",
    //                     hidden      : false,
    //                     default     : "EQEP_LATCH_CNT_READ_BY_CPU",
    //                     options     :
    //                     [
    //                         {name: "EQEP_LATCH_CNT_READ_BY_CPU",    displayName: "On position counter read"},
    //                         {name: "EQEP_LATCH_UNIT_TIME_OUT",      displayName: "On unit time-out event"},
    //                     ]
    //                 },
    //                 {
    //                     name        : "latchStrobePosition",
    //                     displayName : "Strobe Event Latch (SEL)",
    //                     description : "Specify which strobe event will latch the position counter into the strobe position latch register. ",
    //                     hidden      : false,
    //                     default     : "EQEP_LATCH_RISING_STROBE",
    //                     options     :
    //                     [
    //                         {name: "EQEP_LATCH_RISING_STROBE",      displayName: "On rising edge of strobe"},
    //                         {name: "EQEP_LATCH_EDGE_DIR_STROBE",    displayName: "On rising edge when clockwise, on falling when counter clockwise"},
    //                     ]
    //                 },
    //                 {
    //                     name        : "latchIndexPosition",
    //                     displayName : "Index Event Latch (IEL)",
    //                     description : "Specify which index event will latch the position counter into the index position latch register.",
    //                     hidden      : false,
    //                     default     : "EQEP_LATCH_RISING_INDEX",
    //                     options     :
    //                     [
    //                         {name: "EQEP_LATCH_RISING_INDEX",       displayName: "On rising edge of index"},
    //                         {name: "EQEP_LATCH_FALLING_INDEX",      displayName: "On falling edge of index"},
    //                         {name: "EQEP_LATCH_SW_INDEX_MARKER",    displayName: "On software index marker"},
    //                     ]
    //                 },
    //             ]
    //         }, 
    //         // setPositionInitMode
    //         {
    //             name        : "positionStrobeEvents",
    //             displayName : "Position Strobe Events (SEI)",
    //             description : "Specify which strobe event will initialize the position counter.",
    //             hidden      : false,
    //             default     : "EQEP_INIT_DO_NOTHING",
    //             options     :
    //             [
    //                 {name: "EQEP_INIT_DO_NOTHING",   displayName: "Action is disabled"},
    //                 {name: "EQEP_INIT_RISING_STROBE",   displayName: "On rising edge of strobe"},
    //                 {name: "EQEP_INIT_EDGE_DIR_STROBE",   displayName: "On rising edge when clockwise, on falling when counter clockwise"},
    //             ]
    //         },
    //         {
    //             name        : "positionIndexEvents",
    //             displayName : "Position Index Events (IEI)",
    //             description : "Specify which index event will initialize the position counter.",
    //             hidden      : false,
    //             default     : "EQEP_INIT_DO_NOTHING",
    //             options     :
    //             [
    //                 {name: "EQEP_INIT_DO_NOTHING",   displayName: "Action is disabled"},
    //                 {name: "EQEP_INIT_RISING_INDEX",   displayName: "On rising edge of index"},
    //                 {name: "EQEP_INIT_FALLING_INDEX",   displayName: "On falling edge of index"},
    //             ]
    //         },
    //         // setSWPositionInit
    //         {
    //             name        : "swPositionInit",
    //             displayName : " Set Software Initialization Position Counter",
    //             description : 'Sets the software initialization of the encoder position counter.',
    //             hidden      : false,
    //             default     : false
    //         },
    //         // setInitialPosition
    //         {
    //             name        : "initialPosition",
    //             displayName : "Position Counter Initialization Value",
    //             description : 'Sets the init value for the encoder position counter.',
    //             hidden      : false,
    //             default     : 0
    //         },
    //         // enableModule / disableModule
    //         {
    //             name        : "enableModule",
    //             displayName : "Enable Position Counter",
    //             description : 'Enables the eQEP module.',
    //             hidden      : false,
    //             default     : false
    //         },
    //         {
    //             name: "GROUP_COMPARE",
    //             displayName: "Compare Configuration",
    //             description: "",
    //             longDescription: "",
    //             collapsed: false,
    //             config: [
    //                 // setCompareConfig [do we have a boolean to determine if we do this?]
    //                 {
    //                     name        : "compareConfig",
    //                     displayName : "Configure Position-Compare Unit",
    //                     description : 'Enables configuration of eQEP module position-compare unit.',
    //                     hidden      : false,
    //                     default     : false
    //                 },
    //                 {
    //                     name        : "compareSyncPulsePin",
    //                     displayName : "Sync Output Pin Selection (SPSEL)",
    //                     description : "Specify if there is a sync output pulse and which pin should be used.",
    //                     hidden      : false,
    //                     default     : "EQEP_COMPARE_NO_SYNC_OUT",
    //                     options     :
    //                     [
    //                         {name: "EQEP_COMPARE_NO_SYNC_OUT",      displayName: "Disable sync output"},
    //                         {name: "EQEP_COMPARE_IDX_SYNC_OUT",     displayName: "Sync output on index pin"},
    //                         {name: "EQEP_COMPARE_STROBE_SYNC_OUT",  displayName: "Sync output on strobe pin"},
    //                     ]
    //                 },
    //                 {
    //                     name        : "compareShadowRegisterUse",
    //                     displayName : "Position Compare of Shadow Load (PCLOAD)",
    //                     description : "Specify if a shadow is enabled and when should the load should occur.",
    //                     hidden      : false,
    //                     default     : "EQEP_COMPARE_NO_SHADOW",
    //                     options     :
    //                     [
    //                         {name: "EQEP_COMPARE_NO_SHADOW",        displayName: "Disable shadow of QPOSCMP"},
    //                         {name: "EQEP_COMPARE_LOAD_ON_ZERO",     displayName: "Load on QPOSCNT = 0"},
    //                         {name: "EQEP_COMPARE_LOAD_ON_MATCH",    displayName: "Load on QPOSCNT = QPOSCMP"},
    //                     ]
    //                 },
    //                 {
    //                     name        : "compareValue",
    //                     displayName : "Compare Value",
    //                     description : 'The value to which the position count value is compared for a position-compare event.',
    //                     hidden      : false,
    //                     default     : 0
    //                 },
    //                 {
    //                     name        : "compareCycles",
    //                     displayName : "Compare Cycles",
    //                     description : 'The width of the pulse that can be generated on a position-compare event.  It is in units of 4 SYSCLKOUT cycles.',
    //                     hidden      : false,
    //                     default     : 0
    //                 },
    //                 // enableCompare / disableCompare
    //                 {
    //                     name        : "enableCompare",
    //                     displayName : "Enable Position-Compare Unit",
    //                     description : 'Enables the eQEP module position-compare unit.',
    //                     hidden      : false,
    //                     default     : false
    //                 },
    //             ]
    //         }, 
    //     ]
    // },
    // {
    //     name            : "GROUP_EDGE_CAPTURE",
    //     displayName     : "Edge Capture Unit",
    //     description     : "",
    //     longDescription : "",
    //     config          : [
    //         // setCaptureConfig [do we have a boolean to determine if we do this?]
    //         {
    //             name        : "captureConfig",
    //             displayName : "Configure Edge-Capture Unit",
    //             description : 'Enables configuration of eQEP module edge-capture unit.',
    //             hidden      : false,
    //             default     : false
    //         },
    //         {
    //             name        : "capPrescale",
    //             displayName : "Capture Prescaler (QC Timer)",
    //             description : "Prescaler setting of the eQEP capture timer clk.",
    //             hidden      : false,
    //             default     : device_driverlib_peripheral.EQEP_CAPCLKPrescale[0].name,
    //             options     : device_driverlib_peripheral.EQEP_CAPCLKPrescale
    //         },
    //         {
    //             name: "qcTimeFreq",
    //             displayName : "QC Timer Frequency [MHz]",
    //             getValue    : (inst) => {
    //                 if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_1")
    //                 {
    //                     return (Common.getSYSCLK() / 1);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_2")
    //                 {
    //                     return (Common.getSYSCLK() / 2);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_4")
    //                 {
    //                     return (Common.getSYSCLK() / 4);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_8")
    //                 {
    //                     return (Common.getSYSCLK() / 8);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_16")
    //                 {
    //                     return (Common.getSYSCLK() / 16);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_32")
    //                 {
    //                     return (Common.getSYSCLK() / 32);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_64")
    //                 {
    //                     return (Common.getSYSCLK() / 64);
    //                 }
    //                 else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_128")
    //                 {
    //                     return (Common.getSYSCLK() / 128);
    //                 }
    //             },
    //             default : Common.getSYSCLK(),
    //         },
    //         {
    //             name        : "evntPrescale",
    //             displayName : "Unit Position Event Prescaler",
    //             description : "Prescaler setting of the unit position event.",
    //             hidden      : false,
    //             default     : device_driverlib_peripheral.EQEP_UPEVNTPrescale[0].name,
    //             options     : device_driverlib_peripheral.EQEP_UPEVNTPrescale
    //         },
    //         // enableCapture / disableCapture
    //         {
    //             name        : "enableCapture",
    //             displayName : "Enable Edge-Capture Unit",
    //             description : 'Enables the eQEP module edge-capture unit.',
    //             hidden      : false,
    //             default     : false
    //         },
    //         // enableUnitTimer / disableUnitTimer
    //         {
    //             name        : "enableUnitTimer",
    //             displayName : "Enable Unit Timer",
    //             description : 'Enables the eQEP module unit timer.',
    //             hidden      : false,
    //             default     : false
    //         },
    //         {
    //             name        : "unitTimerPeriod",
    //             displayName : "Unit Timer Period",
    //             description : "Period value at which a unit time-out interrupt is set.",
    //             hidden      : false,
    //             default     : 0
    //         },
    //         {
    //             name        : "unitTimerValNS",
    //             displayName : "Unit Timer Period [ns]",
    //             description : "Value of Unit Timer in nanoseconds.",
    //             getValue    : (inst) => 
    //             {
    //                 return ((inst.unitTimerPeriod / Common.getSYSCLK()) * 1000);
    //             },
    //             default     : 0
    //         },
    //     ]
    // },
    
    // {
    //     name            : "GROUP_WATCHDOG",
    //     displayName     : "EQEP Watchdog Timer",
    //     description     : "",
    //     longDescription : "",
    //     config          : [
    //         // enableWatchDog / disableWatchdog
    //         {
    //             name        : "enableWatchdog",
    //             displayName : "Enable EQEP Watchdog",
    //             description : "Enables the eQEP module watchdog timer.",
    //             hidden      : false,
    //             default     : false
    //         },
    //         {
    //             name        : "watchdogTimerPeriod",
    //             displayName : "EQEP Watchdog Timer Period",
    //             description : "Watchdog period value at which a time-out will occur if no quadrature-clock event is detected.",
    //             hidden      : false,
    //             default     : 0
    //         },
    //         // setWatchdogTimerValue
    //         {
    //             name        : "watchdogTimerValue",
    //             displayName : "EQEP Watchdog Timer Value",
    //             description : "Sets the eQEP module watchdog timer value.",
    //             hidden      : false,
    //             default     : 0
    //         },
    //         {
    //             name        : "watchdogTimerValueNS",
    //             displayName : "EQEP Watchdog Timer Value [ns]",
    //             description : "Value of EQEP Watchdog Timer in nanoseconds.",
    //             getValue    : (inst) => 
    //             {
    //                 return ((1 / Common.getSYSCLK()) * 1000);
    //             },
    //             default     : 0
    //         },
    //     ]
    // },
    

//]);
config.push(
    {
        name : "Group_Peripheral",
        collapsed : false,
        displayName: "Peripheral Configuration",
        config :[]  
    }
)
config[config.length - 1].config.push(
     // setEmulationMode
     {
        name        : "emulationMode",
        displayName : "Emulation Mode",
        description : "Set the emulation mode of the eQEP module.",
        hidden      : false,
        default     : device_driverlib_peripheral.EQEP_EmulationMode[0].name,
        options     : device_driverlib_peripheral.EQEP_EmulationMode
     
   }
)


if (device_driverlib_peripheral.EQEP_QMAMode){
config[config.length - 1].config.push(
        // setQMAModuleMode
        {
            name        : "qmaModuleMode",
            displayName : "QMA Module Mode",
            description : "Set the quadrature mode adapter (QMA) module mode.",
            hidden      : false,
            default     : device_driverlib_peripheral.EQEP_QMAMode[0].name,
            options     : device_driverlib_peripheral.EQEP_QMAMode
        },
    )
}

config[config.length-1].config.push(
    {
        name            : "GROUP_DECODER",
        displayName     : "Quadrature Decoder Unit",
        description     : "",
        longDescription : "",
        config          : conditionalConfig
    },
    {
        name            : "GROUP_POSITION",
        displayName     : "Position Counter and Control Unit",
        description     : "",
        longDescription : "",
        config          : [
            // setPositionCounterConfig
            {
                name        : "positionCounterMode",
                displayName : "Position Counter Mode",
                description : "Configuration for the eQEP module position counter.",
                hidden      : false,
                default     : device_driverlib_peripheral.EQEP_PositionResetMode[0].name,
                options     : device_driverlib_peripheral.EQEP_PositionResetMode
            },
            {
                name        : "positionCounterMax",
                displayName : "Maximum Position",
                description : "Specifies the maximum position value.",
                hidden      : false,
                default     : 0
            },
            // setPosition
            {
                name        : "setPosition",
                displayName : "Position Counter (QPOSCNT)",
                description : "Sets the current encoder position.",
                hidden      : false,
                default     : 0
            },
            {
                name: "GROUP_LATCH",
                displayName: "Latch Mode",
                description: "",
                longDescription: "",
                collapsed: false,
                config: [
                    // setLatchMode
                    {
                        name        : "latchPositionCounter",
                        displayName : "QEP Capture Latch Mode (QCLM)",
                        description : "Specify the event that latches the position counter.",
                        hidden      : false,
                        default     : "EQEP_LATCH_CNT_READ_BY_CPU",
                        options     :
                        [
                            {name: "EQEP_LATCH_CNT_READ_BY_CPU",    displayName: "On position counter read"},
                            {name: "EQEP_LATCH_UNIT_TIME_OUT",      displayName: "On unit time-out event"},
                        ]
                    },
                    {
                        name        : "latchStrobePosition",
                        displayName : "Strobe Event Latch (SEL)",
                        description : "Specify which strobe event will latch the position counter into the strobe position latch register. ",
                        hidden      : false,
                        default     : "EQEP_LATCH_RISING_STROBE",
                        options     :
                        [
                            {name: "EQEP_LATCH_RISING_STROBE",      displayName: "On rising edge of strobe"},
                            {name: "EQEP_LATCH_EDGE_DIR_STROBE",    displayName: "On rising edge when clockwise, on falling when counter clockwise"},
                        ]
                    },
                    {
                        name        : "latchIndexPosition",
                        displayName : "Index Event Latch (IEL)",
                        description : "Specify which index event will latch the position counter into the index position latch register.",
                        hidden      : false,
                        default     : "EQEP_LATCH_RISING_INDEX",
                        options     :
                        [
                            {name: "EQEP_LATCH_RISING_INDEX",       displayName: "On rising edge of index"},
                            {name: "EQEP_LATCH_FALLING_INDEX",      displayName: "On falling edge of index"},
                            {name: "EQEP_LATCH_SW_INDEX_MARKER",    displayName: "On software index marker"},
                        ]
                    },
                ]
            }, 
            // setPositionInitMode
            {
                name        : "positionStrobeEvents",
                displayName : "Position Strobe Events (SEI)",
                description : "Specify which strobe event will initialize the position counter.",
                hidden      : false,
                default     : "EQEP_INIT_DO_NOTHING",
                options     :
                [
                    {name: "EQEP_INIT_DO_NOTHING",   displayName: "Action is disabled"},
                    {name: "EQEP_INIT_RISING_STROBE",   displayName: "On rising edge of strobe"},
                    {name: "EQEP_INIT_EDGE_DIR_STROBE",   displayName: "On rising edge when clockwise, on falling when counter clockwise"},
                ]
            },
            {
                name        : "positionIndexEvents",
                displayName : "Position Index Events (IEI)",
                description : "Specify which index event will initialize the position counter.",
                hidden      : false,
                default     : "EQEP_INIT_DO_NOTHING",
                options     :
                [
                    {name: "EQEP_INIT_DO_NOTHING",   displayName: "Action is disabled"},
                    {name: "EQEP_INIT_RISING_INDEX",   displayName: "On rising edge of index"},
                    {name: "EQEP_INIT_FALLING_INDEX",   displayName: "On falling edge of index"},
                ]
            },
            // setSWPositionInit
            {
                name        : "swPositionInit",
                displayName : " Set Software Initialization Position Counter",
                description : 'Sets the software initialization of the encoder position counter.',
                hidden      : false,
                default     : false
            },
            // setInitialPosition
            {
                name        : "initialPosition",
                displayName : "Position Counter Initialization Value",
                description : 'Sets the init value for the encoder position counter.',
                hidden      : false,
                default     : 0
            },
            // enableModule / disableModule
            {
                name        : "enableModule",
                displayName : "Enable Position Counter",
                description : 'Enables the eQEP module.',
                hidden      : false,
                default     : false
            },
            {
                name: "GROUP_COMPARE",
                displayName: "Compare Configuration",
                description: "",
                longDescription: "",
                collapsed: false,
                config: [
                    // setCompareConfig [do we have a boolean to determine if we do this?]
                    {
                        name        : "compareConfig",
                        displayName : "Configure Position-Compare Unit",
                        description : 'Enables configuration of eQEP module position-compare unit.',
                        hidden      : false,
                        default     : false
                    },
                    {
                        name        : "compareSyncPulsePin",
                        displayName : "Sync Output Pin Selection (SPSEL)",
                        description : "Specify if there is a sync output pulse and which pin should be used.",
                        hidden      : false,
                        default     : "EQEP_COMPARE_NO_SYNC_OUT",
                        options     :
                        [
                            {name: "EQEP_COMPARE_NO_SYNC_OUT",      displayName: "Disable sync output"},
                            {name: "EQEP_COMPARE_IDX_SYNC_OUT",     displayName: "Sync output on index pin"},
                            {name: "EQEP_COMPARE_STROBE_SYNC_OUT",  displayName: "Sync output on strobe pin"},
                        ]
                    },
                    {
                        name        : "compareShadowRegisterUse",
                        displayName : "Position Compare of Shadow Load (PCLOAD)",
                        description : "Specify if a shadow is enabled and when should the load should occur.",
                        hidden      : false,
                        default     : "EQEP_COMPARE_NO_SHADOW",
                        options     :
                        [
                            {name: "EQEP_COMPARE_NO_SHADOW",        displayName: "Disable shadow of QPOSCMP"},
                            {name: "EQEP_COMPARE_LOAD_ON_ZERO",     displayName: "Load on QPOSCNT = 0"},
                            {name: "EQEP_COMPARE_LOAD_ON_MATCH",    displayName: "Load on QPOSCNT = QPOSCMP"},
                        ]
                    },
                    {
                        name        : "compareValue",
                        displayName : "Compare Value",
                        description : 'The value to which the position count value is compared for a position-compare event.',
                        hidden      : false,
                        default     : 0
                    },
                    {
                        name        : "compareCycles",
                        displayName : "Compare Cycles",
                        description : 'The width of the pulse that can be generated on a position-compare event.  It is in units of 4 SYSCLKOUT cycles.',
                        hidden      : false,
                        default     : 0
                    },
                    // enableCompare / disableCompare
                    {
                        name        : "enableCompare",
                        displayName : "Enable Position-Compare Unit",
                        description : 'Enables the eQEP module position-compare unit.',
                        hidden      : false,
                        default     : false
                    },
                ]
            }, 
        ]
    },
    {
        name            : "GROUP_EDGE_CAPTURE",
        displayName     : "Edge Capture Unit",
        description     : "",
        longDescription : "",
        config          : [
            // setCaptureConfig [do we have a boolean to determine if we do this?]
            {
                name        : "captureConfig",
                displayName : "Configure Edge-Capture Unit",
                description : 'Enables configuration of eQEP module edge-capture unit.',
                hidden      : false,
                default     : false
            },
            {
                name        : "capPrescale",
                displayName : "Capture Prescaler (QC Timer)",
                description : "Prescaler setting of the eQEP capture timer clk.",
                hidden      : false,
                default     : device_driverlib_peripheral.EQEP_CAPCLKPrescale[0].name,
                options     : device_driverlib_peripheral.EQEP_CAPCLKPrescale
            },
            {
                name: "qcTimeFreq",
                displayName : "QC Timer Frequency [MHz]",
                getValue    : (inst) => {
                    if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_1")
                    {
                        return (Common.getSYSCLK() / 1);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_2")
                    {
                        return (Common.getSYSCLK() / 2);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_4")
                    {
                        return (Common.getSYSCLK() / 4);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_8")
                    {
                        return (Common.getSYSCLK() / 8);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_16")
                    {
                        return (Common.getSYSCLK() / 16);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_32")
                    {
                        return (Common.getSYSCLK() / 32);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_64")
                    {
                        return (Common.getSYSCLK() / 64);
                    }
                    else if(inst.capPrescale == "EQEP_CAPTURE_CLK_DIV_128")
                    {
                        return (Common.getSYSCLK() / 128);
                    }
                },
                default : Common.getSYSCLK(),
            },
            {
                name        : "evntPrescale",
                displayName : "Unit Position Event Prescaler",
                description : "Prescaler setting of the unit position event.",
                hidden      : false,
                default     : device_driverlib_peripheral.EQEP_UPEVNTPrescale[0].name,
                options     : device_driverlib_peripheral.EQEP_UPEVNTPrescale
            },
            // enableCapture / disableCapture
            {
                name        : "enableCapture",
                displayName : "Enable Edge-Capture Unit",
                description : 'Enables the eQEP module edge-capture unit.',
                hidden      : false,
                default     : false
            },
            // enableUnitTimer / disableUnitTimer
            {
                name        : "enableUnitTimer",
                displayName : "Enable Unit Timer",
                description : 'Enables the eQEP module unit timer.',
                hidden      : false,
                default     : false
            },
            {
                name        : "unitTimerPeriod",
                displayName : "Unit Timer Period",
                description : "Period value at which a unit time-out interrupt is set.",
                hidden      : false,
                default     : 0
            },
            {
                name        : "unitTimerValNS",
                displayName : "Unit Timer Period [ns]",
                description : "Value of Unit Timer in nanoseconds.",
                getValue    : (inst) => 
                {
                    return ((inst.unitTimerPeriod / Common.getSYSCLK()) * 1000);
                },
                default     : 0
            },
        ]
    },
    
    {
        name            : "GROUP_WATCHDOG",
        displayName     : "EQEP Watchdog Timer",
        description     : "",
        longDescription : "",
        config          : [
            // enableWatchDog / disableWatchdog
            {
                name        : "enableWatchdog",
                displayName : "Enable EQEP Watchdog",
                description : "Enables the eQEP module watchdog timer.",
                hidden      : false,
                default     : false
            },
            {
                name        : "watchdogTimerPeriod",
                displayName : "EQEP Watchdog Timer Period",
                description : "Watchdog period value at which a time-out will occur if no quadrature-clock event is detected.",
                hidden      : false,
                default     : 0
            },
            // setWatchdogTimerValue
            {
                name        : "watchdogTimerValue",
                displayName : "EQEP Watchdog Timer Value",
                description : "Sets the eQEP module watchdog timer value.",
                hidden      : false,
                default     : 0
            },
            {
                name        : "watchdogTimerValueNS",
                displayName : "EQEP Watchdog Timer Value [ns]",
                description : "Value of EQEP Watchdog Timer in nanoseconds.",
                getValue    : (inst) => 
                {
                    return ((1 / Common.getSYSCLK()) * 1000);
                },
                default     : 0
            },
        ]
    },
    
)

config.push(
    {
        name: "Pinmux Config",
        displayName: "Input Configuration",
        collapsed: true,
        config: []
    }
)

if (device_driverlib_peripheral.EQEP_Source){
        config[config.length - 1].config.push(
            
            // selectSource
            {
                name        : "selectSourceA",
                displayName : "QEPA Source",
                description : "Selects the source for QEPA signal.",
                hidden      : false,
                default     : device_driverlib_peripheral.EQEP_Source[0].name,
                options     : device_driverlib_peripheral.EQEP_Source
            },
            {
                name        : "selectSourceB",
                displayName : "QEPB Source",
                description : "Selects the source for QEPB signal.",
                hidden      : false,
                default     : device_driverlib_peripheral.EQEP_Source[0].name,
                options     : device_driverlib_peripheral.EQEP_Source
            },
            {
                name        : "selectSourceIndex",
                displayName : "QEPI/Index Source",
                description : "Selects the source for Index signal.",
                hidden      : false,
                default     : device_driverlib_peripheral.EQEP_Source[0].name,
                options     : device_driverlib_peripheral.EQEP_Source
            },
        )
    }
if (device_driverlib_peripheral.EQEP_StrobeSource){
    
    config[config.length - 1].config.push(
        // setStrobeSource
        {
        name        : "strobeSource",
        displayName : "Strobe Source",
        description : "Set the strobe input source of the eQEP module.",
        hidden      : false,
        default     : device_driverlib_peripheral.EQEP_StrobeSource[0].name,
        options     : device_driverlib_peripheral.EQEP_StrobeSource
    },
    )
}


config.push(
    // interrupt tab

    {
        name            : "GROUP_INTERRUPTS",
        displayName     : "Interrupts Configuration",
        description     : "",
        longDescription : "",
        config          : [
            // use & register interrupt
            {
                name        : "useInterrupts",
                displayName : "Use Interrupt",
                onChange    : onChangeUseInterrupts,
                description : 'Whether or not to use Interrupt mode.',
                hidden      : false,
                default     : true
            },
            {
                name        : "registerInterrupts",
                displayName : "Register Interrupt Handler",
                description : 'Whether or not to register interrupt handlers in the interrupt module.',
                hidden      : false,
                default     : false
            },
            // enableInterrupt / disableInterrupt
            {
                name        : "enableInterrupt",
                displayName : "Enable Interrupt",
                description : 'Enables interrupt source.',
                hidden      : false,
                default     : false
            },
            {
                name        : "interruptSources",
                displayName : "Interrupt Sources",
                description : "The interrupt sources to be enabled.",
                hidden      : false,
                default     : [],
                minSelections: 0,
                options     : device_driverlib_peripheral.EQEP_INT 
            },
        ]
    },
)
config.push(
    {
        name : "Group_Sys",
        displayName : "System Configuration",
        collapsed : true,
        config : []
    }
)


function onValidate(inst, validation) {
    /* Validate Position Counter Max up to 32 bit unsigned int */
    var usedEQEPInsts = [];
    for (var instance_index in inst.$module.$instances)
    {
        var instance_obj = inst.$module.$instances[instance_index];
        usedEQEPInsts.push(instance_obj.eqepBase);
    }

    var otherContexts = Common.getOtherContextNames()
    for (var cntx of otherContexts)
    {
        var onOtherCntx = Common.getModuleForCore(inst.$module.$name, cntx);
        if (onOtherCntx)
        {
            for (var instance_index in onOtherCntx.$instances)
            {
                var instance_obj = onOtherCntx.$instances[instance_index];
                usedEQEPInsts.push(instance_obj.eqepBase);
            }
        }
    }

    var duplicatesResult = Common.findDuplicates(usedEQEPInsts)

    if (duplicatesResult.duplicates.length != 0)
    {
        var allDuplicates = "";
        for (var duplicateNamesIndex in duplicatesResult.duplicates)
        {
            allDuplicates = allDuplicates + Common.stringOrEmpty(allDuplicates, ", ") 
                            + duplicatesResult.duplicates[duplicateNamesIndex];
        }
        validation.logError(
            "The EQEP Instance used. Duplicates: " + allDuplicates, 
            inst, "eqepBase");
    }




    if (inst.positionCounterMax < 0 || inst.positionCounterMax > 4294967295)
    {
        validation.logError(
            "Enter an integer for Position Counter Maximum between 0 and 4,294,967,295!", 
            inst, "positionCounterMax");
    }
    if (!Number.isInteger(inst.positionCounterMax))
    {
        validation.logError(
            "Position Counter Maximum must be an integer", 
            inst, "positionCounterMax");
    }

    /* Validate Position Counter Initialization Value up to 32 bit unsigned int */
    if (inst.initialPosition < 0 || inst.initialPosition > 4294967295)
    {
        validation.logError(
            "Enter an integer for Position Counter Initialization Value between 0 and 4,294,967,295!", 
            inst, "initialPosition");
    }
    if (!Number.isInteger(inst.initialPosition))
    {
        validation.logError(
            "Position Counter Initialization Value must be an integer", 
            inst, "initialPosition");
    }
    
    /* Validate Unit Timer Period up to 32 bit unsigned int */
    if (inst.unitTimerPeriod < 0 || inst.unitTimerPeriod > 4294967295)
    {
        validation.logError(
            "Enter an integer for Unit Timer Period between 0 and 4,294,967,295!", 
            inst, "unitTimerPeriod");
    }
    if (!Number.isInteger(inst.unitTimerPeriod))
    {
        validation.logError(
            "Unit Timer Period must be an integer", 
            inst, "unitTimerPeriod");
    }

    /* Validate Encoder Position up to 32 bit unsigned int */
    if (inst.setPosition < 0 || inst.setPosition > 4294967295)
    {
        validation.logError(
            "Enter an integer for Encoder Position between 0 and 4,294,967,295!", 
            inst, "setPosition");
    }
    if (!Number.isInteger(inst.setPosition))
    {
        validation.logError(
            "Encoder Position must be an integer", 
            inst, "setPosition");
    }
    
    /* Validate Watchdog Timer Period up to 16 bit unsigned int */
    if (inst.watchdogTimerPeriod < 0 || inst.watchdogTimerPeriod > 65535)
    {
        validation.logError(
            "Enter an integer for EQEP Watchdog Timer Period between 0 and 65,535!", 
            inst, "watchdogTimerPeriod");
    }
    if (!Number.isInteger(inst.watchdogTimerPeriod))
    {
        validation.logError(
            "EQEP Watchdog Timer Period must be an integer", 
            inst, "watchdogTimerPeriod");
    }
    
    /* Validate Watchdog Timer Value up to 16 bit unsigned int */
    if (inst.watchdogTimerValue < 0 || inst.watchdogTimerValue > 65535)
    {
        validation.logError(
            "Enter an integer for EQEP Watchdog Timer Value between 0 and 65,535!", 
            inst, "watchdogTimerValue");
    }
    if (!Number.isInteger(inst.watchdogTimerValue))
    {
        validation.logError(
            "EQEP Watchdog Timer Value must be an integer", 
            inst, "watchdogTimerValue");
    }

    /* Validate Compare Value up to 32 bit unsigned int */
    if (inst.compareValue < 0 || inst.compareValue > 4294967295)
    {
        validation.logError(
            "Enter an integer for Compare Value between 0 and 4,294,967,295!", 
            inst, "compareValue");
    }
    if (!Number.isInteger(inst.compareValue))
    {
        validation.logError(
            "Compare Value between must be an integer", 
            inst, "compareValue");
    }

    /* Validate Compare Cycles up to 16 bit unsigned int */
    if (inst.compareCycles < 0 || inst.compareCycles > 65535)
    {
        validation.logError(
            "Enter an integer for Compare Cycles between 0 and 65,535!", 
            inst, "compareCycles");
    }
    if (!Number.isInteger(inst.compareCycles))
    {
        validation.logError(
            "Compare Cycles must be an integer", 
            inst, "compareCycles");
    }

}

/*
 *  ======== filterHardware ========
 *  Control RX, TX Pin usage by the user specified dataDirection.
 *
 *  param component - hardware object describing signals and
 *                     resources they're attached to
 *
 *  returns Boolean indicating whether or not to allow the component to
 *           be assigned to an instance's $hardware config
 */
function filterHardware(component)
{
    return (Common.typeMatches(component.type, ["EQEP"]));
}

if (Common.onlyPinmux())
{
    config = [config[config.length - 1]];
}
var numberOfEQEPs = 6;
var eqepModule = {
    peripheralName: "EQEP",
    displayName: "EQEP",
    maxInstances: numberOfEQEPs,
    defaultInstanceName: "myEQEP",
    description: "Enhanced Quadrature Encoder Peripheral",
    longDescription: longDescription,
    //longDescription: longDescription + "\n" + (Common.getCollateralFindabilityList("EQEP")),
    filterHardware : filterHardware,
    config: config,
    moduleInstances: (inst) => {
        var ownedInstances = []
        
        if (inst.useInterrupts && inst.registerInterrupts)
        {
	        ownedInstances = ownedInstances.concat([{
                name: "eqepInt",
                group : "GROUP_INTERRUPTS",      
                displayName: "EQEP Interrupt",
                moduleName: "/driverlib/interrupt.js",
                collapsed: true,
                args: {
            		$name : inst.$name + "_INT",
                    typeInterruptName : true,
                    pinmuxPeripheralModule : "",
                    driverlibInt: "INT_"+inst.eqepBase.replace("_BASE", ""),
                    interruptHandler : "INT_" + inst.$name + "_ISR",
                }
            }])
        }
        ownedInstances = ownedInstances.concat([
            {
                name: "periphClock",
                group : "Group_Sys",
                displayName: "",
                moduleName: "/driverlib/perClock.js",
                collapsed: false,
                requiredArgs:{
                    pinmuxPeripheralModule : "",
                    peripheralInst: inst.eqepBase.replace("_BASE", "")
                }
            },
            {
                name: "periphConfig",
                group : "Group_Sys",
                displayName: "",
                moduleName: "/driverlib/perConfig.js",
                collapsed: false,
                requiredArgs:{
                    pinmuxPeripheralModule : "",
                    peripheralInst: inst.eqepBase.replace("_BASE", "")
                }
            },
        ])
    	return ownedInstances;
    },
    templates: {
        boardc : "/driverlib/eqep/eqep.board.c.xdt",
        boardh : "/driverlib/eqep/eqep.board.h.xdt"
    },
    validate    : onValidate,
};




exports = eqepModule;