Copyright (c) 2021 Fluke Calibration                        MET/CAL Procedure
=============================================================================
INSTRUMENT:            Sub Initialize /LVLG
INSTRUMENT:            Sub Reset /LVLG
INSTRUMENT:            Sub Output Off /LVLG
INSTRUMENT:            Sub Apply /LVLG
INSTRUMENT:            Sub Get Options /LVLG
INSTRUMENT:            Sub Get Accuracy /LVLG
DATE:                  2021-04-30 08:48:24
AUTHOR:                Fluke
REVISION:              $Revision: 30156 $
ADJUSTMENT THRESHOLD:  70%
NUMBER OF TESTS:       7
NUMBER OF LINES:       479
=============================================================================
#
#  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
#  ---------------  ---------------------------------------------------------
#  @LVLG_Freq       <NR3>[][<prefix>]Hz
#
#  @LVLG_Ampl       <NR3>[]dBm | <NR3>[][<prefix>]V | <NR3>[][<prefix>]Vp |
#                   <NR3>[][<prefix>]Vpp
#
#  @LVLG_ROSC *     Int | Ext
#
#  NOTES:
#  * Manual selection prompts for rear panel switches will ONLY be displayed
#    when explicitly requesting "Int" or "Ext".  Leaving @LVLG_ROSC blank
#    after calling Sub Initialize will NOT prompt the operator for a change.
#
#  Example Usage:
#
#    Initialize Local Oscillator parameters
#
#      CALL         Sub Initialize /LVLG
#      CALL         Sub Reset /LVLG
#      CALL         Sub Output Off /LVLG
#
#      MATH         @LVLG_Freq     = "500 MHz"
#      MATH         @LVLG_Ampl     = "-10 dBm"
#      CALL         Sub Apply /LVLG
#
#      CALL         Sub Output Off /LVLG
#
 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 /LVLG  ============================================

  2.001  LABEL        INITIALIZE

# Get and store:
#   device name
#   converage 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         @LVLG_DevName = INSTR("LVLG")

  2.003  IF           0
  2.004  MATH         @LVLG_Conf = CONF(@LVLG_DevName)
  2.005  ENDIF

  2.006  MATH         @LVLG_ProgSecName = RINFE(@LVLG_DevName, "ProgSecName")
  2.007  MATH         @LVLG_FSC    = RINFE(@LVLG_ProgSecName, "FSC")
  2.008  MATH         @LVLG_Output = RINFE(@LVLG_ProgSecName, "Output50_Ohm")
  2.009  MATH         @LVLG_RefIn  = RINFE(@LVLG_ProgSecName, "RefIn")
  2.010  MATH         @LVLG_RefOut = RINFE(@LVLG_ProgSecName, "RefOut")

# Initialize parameters to the empty string (unset).
  2.011  MATH         @LVLG_CPT      = ""
  2.012  MATH         @LVLG_Freq     = ""
  2.013  MATH         @LVLG_Ampl     = ""
  2.014  MATH         @LVLG_ROSC     = ""

# 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.015  IF           NOT(ISVAR("@LVLG_ROSC_Set"))
  2.016  MATH         @LVLG_ROSC_Set   = ""
  2.017  ENDIF

# Check for options that affect accuracy lookup.
  2.018  CALL         Sub Get Options /LVLG

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

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

  2.021  IF           ZCMPI(ResetCmd, "[SDC]")
  2.022  RESET        [@LVLG][SDC]
  2.023  ELSE
  2.024  RESET        [@LVLG][V ResetCmd]
  2.025  ENDIF

  2.026  ENDIF

  2.027  END

  2.028  EVAL   Increment Step Number

# =====  Sub Reset /LVLG  ===================================================

  3.001  LABEL        RESET

  3.002  MATH         @LVLG_Cmd = RINFE(@LVLG_ProgSecName, "Reset")
  3.003  CALL         Sub Send Command /LVLG
  3.004  END

  3.005  EVAL   Increment test number


# =====  Sub Output Off /LVLG  ==============================================

  4.001  LABEL        OUTPUT_OFF

  4.002  MATH         @LVLG_Cmd = RINF(@LVLG_ProgSecName, "OutputOff")

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

  4.006  END

  4.007  EVAL   Increment test number


# =====  Sub Apply /LVLG  ===================================================

  5.001  LABEL        APPLY

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

# Get the command string.
  5.002  MATH         FreqCmd = RINFE(@LVLG_ProgSecName, "Freq")
# Convert to base units and insert in programming string.
  5.003  MATH         @LVLG_Cmd = REPL("<val>", BASE(@LVLG_Freq), FreqCmd)
  5.004  CALL         Sub Send Command /LVLG

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

  5.005  MATH         Ampl = BASE(@LVLG_Ampl); AmplUnits = UNIT(@LVLG_Ampl)
  5.006  MATH         AmplCmd = ""

  5.007  IF           ZCMPI(AmplUnits, "dBm")

# Use discrete command for negative dBm, if one exists.
  5.008  IF           Ampl < 0
  5.009  MATH         AmplCmd = RINF(@LVLG_ProgSecName, "Ampl_dBmNeg")
  5.010  ELSE
