; TestController device configuration file for Racal-Dana 1991 en 1992 Universal Counters
; version 1.01
; date 04-06-2023
; Written by Gertjan Miedema,  info at miedemageluid dot nl,  Username "Gertjan" at EEVblog.
; Beta tested by Peter, PE1DTN.


; For use with TestController, software to control and log data: https://lygte-info.dk/project/TestControllerIntro%20UK.html
; For use with a Prologix GPIB interface, or clone. (AR488!)
; Tested with a AR488 GPIB interface.
;
; - For use with the counter in the ADDRESSED MODE (GPIB dip switch 1 DOWN)
;
; - The counter is used in one-shot measurement mode. One measurement is made in each logging interval.
;
; - Take care that the gate-time setting is shorter than the logging interval, plus a bit overhead!
;
; - When logging, the first reading can be empty, when there was no previous measurement.
;   This is because the counter buffer is first read-out, then the next measurement is triggered.
;
;
; Known issues:
; - The counter buffer can be read-out only once. After read-out the buffer is cleared.
;   So, while logging, if you look at the "Current values" tab, or use a Readout popup, 
;   you will be missing values in in your log table.... 
;   (because those values were already read-out by something else)

; - There is a bug in the GPIB implementation that HKJ has not fixed yet: 
;   It can only handle one device for each GPIB controller.
;
; - When using Auto Trigger, the counter automatically switches the 10x channel attenuator ON when the
;   measurement signal exceeds 5,1V peak to peak. This is NOT reported back to the TestContoller. 
;   So discrepancy between X10 setting in the TestController Setup menu and reality can arise...




; Meta definition for Racal-Dana 1992 counter
#metadef
#idString Racal-Dana,1992
#name Racal-Dana 1992
#handle Racal1992


; Meta definition to also support Racal-Dana 1991 counter
#metadef
#idString Racal-Dana,1991
#name Racal-Dana 1991
#handle Racal1991

; Command to get a full id line and prevent connection to other devices
#verifyDevice "1991" model?

; The 1991 model does not have the "Frequency C" and "Ratio C/B" functions
#remove #cmdMode Frequency_C FreqC
#remove #cmdMode Ratio_C/B RatioCB



#meta
#idString Racal-Dana,1992
#name Racal-Dana 1992
#handle Racal1992

#port GPIB
#driver Ascii
#interfaceType Counter

; Start up delay for slow booting Chinese Nano clones
#resetDelay 3.5

; The author statement is used for the listing in the About window.
#author Gertjan Miedema

#notes  Device configuration file for Racal-Dana 1991 en 1992 Universal Counters.

For use with a Prologix GPIB interface, or clone.
Use the counter in the ADDRESSED MODE (Dip switch 1 DOWN)

- Take care to choose the logging interval longer than the gate-time!

- Do NOT use Readout popups etc. while logging, or there will be values missing in the log table.

- For more info, see the notes in the header of the device configuration file (Racal1991-1992.txt)


Device configuration file version: 1.01



;---------  GPIB settings  -------------
; Used to change the standard LF end of line to CR or CRLF.
; For eol a string is used, to write control character escapes must be used, use: /r for CR and /r/n for CRLF
#eol /r/n

; The #gpibReadEol defines how the device terminates its answers, the default uses eoi. 
; Specifying "#gpibReadEol 10" would expect a LF character for terminating a answer.(13 = CR, 10 = LF)
#gpibReadEol 10

; add a small delay after each GPIB write, this can slow down the processing for old slow devices. (in ms)
#gpibWriteDelay 90

; minimum time before trying to read a answer from a device in ms
#gpibWriteReadDelay 10

; ++read_tmo_ms is controlled with #readingDelay
; This specifies the timeout value, in SECONDS, that is used by the ++read command to wait for a character
; to be transmitted while reading data from the GPIB bus. The timeout value may be set between 0 and 32 seconds.
#readingDelay 0.5



; ================= Original Racal-Dana commands to SCPI/TestController commands translations  ======================

; There must be a line for each of the original device commands that will be used, converting it to a similar SCPI command

