Copyright (c) (2016) Fluke Corporation.                  All rights reserved.
=============================================================================
INSTRUMENT:            Sub Initialize /SWPG
INSTRUMENT:            Sub Reset /SWPG
INSTRUMENT:            Sub Output Off /SWPG
INSTRUMENT:            Sub Apply /SWPG
INSTRUMENT:            Sub Get Options /SWPG
INSTRUMENT:            Sub Get Accuracy /SWPG
DATE:                  2016-02-02 14:11:25
AUTHOR:                Fluke
REVISION:              $Revision: 24551 $
ADJUSTMENT THRESHOLD:  70%
NUMBER OF TESTS:       7
NUMBER OF LINES:       1022
CONFIGURATION:         Fluke 96270A
=============================================================================
#
#  Procedure Author:
#        DAC, DFM, CAD
#
#  Compatibility:
#        MET/CAL 7.2 or later
#
#  This procedure is intended for use with MET/CAL calibration software;
#  the terms and conditions set forth in your MET/CAL license apply to this
#  procedure.
#
#  Due to Fluke's policy of continuously updating our products, this procedure
#  may contain minor differences in methods used and/or specifications to
#  those found in the manual or other documentation. While every effort has
#  been made to ensure that this procedure is accurate, Fluke cannot be held
#  responsible for the consequences of error or omissions found within this
#  procedure.
#
#  The copyright in this procedure is owned by Fluke Corporation.
#
#  Parameters        Values
#  ----------------  ---------------------------------------------------------
#  @SWPG_Freq        <NR3>[][<prefix>]Hz
#
#  @SWPG_Ampl        <NR3>[]dBm
#
#  @SWPG_Sweep       On | Off
#
#  @SWPG_StartFreq   <NR3>[][<prefix>]Hz
#  @SWPG_StopFreq    <NR3>[][<prefix>]Hz
#
#  @SWPG_SweepTime   <NR3>[][<prefix>]s
#  (or optionally:)
#  @SWPG_SweepStep   <NR3>[][<prefix>]Hz
#  @SWPG_SweepDwell  <NR3>[][<prefix>]s
#
#  @SWPG_SweepStart  Cont | Single
#
#  @SWPG_TrigType    FreeRun | Line | Ext
#
#  @SWPG_ModFreq     <NR3>[][<prefix>]Hz
#
#  @SWPG_ModSrc      Int | Ext
#
#  @SWPG_ExtCpl      AC | DC
#
#  @SWPG_AM          On | Off
#
#  @SWPG_AM_Depth    <NR3>[][<prefix>]%
#
#  @SWPG_FM          On | Off
#
#  @SWPG_FM_Dev      <NR3>[][<prefix>]Hz
#
#  @SWPG_PM          On | Off
#
#  @SWPG_PM_Dev      <NR3>[][<prefix>]rad
#
#  @SWPG_PL          On | Off
#
#  @SWPG_PL_Width    <NR3>[][<prefix>]s
#
#  @SWPG_PL_Delay    <NR3>[][<prefix>]s
#
#  @SWPG_PL_Imp      <NR3>[][<prefix>]Ohm
#
#  @SWPG_PL_Slope    Pos | Neg
#
#  @SWPG_PL_Cond     On | Off
#
#  @SWPG_ROSC *      Int | Ext
#
#  @SWPG_Leveling    Int | Ext | Pwr
#
#  NOTES:
#  * Manual selection prompts for rear panel switches will ONLY be displayed
#    when explicitly requesting "Int" or "Ext".  Leaving @SWPG_ROSC blank
#    after calling Sub Initialize will NOT prompt the operator for a change.
#
#  Example Usage:
#
#      CALL         Sub Initialize /SWPG
#      CALL         Sub Reset /SWPG
#
#      MATH         @SWPG_StartFreq = "10 MHz"
#      MATH         @SWPG_StopFreq  = "50 MHz"
#      MATH         @SWPG_SweepTime = "10 s"
#      MATH         @SWPG_Ampl      = "0 dBm"
#      CALL         Sub Apply /SWPG
#
#      MATH         @SWPG_Freq      = "500 MHz"
#      MATH         @SWPG_Ampl      = "-10 dBm"
#      MATH         @SWPG_ModSrc    = "Int"
#      MATH         @SWPG_ModFreq   = "1 kHz"
#      MATH         @SWPG_AM_Depth  = "30%"
#      MATH         @SWPG_AM        = "On"
#      CALL         Sub Apply /SWPG
#
#      CALL         Sub Output Off /SWPG
#
 STEP    FSC    RANGE NOMINAL        TOLERANCE     MOD1        MOD2  3  4 CON

  1.001  JMPL         INITIALIZE                   PSUBI("Initialize")
  1.002  JMPL         RESET                        PSUBI("Reset")
  1.003  JMPL         OUTPUT_OFF                   PSUBI("Output Off")
  1.004  JMPL         APPLY                        PSUBI("Apply")
  1.005  JMPL         GET_OPTIONS                  PSUBI("Get Options")
  1.006  JMPL         GET_ACCURACY                 PSUBI("Get Accuracy")
  1.007  DISP         Called subprocedure not found!
  1.008  END

  1.009  EVAL   Increment Step Number


# =====  Sub Initialize /SWPG  ==============================================

  2.001  LABEL        INITIALIZE

# Get and store:
#   device name
#   coverage factor
#   programming section name for looking up programming codes in .ini file.
#   FSC used for IEEE-488 I/O
#   Connection terminal names

  2.002  MATH         @SWPG_DevName = INSTR("SWPG")

  2.003  IF           0
  2.004  MATH         @SWPG_Conf = CONF(@SWPG_DevName)
  2.005  ENDIF

  2.006  MATH         @SWPG_ProgSecName = RINFE(@SWPG_DevName, "ProgSecName")
  2.007  MATH         @SWPG_FSC     = RINFE(@SWPG_ProgSecName, "FSC")
  2.008  MATH         @SWPG_Output  = RINFE(@SWPG_ProgSecName, "Output50_Ohm")
  2.009  MATH         @SWPG_RefIn   = RINFE(@SWPG_ProgSecName, "RefIn")
  2.010  MATH         @SWPG_RefOut  = RINFE(@SWPG_ProgSecName, "RefOut")

