/*
 * TDS820 device support
 */

#include <epicsStdio.h>
#include <devCommonGpib.h>
#include <string.h>
#include <strings.h>

/******************************************************************************
 *
 * The following define statements are used to declare the names to be used
 * for the dset tables.   
 *
 * A DSET_AI entry must be declared here and referenced in an application
 * database description file even if the device provides no AI records.
 *
 ******************************************************************************/
#define DSET_AI     devAiTDS820
#define DSET_AO     devAoTDS820
#define DSET_BI     devBiTDS820
#define DSET_BO     devBoTDS820
#define DSET_EV     devEvTDS820
#define DSET_LI     devLiTDS820
#define DSET_LO     devLoTDS820
#define DSET_MBBI   devMbbiTDS820
#define DSET_MBBID  devMbbidTDS820
#define DSET_MBBO   devMbboTDS820
#define DSET_MBBOD  devMbbodTDS820
#define DSET_SI     devSiTDS820
#define DSET_SO     devSoTDS820
#define DSET_WF     devWfTDS820

#include <devGpib.h> /* must be included after DSET defines */

#define TIMEOUT     1.0    /* I/O must complete within this time */
#define TIMEWINDOW  2.0    /* Wait this long after device timeout */

# line 2 "devTDS820.gt"

static short get_onedata(char wa1[]);
static int rd_data(char wav[], short temp[]);
static int rd_wf_data(struct gpibDpvt *pdpvt,  int p1, int p2, char **p3);
/*static int rd_efast_data(struct gpibDpvt *pdpvt,  int p1, int p2, char **p3);
 */

/******************************************************************************
 * Strings used by the init routines to fill in the znam,onam,...
 * fields in BI and BO record types.
 ******************************************************************************/
static char                *AcqStateList[] = { "STOP", "RUN" };
static struct devGpibNames AcqState = { 2, AcqStateList, 0, 1 };

/******************************************************************************
 * Structures used by the init routines to fill in the onst,twst,... and the
 * onvl,twvl,... fields in MBBI and MBBO record types.
 *
 * Note that the intExtSsBm and intExtSsBmStop structures use the same
 * intExtSsBmStopList and intExtSsBmStopVal lists but have a different number
 * of elements in them that they use... The intExtSsBm structure only represents
 * 4 elements,while the intExtSsBmStop structure represents 5.
 ******************************************************************************/
static char                *AcqModeList[] = { "NORMAL" ,"AVERAGE" ,"ENVELOPE" };
static unsigned long       AcqModeVal[] = { 0 ,1 ,2 };
static struct devGpibNames AcqMode = { 3, AcqModeList, AcqModeVal, 2 };

static char                *HorModeList[] = {"Delay", "Inten", "Main" };
static unsigned long      HorModeVal[] = {0, 1, 2 };
static struct devGpibNames HorMode = {3, HorModeList, HorModeVal, 2 };


/******************************************************************************
 * String arrays for EFAST operations. The last entry must be 0.
 *
 * On input operations,only as many bytes as are found in the string array
 * elements are compared.  Additional bytes are ignored.
 * The first matching string  will be used as a match.
 *
 * For the input operations,the strings are compared literally!  This
 * can cause problems if the instrument is returning things like \r and \n
 * characters.  When defining input strings so you include them as well.
 ******************************************************************************/
static char *(AcqModeE[])={"NORM\n","AVE\n","ENV\n",0};
static char *(AcqModeV[])={"ACQ:MOD NORM\n","ACQ:MOD AVE\n","ACQ:MOD ENV\n",0};
static char *(AcqStateE[])={"0\n","1\n",0};
static char *(AcqStateV[])={"ACQ:STATE OFF\n","ACQ:STATE ON\n",0};

static char *(HorModeE[])={"DELAYE\n","INTENSIF\n","MAI",0};
static char *(HorModeV[])={"HOR:MOD DELAYE\n","HOR:MOD INTENSIF\n","HOR:MOD MAI\n", 0};

/******************************************************************************
 * Array of structures that define all GPIB messages
 * supported for this type of instrument.
 ******************************************************************************/
static struct gpibCmd gpibCmds[] = { 