; command to init
; [LLO]  Set device in remote control mode, i.e. the user interface on the device is disabled.
; REN    Remote
; IP     Set instrument to power up preset
; RE     Stop current measurement cycle and clear output buffer
; T1:    Select one-shot measurement mode
#scpiCmd init tx RE,IP,T1


; Command to initialize and set interface variables
#scpiCmd setVars tx none
:setvar: Function="FreqA"
:setvar: TriggerA="AtrigMan"
:setvar: CouplingA="AcouplingAC"
:setvar: SlopeA="AslopeNeg"
:setvar: ImpA="AimpHigh"
:setvar: AttenA="AattenOff"
:setvar: FilterA="AfilterOff"
:setvar: TriggerB="BtrigMan"
:setvar: CouplingB="BcouplingAC"
:setvar: SlopeB="BslopeNeg"
:setvar: ImpB="BimpHigh"
:setvar: AttenB="BattenOff"
:setvar: ABcommon="ABcommonOff"


; Final commands to counter before breaking connection, used to restore local control
; RE    Stop measurement cycle, and clear output buffer
; T0    Back to continuous measurement mode
; IP    Set instrument to power up state
; GTL   Go To Local
; UNL   UNListen
; [CLR] Do a "Selected Device Clear" function.
; [LOC] Set device in local control mode, i.e. the user interface on the device is active.

#scpiCmd reset tx RE,T0,IP

#scpiCmd goLocal tx [LOC]




; -----  Instrument identification    -----
; RUT  Recall unit type
; RMS  Recall Master software issue number
; RGS  Recall GPIB software issue number
 
; Recall the model number
#scpiCmd model? txrx? T1,RUT
:string: 
:readmath: substring(value,10,14);

; Recall the firmware version
#scpiCmd getDeviceSW? txrx? T1,RMS
:string: 
:readmath: substring(value,6,14);

; Recall the GPIB firmware version.
#scpiCmd getDeviceGpibSW? txrx? T1,RGS
:string: 
:readmath: substring(value,6,14);

; Recall the device serial number 
; (Not available on these counters. For identification purposes TestController uses firmware version as serial number)
#scpiCmd getDeviceSN? txrx? T1,RMS
:string: 
:readmath: substring(value,6,14);




; -----  data read out  -----

; Prepare the meter to response to #askValues
; T1   Select one-shot measurement mode
; T2   Take one measurement
#scpiCmd prepareSample tx T2

; command to read current value from the counter buffer
#scpiCmd value? txrx?
:string: 
:readmath: substring(value,2);



; ----------------  control  -----------------

; Select continuous measurement mode
#scpiCmd measureCont tx T0

; Select one-shot measurement mode
#scpiCmd measureOneShot tx T1

; Take one measurement
#scpiCmd measureTake tx T2



; -----  Mode selection  ------
; FA   Frequency A
; FC   Frequency C
; PA   Period A
; RA   Ratio A/B
; RC   Ratio C/B
; TI   Time Interval A->B
; TA   Total A by B
; PH   Phase A relative to B
; CK   Check

; Recall Measurement Function
#scpiCmd askMode? none?
:readmath: Function

; Set Measurement function: Frequency A
#scpiCmd freqA tx FA
:setvar: Function="FreqA"

; Set Measurement function: Frequency C
#scpiCmd freqC tx FC
:setvar: Function="FreqC"

; Set Measurement function: Period A
#scpiCmd periodA tx PA
:setvar: Function="PerA"

; Set Measurement function: Ratio A/B
#scpiCmd ratioBA tx RA
:setvar: Function="RatioAB"

; Set Measurement function: Ratio C/B
#scpiCmd ratioCB tx RC
:setvar: Function="RatioCB"

; Set Measurement function: Time Interval A->B
#scpiCmd timeInt tx TI
:setvar: Function="TimeInt"

; Set Measurement function: Phase
#scpiCmd phase tx PH
:setvar: Function="Phase"

; Set Measurement function: Check
#scpiCmd check tx CK
:setvar: Function="Check"


