﻿Copyright (c) 2021 Fluke Calibration                        MET/CAL Procedure
=============================================================================
INSTRUMENT:            Sub Initialize /LFCTR
INSTRUMENT:            Sub Reset /LFCTR
INSTRUMENT:            Sub Measure /LFCTR
INSTRUMENT:            Sub Setup /LFCTR
INSTRUMENT:            Sub Read /LFCTR
INSTRUMENT:            Sub Get Accuracy /LFCTR
DATE:                  2021-08-25 11:57:44
AUTHOR:                Fluke
REVISION:              $Revision: 30707 $
ADJUSTMENT THRESHOLD:  70%
NUMBER OF TESTS:       5
NUMBER OF LINES:       838
CONFIGURATION:         Low Frequency Counter
=============================================================================
#
#  Procedure Author:
#        DAC, DFM
#
#  Compatibility:
#        MET/CAL 7.2 or later
#
#  Subprocedures:
#        None
#
#  Required Files:
#        user_config_instr.ini
#
#  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
#  -----------------------  -------------------------------------------------
#  @LFCTR_Func              FreqCh1 | FreqCh2 | FreqChHF
#                           PeriodCh1 | PeriodCh2 |
#                           FreqRatioCh1/2 | FreqRatioCh2/1 |
#                           PosPulseWidthCh1 | PosPulseWidthCh2 |
#                           NegPulseWidthCh1 | NegPulseWidthCh2 |
#                           TimeIntCh1-2 | TimeIntCh2-1 |
#                           TotalizeManualCh1 | TotalalizeManualCh2 |
#                           PhaseCh1-2 | PhaseCh2-1 |
#                           DutyCycleCh1 | DutyCycleCh2 |
#                           RiseTimeCh1 | RiseTimeCh2 |
#                           FallTimeCh1 | FallTimeCh2 |
#                           VminCh1 | VminCh2 |
#                           VmaxCh1 | VmaxCh2 |
#                           VppCh1 | VppCh2
#
#  @LFCTR_Ampl              <NR3>[][<prefix>]V | Vp | Vpp (for accuracy only)
#
#  @LFCTR_ArmFreqStart      Imm | Ext
#
#  @LFCTR_ArmFreqStop       Imm | Ext
#
#  @LFCTR_ArmPhaseStart     Imm | Ext
#
#  @LFCTR_ArmTotalizeStart  Imm | Ext
#
#  @LFCTR_ArmTotalizeStop   Imm | Ext
#
#  @LFCTR_ArmTimeIntStart   Imm | Ext
#
#  @LFCTR_ArmTimeIntStop    Imm | Ext
#
#  @LFCTR_Ch1Attn           x1 | x10
#
#  @LFCTR_Ch2Attn           x1 | x10
#
#  @LFCTR_Ch1Cpl            AC | DC
#
#  @LFCTR_Ch2Cpl            AC | DC
#
#  @LFCTR_Ch1Slope          Pos | Neg
#
#  @LFCTR_Ch2Slope          Pos | Neg
#
#  @LFCTR_Ch1Lvl            <NR3>[][<prefix>]V
#
#  @LFCTR_Ch2Lvl            <NR3>[][<prefix>]V
#
#  @LFCTR_Ch1Hyst           <NR3>[]%
#
#  @LFCTR_Ch2Hyst           <NR3>[]%
#
#  @LFCTR_Ch1Imp            LoZ | HiZ
#
#  @LFCTR_Ch2Imp            LoZ | HiZ
#
#  @LFCTR_Ch1Lpf            On | Off
#
#  @LFCTR_COM               On | Off
#
#  @LFCTR_MeasTime          <NR3>[][<prefix>]s
#
#  @LFCTR_ROSC              Int | Ext
#
#  Example Usage:
#
#    Measure frequency on channel 1
#
#      1.001  CALL      Sub Initialize /LFCTR
#      1.002  MATH      @LFCTR_Func = "FreqCh1"
#      1.003  TARGET    -p
#      1.004  CALL      Sub Reset /LFCTR
#      1.005  CALL      Sub Setup /LFCTR
#      1.007  DISP      Connect the DUT to [V @LFCTR_DevName] [V @LFCTR_Ch1]
#      1.008  DISP      Set DUT to output 1 kHz @ 1 Vpp.
#      1.009  TARGET    -m
#      1.010  CALL      Sub Read /LFCTR
#
 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         SETUP                        PSUBI("Measure")
  1.004  JMPL         SETUP                        PSUBI("Setup")
  1.005  JMPL         READ                         PSUBI("Read")
  1.006  JMPL         GET_ACCURACY                 PSUBI("Get Accuracy")
  1.007  DISP         Subprocedure not found!
  1.008  END

  1.009  EVAL   Increment test number

# =============================== Initialize =================================

  2.001  LABEL        INITIALIZE
