#include <stdio.h>
#include <string.h>
#ifndef __USE_ISOC99
#define __USE_ISOC99
#endif
#include <math.h>
#include "gpib.h"
#include "serial-util.h"

#define gputv(string, rv) do {	    \
	int ____l = strlen(string); \
	if (safewrite(fd, string, ____l) != ____l) return rv; \
	if (safewrite(fd, "\r", 1) != 1) return rv; } while(0)
#define gput(string) gputv(string, -1)

int gpib_init(int fd)
{
	gput("++mode 1");
	gput("++auto 0");
	gput("++eos 1");
	gput("++eoi 1");
	gput("++read_tmo_ms 4000");
	gput("++eot_enable 1");
	gput("++eot_char 13");
	return 0;
}

int gpib_addr(int fd, int addr)
{
	char s[128];
	sprintf(s, "++addr %d", addr);
	gput(s);
	return 0;
}

int keithley_init(int fd)
{
 	double i;
	gput(":syst:beep:stat 1");
	gput(":sour:func:mode curr");
	gput(":sour:del 0");
	gput(":sour:curr 0");
	gput(":sour:curr:range:auto on");
	gput(":outp on");
	drain(fd);
	i = keithley_read(fd);
	if (isnan(i))
		return -1;
	return 0;
}

int keithley_current(int fd, double amps)
{
	char s[128];
	sprintf(s, ":sour:curr %0.12f", amps);
	gput(s);
	return 0;
}

double keithley_read(int fd)
{
	char s[128];
	double i, dummy;
	gputv("read?", NAN);
	gputv("++read", NAN);
	if (fdgets(s, 128, fd, 2000) == NULL)
		return NAN;
	if (sscanf(s, "%lf,%lf,", &dummy, &i) != 2)
		return NAN;
	return i;
}

int keithley_off(int fd)
{
	gput(":outp off");
	return 0;
}


/* this function is for Keithley2002 Digital multimeter */
int keithley2002_init(int fd)
{
	double i;
	gput(":trac:cle");
	gput(":sens:curr:dc:rang:auto on");
	gput(":sens:curr:dc:dig 8");
	gput(":form:elem read");
	gput(":init:cont off");
       	drain(fd);
	i = keithley2002_read(fd);
	if (isnan(i))
		return -1;
	return 0;
}

int keithley2002_init2(int fd)
{
	double i;
	gput(":trac:cle");
	gput(":sens:curr:dc:rang:auto on");
	gput(":sens:curr:dc:dig 8");
	gput(":form:elem read, time");
	gput(":syst:tst:type rel");
	gput(":syst:tst:rel:res");
	gput(":init:cont off");
       	drain(fd);
	i = keithley2002_read(fd);
	if (isnan(i))
		return -1;
	return 0;
}

int keithley2002_init_volts(int fd)
{
	double i;
	gput(":trac:cle");
	gput(":sens:volt:dc:rang 5");
	gput(":sens:volt:dc:dig 8");
	gput(":form:elem read");
	gput(":init:cont off");
       	drain(fd);
	i = keithley2002_read(fd);
	if (isnan(i))
		return -1;
	return 0;
}

double keithley2002_read(int fd)
{
	char s[128];
	double i;
	gputv("read?", NAN);
	gputv("++read", NAN);
	if (fdgets(s, 128, fd, 2000) == NULL)
		return NAN;
	if (sscanf(s, "%lf", &i) != 1)
		return NAN;
	return i;

}

double keithley2002_read2(int fd, double *tx)
{
	char s[128];
	double i;
	gputv("read?", NAN);
	gputv("++read", NAN);
	if (fdgets(s, 128, fd, 2000) == NULL)
		return NAN;
	if (sscanf(s, "%lf,%lf", &i, tx) < 1)
		return NAN;
	return i;

}