# Initialize parameters to the empty string (unset).
  2.011  MATH         @SWPG_Freq       = ""
  2.012  MATH         @SWPG_Sweep      = ""
  2.013  MATH         @SWPG_StartFreq  = ""
  2.014  MATH         @SWPG_StopFreq   = ""
  2.015  MATH         @SWPG_SweepTime  = ""
  2.016  MATH         @SWPG_SweepStep  = ""
  2.017  MATH         @SWPG_SweepDwell = ""
  2.018  MATH         @SWPG_SweepStart = ""
  2.019  MATH         @SWPG_TrigType   = ""
  2.020  MATH         @SWPG_Ampl       = ""
  2.021  MATH         @SWPG_ModFreq    = ""
  2.022  MATH         @SWPG_ModSrc     = ""
  2.023  MATH         @SWPG_ExtCpl     = ""
  2.024  MATH         @SWPG_AM         = ""
  2.025  MATH         @SWPG_AM_Depth   = ""
  2.026  MATH         @SWPG_FM         = ""
  2.027  MATH         @SWPG_FM_Dev     = ""
  2.028  MATH         @SWPG_PM         = ""
  2.029  MATH         @SWPG_PM_Dev     = ""
  2.030  MATH         @SWPG_PL         = ""
  2.031  MATH         @SWPG_PL_Width   = ""
  2.032  MATH         @SWPG_PL_Delay   = ""
  2.033  MATH         @SWPG_PL_Imp     = ""
  2.034  MATH         @SWPG_PL_Slope   = ""
  2.035  MATH         @SWPG_PL_Cond    = ""
  2.036  MATH         @SWPG_ROSC       = ""
  2.037  MATH         @SWPG_Leveling   = ""

# Check for the flag that triggers operator message to manually select
# frequency reference source.  Initialize variable if does not exist, else
# retain existing switch position.
  2.038  IF           NOT(ISVAR("@SWPG_ROSC_Set"))
  2.039  MATH         @SWPG_ROSC_Set   = ""
  2.040  ENDIF

# Get programming string for RESET FSC.
  2.041  MATH         ResetCmd = RINF(@SWPG_ProgSecName, "ResetFSC")

# If RESET_FSC is defined, establish the RESET FSC.
  2.042  IF           NOT(EMPTY(ResetCmd))

  2.043  IF           ZCMPI(ResetCmd, "[SDC]")
  2.044  RESET        [@SWPG][SDC]
  2.045  ELSE
  2.046  RESET        [@SWPG][V ResetCmd]
  2.047  ENDIF

  2.048  ENDIF

  2.049  END

  2.050  EVAL   Increment test number


# =====  Sub Reset /SWPG  ===================================================

  3.001  LABEL        RESET

  3.002  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, "Reset")
  3.003  CALL         Sub Send Command /SWPG
  3.004  END

  3.005  EVAL   Increment test number


# =====  Sub Output Off /SWPG  ==============================================

  4.001  LABEL        OUTPUT_OFF

  4.002  MATH         @SWPG_Cmd = RINF(@SWPG_ProgSecName, "OutputOff")

# If "Output_Off" is defined, send the command.
  4.003  IF           NOT(EMPTY(@SWPG_Cmd))
  4.004  CALL         Sub Send Command /SWPG
  4.005  ENDIF

  4.006  END

  4.007  EVAL   Increment test number


# =====  Sub Apply /SWPG  ===================================================

  5.001  LABEL        APPLY

# Check for sweep mode or CW mode.
  5.002  IF           ZCMP(@SWPG_Sweep, "On")
  5.003  MATH         StartFreq = BASE(@SWPG_StartFreq)
  5.004  MATH         StopFreq  = BASE(@SWPG_StopFreq)

  5.005  MATH         StartFreqCmd = RINF(@SWPG_ProgSecName, "StartFreq")

# Check for StartFreq in .ini file.
  5.006  IF           NOT(EMPTY(StartFreqCmd))
  5.007  MATH         @SWPG_Cmd = REPL("<val>", StartFreq, StartFreqCmd)
  5.008  CALL         Sub Send Command /SWPG
  5.009  MATH         StopFreqCmd = RINFE(@SWPG_ProgSecName, "StopFreq")
  5.010  MATH         @SWPG_Cmd = REPL("<val>", StopFreq, StopFreqCmd)
  5.011  CALL         Sub Send Command /SWPG

  5.012  ELSE         ; Check for CenterFreq in .ini file.
  5.013  MATH         CenterFreqCmd = RINF(@SWPG_ProgSecName, "CenterFreq")

  5.014  IF           NOT(EMPTY(CenterFreqCmd))
# Compute frequency span & center frequency.
  5.015  MATH         FreqSpan = StopFreq - StartFreq
  5.016  MATH         CenterFreq = (FreqSpan) / 2 + StartFreq
  5.017  MATH         @SWPG_Cmd = REPL("<val>", CenterFreq, CenterFreqCmd)
  5.018  CALL         Sub Send Command /SWPG
  5.019  MATH         FreqSpanCmd = RINFE(@SWPG_ProgSecName, "FreqSpan")
  5.020  MATH         @SWPG_Cmd = REPL("<val>", FreqSpan, FreqSpanCmd)
  5.021  CALL         Sub Send Command /SWPG
  5.022  ELSE         ; IF CenterFreqCmd EMPTY
  5.023  DISP         Neither "StartFreq" or "CenterFreq" is defined for
  5.024  DISP         [V @SWPG_DevName] in .ini file.
  5.025  ENDIF        ; CenterFreqCmd

  5.026  ENDIF        ; StartFreqCmd