# Get and store device name.
  2.002  MATH         @LFCTR_DevName = INSTR("LFCTR")
# Get and store confidence.
  2.003  MATH         @LFCTR_Conf = CONF(@LFCTR_DevName)

# Get and store programming section name.
  2.004  MATH         Parameter = "ProgSecName"
  2.005  MATH         @LFCTR_ProgSecName = RINFE(@LFCTR_DevName, Parameter)

  2.006  MATH         @LFCTR_MaxFreqCh1 = RINFE(@LFCTR_DevName, "MaxFreqCh1")
# Use RINF instead of RINFE because some counters don't have a channel 2.
  2.007  MATH         @LFCTR_MaxFreqCh2 = RINF(@LFCTR_DevName, "MaxFreqCh2")

# Get and store FSC.
  2.008  MATH         @LFCTR_FSC = RINFE(@LFCTR_ProgSecName, "FSC")

# Get and store terminal names.
  2.009  MATH         @LFCTR_Ch1    = RINFE(@LFCTR_ProgSecName, "Ch1")
# Use RINF instead of RINFE because some counters have only one channel.
  2.010  MATH         @LFCTR_Ch2    = RINF(@LFCTR_ProgSecName, "Ch2")
# Use RINF instead of RINFE because some counters don't have a prescaler.
  2.011  MATH         @LFCTR_ChHF   = RINF(@LFCTR_ProgSecName, "ChHF")
  2.012  MATH         @LFCTR_RefIn  = RINFE(@LFCTR_ProgSecName, "RefIn")
  2.013  MATH         @LFCTR_RefOut = RINFE(@LFCTR_ProgSecName, "RefOut")
  2.014  MATH         @LFCTR_ExtArm = RINFE(@LFCTR_ProgSecName, "ExtArm")

# Initialize parameters to the empty string (unset).
  2.015  MATH         @LFCTR_Func             = ""
  2.016  MATH         @LFCTR_ArmFreqStart     = ""
  2.017  MATH         @LFCTR_ArmFreqStop      = ""
  2.018  MATH         @LFCTR_ArmPhaseStart    = ""
  2.019  MATH         @LFCTR_ArmTotalizeStart = ""
  2.020  MATH         @LFCTR_ArmTotalizeStop  = ""
  2.021  MATH         @LFCTR_ArmTimeIntStart  = ""
  2.022  MATH         @LFCTR_ArmTimeIntStop   = ""
  2.023  MATH         @LFCTR_Ch1Attn          = ""
  2.024  MATH         @LFCTR_Ch2Attn          = ""
  2.025  MATH         @LFCTR_Ch1Cpl           = ""
  2.026  MATH         @LFCTR_Ch2Cpl           = ""
  2.027  MATH         @LFCTR_Ch1Slope         = ""
  2.028  MATH         @LFCTR_Ch2Slope         = ""
  2.029  MATH         @LFCTR_Ch1Lvl           = ""
  2.030  MATH         @LFCTR_Ch2Lvl           = ""
  2.031  MATH         @LFCTR_Ch1Hyst          = ""
  2.032  MATH         @LFCTR_Ch2Hyst          = ""
  2.033  MATH         @LFCTR_Ch1Imp           = ""
  2.034  MATH         @LFCTR_Ch2Imp           = ""
  2.035  MATH         @LFCTR_Ch1Lpf           = ""
  2.036  MATH         @LFCTR_COM              = ""
  2.037  MATH         @LFCTR_MeasTime         = ""
  2.038  MATH         @LFCTR_ROSC             = ""
# These parameters are only used for accuracy file lookup.
  2.039  MATH         @LFCTR_Ampl             = 0;
  2.040  MATH         @LFCTR_Freq             = 0;
# Unset flag to trigger operator message to manually select reference source.
  2.041  MATH         @LFCTR_ROSC_Set         = 0

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

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

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

  2.049  ENDIF

  2.050  END

  2.051  EVAL   Increment test number

# ================================= Reset ====================================

  3.001  LABEL        RESET
  3.002  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, "Reset")
  3.003  CALL         Sub Send Command /LFCTR
  3.004  END

  3.005  EVAL   Increment test number

# ============================== Setup or Measure ============================

  4.001  LABEL        SETUP

# -----  Function

  4.002  MATH         @LFCTR_Cmd = ""