; -----  Set the Gate Time / Resolution  ------
; SRS6  gate time:  1ms
; SRS7  gate time: 10ms
; SRS8  gate time: 100ms
; SRS9  gate time:  1s
; SRS10 gate time: 20s

#scpiCmd gateTime tx SRS(value)

; Recall  Resolution (Query the Gate Time)
#scpiCmd gateTime? txrx? RRS
:string: 
:readmath: substring(value,2);



; ------- Channel A Input Settings -------------

; ----- Set A channel manual or auto trigger   -----
; AMN  A channel manual trigger
; AAU  A channel auto trigger

#scpiCmd AtrigMan tx AMN
:setvar: TriggerA="AtrigMan"

#scpiCmd AtrigAuto tx AAU
:setvar: TriggerA="AtrigAuto"

; Query the status of ch.A trigger
#scpiCmd Atrig? none?
:readmath: TriggerA


; ----- Set A channel  trigger level   -----
; SLA  Store A channel trigger level
; RLA  Recall A channel trigger level

; Set A channel trigger level
#scpiCmd AtrigLevel tx SLA(value)

; Query the ch.A trigger level
#scpiCmd AtrigLevel? txrx? RLA
:string: 
:readmath: substring(value,2);


; ----- Set A channel trigger slope  -----
; ANS  A channel negative slope triggered
; APS  A channel positive slope triggered

#scpiCmd AslopeNeg tx ANS
:setvar: SlopeA="AslopeNeg"

#scpiCmd AslopePos tx APS
:setvar: SlopeA="AslopePos"

; Query the status of ch.A trigger slope
#scpiCmd Aslope? none?
:readmath: SlopeA


; ----- Set A channel input coupling  -----
; AAC  A channel AC coupled
; ADC  A channel DC coupled

#scpiCmd AcouplingAC tx AAC
:setvar: CouplingA="AcouplingAC"

#scpiCmd AcouplingDC tx ADC
:setvar: CouplingA="AcouplingDC"

; Query the status of ch.A coupling
#scpiCmd Acoupling? none?
:readmath: CouplingA


; ----- Set A channel input impedance  -----
; AHI  A channel High Impedance (1M)
; ALI  A channel low Impedance (50R)

#scpiCmd AimpHigh tx AHI
:setvar: ImpA="AimpHigh"

#scpiCmd AimpLow tx ALI
:setvar: ImpA="AimpLow"

; Query the status of Ch.A input impedance
#scpiCmd AImp? none?
:readmath: ImpA


; ----- Set A channel Attenuator  -----
; AAD  A channel 10x Attenuator Disabled
; AAE  A channel 10x Attenuator Enabled

#scpiCmd AattenOff tx AAD
:setvar: AttenA="AattenOff"

#scpiCmd AattenOn tx AAE
:setvar: AttenA="AattenOn"

; Query the status of the Ch.A Attenuator
#scpiCmd Aatten? none?
:readmath: AttenA


; ----- Set A channel Filter  -----
; AFD  A channel Filter Disabled
; AEE  A channel Filter Enabled

#scpiCmd AfilterOff tx AFD
:setvar: FilterA="AfilterOff"

#scpiCmd AfilterOn tx AFE
:setvar: FilterA="AfilterOn"

; Query the status of the Ch.A Filter
#scpiCmd Afilter? none?
:readmath: FilterA


; ------- Channel B Input Settings -------------

; ----- Set B channel manual or auto trigger   -----
; BMN  A channel manual trigger
; BAU  A channel auto trigger

#scpiCmd BtrigMan tx BMN
:setvar: TriggerB="BtrigMan"

#scpiCmd BtrigAuto tx BAU
:setvar: TriggerB="BtrigAuto"

; Query the status of ch.B trigger
#scpiCmd Btrig? none?
:readmath: TriggerB


; ----- Set B channel  trigger level   -----
; SLB  Store A channel trigger level
; RLB  Recall A channel trigger level

; Set B channel trigger level
#scpiCmd BtrigLevel tx SLB(value)