# Otherwise use discrete command for positive dBm, if one exists.
  5.011  MATH         AmplCmd = RINF(@LVLG_ProgSecName, "Ampl_dBmPos")
  5.012  ENDIF

# Otherwise use the general command.
  5.013  IF           EMPTY(AmplCmd)
  5.014  MATH         AmplCmd = RINFE(@LVLG_ProgSecName, "Ampl_dBm")
  5.015  ELSEIF       Ampl < 0
  5.016  MATH         Ampl = ABS(Ampl)
  5.017  ENDIF

  5.018  ELSEIF       ZCMPI(AmplUnits, "V")
  5.019  MATH         AmplCmd = RINFE(@LVLG_ProgSecName, "Ampl_Vrms")
  5.020  ELSEIF       ZCMPI(AmplUnits, "Vp")
  5.021  MATH         AmplCmd = RINF(@LVLG_ProgSecName, "Ampl_Vp")

# If there is no Vp command see if there is a Vpp command.
  5.022  IF           EMPTY(AmplCmd)
  5.023  MATH         AmplCmd = RINFE(@LVLG_ProgSecName, "Ampl_Vpp")
# Convert Vp to Vpp.
  5.024  MATH         Ampl = Ampl * 2
  5.025  ENDIF

  5.026  ELSEIF       ZCMPI(AmplUnits, "Vpp")
  5.027  MATH         AmplCmd = RINF(@LVLG_ProgSecName, "Ampl_Vpp")

# If there is no Vpp command see if there is a Vp command.
  5.028  IF           EMPTY(AmplCmd)
  5.029  MATH         AmplCmd = RINFE(@LVLG_ProgSecName, "Ampl_Vp")
# Convert Vpp to Vp.
  5.030  MATH         Ampl = Ampl / 2
  5.031  ENDIF

  5.032  ENDIF

  5.033  MATH         @LVLG_Cmd = REPL("<val>", Ampl, AmplCmd)
  5.034  CALL         Sub Send Command /LVLG

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

  5.035  IF           NOT(EMPTY(@LVLG_ROSC))

  5.036  IF           ZCMPI(@LVLG_ROSC, "Int")
  5.037  MATH         RefOsc = "RefOscInt"
  5.038  ELSE
  5.039  MATH         RefOsc = "RefOscExt"
  5.040  ENDIF

  5.041  MATH         RefSelect = RINF(@LVLG_ProgSecName, "RefSelect")

  5.042  IF           ZCMPI(RefSelect, "Manual")

# Only prompt for switch selection when the desired setting does not match the
# current setting.
  5.043  IF           NOT(ZCMPI(@LVLG_ROSC, @LVLG_ROSC_Set))
  5.044  MATH         Switch = RINFE(@LVLG_ProgSecName, "RefOscSwitch")
  5.045  MATH         Setting = RINFE(@LVLG_ProgSecName, RefOsc)
  5.046  DISP         Set [V @LVLG_DevName] [V Switch] switch to [V Setting].
  5.046  DISP         [7][D250][7][D250][7][D250][7][D250][7]
  5.047  MATH         @LVLG_ROSC_Set = @LVLG_ROSC
  5.048  ENDIF        ; Prompt to set Reference Oscillator switch

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

  5.050  ELSE
  5.051  MATH         @LVLG_Cmd = RINFE(@LVLG_ProgSecName, RefOsc)
  5.052  CALL         Sub Send Command /LVLG
  5.053  ENDIF

  5.054  ENDIF        ; IF Reference Oscillator

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

  5.055  MATH         @LVLG_Cmd = RINF(@LVLG_ProgSecName, "OutputOn")

# If "Output_On" is defined, send the command.
  5.056  IF           NOT(EMPTY(@LVLG_Cmd))
  5.057  CALL         Sub Send Command /LVLG
  5.058  ENDIF

  5.059  END

  5.060  EVAL   Increment test number


# =====  Sub Get Options /LVLG  =============================================

  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("@LVLG_Opt_Set"))
  6.003  MATH         @LVLG_FreqOpt = ""; @LVLG_AmplOpt = ""