# If the procedure specfies @LFCTR_COM = "On" and @LFCTR_Func = "TimeIntCh1-2"
# the driver checks to see if the configured LFCTR supports "TimeIntCh1-1" in
# lieu of "TimeIntCh1-2" (as is the case of the PM 6690 vs. the PM 6680). The
# converse is true if @LFCTR_Func = "TimeIntCh2-1". In that case, the driver
# checks to see if the configured LFCTR supports "TimeIntCh2-2".

  4.003  IF           ZCMPI(@LFCTR_COM, "On")

  4.004  IF           ZCMPI(@LFCTR_Func, "TimeIntCh1-2")
  4.005  MATH         @LFCTR_Cmd = RINF(@LFCTR_ProgSecName, "TimeIntCh1-1")
  4.006  ELSEIF       ZCMPI(@LFCTR_Func, "TimeIntCh2-1")
  4.007  MATH         @LFCTR_Cmd = RINF(@LFCTR_ProgSecName, "TimeIntCh2-2")
  4.008  ENDIF

  4.009  ENDIF

  4.010  IF           EMPTY(@LFCTR_Cmd)
  4.011  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, @LFCTR_Func)
  4.012  ENDIF
  4.013  CALL         Sub Send Command /LFCTR

# -----  Measurement Time

  4.014  IF           NOT(EMPTY(@LFCTR_MeasTime))
  4.015  MATH         Cmd = RINFE(@LFCTR_ProgSecName, "MeasTime")
# Convert to base units and insert in programming string.
  4.016  MATH         @LFCTR_Cmd = REPL("<val>", BASE(@LFCTR_MeasTime), Cmd)
  4.017  CALL         Sub Send Command /LFCTR
  4.018  ENDIF

# -----  Reference Oscillator

  4.019  IF           NOT(EMPTY(@LFCTR_ROSC))

  4.020  IF           ZCMPI(@LFCTR_ROSC, "Int")
  4.021  MATH         RefOsc = "RefOscInt"
  4.022  ELSE
  4.023  MATH         RefOsc = "RefOscExt"
  4.024  ENDIF

  4.025  MATH         RefSelect = RINF(@LFCTR_ProgSecName, "RefSelect")

  4.026  IF           ZCMPI(RefSelect, "Manual")

  4.027  IF           NOT(@LFCTR_ROSC_Set)
  4.028  MATH         Switch = RINFE(@LFCTR_ProgSecName, "RefOscSwitch")
  4.029  MATH         Setting = RINFE(@LFCTR_ProgSecName, RefOsc)
  4.030  DISP         Set [V @LFCTR_DevName] [V Switch] switch to [V Setting].
  4.031  MATH         @LFCTR_ROSC_Set = 1
  4.032  ENDIF        ; Prompt to set Reference Oscillator switch

  4.033  ELSEIF       ZCMPI(RefSelect, "Auto")
#                     Automatic selection.  Nothing to do.
  4.034  ELSE
  4.035  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, RefOsc)
  4.036  CALL         Sub Send Command /LFCTR
  4.037  ENDIF

  4.038  ENDIF        ; IF Reference Oscillator

# -----  Arming

# Determine applicable arming parameters based on function.
  4.039  MATH         L[1] = ZCMPI(@LFCTR_Func, "FreqCh1")
  4.040  MATH         L[1] = ZCMPI(@LFCTR_Func, "FreqCh2")        || L[1]
  4.041  MATH         L[1] = ZCMPI(@LFCTR_Func, "FreqChHF")       || L[1]
  4.042  MATH         L[1] = ZCMPI(@LFCTR_Func, "PeriodCh1")      || L[1]
  4.043  MATH         L[1] = ZCMPI(@LFCTR_Func, "PeriodCh2")      || L[1]
  4.044  MATH         L[1] = ZCMPI(@LFCTR_Func, "FreqRatioCh1/2") || L[1]
  4.045  MATH         L[1] = ZCMPI(@LFCTR_Func, "FreqRatioCh2/1") || L[1]

  4.046  MATH         L[2] = ZCMPI(@LFCTR_Func, "PhaseCh1-2")
  4.047  MATH         L[2] = ZCMPI(@LFCTR_Func, "PhaseCh2-1") || L[2]

  4.048  MATH         L[3] = ZCMPI(@LFCTR_Func, "TotalizeManualCh1")
  4.049  MATH         L[3] = ZCMPI(@LFCTR_Func, "TotalalizeManualCh2") || L[3]

  4.050  MATH         L[4] = ZCMPI(@LFCTR_Func, "TimeIntCh1-2")
  4.051  MATH         L[4] = ZCMPI(@LFCTR_Func, "TimeIntCh2-1")     || L[4]
  4.052  MATH         L[4] = ZCMPI(@LFCTR_Func, "RiseTimeCh1")      || L[4]
  4.053  MATH         L[4] = ZCMPI(@LFCTR_Func, "RiseTimeCh2")      || L[4]
  4.054  MATH         L[4] = ZCMPI(@LFCTR_Func, "FallTimeCh1")      || L[4]
  4.055  MATH         L[4] = ZCMPI(@LFCTR_Func, "FallTimeCh2")      || L[4]
  4.056  MATH         L[4] = ZCMPI(@LFCTR_Func, "PosPulseWidthCh1") || L[4]
  4.057  MATH         L[4] = ZCMPI(@LFCTR_Func, "PosPulseWidthCh2") || L[4]
  4.058  MATH         L[4] = ZCMPI(@LFCTR_Func, "NegPulseWidthCh1") || L[4]
  4.059  MATH         L[4] = ZCMPI(@LFCTR_Func, "NegPulseWidthCh2") || L[4]
  4.060  MATH         L[4] = ZCMPI(@LFCTR_Func, "DutyCycleCh1")     || L[4]
  4.061  MATH         L[4] = ZCMPI(@LFCTR_Func, "DutyCycleCh2")     || L[4]

