#!/usr/bin/perl -w
#
# hp5370-tint.pl
# version 0.9 --  6 February 2005
#
# Record time interval readings from HP 5370b counter
# 
# Copyright 2004-2005 by John R. Ackermann  N8UR (jra@febo.com)
#
# This program may be copied, modified, distributed and used for 
# any legal purpose provided that (a) the copyright notice above as well
# as these terms are retained on all copies; (b) any modifications that 
# correct bugs or errors, or increase the program's functionality, are 
# sent via email to the author at the address above; and (c) such 
# modifications are made subject to these license terms.

use strict;
use POSIX qw(setsid);
use Getopt::Std;
use Time::HiRes qw(usleep);
use LinuxGpib;
use DateTime;
use n8ur qw(trim squash collapse round);
use n8ur_gpib qw(checkSRQ serviceSRQ logline);

##########################
my $board = "gpib0";
my $device = "hp5370b";
##########################

#----------
# handle signals and errors -- mainly to clear lockfile on termination
sub sig_handler {
	sleep 2;
	close LOG;
	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 = 'ha:pgt:f:';

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

usage: $0 [-h] [-a samples to average][-t mjd|iso|none] -f logfile

-h	: this (help) message
-a	: samples to average; default 1
-t      : timetag format: mjd,iso,none (default is ISO8601)
-p	: set to positive time interval only (default is +/-)
-g	: use external trigger
-f	: logfile using full pathname;
	  for output to console, use "-f -"

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 $samples = 1;
if ($opt{a}) {
        $samples = $opt{a};
        }

my $tags = "iso";
if ($opt{t}) {
        $tags = lc($opt{t});
        }

my $pos = 0;
if ($opt{p}) {
	$pos = 1;
	}
	 
my $gate = 0;
if ($opt{g}) {
	$gate = 1;
	}

my $logfile = $opt{f};

#----------
# set up logfile
open (LOG, ">>$logfile") ||
	die "Can't open logfile $logfile!\n";
# set nonbuffered mode
select(LOG), $| = 1;


#----------
# initialize counter
my $brd = LinuxGpib::ibfind($board);
my $dev = LinuxGpib::ibfind($device);
my $command;

# clear
LinuxGpib::ibclr($dev);

# AR1 for + time interval; AR2 for +/-
if ($pos) {
	$command = "FN1" . "AR1" . "MD4";
	}
else {
	$command = "FN1" . "AR2" . "MD4";
	}
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(50000);
if ($gate) {
	$command = "EA1DE1";
	LinuxGpib::ibwrt($dev,$command,length($command));
	usleep(50000);
	}

#----------

# write header line
my $dt = DateTime->now;
my $current_iso = $dt->ymd('-') . 'T' . $dt->hms(':');
my $current_mjd = $dt->mjd;
printf LOG "# Run started at %s (MJD %11.6F).\n",$current_iso,$current_mjd;
print LOG "# Data from $device.  Average by $samples, phase values in seconds.\n";

#----------
my $last_avg_value = 0;
my $sum = 0;

sub dolog {
	my $avg_value = $sum/$samples;
	# to avoid zero phase, add 1 fs if same as last value
	if ($avg_value == $last_avg_value) {
		$avg_value += 1e-15;
	}
	print LOG logline($tags,12,$avg_value);
	$last_avg_value = $avg_value;
}

my $result;
my $counter = 1;

# main loop
$command = "MR";
LinuxGpib::ibwrt($dev,$command,length($command));
while (1) {

        if (checkSRQ($brd)) {
                $result = substr(substr(squash(trim(serviceSRQ($dev))),1),2);
		$sum += $result;
		if ($counter == $samples) {
			dolog;
			$sum = 0;
			$counter = 1;
		} else {
			$counter++;	
			}
                $command = "MR";
                LinuxGpib::ibwrt($dev,$command,length($command));
	}
	usleep(200000);
}	

#----------

exit 0;
