/*
  xfr.c

  Copyright 19-Nov-2002 MBARI
  Written: 19-Nov-2002 Mark Sibenac
  Last mod: 19-Nov-2002 sib - creation

  Interface library to the Xantrex XFR power supply
*/

#include <stdio.h>
#include "xfr.h"
#include "serial.h"
#include "error.h"

#define MAX_VOLT (45.0)
#define MAX_CURRENT (60.0)
#define XFR_SERIAL_RETRY (10) /* 10x !!! */

// CLR command
int xfrInit (int xfr_port)
{
  return (sendStr (xfr_port, "CLR\r"));
}

// OUT 1 command
int xfrEnableOutput (int xfr_port)
{
  return (sendStr (xfr_port, "OUT 1\r"));
}

// OUT 0 command
int xfrDisableOutput (int xfr_port)
{
  return (sendStr (xfr_port, "OUT 0\r"));
}

// OVSET command
int xfrOverVoltSet (int xfr_port, double ovp)
{
  char str[20];

  if (ovp < 0.0 || ovp > MAX_VOLT)
  {
    ERROR ("err: xfrOverVoltSet(%f) > %f\n", ovp, MAX_VOLT);
    return ERROR_ARG;
  }

  sprintf (str, "OVSET %0.4fV\r", ovp);
  
  return (sendStr (xfr_port, str));
}

// RST command
int xfrReset (int xfr_port)
{
  return (sendStr (xfr_port, "RST\r"));
}

// TRG command
int xfrTrigger (int xfr_port)
{
  return (sendStr (xfr_port, "TRG\r"));
}

// VMAX command
int xfrVMax (int xfr_port, double Vmax)
{
  char str[20];

  if (Vmax < 0.0 || Vmax > MAX_VOLT)
  {
    ERROR ("err: xfrVMax(%f) > %f\n", Vmax, MAX_VOLT);
    return ERROR_ARG;
  }

  sprintf (str, "VMAX %0.4fV\r", Vmax);
  return (sendStr (xfr_port, str));
}

// VSET command
int xfrSetVolts (int xfr_port, double volts)
{
  char str[20];

  if (volts < 0.0 || volts >= MAX_VOLT)
  {
    ERROR ("err: xfrSetVolts(%f) >= %f\n", volts, MAX_VOLT);
    return ERROR_ARG;
  }

  sprintf (str, "VSET %0.4fV\r", volts);
  return (sendStr (xfr_port, str));
}

// IMAX command
int xfrIMax (int xfr_port, double current)
{
  char str[20];

  ASSERT (current >= 0.0 && current <= MAX_CURRENT);

  sprintf (str, "IMAX %0.4fA\r", current);
  return (sendStr (xfr_port, str));
}

// ISET command
int xfrSetCurrent (int xfr_port, double current)
{
  char str[20];

  ASSERT (current >= 0.0 && current <= MAX_CURRENT);

  sprintf (str, "ISET %0.4fA\r", current);
  return (sendStr (xfr_port, str));
}

// IOUT? command
int xfrGetIOut (int xfr_port, double *Iout)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
	  flushRecv (xfr_port);

	  if ((ret = sendStr (xfr_port, "IOUT?\r")) < 0)
	  {
		  ERROR ("err: xfrGetIOut: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetIOut: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "IOUT %lf", Iout);
  DEBUG (1, "xfrGetIOut = %f, sscanf returned %d\n", *Iout, ret);
  return ret;
}

// ISET? command
int xfrGetISet (int xfr_port, double *Iset)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "ISET?\r")) < 0)
	  {
		  ERROR ("err: xfrGetISet: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetISet: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  

  ret = sscanf(str, "ISET %lf", Iset);
  DEBUG (1, "xfrGetISet = %f, sscanf returned %d\n", *Iset, ret);
  return ret;
}

// OUT? command
int xfrGetOut (int xfr_port, int *status)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "OUT?\r")) < 0)
	  {
		  ERROR ("err: xfrGetOut: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetOut: recvStr returned %d\n", ret);
			//return ret;
	  }
  }

  ret = sscanf(str, "OUT %d", status);
  DEBUG (1, "xfrGetOut = %d, sscanf returned %d\n", *status, ret);
  return ret;
}

// VOUT? command
int xfrGetVOut (int xfr_port, double *volts)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "VOUT?\r")) < 0)
	  {
		  ERROR ("err: xfrGetVout: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetVout: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "VOUT %lf", volts);
  DEBUG (1, "xfrGetVout = %f, sscanf returned %d\n", *volts, ret);
  return ret;
}

// VSET? command
int xfrGetVSet (int xfr_port, double *Vset)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "VSET?\r")) < 0)
	  {
		  ERROR ("err: xfrGetVset: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetVset: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "VSET %lf", Vset);
  DEBUG (1, "xfrGetVset = %f, sscanf returned %d\n", *Vset, ret);
  return ret;
}

// ERR? command
int xfrGetErr (int xfr_port, int *err)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "ERR?\r")) < 0)
	  {
		  ERROR ("err: xfrGetErr: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetErr: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "ERR %d", err);
  DEBUG (1, "xfrGetErr = %d, sscanf returned %d\n", *err, ret);
  return ret;
}

 // ASTS?, STS?, and FAULT? commands
int xfrGetStatus (int xfr_port, int *astatus, int *status, int *fault)
{
  int ret;
  char str[20];
  int retry;
  
  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
		// ASTS? command
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "ASTS?\r")) < 0)
	  {
		  ERROR ("err: xfrGetStatus: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetStatus: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "ASTS %d", astatus);
  DEBUG (1, "xfrGetStatus = %d, sscanf returned %d\n", *astatus, ret);

  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
		// STS? command
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "STS?\r")) < 0)
	  {
		  ERROR ("err: xfrGetStatus: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetStatus: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "STS %d", status);
  DEBUG (1, "xfrGetStatus = %d, sscanf returned %d\n", *status, ret);

  for (ret=-1,retry=0; retry<XFR_SERIAL_RETRY && ret<=0; ++retry)
  {
		// FAULT? command
	  flushRecv (xfr_port);
	  
	  if ((ret = sendStr (xfr_port, "FAULT?\r")) < 0)
	  {
		  ERROR ("err: xfrGetStatus: sendStr returned %d\n", ret);
		  return ret;
	  }
	  
	  if ((ret = recvStr (xfr_port, str, 20)) < 0)
	  {
		  ERROR ("err: xfrGetStatus: recvStr returned %d\n", ret);
			//return ret;
	  }
  }
  
  ret = sscanf(str, "FAULT %d", fault);
  DEBUG (1, "xfrGetStatus = %d, sscanf returned %d\n", *fault, ret);

  return ret;
}