# Frequency, Period, or Ratio
  4.062  IF           L[1]

  4.063  IF           NOT(EMPTY(@LFCTR_ArmFreqStart))

  4.064  IF           ZCMPI(@LFCTR_ArmFreqStart, "Ext")
  4.065  MATH         Arm = "ArmFreqStartExt"
  4.066  ELSE
  4.067  MATH         Arm = "ArmFreqStartImm"
  4.068  ENDIF

  4.069  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.070  CALL         Sub Send Command /LFCTR
  4.071  ENDIF

  4.072  IF           NOT(EMPTY(@LFCTR_ArmFreqStop))

  4.073  IF           ZCMPI(@LFCTR_ArmFreqStop, "Ext")
  4.074  MATH         Arm = "ArmFreqStopExt"
  4.075  ELSE
  4.076  MATH         Arm = "ArmFreqStopImm"
  4.077  ENDIF

  4.078  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.079  CALL         Sub Send Command /LFCTR
  4.080  ENDIF

# Phase
  4.081  ELSEIF       L[2]

  4.082  IF           NOT(EMPTY(@LFCTR_ArmPhaseStart))

  4.083  IF           ZCMPI(@LFCTR_ArmPhaseStart, "Ext")
  4.084  MATH         Arm = "ArmPhaseStartExt"
  4.085  ELSE
  4.086  MATH         Arm = "ArmPhaseStartImm"
  4.087  ENDIF

  4.088  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.089  CALL         Sub Send Command /LFCTR
  4.090  ENDIF

# Totalize
  4.091  ELSEIF       L[3]

  4.092  IF           NOT(EMPTY(@LFCTR_ArmTotalizeStart))

  4.093  IF           ZCMPI(@LFCTR_ArmTotalizeStart, "Ext")
  4.094  MATH         Arm = "ArmTotalizeStartExt"
  4.095  ELSE
  4.096  MATH         Arm = "ArmTotalizeStartImm"
  4.097  ENDIF

  4.098  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.099  CALL         Sub Send Command /LFCTR
  4.100  ENDIF

  4.101  IF           NOT(EMPTY(@LFCTR_ArmTotalizeStop))

  4.102  IF           ZCMPI(@LFCTR_ArmTotalizeStop, "Ext")
  4.103  MATH         Arm = "ArmTotalizeStopExt"
  4.104  ELSE
  4.105  MATH         Arm = "ArmTotalizeStopImm"
  4.106  ENDIF

  4.107  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.108  CALL         Sub Send Command /LFCTR
  4.109  ENDIF

# Time Interval, Rise Time, Fall Time, +/-Pulse Width, Duty Cycle
  4.110  ELSEIF       L[4]

  4.111  IF           NOT(EMPTY(@LFCTR_ArmTimeIntStart))

  4.112  IF           ZCMPI(@LFCTR_ArmTimeIntStart, "Ext")
  4.113  MATH         Arm = "ArmTimeIntStartExt"
  4.114  ELSE
  4.115  MATH         Arm = "ArmTimeIntStartImm"
  4.116  ENDIF

  4.117  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.118  CALL         Sub Send Command /LFCTR
  4.119  ENDIF

  4.120  IF           NOT(EMPTY(@LFCTR_ArmTimeIntStop))

  4.121  IF           ZCMPI(@LFCTR_ArmTimeIntStop, "Ext")
  4.122  MATH         Arm = "ArmTimeIntStopExt"
  4.123  ELSE
  4.124  MATH         Arm = "ArmTimeIntStopImm"
  4.125  ENDIF

  4.126  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Arm)
  4.127  CALL         Sub Send Command /LFCTR
  4.128  ENDIF

  4.129  ENDIF        ; L[1]

# -----  Channel 1 Input Impedance

  4.130  IF           NOT(EMPTY(@LFCTR_Ch1Imp))

  4.131  IF           ZCMPI(@LFCTR_Ch1Imp, "LoZ")
  4.132  MATH         Imp = "Ch1Imp50_Ohm"; ImpVal = 50
  4.133  ELSE
  4.134  MATH         Imp = "Ch1Imp1_MOhm"; ImpVal = 1E+6
  4.135  ENDIF