# -----  Sweep Time  ------------------------------
#
# Some sweep generators do not support all sweep time configuration commands.
# This driver supports either a sweep time command, or combination of Sweep
# Step size (Hz) and Sweep Dwell time commands.
#
# SweepTime will be calculated if the Start and Stop Frequencies, Step Size
# and Dwell Time are specified.
#
# If neither method is defined or supported, the driver performs no action
# and assumes that Sweep Time is part of the Sweep Start command.

# Check if Sweep Time, Step, or Dwell global variables are defined.
  5.027  MATH         L[1] =        NOT(EMPTY(@SWPG_SweepTime))
  5.028  MATH         L[1] = L[1] + NOT(EMPTY(@SWPG_SweepStep))
  5.029  MATH         L[1] = L[1] + NOT(EMPTY(@SWPG_SweepDwell))

# Only configure the sweep if parameters have been defined.
  5.030  IF           L[1] > 0

# Establish sweep parameters from defined global variables.
  5.031  IF           NOT(EMPTY(@SWPG_SweepTime))
  5.032  MATH         SweepTime  = BASE(@SWPG_SweepTime)
  5.033  ENDIF

  5.034  IF           NOT(EMPTY(@SWPG_SweepStep))
  5.035  MATH         SweepStep  = BASE(@SWPG_SweepStep)
  5.036  ENDIF

  5.037  IF           NOT(EMPTY(@SWPG_SweepDwell))
  5.038  MATH         SweepDwell = BASE(@SWPG_SweepDwell)
  5.039  ENDIF

# Calculate sweep time for SWPGs that need it, if Step and Dwell were defined.
  5.040  IF           ISVAR("SweepStep") && ISVAR("SweepDwell")
  5.041  MATH         SweepTime = (StopFreq - StartFreq)
  5.042  MATH         SweepTime = SweepTime / SweepStep * SweepDwell
  5.043  ENDIF

# Check the .ini file for supported commands.
  5.044  MATH         SweepTimeCmd  = RINF(@SWPG_ProgSecName, "SweepTime")
  5.045  MATH         SweepStepCmd  = RINF(@SWPG_ProgSecName, "SweepStep")
  5.046  MATH         SweepDwellCmd = RINF(@SWPG_ProgSecName, "SweepDwell")

# If there is a sweep time command, send it.
  5.047  IF           NOT(EMPTY(SweepTimeCmd))
  5.048  MATH         @SWPG_Cmd = REPL("<val>", SweepTime, SweepTimeCmd)
  5.049  CALL         Sub Send Command /SWPG

# Or use the SweepStep and SweepDwell commands, if supported AND variables
# have been defined.
  5.050  ELSEIF       NOT(EMPTY(SweepStepCmd)) && NOT(EMPTY(SweepDwellCmd))

  5.051  IF           ISVAR("SweepStep") && ISVAR("SweepDwell")
  5.052  MATH         @SWPG_Cmd  = REPL("<val>", SweepStep, SweepStepCmd)
  5.053  CALL         Sub Send Command /SWPG

  5.054  MATH         @SWPG_Cmd  = REPL("<val>", SweepDwell, SweepDwellCmd)
  5.055  CALL         Sub Send Command /SWPG
  5.056  ENDIF        ; End check for SweepStep & SweepDwell

  5.057  ENDIF        ; End Supported Sweep Time commands

# If neither method is supported, do nothing; it is assumed that Sweep Time
# is part of the Sweep Start command.

  5.058  ENDIF        ; End Sweep Time configuration

# -----  Trigger Type  ----------------------------

  5.059  IF           NOT(EMPTY(@SWPG_TrigType))

  5.060  IF           ZCMPI(@SWPG_TrigType, "FreeRun")
  5.061  MATH         TrigType = "FreeRun"
  5.062  ELSEIF       ZCMPI(@SWPG_TrigType, "Line")
  5.063  MATH         TrigType = "LineTrig"
  5.064  ELSE         ; IF @SWPG_TrigType is not defined.
  5.065  MATH         TrigType = "ExtTrig"
  5.066  ENDIF        ; Define @SWPG_TrigType

  5.067  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, TrigType)
  5.068  CALL         Sub Send Command /SWPG
  5.069  ENDIF        ; @SWPG_TrigType

# NOTE: Sweep Start is programmed following Output On.

# -----  Frequency  -------------------------------

  5.070  ELSE         ; If @SWPG_Sweep is not "On"
# Get the command string.
  5.071  MATH         FreqCmd = RINFE(@SWPG_ProgSecName, "Freq")
# Convert to base units and insert in programming string.
  5.072  MATH         @SWPG_Cmd = REPL("<val>", BASE(@SWPG_Freq), FreqCmd)
  5.073  CALL         Sub Send Command /SWPG
  5.074  ENDIF        ; End apply @SWPG_Sweep "On" or "Off"

# -----  Amplitude  -------------------------------

# Only program amplitude if internal leveling specified.
  5.075  IF           EMPTY(@SWPG_Leveling) || ZCMPI(@SWPG_Leveling, "Int")

  5.076  IF           NOT(ZCMPI(UNIT(@SWPG_Ampl), "dBm"))
  5.077  DISP         SWPG currently only supports dBm.
  5.078  END
  5.079  ENDIF

  5.080  MATH         Ampl = BASE(@SWPG_Ampl); AmplCmd = ""

# Use discrete command for negative dBm, if one exists.
  5.081  IF           Ampl < 0
  5.082  MATH         AmplCmd = RINF(@SWPG_ProgSecName, "Ampl_dBmNeg")
  5.083  ELSE
# Otherwise use discrete command for positive dBm, if one exists.
  5.084  MATH         AmplCmd = RINF(@SWPG_ProgSecName, "Ampl_dBmPos")
  5.085  ENDIF