# Check for Fluke 6080A/82A fitted options.
  6.004  MATH         F608x = FINDI(@LVLG_DevName, "6080", 1)
  6.005  MATH         F608x = FINDI(@LVLG_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         @LVLG_FreqOpt = "130"
  6.012  ELSE
  6.013  MATH         @LVLG_FreqOpt = "132"
  6.014  ENDIF

  6.015  ENDIF

  6.016  ENDIF        ; F608x

# Check for HP 8340/8341 fitted options.
  6.017  MATH         HP834x = FINDI(@LVLG_DevName, "8340", 1)
  6.018  MATH         HP834x = FINDI(@LVLG_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         @LVLG_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(@LVLG_DevName, "83620", 1)
  6.030  MATH         Opt001_A = FINDI(@LVLG_DevName, "83622", 1) || Opt001_A
  6.031  MATH         Opt001_A = FINDI(@LVLG_DevName, "83623", 1) || Opt001_A
  6.032  MATH         Opt001_A = FINDI(@LVLG_DevName, "83624", 1) || Opt001_A
  6.033  MATH         Opt001_A = FINDI(@LVLG_DevName, "83630", 1) || Opt001_A
  6.034  MATH         Opt001_A = FINDI(@LVLG_DevName, "83640", 1) || Opt001_A
  6.035  MATH         Opt001_A = FINDI(@LVLG_DevName, "83650", 1) || Opt001_A

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

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

  6.041  ENDIF        ; Opt001_A

# Check for HP 8648A/B/C/D fitted options.
  6.042  IF           FINDI(@LVLG_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         @LVLG_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(@LVLG_DevName, "8656", 1)
  6.049  MATH         Opt001_F = FINDI(@LVLG_DevName, "8657", 1) || Opt001_F

  6.050  IF           Opt001_F
  6.051  OPBR         -z The [V @LVLG_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         @LVLG_FreqOpt = "001"
  6.054  ENDIF

  6.055  ENDIF        ; Opt001_F

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

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

  6.061  ENDIF        ; SMF100A

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

  6.064  END

  6.065  EVAL   Increment Step Number


# =====  Sub Get Accuracy /LVLG  ============================================

  7.001  LABEL        GET_ACCURACY

# If cardinal point parameter is frequency...
  7.002  IF           ZCMPI(@LVLG_CPT, "Freq")
# Specify Nominal value of parameter.
  7.003  MATH         @LVLG_Nominal = @LVLG_Freq
# Specify third (frequency) and fourth (amplitude) ACCV2 arguments.
  7.004  MATH         FreqBase = BASE(@LVLG_Freq)
  7.005  MATH         AmplBase = BASE(@LVLG_Ampl)
# Specify LVLG frequency mode string in ModeStr from ini file.
  7.006  MATH         ModeStr = RINFE(@LVLG_DevName, "ModeStringFreq")

# Check for options that affect frequency.
# If LVLG has options that affect frequency...
  7.007  IF           NOT(EMPTY(@LVLG_FreqOpt))
# Retrieve frequency-affecting options from variable.
# Append option to mode string in ModeStr to specify correct mode string.
  7.008  MATH         ModeStr = ModeStr & " " & @LVLG_FreqOpt
  7.009  ENDIF

# Retrieve LVLG frequency accuracy.
  7.010  MATH         Acc = ACCV2(@LVLG_DevName, ModeStr, FreqBase, AmplBase)

# If cardinal point parameter is amplitude...
  7.011  ELSEIF       ZCMPI(@LVLG_CPT, "Ampl")
# Specify Nominal value of parameter.
  7.012  MATH         @LVLG_Nominal = @LVLG_Ampl
# Specify third and fourth ACCV2 arguments (level and frequency).
  7.013  MATH         FreqBase = BASE(@LVLG_Ampl)
  7.014  MATH         AmplBase = BASE(FreqBase)
# Specify LVLG amplitude mode string in ModeStr from ini file.
  7.015  MATH         ModeStr = RINFE(@LVLG_DevName, "ModeStringAmpl")

# Check for options that affect amplitude.
# If LVLG has options that affect amplitude...
  7.016  IF           NOT(EMPTY(@LVLG_AmplOpt))
# Retrieve amplitude-affecting options from variable.
# Append option to mode string in ModeStr to specify correct mode string.
  7.017  MATH         ModeStr = ModeStr & " " & @LVLG_AmplOpt
  7.018  ENDIF

  7.019  ELSEIF       ZCMPI(@LVLG_CPT, "Flat")
# Specify Nominal value of parameter.
  7.020  MATH         @LVLG_Nominal = @LVLG_Ampl
# Specify third and fourth ACCV2 arguments (level and frequency).
  7.021  MATH         FreqBase = BASE(@LVLG_Ampl)
  7.022  MATH         AmplBase = BASE(FreqBase)
# Specify LVLG amplitude mode string in ModeStr from ini file.
  7.023  MATH         ModeStr = RINFE(@LVLG_DevName, "ModeStringFlat")

# Check for options that affect flatness.
# If LVLG has options that affect flatness...
  7.024  IF           NOT(EMPTY(@LVLG_AmplOpt))
# Retrieve amplitude-affecting options from variable.
# Append option to mode string in ModeStr to specify correct mode string.
  7.025  MATH         ModeStr = ModeStr & " " & LVLG_AmplOpt
  7.026  ENDIF

# Retrieve LVLG amplitude accuracy.
  7.027  MATH         Acc = ACCV2(@LVLG_DevName, ModeStr, AmplBase, FreqBase)
  7.028  ENDIF

  7.029  MATH         Confidence = VGET("CONF")

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

  7.033  MATH         Acc = (Acc / CONF(@LVLG_DevName)) * Confidence
# Convert to specified units of ACC nominal, e.g., GHz.
  7.034  MATH         @LVLG_Acc = Acc / PSCALE(@LVLG_Nominal)

  7.035  END