# See if channel 1 input impedance is fixed.
  4.136  MATH         FixedImp = RINF(@LFCTR_ProgSecName, "Ch1ImpFixed")

  4.137  IF           EMPTY(FixedImp)
  4.138  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Imp)
  4.139  CALL         Sub Send Command /LFCTR

  4.140  ELSE

# Check to make sure the fixed impedance is the desired impedance.
  4.141  IF           BASE(FixedImp) != ImpVal
  4.142  DISP         [V @LFCTR_DevName] has a [V FixedImp] fixed input
  4.142  DISP         impedance.  Requested input impedance [V ImpVal].
  4.143  END
  4.144  ENDIF

  4.145  ENDIF        ; EMPTY(FixedImp)

  4.146  ENDIF        ; NOT(EMPTY(@LFCTR_Ch1Imp))

# -----  Channel 1 Input Coupling

  4.147  IF           NOT(EMPTY(@LFCTR_Ch1Cpl))

  4.148  IF           ZCMPI(@LFCTR_Ch1Cpl, "AC")
  4.149  MATH         Cpl = "Ch1CplAC"
  4.150  ELSE
  4.151  MATH         Cpl = "Ch1CplDC"
  4.152  ENDIF

  4.153  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Cpl)
  4.154  CALL         Sub Send Command /LFCTR
  4.155  ENDIF

# -----  Channel 1 Input Attenuation

  4.156  IF           NOT(EMPTY(@LFCTR_Ch1Attn))

  4.157  IF           ZCMPI(@LFCTR_Ch1Attn, "x10")
  4.158  MATH         Attn = "Ch1Attn_x10"
  4.159  ELSE
  4.160  MATH         Attn = "Ch1Attn_x1"
  4.161  ENDIF

  4.162  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Attn)
  4.163  CALL         Sub Send Command /LFCTR
  4.164  ENDIF

# -----  Channel 1 Low-pass Filter

  4.165  IF           NOT(EMPTY(@LFCTR_Ch1Lpf))

  4.166  IF           ZCMPI(@LFCTR_Ch1Lpf, "On")
  4.167  MATH         Lpf = "Ch1LpfOn"
  4.168  ELSE
  4.169  MATH         Lpf = "Ch1LpfOff"
  4.170  ENDIF

  4.171  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Lpf)
  4.172  CALL         Sub Send Command /LFCTR
  4.173  ENDIF

# -----  Channel 1 Trigger Slope

  4.174  IF           NOT(EMPTY(@LFCTR_Ch1Slope))

  4.175  IF           ZCMPI(@LFCTR_Ch1Slope, "Pos")
  4.176  MATH         Slope = "Ch1SlopePos"
  4.177  ELSE
  4.178  MATH         Slope = "Ch1SlopeNeg"
  4.179  ENDIF

  4.180  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Slope)
  4.181  CALL         Sub Send Command /LFCTR
  4.182  ENDIF

# -----  Channel 1 Trigger Level

  4.183  IF           NOT(EMPTY(@LFCTR_Ch1Lvl))
  4.184  MATH         Cmd = RINFE(@LFCTR_ProgSecName, "Ch1TrigLevel")
  4.185  MATH         @LFCTR_Cmd = REPL("<val>", BASE(@LFCTR_Ch1Lvl), Cmd)
  4.186  CALL         Sub Send Command /LFCTR
  4.187  ENDIF

# -----  Channel 1 Trigger Hysteresis

  4.188  IF           NOT(EMPTY(@LFCTR_Ch1Hyst))
  4.189  MATH         Cmd = RINFE(@LFCTR_ProgSecName, "Ch1TrigHyst")
  4.190  MATH         @LFCTR_Cmd = REPL("<val>", BASE(@LFCTR_Ch1Hyst), Cmd)
  4.191  CALL         Sub Send Command /LFCTR
  4.192  ENDIF

# -----  Channel 2 Input Impedance

  4.193  IF           NOT(EMPTY(@LFCTR_Ch2Imp))

  4.194  IF           ZCMPI(@LFCTR_Ch2Imp, "LoZ")
  4.195  MATH         Imp = "Ch2Imp50_Ohm"; ImpVal = 50
  4.196  ELSE
  4.197  MATH         Imp = "Ch2Imp1_MOhm"; ImpVal = 1E+6
  4.198  ENDIF

# See if channel 1 input impedance is fixed.
  4.199  MATH         FixedImp = RINF(@LFCTR_ProgSecName, "Ch2ImpFixed")

  4.200  IF           EMPTY(FixedImp)
  4.201  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Imp)
  4.202  CALL         Sub Send Command /LFCTR

  4.203  ELSE