; Query the ch.B trigger level
#scpiCmd BtrigLevel? txrx? RLB
:string: 
:readmath: substring(value,2);


; ----- Set B channel trigger slope  -----
; BNS  A channel negative slope triggered
; BPS  A channel positive slope triggered

#scpiCmd BslopeNeg tx BNS
:setvar: SlopeB="BslopeNeg"

#scpiCmd BslopePos tx BPS
:setvar: SlopeB="BslopePos"

; Query the status of ch.B trigger slope
#scpiCmd Bslope? none?
:readmath: SlopeB


; ----- Set B channel input coupling  -----
; BAC  B channel AC coupled
; BDC  B channel DC coupled

#scpiCmd BcouplingAC tx BAC
:setvar: CouplingB="BcouplingAC"

#scpiCmd BcouplingDC tx BDC
:setvar: CouplingB="BcouplingDC"

; Query the status of ch.B coupling
#scpiCmd Bcoupling? none?
:readmath: CouplingB


; ----- Set B channel input impedance  -----
; BHI  B channel High Impedance (1M)
; BLI  B channel low Impedance (50R)

#scpiCmd BimpHigh tx BHI
:setvar: ImpB="BimpHigh"

#scpiCmd BimpLow tx BLI
:setvar: ImpB="BimpLow"

; Query the status of Ch.B input impedance
#scpiCmd Bimp? none?
:readmath: ImpB


; ----- Set B channel Attenuator  -----
; BAD  B channel 10x Attenuator Disabled
; BAE  B channel 10x Attenuator Enabled

#scpiCmd BattenOff tx BAD
:setvar: AttenB="BattenOff"

#scpiCmd BattenOn tx BAE
:setvar: AttenB="BattenOn"

; Query the status of the Ch.A Attenuator
#scpiCmd Batten? none?
:readmath: AttenB


; ----- Set A and B channel separate or common  -----
; BCS  A and B channel separate
; BCC  A and B channel common

#scpiCmd ABcommonOff tx BCS
:setvar: ABcommon="ABcommonOff"

#scpiCmd ABcommonOn tx BCC
:setvar: ABcommon="ABcommonOn"

; Query the status of the Ch.A Filter
#scpiCmd ABcommon? none?
:readmath: ABcommon




; =================================  End command conversion Racal -> TC SCPI  ===========================



;----------------------- Data read out  ------------------

; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6)
; Unit example for 10MHz: SI: 10M, D: 1.E7
; code: #value name unit format {selector}
#value Freq.A Hz SI Frequency_A
#value Freq.C Hz SI Frequency_C
#value Phase D D6 Phase_A_rel_B
#value Period sec SI Period_A
#value Ratio.A/B _ D6 Ratio_A/B
#value Ratio.C/B _ D6 Ratio_C/B
#value Time.Int S SI Time_Int._A->B 

; Prepare the meter to response to #askValues
; Take a measurement in advance, to fill the buffer before the logging starts
#prepareSample prepareSample;[1500]

; This is a single line command
; First read the value of the previous measurement out of the buffer, then clear buffer and start the next measurement
#askValues value?;measureTake

#askMode askMode?





;------------------  Initial commands &Final command  --------------

; Command to get a full id line and prevent connection to other devices
#verifyDevice "1992" model?

; Initial commands to meter when establishing connection, used to disable local control
; With "setVars" the Menu commands are executed to declare and set their variables
#initCmd init;setVars

; Final command to meter before breaking connection, used to restore local control
#finalCmd reset;goLocal;[1000];




; ================== Menu's  ================================

; -----  Mode (Function) menu  -----

; code: #cmdMode modeLabel deviceModeString SCPI commands
#cmdMode Frequency_A FreqA
freqA;measureOneShot

#cmdMode Frequency_C FreqC
freqC;measureOneShot

#cmdMode Period_A PerA
periodA;measureOneShot

#cmdMode Phase_A_rel_B Phase
phase;measureOneShot

#cmdMode Ratio_A/B RatioAB
ratioBA;measureOneShot