# Otherwise use the general command.
  5.086  IF           EMPTY(AmplCmd)
  5.087  MATH         AmplCmd = RINFE(@SWPG_ProgSecName, "Ampl_dBm")
  5.088  ELSE
  5.089  MATH         Ampl = ABS(Ampl)
  5.090  ENDIF

  5.091  MATH         @SWPG_Cmd = REPL("<val>", Ampl, AmplCmd)
  5.092  CALL         Sub Send Command /SWPG
  5.093  ENDIF        ; End Apply Amplitude

# -----  AM  --------------------------------------

  5.094  IF           NOT(EMPTY(@SWPG_AM))

# -----  Modulation Source
  5.095  IF           NOT(EMPTY(@SWPG_ModSrc))

  5.096  IF           ZCMPI(@SWPG_ModSrc, "Int")

# For devices where internal modulation source and frequency are programmed
# with a single command, postpone programming these settings to the mod
# frequency block below.
  5.097  IF           NOT(EMPTY(RINF(@SWPG_ProgSecName, "AM_Int400Hz")))
  5.098  MATH         ModSrc = ""
  5.099  ELSEIF       NOT(EMPTY(RINF(@SWPG_ProgSecName, "AM_Int1kHz")))
  5.100  MATH         ModSrc = ""
  5.101  ELSE
  5.102  MATH         ModSrc = "AM_Int"
  5.103  ENDIF

  5.104  ELSE         ; External Coupling

  5.105  IF           ZCMPI(@SWPG_ExtCpl, "AC")
  5.106  MATH         ModSrc = "AM_ExtAC"
  5.107  ELSEIF       ZCMPI(@SWPG_ExtCpl, "DC")
  5.108  MATH         ModSrc = "AM_ExtDC"
  5.109  ELSE
  5.110  MATH         ModSrc = "AM_Ext"
  5.111  ENDIF

  5.112  ENDIF        ; ZCMPI(@SWPG_ModSrc, "Int")

  5.113  IF           NOT(EMPTY(ModSrc))
  5.114  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, ModSrc)
  5.115  CALL         Sub Send Command /SWPG
  5.116  ENDIF

  5.117  ENDIF        ; IF Modulation Source

# -----  Modulation Frequency.
  5.118  IF           NOT(EMPTY(@SWPG_ModFreq))
  5.119  MATH         ModFreq = BASE(@SWPG_ModFreq); ModFreqCmd = ""

# Use discrete command for 400 Hz Mod. Freq., if one exists.
  5.120  IF           ModFreq == 400
  5.121  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "AM_Int400Hz")
# Otherwise use discrete command for 1 kHz Mod. Freq, if one exists.
  5.122  ELSEIF       ModFreq == 1E+3
  5.123  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "AM_Int1kHz")
  5.124  ENDIF

# Otherwise use the general command.
  5.125  IF           EMPTY(ModFreqCmd)
  5.126  MATH         ModFreqCmd = RINFE(@SWPG_ProgSecName, "AM_ModFreq")
  5.127  MATH         @SWPG_Cmd  = REPL("<val>", ModFreq, ModFreqCmd)
  5.128  ELSE
  5.129  MATH         @SWPG_Cmd  = ModFreqCmd
  5.130  ENDIF

  5.131  CALL         Sub Send Command /SWPG
  5.132  ENDIF        ; IF Modulation Frequency

# -----  AM Depth
  5.133  IF           NOT(EMPTY(@SWPG_AM_Depth))
  5.134  MATH         AMDepth    = BASE(@SWPG_AM_Depth)
  5.135  MATH         AMDepthCmd = RINF(@SWPG_ProgSecName, "AM_Depth")
  5.136  MATH         @SWPG_Cmd  = REPL("<val>", AMDepth, AMDepthCmd)
  5.137  CALL         Sub Send Command /SWPG
  5.138  ENDIF

# Get the AM ON programming command string.
  5.139  MATH         @SWPG_Cmd = RINF(@SWPG_ProgSecName, "AM_On")

  5.140  IF           NOT(EMPTY(@SWPG_Cmd))
  5.141  CALL         Sub Send Command /SWPG
  5.142  ENDIF

  5.143  ENDIF        ; IF AM

# -----  FM  --------------------------------------

  5.144  IF           NOT(EMPTY(@SWPG_FM))

# -----  Modulation source.
  5.145  IF           NOT(EMPTY(@SWPG_ModSrc))

  5.146  IF           ZCMPI(@SWPG_ModSrc, "Int")

# See comments in AM Modulation source, above.
  5.147  IF           NOT(EMPTY(RINF(@SWPG_ProgSecName, "FM_Int400Hz")))
  5.148  MATH         ModSrc = ""
  5.149  ELSEIF       NOT(EMPTY(RINF(@SWPG_ProgSecName, "FM_Int1kHz")))
  5.150  MATH         ModSrc = ""
  5.151  ELSE
  5.152  MATH         ModSrc = "FM_Int"
  5.153  ENDIF

  5.154  ELSE         ; External Coupling

  5.155  IF           ZCMP(@SWPG_ExtCpl, "AC")
  5.156  MATH         ModSrc = "FM_ExtAC"
  5.157  ELSEIF       ZCMP(@SWPG_ExtCpl, "DC")
  5.158  MATH         ModSrc = "FM_ExtDC"
  5.159  ELSE
  5.160  MATH         ModSrc = "FM_Ext"
  5.161  ENDIF

  5.162  ENDIF

  5.163  IF           NOT(EMPTY(ModSrc))
  5.164  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, ModSrc)
  5.165  CALL         Sub Send Command /SWPG
  5.166  ENDIF

  5.167  ENDIF        ; IF Modulation Source

# -----  Modulation Frequency.
  5.168  IF           NOT(EMPTY(@SWPG_ModFreq))
  5.169  MATH         ModFreq = BASE(@SWPG_ModFreq); ModFreqCmd = ""