# Check to make sure the fixed impedance is the desired impedance.
  4.204  IF           BASE(FixedImp) != ImpVal
  4.205  DISP         [V @LFCTR_DevName] has a [V FixedImp] fixed input
  4.205  DISP         impedance.  Requested input impedance [V ImpVal].
  4.206  END
  4.207  ENDIF

  4.208  ENDIF        ; EMPTY(FixedImp)

  4.209  ENDIF        ; NOT(EMPTY(@LFCTR_Ch2Imp))

# -----  Channel 2 Input Coupling

  4.210  IF           NOT(EMPTY(@LFCTR_Ch2Cpl))

  4.211  IF           ZCMPI(@LFCTR_Ch2Cpl, "AC")
  4.212  MATH         Cpl = "Ch2CplAC"
  4.213  ELSE
  4.214  MATH         Cpl = "Ch2CplDC"
  4.215  ENDIF

  4.216  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Cpl)
  4.217  CALL         Sub Send Command /LFCTR
  4.218  ENDIF

# -----  Channel 2 Input Attenuation

  4.219  IF           NOT(EMPTY(@LFCTR_Ch2Attn))

  4.220  IF           ZCMPI(@LFCTR_Ch2Attn, "x10")
  4.221  MATH         Attn = "Ch2Attn_x10"
  4.222  ELSE
  4.223  MATH         Attn = "Ch2Attn_x1"
  4.224  ENDIF

  4.225  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Attn)
  4.226  CALL         Sub Send Command /LFCTR
  4.227  ENDIF

# -----  Channel 2 Trigger Slope

  4.228  IF           NOT(EMPTY(@LFCTR_Ch2Slope))

  4.229  IF           ZCMPI(@LFCTR_Ch2Slope, "Pos")
  4.230  MATH         Slope = "Ch2SlopePos"
  4.231  ELSE
  4.232  MATH         Slope = "Ch2SlopeNeg"
  4.233  ENDIF

  4.234  MATH         @LFCTR_Cmd = RINFE(@LFCTR_ProgSecName, Slope)
  4.235  CALL         Sub Send Command /LFCTR
  4.236  ENDIF

# -----  Channel 2 Trigger Level

  4.237  IF           NOT(EMPTY(@LFCTR_Ch2Lvl))
  4.238  MATH         Cmd = RINFE(@LFCTR_ProgSecName, "Ch2TrigLevel")
  4.239  MATH         @LFCTR_Cmd = REPL("<val>", BASE(@LFCTR_Ch2Lvl), Cmd)
  4.240  CALL         Sub Send Command /LFCTR
  4.241  ENDIF

# -----  Channel 2 Trigger Hysteresis

  4.242  IF           NOT(EMPTY(@LFCTR_Ch2Hyst))
  4.243  MATH         Cmd = RINFE(@LFCTR_ProgSecName, "Ch2TrigHyst")
  4.244  MATH         @LFCTR_Cmd = REPL("<val>", BASE(@LFCTR_Ch2Hyst), Cmd)
  4.245  CALL         Sub Send Command /LFCTR
  4.246  ENDIF

# -----  Channel 2 COM (2 via 1)

  4.247  IF           NOT(EMPTY(@LFCTR_COM))

  4.248  IF           ZCMPI(@LFCTR_COM, "Off")
  4.249  MATH         @LFCTR_Cmd = RINF(@LFCTR_ProgSecName, "Ch2ComOff")
  4.250  ELSE
  4.251  MATH         @LFCTR_Cmd = RINF(@LFCTR_ProgSecName, "Ch2ComOn")
  4.252  ENDIF

  4.253  IF           NOT(EMPTY(@LFCTR_Cmd))
  4.254  CALL         Sub Send Command /LFCTR
  4.255  ENDIF

  4.256  ENDIF

# Exit here if Setup.
  4.257  IF           PSUBI("Setup")
  4.258  END
  4.259  ENDIF

# Drop through for Measure.

# ============================== Read or Measure ============================

  4.260  LABEL        READ
# See if there is an initiate command.
  4.261  MATH         @LFCTR_Cmd = RINF(@LFCTR_ProgSecName, "Initiate")

# If there is an initiate command, send it.
  4.262  IF           NOT(EMPTY(@LFCTR_Cmd))
  4.263  CALL         Sub Send Command /LFCTR