#cmdMode Ratio_C/B RatioCB
ratioCB;measureOneShot

#cmdMode Time_Int._A->B TimeInt
timeInt;measureOneShot



; ----- Setup menu  -----

#cmdSetup radio Gate_Time
:read: gateTime?;
:write: gateTime #
:tip: <html>Set Resolution using the Gate Time:<br>1ms=6digits, 10ms=7digits, 100ms=8digits, 1sec=9digits, 10sec=10digits
1ms 6
10ms 7
100ms 8
1s 9
10s 10


#cmdSetup separator Ch.A_Auto_Trigger
2 100 Raised


; ----- Channel A input setup -----

#cmdSetup buttonsOn Ch.A_Auto_Trigger
:read: Atrig?
:string:
:write: #
:update: Ch.A_Trigger_Level
:tip: Default is Manual Trigger, with 0V trigger level
Off AtrigMan
On AtrigAuto


#cmdSetup number Ch.A_Trigger_Level
:read: AtrigLevel?
:format: D2
:write: AtrigLevel
:tip: Set manual trigger level. 0V is best in most cases
V -5.10 5.10


#cmdSetup buttonsOn Ch.A_Trigger_Slope
:read: Aslope?
:string:
:write: #
:update: Ch.A_Trigger_Level
:tip: Trigger on the down or on the up slope of the signal
Neg_slope AslopeNeg
Pos_slope AslopePos


#cmdSetup separator Ch.A_Input_Coupling
2 100 Raised


#cmdSetup buttonsOn Ch.A_Input_Coupling
:read: Acoupling?
:string:
:write: #
AC AcouplingAC
DC AcouplingDC


#cmdSetup buttonsOn Ch.A_Input_Impedance
:read: Aimp?
:string:
:write: #
1_Meg AimpHigh
50_Ohm AimpLow


#cmdSetup buttonsOn Ch.A_Attenuator
:read: Aatten?
:string:
:write: #
:tip: Channel A input 10x attenuator
Off AattenOff
On AattenOn


#cmdSetup buttonsOn Ch.A_Low-Pass_Filter
:read: Afilter?
:string:
:write: #
:tip: Channel A 50kHz Low Pass filter
Off AfilterOff
On AfilterOn


#cmdSetup separator Ch.B_Auto_Trigger
2 100 Raised



; ----- Channel B input setup -----

#cmdSetup buttonsOn Ch.B_Auto_Trigger
:read: Btrig?
:string:
:write: #
:update: Ch.B_Trigger_Level
:tip: Default is Manual Trigger, with 0V trigger level
Off BtrigMan
On BtrigAuto


#cmdSetup number Ch.B_Trigger_Level
:read: BtrigLevel?
:format: D2
:write: BtrigLevel
:tip: Set manual trigger level. 0V is best in most cases
V -5.10 5.10


#cmdSetup buttonsOn Ch.B_Trigger_Slope
:read: Bslope?
:string:
:write: #
:update: Ch.B_Trigger_Level
:tip: Trigger on the down or on the up slope of the signal
Neg_slope BslopeNeg
Pos_slope BslopePos


#cmdSetup separator Ch.B_Input_Coupling
2 100 Raised


#cmdSetup buttonsOn Ch.B_Input_Coupling
:read: Bcoupling?
:string:
:write: #
AC BcouplingAC
DC BcouplingDC


#cmdSetup buttonsOn Ch.B_Input_Impedance
:read: Bimp?
:string:
:write: #
1_Meg BimpHigh
50_Ohm BimpLow


#cmdSetup buttonsOn Ch.B_Attenuator
:read: Batten?
:string:
:write: #
:tip: Channel B input 10x attenuator
Off BattenOff
On BattenOn


#cmdSetup separator Ch.A_&_Ch.B_Inputs
2 100 Raised


#cmdSetup buttonsOn Ch.A_&_Ch.B_Inputs
:read: ABcommon?
:string:
:write: #
:tip: Connect the Ch.A input to both Ch.A and Ch.B in parallel
Separate ABcommonOff
Common ABcommonOn