# Use discrete command for 400 Hz Mod. Freq., if one exists.
  5.170  IF           ModFreq == 400
  5.171  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "FM_Int400Hz")
# Otherwise use discrete command for 1 kHz Mod. Freq., if one exists.
  5.172  ELSEIF       ModFreq == 1E+3
  5.173  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "FM_Int1kHz")
  5.174  ENDIF

# Otherwise use the general command.
  5.175  IF           EMPTY(ModFreqCmd)
  5.176  MATH         ModFreqCmd = RINFE(@SWPG_ProgSecName, "FM_ModFreq")
  5.177  MATH         @SWPG_Cmd = REPL("<val>", ModFreq, ModFreqCmd)
  5.178  ENDIF

  5.179  CALL         Sub Send Command /SWPG
  5.180  ENDIF        ; IF Modulation Frequency

# -----  FM Deviation
  5.181  IF           NOT(EMPTY(@SWPG_FM_Dev))
  5.182  MATH         FMDevCmd = RINFE(@SWPG_ProgSecName, "FM_Dev")
  5.183  MATH         @SWPG_Cmd = REPL("<val>", BASE(@SWPG_FM_Dev), FMDevCmd)
  5.184  CALL         Sub Send Command /SWPG
  5.185  ENDIF

# FM On programming command string.
  5.186  MATH         @SWPG_Cmd = RINF(@SWPG_ProgSecName, "FM_ON")

  5.187  IF           NOT(EMPTY(@SWPG_Cmd))
  5.188  CALL         Sub Send Command /SWPG
  5.189  ENDIF

  5.190  ENDIF        ; IF FM

# -----  Phase Modulation  ------------------------

  5.191  IF           NOT(EMPTY(@SWPG_PM))

# -----  Modulation Source
  5.192  IF           NOT(EMPTY(@SWPG_ModSrc))

  5.193  IF           ZCMPI(@SWPG_ModSrc, "Int")
  5.194  MATH         ModSrc = "PM_Int"
  5.195  ELSE

  5.196  IF           ZCMP(@SWPG_ExtCpl, "AC")
  5.197  MATH         ModSrc = "PM_ExtAC"
  5.198  ELSEIF       ZCMP(@SWPG_ExtCpl, "DC")
  5.199  MATH         ModSrc = "PM_ExtDC"
  5.200  ELSE
  5.201  MATH         ModSrc = "PM_Ext"
  5.202  ENDIF

  5.203  ENDIF

  5.204  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, ModSrc)
  5.205  CALL         Sub Send Command /SWPG
  5.206  ENDIF        ; IF Modulation Source

# -----  Modulation Frequency
  5.207  IF           NOT(EMPTY(@SWPG_ModFreq))
  5.208  MATH         ModFreq = BASE(@SWPG_ModFreq); ModFreqCmd = ""

# Use discrete command for 400 Hz Mod. Freq., if one exists.
  5.209  IF           ModFreq == 400
  5.210  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "PM_Int400Hz")
# Otherwise use discrete command for 1 kHz Mod. Freq., if one exists.
  5.211  ELSEIF       ModFreq == 1E+3
  5.212  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "PM_Int1kHz")
  5.213  ENDIF

# Otherwise use the general command.
  5.214  IF           EMPTY(ModFreqCmd)
  5.215  MATH         ModFreqCmd = RINFE(@SWPG_ProgSecName, "PM_ModFreq")
  5.216  MATH         @SWPG_Cmd = REPL("<val>", ModFreq, ModFreqCmd)
  5.217  ENDIF

  5.218  CALL         Sub Send Command /SWPG
  5.219  ENDIF        ; IF Modulation Frequency

# -----  Phase Deviation
  5.220  IF           NOT(EMPTY(@SWPG_PM_Dev))
  5.221  MATH         PMDevCmd = RINFE(@SWPG_ProgSecName, "PM_Dev")
  5.222  MATH         @SWPG_Cmd = REPL("<val>", BASE(@SWPG_PM_Dev), PMDevCmd)
  5.223  CALL         Sub Send Command /SWPG
  5.224  ENDIF

# Get the Phase Modulation On programming command string.
  5.225  MATH         @SWPG_Cmd = RINF(@SWPG_ProgSecName, "PM_ON")

  5.226  IF           NOT(EMPTY(@SWPG_Cmd))
  5.227  CALL         Sub Send Command /SWPG
  5.228  ENDIF

  5.229  ENDIF        ; IF PM

# -----  Pulse Modulation  ------------------------

  5.230  IF           NOT(EMPTY(@SWPG_PL))

# -----  Modulation Source
  5.231  IF           NOT(EMPTY(@SWPG_ModSrc))