# Fluke RF Reference Source must be special cased.
  4.264  MATH         DevName = @LFCTR_DevName
  4.265  MATH         L[1] = ZCMP(DevName, "Fluke 9640A")
  4.266  MATH         L[1] = ZCMP(DevName, "Fluke 9640A-LPN")  || L[1]
  4.267  MATH         L[1] = ZCMP(DevName, "Fluke 9640A-LPNX") || L[1]
  4.268  MATH         L[1] = ZCMP(DevName, "Fluke 96040A")     || L[1]
  4.269  MATH         L[1] = ZCMP(DevName, "Fluke 96270A")     || L[1]

  4.270  IF           L[1]

  4.271  IF           ISVAR("@LFCTR_MeasTime")

  4.272  IF           EMPTY(@LFCTR_MeasTime)
  4.273  DISP         Press Advance measurement completes.
  4.274  ELSE
  4.275  MATH         L[1] = BASE(@LFCTR_MeasTime)

  4.276  IF           L[1] >= 80
  4.277  WAIT         -t 81 Waiting for measurement to complete...
  4.278  ELSEIF       L[1] >= 20
  4.279  WAIT         -t 21 Waiting for measurement to complete...
  4.280  ELSEIF       L[1] >= 2
  4.281  WAIT         -t 3 Waiting for measurement to complete...
  4.282  ENDIF

  4.283  ENDIF        ; EMPTY(@LFCTR_MeasTime)

  4.284  ELSE
  4.285  DISP         Press Advance measurement completes.
  4.286  ENDIF        ; ISVAR("@LFCTR_MeasTime")

  4.287  ENDIF        ; L[1]

  4.288  ENDIF

# See if there is an input terminator.
  4.289  MATH         InputTerm = RINF(@LFCTR_ProgSecName, "InputTerminator")

  4.290  IF           NOT(ZCMP(InputTerm, ""))

  4.291  IF           ZCMPI(InputTerm, "CR")
  4.292  IEEE         [TERM CR]
  4.293  ELSEIF       ZCMPI(InputTerm, "LF") || ZCMPI(InputTerm, "CRLF")
  4.294  IEEE         [TERM LF]
  4.295  ELSE
  4.296  DISP         Flexible driver "LFCTR" does not
  4.296  DISP         support "InputTerminator = [V InputTerm]"
  4.296  DISP         in [91][V @LFCTR_ProgSecName][93] section of
  4.296  DISP         "user_config_instr.ini".
  4.297  ENDIF

  4.298  ENDIF

# See if there is a fetch command.
  4.299  MATH         @LFCTR_Cmd = RINF(@LFCTR_ProgSecName, "Fetch")

# If there is no fetch command simply get the reading.
  4.300  IF           EMPTY(@LFCTR_Cmd)
  4.301  IEEE         [@LFCTR][I]
# Otherwise send the fetch command and get the reading.
  4.302  ELSEIF       ZCMPI(@LFCTR_FSC, "SCPI")
  4.303  SCPI         [@LFCTR][V @LFCTR_Cmd][I]
  4.304  ELSEIF       ZCMPI(@LFCTR_FSC, "IEEE2")
  4.305  IEEE2        [@LFCTR][V @LFCTR_Cmd][I]
  4.306  ELSE
  4.307  IEEE         [@LFCTR][V @LFCTR_Cmd][I]
  4.308  ENDIF

  4.309  END

  4.310  EVAL   Increment test number

#======= Sub Get Accuracy /LFCTR =============================================

  5.001  LABEL        GET_ACCURACY
  5.002  MATH         Dev = @LFCTR_DevName

# Fluke RF Reference Source must be special cased.
  5.003  MATH         L[1] = ZCMP(Dev, "Fluke 9640A")
  5.004  MATH         L[1] = ZCMP(Dev, "Fluke 9640A-LPN")  || L[1]
  5.005  MATH         L[1] = ZCMP(Dev, "Fluke 9640A-LPNX") || L[1]
  5.006  MATH         L[1] = ZCMP(Dev, "Fluke 96040A")     || L[1]
  5.007  MATH         L[1] = ZCMP(Dev, "Fluke 96270A")     || L[1]

  5.008  IF           L[1]
  5.009  MATH         ModeStr = RINFE(Dev, "ModeStringFreqLF")

  5.010  IF           ZCMPI(@LFCTR_ROSC, "Ext")
  5.011  MATH         ModeStr = ModeStr & " Ext"
  5.012  ELSE
  5.013  MATH         ModeStr = ModeStr & " Int"
  5.014  ENDIF

  5.015  MATH         Modifier = BASE(@LFCTR_MeasTime)
  5.016  MATH         @LFCTR_Acc = ACCV2(Dev, ModeStr, @LFCTR_Meas, Modifier)
  5.017  END
  5.018  ENDIF

# External Frequency Reference not supported by "Sub Get Accuracy /LFCTR",
# see "Sub Get Accuracy (Enhanced) /LFCTR".
  5.019  IF           ZCMPI(@LFCTR_ROSC, "Ext")
  5.020  MATH         @LFCTR_Acc = 0
  5.021  END
  5.022  ENDIF

  5.023  MATH         Func = @LFCTR_Func; Dev = @LFCTR_DevName

