#!/usr/bin/perl
#
# hp8566b-trace.pl

#----------

use strict;
use POSIX qw(setsid);
use Getopt::Std;
use Time::HiRes qw(usleep time gettimeofday);
use LinuxGpib;
use Number::Format;
use n8ur qw(round trim squash parse_value);
use n8ur_gpib qw(checkSRQ serviceSRQ);

my $board = "gpib0";
my $device = "hp8566b";
my $command;
my $status;
my $device_status;
my $done = 0;

#----------
# handle signals and errors -- mainly to clear lockfile on termination
sub sig_handler {
	exit(0);
}

# there's got to be a better way!
$SIG{'HUP'} = 'sig_handler';
$SIG{'INT'} = 'sig_handler';
$SIG{'KILL'} = 'sig_handler';
$SIG{'STOP'} = 'sig_handler';
$SIG{'TERM'} = 'sig_handler';
#----------
# display usage
my $opt_string = 'hf:';

sub usage() {
print STDERR << "EOF";

usage: $0 [-h] -f output file 

-h      : this (help) message
-f      : output file name; format depends on extension

EOF
}

getopts( "$opt_string", \my %opt ) or usage() and exit;

# print usage
usage() and exit if $opt{h};
usage() and exit if !$opt{f};

# set variables to command line params

my $outfile;
$outfile = $opt{f};

#----------
# set up outfile
open (LOG, ">$outfile") ||
        die "Can't open file $outfile!\n";
        
# get board
my $brd = LinuxGpib::ibfind($board);

# initialize instrument
my $dev = LinuxGpib::ibfind($device) ||
	die "Can't open device $device!\n";
usleep(5000);
#----------

# turn on SRQ
$command = "R2;";
LinuxGpib::ibwrt($dev,$command,length($command));
# poll to clear status bit
$status = LinuxGpib::ibrsp($dev,$device_status);

# get instrument params

my $cf;
my $start;
my $stop;
my $span;
my $atten;
my $reflevel;
my $rbw;
my $vbw;
my $sweep;
my $traceA;

$command = "CF?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$cf,128);
$cf = trim($cf);

$command = "FA?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$start,128);
$start = trim($start);

$command = "FB?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$stop,128);
$stop = trim($stop);

$command = "SP?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$span,128);
$span = trim($span);

my $step = round(2,$span/1000);
my @freq;
my $j;

$freq[0] = $start;
for ($j = 1; $j < 1001; $j++) {
	$freq[$j] = $freq[$j-1] + $step;
	}

$command = "AT?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$atten,128);
$atten = trim($atten);

$command = "RL?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$reflevel,128);
$reflevel = trim($reflevel);

$command = "RB?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$rbw,128);
$rbw = trim($rbw);

$command = "VB?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$vbw,128);
$vbw = trim($vbw);

$command = "ST?;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$sweep,128);
$sweep = trim($sweep);

$command = "TA;";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(5000);
LinuxGpib::ibrd($dev,$traceA,32768);

my @amplA = split(/\r\n/,$traceA);
for ($j=0;$j < 1001; $j++) { $amplA[$j] = trim($amplA[$j]); }

# write header line
my $dt = DateTime->now;
my $current_iso = $dt->ymd('-') . 'T' . $dt->hms(':');
my $current_mjd = $dt->mjd;

printf LOG "# Trace from HP 8566B at %s (MJD %11.6F).\n",
	$current_iso,$current_mjd;
print LOG "# CF: $cf  START: $start  STOP: $stop ATTEN: $atten\n";
print LOG "# REF: $reflevel  RBW: $rbw  VBW: $vbw  SWP: $sweep\n";

for ($j = 0; $j < 1001; $j++) { print LOG "$freq[$j] $amplA[$j]\n"; }

# Switch back to normal
# turn off SRQ
$command = "R1;";
LinuxGpib::ibwrt($dev,$command,length($command));

usleep(5000);
# poll to clear status bit
$status = LinuxGpib::ibrsp($dev,$device_status);

# go local
LinuxGpib::ibloc($dev);

exit 0;