# Check modulation source selection capability.
  5.232  MATH         PL_SrcSel = RINF(@SWPG_ProgSecName, "PL_SourceSelect")

  5.233  IF           ZCMPI(PL_SrcSel, "Programmable")

  5.234  IF           ZCMPI(@SWPG_ModSrc, "Int")
  5.235  MATH         ModSrc = "PL_Int"
  5.236  ELSE
  5.237  MATH         ModSrc = "PL_Ext"
  5.238  ENDIF

  5.239  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, ModSrc)
  5.240  CALL         Sub Send Command /SWPG

  5.241  ELSEIF       ZCMPI(PL_SrcSel, "Fixed")
  5.242  MATH         PL_FxdSource = RINFE(@SWPG_ProgSecName, "PL_Source")

  5.243  IF           NOT(ZCMPI(PL_FxdSource, @SWPG_ModSrc))
  5.244  DISP         The required Pulse Modulation Source ([V @SWPG_ModSrc])
  5.244  DISP         capability is not supported for the configured
  5.244  DISP         [V @SWPG_DevName].
  5.244  DISP
  5.244  DISP         [V @SWPG_DevName] only supports fixed ([V PL_FxdSource])
  5.244  DISP         source for pulse modulation.  The calling procedure
  5.244  DISP         requires an "[V @SWPG_ModSrc]" source.
  5.244  DISP
  5.244  DISP         Select "Terminate" to abort this procedure, configure
  5.244  DISP         a suitable SWPG model, then restart this procedure.
  5.245  END
  5.246  ENDIF

  5.247  ELSE
  5.248  DISP         The required Pulse Modulation Source ([V @SWPG_ModSrc])
  5.248  DISP         capability is not supported for the configured
  5.248  DISP         [V @SWPG_DevName].
  5.248  DISP
  5.248  DISP         This may be due to a lack of hardware capability, or
  5.248  DISP         lack of support within user_config_instr.ini.
  5.248  DISP
  5.248  DISP         Select "Terminate" to abort this procedure.  Either
  5.248  DISP         configure a suitable SWPG model or add the required
  5.248  DISP         parameters to user_config_instr.ini, then restart this
  5.248  DISP         procedure.
  5.249  END
  5.250  ENDIF        ; PL Source Selection

  5.251  ENDIF        ; NOT(EMPTY(@SWPG_ModSrc))

# -----  Modulation Frequency
  5.252  IF           NOT(EMPTY(@SWPG_ModFreq))
  5.253  MATH         ModFreq = BASE(@SWPG_ModFreq); ModFreqCmd = ""

# Use discrete command for 400 Hz Mod. Freq., if one exists.
  5.254  IF           ModFreq == 400
  5.255  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "PL_Int400Hz")
# Otherwise use discrete command for 1 kHz Mod. Freq., if one exists.
  5.256  ELSEIF       ModFreq == 1E+3
  5.257  MATH         ModFreqCmd = RINF(@SWPG_ProgSecName, "PL_Int1kHz")
  5.258  ENDIF

# Otherwise use the general Mod. Freq. command.
  5.259  IF           EMPTY(ModFreqCmd)
  5.260  MATH         ModFreqCmd = RINFE(@SWPG_ProgSecName, "PL_ModFreq")
  5.261  MATH         @SWPG_Cmd = REPL("<val>", ModFreq, ModFreqCmd)
  5.262  ENDIF

  5.263  CALL         Sub Send Command /SWPG
  5.264  ENDIF        ; IF Modulation Frequency

# -----  Pulse Width
  5.265  IF           NOT(EMPTY(@SWPG_PL_Width))
  5.266  MATH         PLWidthCmd = RINFE(@SWPG_ProgSecName, "PL_Width")
  5.267  MATH         PLWidth = BASE(@SWPG_PL_Width)
  5.268  MATH         @SWPG_Cmd = REPL("<val>", PLWidth, PLWidthCmd)
  5.269  CALL         Sub Send Command /SWPG
  5.270  ENDIF

# -----  Pulse Delay
  5.271  IF           NOT(EMPTY(@SWPG_PL_Delay))
  5.272  MATH         PLDelayCmd = RINFE(@SWPG_ProgSecName, "PL_Delay")
  5.273  MATH         PLDelay = BASE(@SWPG_PL_Delay)
  5.274  MATH         @SWPG_Cmd = REPL("<val>", PLDelay, PLDelayCmd)
  5.275  CALL         Sub Send Command /SWPG
  5.276  ENDIF

# -----  Pulse Impedance
  5.277  IF           NOT(EMPTY(@SWPG_PL_Imp))
  5.278  MATH         PLImpCmd = RINF(@SWPG_ProgSecName, "PL_Imp")
  5.279  MATH         PLImp = BASE(@SWPG_PL_Imp)
  5.280  MATH         @SWPG_Cmd = REPL("<val>", PLImp, PLImpCmd)
  5.281  CALL         Sub Send Command /SWPG
  5.282  ENDIF        ; IF Pulse Impedance

# -----  Pulse Slope
  5.283  IF           NOT(EMPTY(@SWPG_PL_Slope))

  5.284  IF           ZCMPI(@SWPG_PL_Slope, "Pos")
  5.285  MATH         PLSlope = "PL_SlopePos"
  5.286  ELSE
  5.287  MATH         PLSlope = "PL_SlopeNeg"
  5.288  ENDIF

  5.289  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, PLSlope)
  5.290  CALL         Sub Send Command /SWPG
  5.291  ENDIF

# -----  Pulse Conditioning
  5.292  IF           NOT(EMPTY(@SWPG_PL_Cond))

  5.293  IF           ZCMPI(@SWPG_PL_Cond, "On")
  5.294  MATH         PLCond = "PL_CondOn"
  5.295  ELSE
  5.296  MATH         PLCond = "PL_CondOff"
  5.297  ENDIF

  5.298  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, PLCond)
  5.299  CALL         Sub Send Command /SWPG
  5.300  ENDIF

# Get the Pulse Modulation On programming command string.
  5.301  MATH         @SWPG_Cmd = RINF(@SWPG_ProgSecName, "PL_ON")

  5.302  IF           NOT(EMPTY(@SWPG_Cmd))
  5.303  CALL         Sub Send Command /SWPG
  5.304  ENDIF

  5.305  ENDIF        ; NOT(EMPTY(@SWPG_PL))

# -----  Reference Oscillator  --------------------

  5.306  IF           NOT(EMPTY(@SWPG_ROSC))

  5.307  IF           ZCMPI(@SWPG_ROSC, "Int")
  5.308  MATH         RefOsc = "RefOscInt"
  5.309  ELSE
  5.310  MATH         RefOsc = "RefOscExt"
  5.311  ENDIF

  5.312  MATH         RefSelect = RINF(@SWPG_ProgSecName, "RefSelect")

  5.313  IF           ZCMPI(RefSelect, "Manual")