    /* CMMAND 0 set_default_param */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "HEADER OFF\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 1 set_h_scale */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "HOR:SCA %le\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 2 get_h_scale */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "HOR:SCA?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 3 set_h_pos */
  {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "HOR:POS %ld\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 4 get_h_pos */
  {&DSET_LI, GPIBREAD, IB_Q_LOW, "HOR:POS?\n", "%ld\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 5 set_h_delay_scale */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "HOR:DEL:SCA %le\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 6 get_h_delay_scale */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "HOR:DEL:SCA?\n", "%lf\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 7 set_acq_mode */
  {&DSET_MBBO, GPIBEFASTO, IB_Q_LOW, NULL, NULL, 0, 127, NULL, 0, 0, AcqModeV, &AcqMode, NULL },

  /* CMMAND 8 get_acq_mode */
  {&DSET_MBBI,GPIBEFASTI, IB_Q_LOW,"ACQ:MOD?\n",NULL,0,127,0,0,0,AcqModeE, &AcqMode, NULL},

    /* CMMAND 9 set_numave */
  {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "ACQ:NUMAV %ld\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 10 get_numave */
  {&DSET_LI, GPIBREAD, IB_Q_LOW, "ACQ:NUMAV?\n", "%ld\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 11 set_acq_state */
  {&DSET_BO, GPIBEFASTO, IB_Q_LOW, NULL, NULL, 0, 127, NULL, 0, 0, AcqStateV, &AcqState, NULL },

    /* CMMAND 12 get_acq_state */
  {&DSET_BI, GPIBREAD, IB_Q_LOW, "ACQ:STATE?\n", NULL, 0, 127, NULL, 0, 0, NULL, &AcqState, NULL },

    /* CMMAND 13 set_ch1_offset */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "CH1:OFFSET %le\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 14 set_ch2_offset */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "CH2:OFFSET %le\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 15 get_ch1_offset */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "CH1:OFFSET?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 16 get_ch2_offset */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "CH2:OFFSET?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 17 set_ch1_scale */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "CH1:SCALE %le\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 18 set_ch2_scale */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "CH2:SCALE %lf\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 19 get_ch1_scale */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "CH1:SCALE?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 20 get_ch2_scale */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "CH2:SCALE?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 21 set_cls */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "*CLS\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 22 get_ch1_xinc */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "WFMPRE:CH1:XINCR?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 23 get_ch2_xinc */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "WFMPRE:CH2:XINCR?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 24 get_ch1_ymult */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "WFMPRE:CH1:YMULT?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 25 get_ch2_ymult */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "WFMPRE:CH2:YMULT?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 26 get_ch1_yoff */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "WFMPRE:CH1:YOFF?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 27 get_ch2_yoff */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "WFMPRE:CH2:YOFF?\n", "%lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 28 get_waveform_ch1 */
  {&DSET_WF, GPIBREAD, IB_Q_LOW, "CURVE?\n", NULL, 0, 819100, rd_wf_data, 0, 0, NULL, NULL, NULL },

    /* CMMAND 29 get_waveform_ch2 */
  {&DSET_WF, GPIBREAD, IB_Q_LOW, "CURVE?\n", NULL, 0, 819100, rd_wf_data, 0, 0, NULL, NULL, NULL},

    /* CMMAND 30 set_ch1_read       */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "DAT:SOU CH1;DAT:WID 2;DAT:ENC ASCI;DAT:STAR 1;DAT:STOP 500\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },

    /* CMMAND 31 set_ch2_read       */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "DAT:SOU CH2;DAT:WID 2;DAT:ENC ASCI;DAT:STAR 1;DAT:STOP 500\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },
  /* CMMAND 32 set_hor_tbpos      */
  {&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL, "HOR:DEL:TBP %le\n", 0, 127, NULL, 0, 0, NULL, NULL, NULL },
  /* CMMAND 33 get_hor_tbpos      */
  {&DSET_AI, GPIBREAD, IB_Q_LOW, "HOR:DEL:TBP?\n","%lf\n", 0,2047, NULL,0,0,NULL,NULL,NULL},

    /* CMMAND 34 set_hor_mode */
  {&DSET_MBBO, GPIBEFASTO, IB_Q_LOW, NULL, NULL, 0, 127, NULL, 0, 0, HorModeV, &HorMode, NULL },

  /* CMMAND 35 get_hor_mode */
  {&DSET_MBBI,GPIBEFASTI, IB_Q_LOW,"HOR:MOD?\n",NULL,0,127,0,0,0,HorModeE, &HorMode, NULL}


};




/* The following is the number of elements in the command array above.  */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)

/******************************************************************************
 * Initialize device support parameters
 *
 *****************************************************************************/
static long init_ai(int parm)
{
    if(parm==0) {
        devSupParms.name = "devTDS820";
        devSupParms.gpibCmds = gpibCmds;
        devSupParms.numparams = NUMPARAMS;
        devSupParms.timeout = TIMEOUT;
        devSupParms.timeWindow = TIMEWINDOW;
        devSupParms.respond2Writes = -1;
    }
    return(0);
}

/******************************************************************************
 *
 * c code
 *
 *****************************************************************************/
# line 60 "devTDS820.gt"

static short get_onedata(char wa1[])
{
  /*  printf(" get_one_data %s\n",wa1); */
 return atoi(wa1);
}
static int rd_data(char wav[],short vdata[])
{

 int i;
 char wa1[819100];
 
 strcpy(wa1,strtok(wav,","));
 vdata[0] = get_onedata(wa1);
 
 for (i=1;i<500;i++)
  {
   strcpy(wa1,strtok(NULL,","));
   vdata[i] = get_onedata(wa1);
  }
 return 0;
}


static int rd_wf_data(struct gpibDpvt *pdpvt,  int p1, int p2, char **p3)
{
  struct waveformRecord *pwf = (struct waveformRecord *) (pdpvt->precord);
  unsigned char	*craw;
  unsigned short *temparray;
  unsigned short  temp[819100],*ptemp;
  int	s[819100],ok_flag;        
  unsigned long	numElem;

  temparray = (unsigned short *) pwf->bptr;
  craw = pdpvt->msg; 

  
  ok_flag = rd_data(craw,temp);
 

  if (ok_flag != 0) 
    {
      /* devGpibLib_setPvSevr(pwf,READ_ALARM, INVALID_ALARM); */
      logMsg("Not OK TDS820\n");
      return(-1);
    }
  
  numElem = 500;
  if (numElem > pwf->nelm)      numElem = pwf->nelm;
  pwf->nord = numElem;
  ptemp=temp;	
  while (numElem--)
    {
      /*   printf( "\n%d-th data: %f",numElem, *ptemp);  */  
      *temparray++ = (short) *ptemp++;
    }
  /*  logMsg( "\nread_wf end normally\n"); */
  return(0);
}



mailto: makoto.tobiyama@kek.jp
Last update: 12/Jul/2010