#define DSET_AI devAiAnalytekGpib #define DSET_AO devAoAnalytekGpib #define DSET_LI devLiAnalytekGpib #define DSET_LO devLoAnalytekGpib #define DSET_BI devBiAnalytekGpib #define DSET_BO devBoAnalytekGpib #define DSET_MBBO devMbboAnalytekGpib #define DSET_MBBI devMbbiAnalytekGpib #define DSET_SI devSiAnalytekGpib #define DSET_SO devSoAnalytekGpib #define DSET_WF devWfAnalytekGpib #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define STATIC static long devGpibLib_initWf(); long devGpibLib_readWf(); int devGpibLib_wfGpibWork(); STATIC long init_dev_sup(), report(); STATIC struct devGpibParmBlock devSupParms; STATIC int getamprange(); /* used to get signal amplitude range */ STATIC int getrange(); /* used to get signal range */ STATIC int getoffset(); /* used to get signal offset */ int convertWave(); /* parses waveform data from analytek digitizer */ /****************************************************************************** * * Define all the dset's. * * Note that the dset names are provided via the #define lines at the top of * this file. * * Other than for the debugging flag(s), these DSETs are the only items that * will appear in the global name space within the IOC. * * The last 3 items in the DSET structure are used to point to the parm * structure, the work functions used for each record type, and the srq * handler for each record type. * ******************************************************************************/ gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, devGpibLib_readBi, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, devGpibLib_readSi, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, devGpibLib_readLi, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; gDset DSET_WF = {5, {NULL, NULL, devGpibLib_initWf, NULL, devGpibLib_readWf, (DRVSUPFUN)&devSupParms, (DRVSUPFUN)devGpibLib_wfGpibWork, NULL}}; int AnalytekDebug = 0; /* debugging flags */ extern int ibSrqDebug; static char *onoffList[] = { "Off","On" }; static unsigned long onoffVal[] = { 0,1 }; static struct devGpibNames onoff = { 2, onoffList, onoffVal, 4 }; /* * Use the TIME_WINDOW defn to indicate how long commands should be ignored * for a given device after it times out. The ignored commands will be * returned as errors to device support. * * Use the DMA_TIME to define how long you wish to wait for an I/O operation * to complete once started. */ #define TIME_WINDOW 600 /* 10 seconds on a getTick call */ #define DMA_TIME 6000 /* 1 second on a watchdog time */ static struct gpibCmd gpibCmds[] = { /* Param 0, (model) */ FILL, /* Function Commands */ /* Param 1, Clear status command */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*CLS\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 2, Return Power-on-Status Clear state */ {&DSET_BI, GPIBREAD, IB_Q_LOW, "*PSC?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 3, Set Power-on-Status Clear state */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*PSC %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 4, Recall device state */ {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*RCL %u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 5, Reset */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*RST\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 6, Save device state */ {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*SAV %u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 7, Perform self-test */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "*TST?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 8, Signal info, at end of parameter list */ FILL, /* Param 9, Request base average sample count */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "BASAVG?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 10, Set base average sample count */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BASAVG %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 11, Request state of base correction switch */ {&DSET_BI, GPIBREAD, IB_Q_LOW, "BASCOR?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 12, Set state of base correction switch */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "BASCOR %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 13 Request current channel on board 1 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "BDSEL?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 14, Set current channel on board 1 */ {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*BDSEL 1,%u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 15, Request sampling board types */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "BRDTYPE?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 16, Request state of calibration trigger */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "CALTRIG?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 17, Set state of calibration trigger, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Param 18, Request frequency of base clock in Mhz */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "CLKFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 19, Set frequency of base clock in Mhz */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "CLKFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 20, Return state of display*/ {&DSET_BI, GPIBREAD, IB_Q_LOW, "DISPlay?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 21, Set state of display */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "DISPlay %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 22, Return state of local switch*/ {&DSET_BI, GPIBREAD, IB_Q_LOW, "LOCAL?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 23, Set local switch on/off */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LOCAL %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 24, Return state of lockout switch */ {&DSET_BI, GPIBREAD, IB_Q_LOW, "LOCKOUT?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 25, Set lockout switch on/off */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LOCKOUT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 26, Request state of low pass filter */ {&DSET_BI, GPIBREAD, IB_Q_LOW, "LPFILT?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 27, Set low pass filter */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFILT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 28, Request length of FIR for low pass filter */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "LPFIR?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 29, Set FIR for low pass filter */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFIR %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 30, Request frequency of low pass filter */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "LPFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 31, Set frequency of low pass filter */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 32, Request filter mode, */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "LPMODE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 33, Set filter mode, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Param 34, Select single or multiple events */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "MEVENT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 35, Request number of samples stored in cache memory */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "MIREP?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 36, Set number of samples stored 8in cache memory */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "MIREP %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 37, Restart program, similar to external reset button */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "PGMRST\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 38, Request instrument to acquire a data sample */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "SAMPLE\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 39, Request state of signal averaging switch */ {&DSET_BI, GPIBREAD, IB_Q_LOW, "SIGAVG?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 40, Set state of signal averaging switch */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGAVG %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, /* Param 41, Request current average count */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGCNT?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 42, Request count of cycles to average before display modulo */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGDSP?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 43, Set count of cycles to average before display modulo */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGDSP %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 44, Request maximum count of cycles to be averaged */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGLMT?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 45, Set maximum count of cycles to be averaged */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGLMT %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 46, Signal info, */ FILL, /* Param 47, Request sampling frequency */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "SMPFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 48, Set sampling frequency */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SMPFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 49, Request sample offset for a channel, */ FILL, /* Param 50, Set sample offset for a channel, */ FILL, /* Param 51, Request sample size, */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "SMPSIZE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 52, Set sample size, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Param 53, Halt current sampling operation */ {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "STOP\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 54, Returns trigger coupling, */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGCOUPLE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 55, Set trigger coupling, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Param 56, Request trigger delay */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "TRGDELAY?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 57, Set trigger delay */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TRGDELAY %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 58, Requests trigger mode, */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGMODE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 59, Set trigger mode, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Param 60, Request trigger offset */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "TRGOFF?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 61, Set trigger offset */ {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TRGOFF %f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 62, Request trigger slope setting, */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGSLOPE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 63, Set trigger slope, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Param 64, Request trigger type, */ {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGTYPE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, /* Param 65, Set trigger type, */ {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, /* Channel 1 */ /* Param 66, Request amplitude range for signal on board 1 channel 1 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 67, Request range for signal on board 1 channel 1 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 68, Request offset for signal on board 1 channel 1 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 69, on board 1 channel 1 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,1", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 2 */ /* Param 70, Request amplitude range for signal on board 1 channel 2 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 71, Request range for signal on board 1 channel 2 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 72, Request offset for signal on board 1 channel 2 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 73, on board 1 channel 2 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,2", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 3 */ /* Param 74, Request amplitude range for signal on board 1 channel 3 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 67, Request range for signal on board 1 channel 3 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 68, Request offset for signal on board 1 channel 3 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 71, on board 1 channel 3 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,3", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 4 */ /* Param 72, Request amplitude range for signal on board 1 channel 2 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 73, Request range for signal on board 1 channel 2 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 74, Request offset for signal on board 1 channel 2 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 75, on board 1 channel 4 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,4", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 5 */ /* Param 76, Request amplitude range for signal on board 1 channel 5 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 77, Request range for signal on board 1 channel 5 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 78, Request offset for signal on board 1 channel 5 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 79, on board 1 channel 5 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,5", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 6 */ /* Param 80, Request amplitude range for signal on board 1 channel 6 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 81, Request range for signal on board 1 channel 6 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 82, Request offset for signal on board 1 channel 6 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 83, on board 1 channel 6 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,6", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 7 */ /* Param 84, Request amplitude range for signal on board 1 channel 7 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 85, Request range for signal on board 1 channel 7 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 86, Request offset for signal on board 1 channel 7 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 87, on board 1 channel 7 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,7", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 8 */ /* Param 88, Request amplitude range for signal on board 1 channel 8 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 89, Request range for signal on board 1 channel 8 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 90, Request offset for signal on board 1 channel 8 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 91, on board 1 channel 8 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,8", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 9 */ /* Param 92, Request amplitude range for signal on board 1 channel 9 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 93, Request range for signal on board 1 channel 9 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 94, Request offset for signal on board 1 channel 9 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 95, on board 1 channel 9 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,9", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 10 */ /* Param 96, Request amplitude range for signal on board 1 channel 10 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 97, Request range for signal on board 1 channel 10 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 98, Request offset for signal on board 1 channel 10 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 99, on board 1 channel 10 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,10", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 11 */ /* Param 100, Request amplitude range for signal on board 1 channel 11 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 101, Request range for signal on board 1 channel 11 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 102, Request offset for signal on board 1 channel 11 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 103, on board 1 channel 11 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,11", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 12 */ /* Param 104, Request amplitude range for signal on board 1 channel 12 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 105, Request range for signal on board 1 channel 12 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 106, Request offset for signal on board 1 channel 12 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 107, on board 1 channel 12 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,12", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 13 */ /* Param 108, Request amplitude range for signal on board 1 channel 13 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 109, Request range for signal on board 1 channel 13 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 110, Request offset for signal on board 1 channel 13 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 111, on board 1 channel 13 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,13", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 14 */ /* Param 112, Request amplitude range for signal on board 1 channel 14 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 113, Request range for signal on board 1 channel 14 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 114, Request offset for signal on board 1 channel 14 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 115, on board 1 channel 14 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,14", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, /* Channel 15 */ /* Param 116, Request amplitude range for signal on board 1 channel 15 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 117, Request range for signal on board 1 channel 15 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 118, Request offset for signal on board 1 channel 15 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 119, on board 1 channel 15 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,15", "%u", 0, 1100, convertWave , 0, 0, NULL, NULL, -1}, /* Channel 16 */ /* Param 120, Request amplitude range for signal on board 1 channel 16 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, /* Param 121, Request range for signal on board 1 channel 16 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, /* Param 122, Request offset for signal on board 1 channel 16 */ {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, /* Param 123, on board 1 channel 16 */ {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,16", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, }; /* The following is the number of elements in the command array above. */ #define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) /****************************************************************************** * * Structure containing the user's functions and operating parameters needed * by the gpib library functions. * * The magic SRQ parm is the parm number that, if specified on a passive * record, will cause the record to be processed automatically when an * unsolicited SRQ interrupt is detected from the device. * * If the parm is specified on a non-passive record, it will NOT be processed * when an unsolicited SRQ is detected. * ******************************************************************************/ static struct devGpibParmBlock devSupParms = { &AnalytekDebug, /* debugging flag pointer */ -1, /* set to -1 if the device does NOT respond to writes */ TIME_WINDOW, /* # of clock ticks to skip after a device times out */ NULL, /* hwpvt list head */ gpibCmds, /* GPIB command array */ NUMPARAMS, /* number of supported parameters */ -1, /* magic SRQ param number (-1 if none) */ "devXxAnalytekGpib", /* device support module type name */ DMA_TIME, /* # of clock ticks to wait for DMA completions */ NULL, /* pointer to SRQ handler function (NULL if none) */ NULL /* pointer to secondary conversion routine */ }; /****************************************************************************** * * 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. * * This function will no longer be required after epics 3.3 is released * ******************************************************************************/ STATIC long init_dev_sup(int parm) { return(devGpibLib_initDevSup(parm, &DSET_AI)); } /****************************************************************************** * * Print a report of operating statistics for all devices supported by this * module. * * This function will no longer be required after epics 3.3 is released * ******************************************************************************/ STATIC long report(void) { return(devGpibLib_report(&DSET_AI)); } STATIC int getamprange(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) { int amprange; int i; int status; struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord); if(AnalytekDebug) printf("getamprange AINFO? returned msg:%s\n",pdpvt->msg); /* Change all commas in returned string to blank spaces to seperate fields */ i=0; while(pdpvt->msg[i] != '\0') { if (pdpvt->msg[i] == ',') pdpvt->msg[i] = 0x20; /* blank space */ i++; } if(AnalytekDebug) printf("getamprange AINFO? new msg:%s\n",pdpvt->msg); /* Scan response string for signal amplitude range */ status = sscanf(pdpvt->msg, "%*c%d", &range); /* This sscanf command is command specific */ /* In this case the leading quote is skipped */ /* and the next number is assigned to amprange */ /* and the rest of the string is skipped */ if(AnalytekDebug) printf("getamprange AINFO? :sscan status = %d\n",status); printf("amprange = %d\n",amprange); /* if value was assigned, put value in data base */ if (status == 1) /* make sure message was received ok */ { /* sscanf returns an integer which tells */ pai->val = amprange; /* how many assignments were made */ } else { if (pai->nsev < INVALID_ALARM) { pai->nsev = INVALID_ALARM; pai->nsta = READ_ALARM; } } return(OK); } /* conversion routine */ STATIC int getrange(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) { int range; int i; int status; struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord); if(AnalytekDebug) printf("getrange AINFO? returned msg:%s\n",pdpvt->msg); /* Change all commas in returned string to blank spaces to seperate fields */ i=0; while(pdpvt->msg[i] != '\0') { if (pdpvt->msg[i] == ',') pdpvt->msg[i] = 0x20; i++; } if(AnalytekDebug) printf("getrange AINFO? new msg:%s\n",pdpvt->msg); /* Scan response string for signal amplitude range (paiar), range (pair), and offset (paio) */ status = sscanf(pdpvt->msg, "%*c%*d%d", &range); if(AnalytekDebug) printf("getrange AINFO? :sscan status = %d\n",status); if (status == 1) /* make sure message was received ok */ { /*assign new value */ pai->val = range; } else { if (pai->nsev < INVALID_ALARM) { pai->nsev = INVALID_ALARM; pai->nsta = READ_ALARM; } } return(OK); } /* conversion routine */ STATIC int getoffset(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) { float offset; int i; int status; struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord); if(AnalytekDebug) printf("getoffset AINFO? returned msg:%s\n",pdpvt->msg); /* Change all commas in returned string to blank spaces to seperate fields */ i=0; while(pdpvt->msg[i] != '\0') { if (pdpvt->msg[i] == ',') pdpvt->msg[i] = 0x20; i++; } if(AnalytekDebug) printf("getoffset AINFO? new msg:%s\n",pdpvt->msg); /* Scan response string for signal amplitude range (paiar), range (pair), and offset (paio) */ status = sscanf(pdpvt->msg, "%*c%*d%*d%f", &offset); if(AnalytekDebug) printf("getoffset AINFO? :sscan status = %d\n",status); if (status == 1) /* make sure message was received ok */ { /*assign new value */ pai->val = offset; } else { if (pai->nsev < INVALID_ALARM) { pai->nsev = INVALID_ALARM; pai->nsta = READ_ALARM; } } return(OK); } STATIC convertWave(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) { struct waveformRecord *pwf = (struct waveformRecord *) (pdpvt->precord); short *raw; char *craw; short *clean; unsigned long numElem; char asciiLen[10]; int ix; #define ANALTEK_BIAS 2048 if (AnalytekDebug) printf("Analytek waveform conversion routine entered\n"); clean = (short *) pwf->bptr; craw = pdpvt->msg; if (*craw != '#') { /* don't have a valid analytek waveform */ devGpibLib_setPvSevr(pwf,READ_ALARM,INVALID_ALARM); printf("Got an invalid waveform back!\n"); return(ERROR); } while (*craw == '#') craw++; ix = *craw - '0'; craw ++; raw = (short *) (craw + ix); asciiLen[ix] = '\0'; while(ix--) asciiLen[ix] = craw[ix]; if (sscanf (asciiLen, "%d", &numElem) != 1) { devGpibLib_setPvSevr(pwf,READ_ALARM,INVALID_ALARM); printf("Got an invalid waveform back!!\n"); return(ERROR); } numElem = numElem/2; /* 2 bytes per sample */ /* Fill in the pwf->nord field with number of elements read from analytek */ if (numElem > pwf->nelm) numElem = pwf->nelm; pwf->nord = numElem; /* convert the raw data in pdpvt->msg to a usable data-stream in pwf->bptr */ while (numElem) { *clean = (short) (*raw - ANALTEK_BIAS); clean++; raw++; numElem--; } return(OK); }