# Only prompt for switch selection when the desired setting does not match the
# current setting.
  5.314  IF           NOT(ZCMPI(@SWPG_ROSC, @SWPG_ROSC_Set))
  5.315  MATH         Switch  = RINFE(@SWPG_ProgSecName, "RefOscSwitch")
  5.316  MATH         Setting = RINFE(@SWPG_ProgSecName, RefOsc)
  5.317  DISP         Set [V @SWPG_DevName] [V Switch] switch to [V Setting].
  5.317  DISP         [7][D250][7][D250][7][D250][7][D250][7]
  5.318  MATH         @SWPG_ROSC_Set = @SWPG_ROSC
  5.319  ENDIF        ; Prompt to set Reference Oscillator switch

  5.320  ELSEIF       ZCMPI(RefSelect, "Auto")
# Automatic selection; nothing to do.

  5.321  ELSE
  5.322  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, RefOsc)
  5.323  CALL         Sub Send Command /SWPG
  5.324  ENDIF

  5.325  ENDIF        ; End Apply Reference Oscillator

# -----  Leveling  --------------------------------

  5.326  IF           NOT(EMPTY(@SWPG_Leveling))

  5.327  IF           ZCMPI(@SWPG_Leveling, "Pwr")
  5.328  MATH         Leveling = "LevelPwr"
  5.329  ELSEIF       ZCMPI(@SWPG_Leveling, "Ext")
  5.330  MATH         Leveling = "LevelExt"
  5.331  ELSE
  5.332  MATH         Leveling = "LevelInt"
  5.333  ENDIF

  5.334  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, Leveling)
  5.335  CALL         Sub Send Command /SWPG
  5.336  ENDIF        ; IF Leveling

# -----  Output On  -------------------------------

  5.337  MATH         @SWPG_Cmd = RINF(@SWPG_ProgSecName, "OutputOn")

# If "Output_On" is defined, send the command.
  5.338  IF           NOT(EMPTY(@SWPG_Cmd))
  5.339  CALL         Sub Send Command /SWPG
  5.340  ENDIF

# -----  Sweep Start  -----------------------------

  5.341  IF           NOT(EMPTY(@SWPG_SweepStart))

  5.342  IF           ZCMPI(@SWPG_SweepStart, "Single")
  5.343  MATH         SweepStart = "SweepSingle"
  5.344  ELSE
  5.345  MATH         SweepStart = "SweepCont"
  5.346  ENDIF

  5.347  MATH         @SWPG_Cmd = RINFE(@SWPG_ProgSecName, SweepStart)
  5.348  CALL         Sub Send Command /SWPG
  5.349  ENDIF

  5.350  END

  5.351  EVAL   Increment test number


# =====  Sub Get Options /SWPG  =============================================

  6.001  LABEL        GET_OPTIONS

# Check for the variable flag that indicates whether options have previously
# been configured.  This flag will prevent the driver from asking for option
# configuration more than once.  Initialize variable if it does not exist.
  6.002  IF           NOT(ISVAR("@SWPG_Opt_Set"))
  6.003  MATH         @SWPG_FreqOpt = ""; @SWPG_AmplOpt = ""

# Check for Fluke 6080A/82A fitted options.
  6.004  MATH         F608x = FINDI(@SWPG_DevName, "6080", 1)
  6.005  MATH         F608x = FINDI(@SWPG_DevName, "6082", 1) || F608x

  6.006  IF           F608x
  6.007  OPBR         -z The Fluke 6080A/82A Synthesized RF Signal Generators
  6.007  OPBR         Sweepers may include Options -130 or -132 that affect
  6.007  OPBR         its frequency specifications.
  6.007  OPBR
  6.007  OPBR         Does the configured unit have either Option -130 or
  6.007  OPBR         Option -132 fitted?
  6.007  OPBR         [7][D250][7][D250][7][D250][7][D250][7]

  6.008  IF           MEM1
  6.009  OPBR         -z Does the configured unit have Option -130 fitted?

  6.010  IF           MEM1
  6.011  MATH         @SWPG_FreqOpt = "130"
  6.012  ELSE
  6.013  MATH         @SWPG_FreqOpt = "132"
  6.014  ENDIF

  6.015  ENDIF

  6.016  ENDIF        ; F608x

# Check for HP 8340/8341 fitted options.
  6.017  MATH         HP834x = FINDI(@SWPG_DevName, "8340", 1)
  6.018  MATH         HP834x = FINDI(@SWPG_DevName, "8341", 1) || HP834x

  6.019  IF           HP834x
  6.020  OPBR         -z The HP 8340/8341 Synthesized Sweepers may include
  6.020  OPBR         Options 001, 004, or 005 that affects amplitude
  6.020  OPBR         specifications. (The above options are mutually
  6.020  OPBR         exclusive.)
  6.020  OPBR
  6.020  OPBR         Does the configured unit have any of the above
  6.020  OPBR         options fitted?
  6.020  OPBR         [7][D250][7][D250][7][D250][7][D250][7]

  6.021  IF           MEM1

  6.022  DO
  6.023  MEMI         Enter the fitted option number (001, 004, 005):
# Format option correctly for use in mode string.
  6.024  MATH         Opt = FMT(MEM, "%03.0f")
  6.025  UNTIL        (MEM == 1) || (MEM == 4) || (MEM == 5)

  6.026  MATH         @SWPG_AmplOpt = Opt
  6.027  ENDIF

  6.028  ENDIF        ; HP834x