# Get mode string from user_config_instr.ini file for accuracy lookup.
  5.024  IF           ZCMP(Func, "FreqCh1") || ZCMPI(Func, "FreqCh2")
  5.025  MATH         ModeStr = RINFE(Dev, "ModeStringFreqLF")
  5.026  ELSEIF       ZCMP(Func, "FreqChHF")
  5.027  MATH         ModeStr = RINFE(Dev, "ModeStringFreqHF")
  5.028  ELSEIF       FIND(Func, "Period", 0)
  5.029  MATH         ModeStr = RINFE(Dev, "ModeStringPerLF")
  5.030  ELSEIF       ZCMP(Func, "FreqRatioCh1/2")
  5.031  MATH         ModeStr = RINFE(Dev, "ModeStringFreqRatio1/2")
  5.032  ELSEIF       ZCMP(Func, "FreqRatioCh2/1")
  5.033  MATH         ModeStr = RINFE(Dev, "ModeStringFreqRatio2/1")
  5.034  ELSEIF       FIND(Func, "PulseWidth", 0)
  5.035  MATH         ModeStr = RINFE(Dev, "ModeStringPulseWidth")
  5.036  ELSEIF       FIND(Func, "TimeInt", 0)
  5.037  MATH         ModeStr = RINFE(Dev, "ModeStringTimeInt")
  5.038  ELSEIF       FIND(Func, "Phase",  0)
  5.039  MATH         ModeStr = RINFE(Dev, "ModeStringPhase")
  5.040  ELSEIF       FIND(Func, "DutyCycle", 0)
  5.041  MATH         ModeStr = RINFE(Dev, "ModeStringDutyCycle")
  5.042  ELSEIF       FIND(Func, "RiseTime", 0) || FIND(Func, "FallTime", 0)
  5.043  MATH         ModeStr = RINFE(Dev, "ModeStringRiseFall")
  5.044  ELSEIF       FIND(Func, "Vmin", 0) || FIND(Func, "Vmax", 0)
  5.045  MATH         ModeStr = RINFE(Dev, "ModeStringVminVmax")
  5.046  ELSEIF       FIND(Func, "Vpp", 0)
  5.047  MATH         ModeStr = RINFE(Dev, "ModeStringVpp")
  5.048  ELSE
  5.049  DISP         "Sub Get Accuracy /LFCTR"
  5.049  DISP
  5.049  DISP         @LFCTR_Func = "[V @LFCTR_Func]" not supported.
  5.050  END
  5.051  ENDIF

# -----  Get accuracy for "Timebase" modes. ---------------------------------
  5.052  IF           FIND(ModeStr, "Timebase", 0)
  5.053  MATH         L[1] = FIND(Func, "DutyCycle",  0)
  5.054  MATH         L[1] = FIND(Func, "RiseTime",   0) || L[1]
  5.055  MATH         L[1] = FIND(Func, "FallTime",   0) || L[1]
  5.056  MATH         L[1] = FIND(Func, "PulseWidth", 0) || L[1]

# Determine the frequency of the input signal.
  5.057  IF           L[1]
  5.058  MATH         Freq = BASE(@LFCTR_Freq)

  5.059  ELSEIF       FIND(@LFCTR_Func, "TimeInt", 0)
  5.060  MATH         Freq = 1 / ABS(@LFCTR_Meas)

  5.061  ELSEIF       FIND(@LFCTR_Func, "Period", 0)
  5.062  MATH         Freq = 1 / @LFCTR_Meas

  5.063  ELSE
  5.064  MATH         Freq = @LFCTR_Meas
  5.065  ENDIF

  5.066  MATH         @LFCTR_Acc = ACCV(Dev, ModeStr, Freq)

# If Period or Time Interval measurement convert to time accuracy.
  5.067  IF           L[2]
  5.068  MATH         @LFCTR_Acc = (@LFCTR_Acc / Freq) * @LFCTR_Meas
  5.069  ENDIF

# -----  Get accuracy for all other modes. ----------------------------------
  5.070  ELSE

# Determine 2nd accuracy file lookup parameter, if applicable.
  5.071  IF           FIND(Func, "VminVmax", 0)
  5.072  MATH         AC = (@LFCTR_Freq > 1)

  5.073  IF           AC
  5.074  MATH         Modifier = BASE(@LFCTR_Freq)
  5.075  ENDIF

  5.076  ELSE
  5.077  MATH         AC = 1

  5.078  IF           FIND(Func, "Vpp", 0)
  5.079  MATH         Modifier = BASE(@LFCTR_Freq)
  5.080  ELSE
  5.081  MATH         Modifier = BASE(@LFCTR_Ampl)
  5.082  ENDIF

  5.083  ENDIF

  5.084  IF           AC
  5.085  MATH         @LFCTR_Acc = ACCV2(Dev, ModeStr, @LFCTR_Meas, Modifier)
  5.086  ELSE
  5.087  MATH         @LFCTR_Acc = ACCV(Dev, ModeStr, @LFCTR_Meas)
  5.088  ENDIF

  5.089  ENDIF        ; FIND(ModeStr, "Timebase", 0)

  5.090  END
