/*
* SR830 Lock-in AMP device support
*/
#include <epicsStdio.h>
#include <devCommonGpib.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.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 devAiSR830
#define DSET_AO devAoSR830
#define DSET_BI devBiSR830
#define DSET_BO devBoSR830
#define DSET_EV devEvSR830
#define DSET_LI devLiSR830
#define DSET_LO devLoSR830
#define DSET_MBBI devMbbiSR830
#define DSET_MBBID devMbbidSR830
#define DSET_MBBO devMbboSR830
#define DSET_MBBOD devMbbodSR830
#define DSET_SI devSiSR830
#define DSET_SO devSoSR830
#define DSET_WF devWfSR830
#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 */
static float get_onedata(char wa1[]);
static int rd_data(char wav[], float 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.
******************************************************************************/
/******************************************************************************
* 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.
******************************************************************************/
/******************************************************************************
* 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 and \n
* characters. When defining input strings so you include them as well.
******************************************************************************/
/******************************************************************************
* Array of structures that define all GPIB messages
* supported for this type of instrument.
******************************************************************************/
static struct gpibCmd gpibCmds[] = {
/* CMMAND 0 set referece phase shift */
{&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL,"PHAS %lf\n", 0, 2047, NULL, 0, 0, NULL, NULL, NULL },
/* CMD 1 read reference phase shift */
{&DSET_AI, GPIBREAD, IB_Q_LOW,"PHAS?\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 2 set freq */
{&DSET_AO, GPIBWRITE, IB_Q_LOW, NULL,"FREQ %lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 3 read freq */
{&DSET_AI, GPIBREAD, IB_Q_LOW,"FREQ?\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 4 set output amplitude */
{&DSET_AO, GPIBWRITE,IB_Q_LOW,NULL,"SLVL %lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 5 read output amplitude */
{&DSET_AI,GPIBREAD,IB_Q_LOW,"SLVL?\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 6 set SENS */
{&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL,"SENS %d\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 7 read SENS */
{&DSET_LI,GPIBREAD,IB_Q_LOW,"SENS?\n","%d\n",0.2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 8 set OFLT */
{&DSET_LO,GPIBWRITE,IB_Q_LOW,NULL,"OFLT %d\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 9 read OFLT */
{&DSET_LI,GPIBREAD,IB_Q_LOW,"OFLT?\n","%d\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 10 read detected amplitude */
{&DSET_AI,GPIBREAD,IB_Q_LOW,"OUTP? 3\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 11 read detected phase in degree */
{&DSET_AI,GPIBREAD,IB_Q_LOW,"OUTP?4\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 12 read X */
{&DSET_AI,GPIBREAD,IB_Q_LOW,"OUTP?1\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 13 read Y*/
{&DSET_AI,GPIBREAD,IB_Q_LOW,"OUTP?2\n","%lf\n",0,2047,NULL,0,0,NULL,NULL,NULL}
,
/* CMD 14 fast acquision */
{&DSET_LO,GPIBWRITE,IB_Q_LOW,NULL,"OUTX 1;FAST 2\n",0,2047,NULL,0,0,NULL,NULL,NULL},
/* CMD 15 snap command */
{&DSET_WF, GPIBREAD, IB_Q_LOW,"SNAP?1,2,3,4,9\n",NULL,0,819100,rd_wf_data,0,0,NULL,NULL,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 = "devSR830";
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.timeout = TIMEOUT;
devSupParms.timeWindow = TIMEWINDOW;
devSupParms.respond2Writes = -1;
}
return(0);
}
/******************************************************************************
*
* c code
*
*****************************************************************************/
static float get_onedata(char wa1[])
{
return atof(wa1);
}
static int rd_data(char wav[], float vdata[])
{
int i;
char wa1[819100];
strcpy(wa1,strtok(wav,","));
vdata[0] = get_onedata(wa1);
for (i=1;i<5;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;
float *temparray;
float temp[819100],*ptemp;
int s[819100],ok_flag;
unsigned long numElem;
temparray = ( float *) 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 SR830\n"); */
return(-1);
}
numElem = 5;
if (numElem > pwf->nelm) numElem = pwf->nelm;
pwf->nord = numElem;
ptemp=temp;
while (numElem--)
{
/* printf( "\n%d-th data: %f",numElem, *ptemp); */
*temparray++ = (float) *ptemp++;
}
/* logMsg( "\nread_wf end normally\n"); */
return(0);
}
mailto: makoto.tobiyama@kek.jp
Last update: 16/Sep/2011