# Check for all HP/Agilent models which have different amplitude accuracy
# when equipped with Option 001.
  6.029  MATH         Opt001_A = FINDI(@SWPG_DevName, "83620", 1)
  6.030  MATH         Opt001_A = FINDI(@SWPG_DevName, "83622", 1) || Opt001_A
  6.031  MATH         Opt001_A = FINDI(@SWPG_DevName, "83623", 1) || Opt001_A
  6.032  MATH         Opt001_A = FINDI(@SWPG_DevName, "83624", 1) || Opt001_A
  6.033  MATH         Opt001_A = FINDI(@SWPG_DevName, "83630", 1) || Opt001_A
  6.034  MATH         Opt001_A = FINDI(@SWPG_DevName, "83640", 1) || Opt001_A
  6.035  MATH         Opt001_A = FINDI(@SWPG_DevName, "83650", 1) || Opt001_A

  6.036  IF           Opt001_A
  6.037  IEEE         [@SWPG]*OPT?[I$]

  6.038  IF           FINDI(MEM2, "001", 1)
  6.039  MATH         @SWPG_AmplOpt = "001"
  6.040  ENDIF

  6.041  ENDIF        ; Opt001_A

# Check for HP 8648A/B/C/D fitted options.
  6.042  IF           FINDI(@SWPG_DevName, "8648", 1)
  6.043  OPBR         -z The HP 8648A/B/C/D Synthesized Signal Generators
  6.043  OPBR         may include Option 1E5 that affects frequency
  6.043  OPBR         specifications.
  6.043  OPBR
  6.043  OPBR         Does the configured unit have Option 1E5 fitted?
  6.043  OPBR         [7][D250][7][D250][7][D250][7][D250][7]

  6.044  IF           MEM1
  6.045  MATH         @SWPG_FreqOpt = "1E5"
  6.046  ENDIF

  6.047  ENDIF

# Check for all HP/Agilent models which have different frequency accuracy
# when equipped with Option 001.
  6.048  MATH         Opt001_F = FINDI(@SWPG_DevName, "8656", 1)
  6.049  MATH         Opt001_F = FINDI(@SWPG_DevName, "8657", 1) || Opt001_F

  6.050  IF           Opt001_F
  6.051  OPBR         -z The [V @SWPG_DevName] may include Option 001,
  6.051  OPBR         which affects frequency specifications.
  6.051  OPBR
  6.051  OPBR         Does the configured unit have Option 001 fitted?
  6.051  OPBR         [7][D250][7][D250][7][D250][7][D250][7]

  6.052  IF           MEM1
  6.053  MATH         @SWPG_FreqOpt = "001"
  6.054  ENDIF

  6.055  ENDIF        ; Opt001_F

# Check for R&S SMF100A fitted options.
  6.056  IF           FINDI(@SWPG_DevName, "SMF100A", 1)
  6.057  SCPI         [@SWPG]*OPT?[I$]

  6.058  IF           FINDI(MEM2, "SMF-B1,", 0)
  6.059  MATH         @SWPG_FreqOpt = "SMF-B1"
  6.060  ENDIF

  6.061  ENDIF        ; SMF100A

# Set flag indicating that options have already been configured.
  6.062  MATH         @SWPG_Opt_Set = 1
  6.063  ENDIF        ; NOT(@SWPG_Opt_Set)

  6.064  END

  6.065  EVAL   Increment Step Number


# =====  Sub Get Accuracy /SWPG  ============================================

  7.001  LABEL        GET_ACCURACY

# -----  Cardinal Point: Frequency  ---------------
  7.002  IF           ZCMPI(@SWPG_CPT, "Freq")
# Specify Nominal value of parameter.
  7.003  MATH         Nominal = @SWPG_Freq
# Specify third and fourth ACCV2 arguments (level and frequency).
  7.004  MATH         L[3] = BASE(@SWPG_Freq)
  7.005  MATH         L[4] = BASE(@SWPG_Ampl)
# Specify SWPG frequency mode string in AccMode from ini file.
  7.006  MATH         AccMode = RINFE(@SWPG_DevName, "ModeStringFreq")

# Check for options that affect frequency.
  7.007  IF           NOT(EMPTY(@SWPG_FreqOpt))
# Append option to mode string.
  7.008  MATH         AccMode = AccMode & " " & @SWPG_FreqOut
  7.009  ENDIF

# -----  Cardinal Point: Amplitude  ---------------
  7.010  ELSEIF       ZCMPI(@SWPG_CPT, "Ampl")

  7.011  MATH         Nominal = @SWPG_Ampl
  7.012  MATH         L[3] = BASE(@SWPG_Ampl)
  7.013  MATH         L[4] = BASE(@SWPG_Freq)
  7.014  MATH         AccMode = RINFE(@SWPG_DevName, "ModeStringAmpl")

  7.015  IF           NOT(EMPTY(@SWPG_AmplOpt))
  7.016  MATH         AccMode = AccMode & " " & @SWPG_AmplOut
  7.017  ENDIF

# -----  Cardinal Point: Flatness  ----------------
  7.018  ELSEIF       ZCMPI(@SWPG_CPT, "Flat")

  7.019  MATH         Nominal = @SWPG_Ampl
  7.020  MATH         L[3] = BASE(@SWPG_Ampl)
  7.021  MATH         L[4] = BASE(@SWPG_Freq)
  7.022  MATH         AccMode = RINFE(@SWPG_DevName, "ModeStringFlat")

  7.023  IF           NOT(EMPTY(@SWPG_AmplOpt))
  7.024  MATH         AccMode = AccMode & " " & @SWPG_AmplOut
  7.025  ENDIF

  7.026  ENDIF

# Retrieve SWPG accuracy at desired nominal parameter.
  7.027  MATH         Acc = ACCV2(@SWPG_DevName, AccMode, L[3], L[4])
  7.028  MATH         Confidence = VGET("CONF")

# VGET query returns empty string if CONF is set to default (2).
  7.029  IF           EMPTY(Confidence)
  7.030  MATH         Confidence = 2
  7.031  ENDIF

  7.032  MATH         Acc = (Acc / CONF(@SWPG_DevName)) * Confidence

# Convert to specified units of ACC nominal, e.g., GHz.
  7.033  MATH         @SWPG_Acc = Acc / PSCALE(Nominal)

  7.034  END
