/* devB4phase.c */
/*
 *      Author: Makoto Tobiyama
 *      Date:   06_Jan_2005
 */
/***********************************************************************
* asynDriver is distributed subject to a Software License Agreement
* found in file LICENSE that is included with this distribution.
***********************************************************************/
#define	DSET_AI		devAiB4phase
#define	DSET_AO		devAoB4phase
#define	DSET_BI		devBiB4phase
#define	DSET_BO		devBoB4phase
#define	DSET_LI		devLiB4phase
#define	DSET_LO		devLoB4phase
#define	DSET_MBBO	devMbboB4phase
#define	DSET_MBBI	devMbbiB4phase
#define	DSET_SI		devSiB4phase
#define	DSET_SO		devSoB4phase

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <alarm.h>
#include <errlog.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>

#include <devCommonGpib.h>
#include <devGpib.h>

#define	TIMEOUT	5.0
#define TIMEWINDOW  2.0

static int readString(gpibDpvt *pdpvt,int P1, int P2, char **P3);
static int convAi(gpibDpvt *pdpvt, int P1, int P2, char **P3);
static int convMi(gpibDpvt *pdpvt, int P1, int P2, char **P3);

/*
 * Define end-of-string character(s) here to allow
 * easier changes when testing the driver.
 */


#define EOSNL "\n"
static char                *MIX_IOList[] = { "CH1-CH2" ,"CH1-REF" ,"CH2-REF" };
static unsigned long       MIX_IOVal[] = { 0 ,1 ,2 };
static struct devGpibNames MIX_IO = { 3, MIX_IOList, MIX_IOVal, 2 };

static char *(MIX_IN[])={"INP:1,2\r\n","INP:1,3\r\n","INP:2,3\r\n",NULL};
static char *(MIX_OUT[])={"SINP:1,2\r\n","SINP:1,3\r\n","SINP:2,3\r\n",NULL};




static struct gpibCmd gpibCmds[] = 
{ 
    /* CMMAND 0 read_at_ch1 */
  {&DSET_LI, GPIBREAD, IB_Q_LOW, "RAT1\r\n", "AT1:%ld\r\n", 0, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 1 read_at_ch2 */
  {&DSET_LI, GPIBREAD, IB_Q_LOW, "RAT2\r\n", "AT2:%ld\r\n", 0, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 2 read_ch1_level */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "RCH1\r\n", NULL, 0, 511, convAi, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 3 read_ch2_level */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "RCH2\r\n", NULL, 0, 511, convAi, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 4 read_signal_in */
  {&DSET_MBBI, GPIBEFASTI, IB_Q_LOW, NULL, NULL, 0, 32, NULL, 0, 0, MIX_IN, &MIX_IO, EOSNL },

    /* CMMAND 5 read_phase */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "RPHV\r\n", NULL,0, 511, convAi, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 6 read_ref_level */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "RREF\r\n", NULL, 0, 511, convAi, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 7 read_samp_num */
  {&DSET_LI, GPIBREAD, IB_Q_LOW, "RSAM\r\n", "SAM:%ld\r\n", 0, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 8 read_temp */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "RTEM\r\n", NULL, 0, 511, convAi, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 9 read_ver */
  {&DSET_SI, GPIBREAD, IB_Q_LOW, "RVER\r\n", "%s\r\n", 0, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 10 set_at_ch1 */
  {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "SAT1:%ld\r\n", 511,511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 11 set_at_ch2 */
  {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "SAT2:%ld\r\n", 511, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 12 set_signal_in */
  {&DSET_MBBO, GPIBEFASTO, IB_Q_LOW, NULL, NULL, 511, 511, NULL, 0, 0, MIX_OUT, &MIX_IO, EOSNL },

    /* CMMAND 13 set_samp_num */
  {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "SSAM:%ld\r\n", 511, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 14 set_ch1-ch2 */
  {&DSET_BO, GPIBWRITE, IB_Q_LOW, NULL, "SINP:1,2\r\n", 511, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 15 set_ch1-ch3 */
  {&DSET_BO, GPIBWRITE, IB_Q_LOW, NULL, "SINP:1,3\r\n", 511, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 16 set_ch2-ch3 */
  {&DSET_BO, GPIBWRITE, IB_Q_LOW, NULL, "SINP:2,3\r\n", 511, 511, NULL, 0, 0, NULL, NULL, EOSNL },

    /* CMMAND 17 read_input_sel */
  {&DSET_LI, GPIBREAD, IB_Q_LOW, "RINP\r\n", NULL, 0, 511, convMi, 0, 0, NULL, NULL, EOSNL }

};


/* The following is the number of elements in the command array above.  */
#define NUMPARAMS	sizeof(gpibCmds)/sizeof(struct gpibCmd)

/******************************************************************************
 *
 * Initialization for device support
 * This is called one time before any records are initialized with a parm
 * value of 0.  And then again AFTER all record-level init is complete
 * with a param value of 1.
 *
 ******************************************************************************/
static long init_ai(int parm)
{
  if(parm==0)  {
    devSupParms.name = "devB4phase";
    devSupParms.gpibCmds = gpibCmds;
    devSupParms.numparams = NUMPARAMS;
    devSupParms.timeout = TIMEOUT;
    devSupParms.timeWindow = TIMEWINDOW;
    devSupParms.respond2Writes = 1.0;
  }
  return(0);
}

static int readString(gpibDpvt *pdpvt,int P1, int P2, char **P3)
{
    stringinRecord *prec = (stringinRecord*)pdpvt->precord;
    strncpy(prec->val,pdpvt->msg,sizeof(prec->val));
    prec->val[sizeof(prec->val) - 1] = 0;
    return(0);
}

static int convAi(gpibDpvt *pdpvt, int P1, int P2, char **P3)
{
  struct aiRecord *pai = ((struct aiRecord *)(pdpvt->precord));

  char *craw;
  char wa1[3000];

  craw = pdpvt->msg;
  craw = strtok(craw,":");
  strcpy(wa1,strtok(NULL,","));

  /* printf("data wa1 %s\n",wa1); */
  pai->val = atof(wa1);
  pai->udf = FALSE;   
  return 0;
}

#define CH1_CH2  "1,2"
#define CH1_CH3  "1,3"
#define CH2_CH3  "2,3"

static int convMi(gpibDpvt *pdpvt, int P1, int P2, char **P3)
{
  struct longinRecord *pli = ((struct longinRecord *)(pdpvt->precord));

  char *craw;
  char wa1[3000]; 

  craw = pdpvt->msg;
  craw = strtok(craw,":");

  strcpy(wa1,strtok(NULL,"\r"));
  /*   printf("input %s\n",wa1);  */ 

  if (strncmp(wa1,CH1_CH2,3)==0) {
    pli->val = 0;
  }
  else if (strncmp(wa1,CH1_CH3,3)==0) {
    pli->val = 1;
  }
  else if (strncmp(wa1,CH2_CH3,3)==0) {
    pli->val = 2;
  }
  else printf("error %s\n",wa1);
  pli->udf = FALSE;
  return 0;


}