From 59bda685fae5c404189565cce599ce8bcfaf7766 Mon Sep 17 00:00:00 2001 From: John Winans Date: Tue, 7 Jan 1992 14:40:36 +0000 Subject: [PATCH] changed to support gpib library --- src/devOpt/devXxDg535Gpib.c | 2445 ++++++--------------------- src/vxWorks/devOpt/devXxDg535Gpib.c | 2445 ++++++--------------------- 2 files changed, 1026 insertions(+), 3864 deletions(-) diff --git a/src/devOpt/devXxDg535Gpib.c b/src/devOpt/devXxDg535Gpib.c index eb43dc513..455ab9f91 100644 --- a/src/devOpt/devXxDg535Gpib.c +++ b/src/devOpt/devXxDg535Gpib.c @@ -1,8 +1,8 @@ /* devXxDg535Gpib.c */ -/* share/src/devOpt $Id$ */ +/* share/src/devOpt $Id$ */ /* - * Author: Ned D. Arnold - * Date: 05-28-91 + * Author: John Winans + * Date: 11-19-91 * * Experimental Physics and Industrial Control System (EPICS) * @@ -33,22 +33,14 @@ * * Modification Log: * ----------------- - * .01 05-30-91 nda Initial Release - * .02 06-18-91 nda init_rec_mbbo must return(2) if no init value - * .03 07-02-91 nda renamed String/StringOut DSET's to Si/So - * .04 07-11-91 jrw added the callbackRequest to process() - * .05 07-15-91 jrw redesigned init processing... more generic - * .06 11-01-91 jrw major rework to fit into new GPIB driver - * .07 11-11-91 jrw added new version of SRQ support - * ... + * .01 05-30-91 jrw Initial Release + * .02 01-06-92 nda dg535 support under EPICS 3.3 */ - - -/* devDg535Gpib.c - Device Support Routines */ -/* includes support for the following device types : */ - + #define DSET_AI devAiDg535Gpib #define DSET_AO devAoDg535Gpib +#define DSET_LI devLiDg535Gpib +#define DSET_LO devLoDg535Gpib #define DSET_BI devBiDg535Gpib #define DSET_BO devBoDg535Gpib #define DSET_MBBO devMbbiDg535Gpib @@ -80,764 +72,763 @@ #include #include #include +#include +#include #include +#include -extern struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; - int (*qGpibReq)(); - int (*registerSrqCallback)(); - int (*writeIb)(); - int (*readIb)(); - int (*writeIbCmd)(); - int (*ioctl)(); -} drvGpib; - -long init_dev_sup(); -long init_rec_ai(); -long read_ai(); -long init_rec_ao(); -long write_ao(); -long init_rec_bi(); -long read_bi(); -long init_rec_bo(); -long write_bo(); -long init_rec_mbbi(); -long read_mbbi(); -long init_rec_mbbo(); -long write_mbbo(); -long init_rec_stringin(); -long read_stringin(); -long init_rec_stringout(); -long write_stringout(); -long init_rec_xx(); - -long report(); - -int aiGpibWork(), aiGpibSrq(), aiGpibFinish(); -int aoGpibWork(); -int biGpibWork(), biGpibSrq(), biGpibFinish(); -int boGpibWork(); -int mbbiGpibWork(), mbbiGpibSrq(), mbbiGpibFinish(); -int mbboGpibWork(); -int stringinGpibWork(), stringinGpibSrq(), stringinGpibFinish(); -int stringoutGpibWork(); -int xxGpibWork(); - -int srqHandler(); - -void processCallback(); -void callbackRequest(); +long init_dev_sup(), report(); +int srqHandler(); +int aiGpibSrq(), liGpibSrq(), biGpibSrq(), mbbiGpibSrq(), stringinGpibSrq(); +struct devGpibParmBlock devSupParms; /****************************************************************************** * * Define all the dset's. * * Note that the dset names are provided via the #define lines at the top of - * the file. + * this file. * - * Other than for the debugging flag, these DSETs are the only items that + * 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. + * ******************************************************************************/ -/* ai dset*/ -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} gDset; +gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, + devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, + (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; -gDset DSET_AI = { 6, report, init_dev_sup, init_rec_ai, NULL, read_ai, NULL }; -gDset DSET_AO = { 6, NULL, NULL, init_rec_ao, NULL, write_ao, NULL }; -gDset DSET_BI = { 5, NULL, NULL, init_rec_bi, NULL, read_bi }; -gDset DSET_BO = { 5, NULL, NULL, init_rec_bo, NULL, write_bo }; -gDset DSET_MBBI = { 5, NULL, NULL, init_rec_mbbi, NULL, read_mbbi }; -gDset DSET_MBBO = { 5, NULL, NULL, init_rec_mbbo, NULL, write_mbbo }; -gDset DSET_SI = { 5, NULL, NULL, init_rec_stringin, NULL, read_stringin }; -gDset DSET_SO = { 5, NULL, NULL, init_rec_stringout, NULL, write_stringout }; +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}}; -/****************************************************************************** - * - * This section defines any device-type specific data areas. - * - ******************************************************************************/ -/*#define RESPONDS_2_WRITES */ /* if GPIB machine responds to writes */ -#define _SRQSUPPORT_ /* for srq support */ - -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ - -int dg535Debug = 0; +int Dg535Debug = 0; /* debugging flags */ extern int ibSrqDebug; -static char UDF[10] = "Undefined"; -static char pOK[3] = "OK"; - -/* forward declarations of some custom convert routines */ - -int setDelay(); /* used to set delay */ -int rdDelay(); /* used to place string in .DESC field */ - -/****************************************************************************** +/* + * 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. * - * This structure holds device-related data on a per-device basis and is - * referenced by the gpibDpvt structures. They are built using a linked - * list entered from hwpvtHead. This linked list is only for this specific - * device type (other gpib devices may have their own lists.) - * - ******************************************************************************/ -struct hwpvt { - struct hwpvt *next; /* to next structure for same type device */ + * 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 20 /* 1/3 second on a watchdog time */ - int linkType; /* is a GPIB_IO, BBGPIB_IO... from link.h */ - int link; /* link number */ - int bug; /* used only on BBGPIB_IO links */ - int device; /* gpib device number */ - - unsigned long tmoVal; /* time last timeout occurred */ - unsigned long tmoCount; /* total number of timeouts since boot time */ - - /* No semaphore guards here because can inly be mod'd by the linkTask */ - int (*srqCallback)(); /* filled by cmds expecting SRQ callbacks */ - caddr_t parm; /* filled in by cmds expecting SRQ callbacks */ -}; -static struct hwpvt *hwpvtHead = NULL; /* pointer to first hwpvt in chain */ - -/****************************************************************************** - * - * This structure will be attached to each pv (via psub->dpvt) to store the - * appropriate head.workStart pointer, callback address to record support, - * gpib link #, device address, and command information. - * - ******************************************************************************/ - -struct gpibDpvt { - struct dpvtGpibHead head; /* fields used by the GPIB driver */ - - short parm; /* parameter index into gpib commands */ - char *rsp; /* for read/write message error Responses*/ - char *msg; /* for read/write messages */ - struct dbCommon *precord; /* record this dpvt is part of */ - void (*process)(); /* callback to perform forward db processing */ - int processPri; /* process callback's priority */ - long linkType; /* GPIB_IO, BBGPIB_IO... */ - struct hwpvt *phwpvt; /* pointer to per-device private area */ -}; - -/****************************************************************************** - * - * This is used to define the strings that are used for button labels. - * These strings are put into the record's znam & onam foelds if the - * record is a BI or BO type and into the zrst, onst... fields of an - * MBBI or MBBO record. - * - * Before these strings are placed into the record, the record is - * check to see if there is already a string defined (could be user-entered - * with DCT.) If there is already a string present, it will be preserved. - * - * There MUST ALWAYS be 2 and only 2 entries in the names.item list - * for BI and BO records if a name list is being specified for them here. - * The names.count field is ignored for BI and BO record types, but - * should be properly specified as 2 for future compatibility. - * - * NOTE: - * If a name string is filled in an an MBBI/MBBO record, it's corresponding - * value will be filled in as well. For this reason, there MUST be - * a value array and a valid nobt value for every MBBI/MBBO record that - * contains an item array! - * - ******************************************************************************/ - -struct names { - int count; /* CURRENTLY only used for MBBI and MBBO */ - char **item; - unsigned long *value; /* CURRENTLY only used for MBBI and MBBO */ - short nobt; /* CURRENTLY only used for MBBI and MBBO */ -}; +/* + * Strings used by the init routines to fill in the znam, onam, ... + * fields in BI, BO, MBBI, and MBBO record types. + */ static char *offOnList[] = { "Off", "On" }; -static struct names offOn = { 2, offOnList, NULL, 1 }; +static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; static char *disableEnableList[] = { "Disable", "Enable" }; -static struct names disableEnable = { 2, disableEnableList, NULL, 1 }; +static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; static char *resetList[] = { "Reset", "Reset" }; -static struct names reset = { 2, resetList, NULL, 1 }; +static struct devGpibNames reset = { 2, resetList, NULL, 1 }; static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct names lozHiz = {2, lozHizList, NULL, 1}; +static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; static char *invertNormList[] = { "INVERT", "NORM" }; -static struct names invertNorm = { 2, invertNormList, NULL, 1 }; +static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct names fallingRising = { 2, fallingRisingList, NULL, 1 }; +static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; static char *singleShotList[] = { "SINGLE", "SHOT" }; -static struct names singleShot = { 2, singleShotList, NULL, 1 }; +static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 }; static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct names clear = { 2, clearList, NULL, 1 }; +static struct devGpibNames clear = { 2, clearList, NULL, 1 }; static char *tABCDList[] = { "T", "A", "B", "C", "D" }; static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 }; -static struct names tABCD = { 5, tABCDList, tABCDVal, 3 }; +static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 }; static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" }; static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 }; -static struct names ttlNimEclVar = { 4, ttlNimEclVarList, +static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList, ttlNimEclVarVal, 2 }; static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL", "SINGLE SHOT", "BURST MODE", "STOP" }; static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 }; -static struct names intExtSsBm = { 4, intExtSsBmStopList, +static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList, intExtSsBmStopVal, 2 }; -static struct names intExtSsBmStop = { 5, intExtSsBmStopList, +static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList, intExtSsBmStopVal, 3 }; /* Channel Names, used to derive string representation of programmed delay */ char *pchanName[8] = {" ", "T + ", "A + ", "B + ", " ", "C + ", "D + ", " "}; -/****************************************************************************** - * - * The following #define statements enumerate the record types that - * are supported by this device support module. These are used by the init - * routines when they to type checking against the records that have - * been defined for use with this type of GPIB device. - * - ******************************************************************************/ - -#define GPIB_AO 1 -#define GPIB_AI 2 -#define GPIB_BO 3 -#define GPIB_BI 4 -#define GPIB_MBBO 5 -#define GPIB_MBBI 6 -#define GPIB_SI 7 -#define GPIB_SO 8 /****************************************************************************** * - * Enumeration of gpib command types supported by this device type. + * String arrays for EFAST operations. Note that the last entry must be + * NULL. + * + * On input operations, only as many bytes as are found in the string array + * elements are compared. If there are more bytes than that in the input + * message, they are ignored. The first matching string found (starting + * from the 0'th element) will be used as a match. + * + * NOTE: For the input operations, the strings are compared literally! This + * can cause problems if the instrument is returning things like \r and \n + * characters. You must take care when defining input strings so you include + * them as well. * ******************************************************************************/ -#define GPIBREAD 1 -#define GPIBWRITE 2 -#define GPIBCMD 3 -#define GPIBCNTL 4 -#define GPIBSOFT 5 -#define GPIBREADW 6 -#define GPIBRAWREAD 7 - -/****************************************************************************** - * - * The next structure defines the GPIB command and format statements to - * extract or send data to a GPIB Instrument. Each transaction type is - * described below : - * - * GPIBREAD : (1) The cmd string is sent to the instrument - * (2) Data is read from the inst into a buffer (gpibDpvt.msg) - * (3) The important data is extracted from the buffer using the - * format string. - * - * GPIBWRITE: (1) An ascii string is generated using the format string and - * contents of the gpibDpvt->dbAddr->precord->val - * (2) The ascii string is sent to the instrument - * - * GPIBCMD : (1) The cmd string is sent to the instrument - * - * GPIBCNTL : (1) The control string is sent to the instrument (ATN active) - * - * GPIBSOFT : (1) No GPIB activity involved - normally retrieves internal data - * - * GPIBREADW : (1) The cmd string is sent to the instrument - * (2) Wait for SRQ - * (3) Data is read from the inst into a buffer (gpibDpvt.msg) - * (4) The important data is extracted from the buffer using the - * format string. - * - * GPIBRAWREAD: Used internally with GPIBREADW. Not useful from cmd table. - * - * If a particular GPIB message does not fit one of these formats, a custom - * routine may be provided. Store a pointer to this routine in the - * gpibCmd.convert field to use it rather than the above approaches. - * - ******************************************************************************/ - -struct gpibCmd { - int rec_typ; /* enum - GPIB_AO GPIB_AI GPIB_BO... */ - int type; /* enum - GPIBREAD, GPIBWRITE, GPIBCMND */ - short pri; /* priority of gpib request--IB_Q_HIGH or IB_Q_LOW*/ - char *sta; /* status string */ - char *cmd; /* CONSTANT STRING to send to instrument */ - char *format; /* string used to generate or interpret msg*/ - short rspLen; /* room for response error message*/ - short msgLen; /* room for return data message length*/ - - int (*convert)(); /* custom routine for wierd conversions */ - int P1; /* parameter used in convert*/ - int P2; /* parameter user in convert*/ - char **P3; /* pointer to array containing pointers to - strings */ - struct names *namelist; /* pointer to button label strings */ -}; - +static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; + /****************************************************************************** * * Array of structures that define all GPIB messages * supported for this type of instrument. * ******************************************************************************/ - -#define FILL {0,0,IB_Q_LOW, UDF,NULL,NULL,0,0,NULL,0,0,NULL,NULL } -#define FILL10 FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL +#define dg535FILL {0,0,0,NULL,NULL,0,0,NULL,0,0,NULL,NULL,-1} + +/* forward declarations of some custom convert routines */ +int setDelay(); +int rdDelay(); static struct gpibCmd gpibCmds[] = { /* Param 0, (model) */ -FILL, +dg535FILL, /* Channel A Delay and Output */ /* Param 1, write A delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 2\n", "DT 2,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 2, currently undefined */ - FILL, + dg535FILL, /* Param 3, read A Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL }, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, - /* Param 4, not yet implemented */ - FILL, + /* Param 4, read A delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 5, set A delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 2\n", "DT 2,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 6, read A delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, &tABCD, -1}, /* Param 7, set A output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 2,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 8, read A output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 2\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 9, set A output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 2,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 2,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 10, read A output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 2\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 2\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 11, set A output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 2,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 2,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 12, read A output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 2\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 2\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 13, set A output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 2,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 14, read A output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 2\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 15, set A output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 2,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 16, read A output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 2\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel B Delay and Output */ /* Param 17, write B delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 3\n", "DT 3,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 18, currently undefined */ - FILL, + dg535FILL, /* Param 19, read B Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 3\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1}, - /* Param 20, not yet implemented */ - FILL, + /* Param 20, read B delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 21, set B delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 3\n", "DT 3,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 22, read B delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 3\n", NULL, 0, 32, - rdDelay, 0 ,0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, + rdDelay, 0 ,0, NULL, &tABCD, -1}, /* Param 23, set B output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 3,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 24, read B output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 3\n", "%lu", 0 ,32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 3\n", "%lu", 0 ,32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 25, set B output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 3,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 3,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 26, read B output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 3\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 3\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 27, set B output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 3,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 3,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 28, read B output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 3\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 3\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 29, set B output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 3,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 30, read B output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 3\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 3\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 31, set B output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 3,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 32, read B output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 3\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 3\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel AB Outputs */ /* Param 33, set AB output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 4,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 34, read AB output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 4\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 35, set AB output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 4,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 4,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 36, read AB output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 4\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 4\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 37, set AB output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 4,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 4,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 38, read AB output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 4\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 4\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 39, set AB output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 4,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 40, read AB output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 4\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 41, set AB output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 4,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 42, read AB output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 4\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel C Delay and Output */ /* Param 43, write C delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 5\n", "DT 5,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 44, currently undefined */ - FILL, + dg535FILL, /* Param 45, read C Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1}, - /* Param 46, not yet implemented */ - FILL, + /* Param 46, read C delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 47, set C delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 5\n", "DT 5,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 48, read C delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, &tABCD, -1}, /* Param 49, set C output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 5,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 50, read C output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 5\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 51, set C output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 5,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 5,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 52, read C output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 5\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 5\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 53, set C output offset */ - {GPIB_AI, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 5,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 5,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 54, read C output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 5\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 5\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 55, set C output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 5,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 56, read C utput Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 5\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 57, set C output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 5,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 58, read C output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 5\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel D Delay and Output */ /* Param 59, write D delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 6\n", "DT 6,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 60, currently undefined */ - FILL, + dg535FILL, /* Param 61, read D Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 6\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1}, - /* Param 62, not yet implemented */ - FILL, + /* Param 62, read D delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 63, set D delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 6\n", "DT 6,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 64, read D delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 6\n", NULL, 0, 32, - rdDelay, 0 ,0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, + rdDelay, 0 ,0, NULL, &tABCD, -1}, /* Param 65, set D output mode */ - {GPIB_MBBI, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBWRITE, IB_Q_HIGH, NULL, "OM 6,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 66, read D output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 6\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 67, set D output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 6,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 6,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 68, read D output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 6\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 6\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 69, set D output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 6,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 6,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 70, read D output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 6\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 6\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 71, set D output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 6,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 72, read D output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 6\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 73, set D output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 6,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 74, read D output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 6\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel CD Outputs */ /* Param 75, set CD output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 7,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 76, read CD output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 7\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 77, set CD output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 7,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 7,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 78, read CD output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 7\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 7\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 79, set CD output offset */ - {GPIB_AI, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 7,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 7,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 80, read CD output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 7\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 7\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 81, set CD output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 7,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 82, read CD output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 7\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 83, set CD output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 7,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 84, read CD output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 7\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Trigger Settings */ /* Param 85, set Trig Mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TM %u\n", 0, 32, - NULL, 0, 0, NULL, &intExtSsBmStop}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "TM %u\n", 0, 32, + NULL, 0, 0, NULL, &intExtSsBmStop, -1}, /* Param 86, read Trig Mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "TM \n", "%lu", 0, 32, - NULL, 0, 0, NULL, &intExtSsBm}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "TM \n", "%lu", 0, 32, + NULL, 0, 0, NULL, &intExtSsBm, -1}, /* Param 87, set Trig Rate */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TR 0,%.3lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 0,%.3lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 88, read Trig Rate */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "TR 0\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 0\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 89, set Burst Rate */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TR 1,%.3lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 1,%.3lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 90, read Burst Rate */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "TR 1\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 1\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 91, set Burst Count */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "BC %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BC %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 92, read Burst Count */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "BC \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "BC \n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 93, set Burst Period */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "BP %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BP %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 94, read Burst Period */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "BP \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "BP \n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 95, set Trig Input Z */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 0,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 0,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 96, read Trig Input Z */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 0\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 0\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 97, set Trig Input slope */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TS %u\n", 0, 32, - NULL, 0, 0, NULL, &fallingRising}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TS %u\n", 0, 32, + NULL, 0, 0, NULL, &fallingRising, -1}, /* Param 98, read Trig Input slope */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TS \n", "%lu", 0, 32, - NULL, 0, 0, NULL, &fallingRising}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TS \n", "%lu", 0, 32, + NULL, 0, 0, NULL, &fallingRising, -1}, /* Param 99, set Trig Input level */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TL %.2lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TL %.2lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 100, read Trig Input Level */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "TL \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "TL \n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 101, generate Single Trig */ - {GPIB_BO, GPIBCMD, IB_Q_HIGH, UDF, "SS \n", NULL, 0, 32, - NULL, 0, 0, NULL, &singleShot}, + {&DSET_BO, GPIBCMD, IB_Q_HIGH, "SS \n", NULL, 0, 32, + NULL, 0, 0, NULL, &singleShot, -1}, /* Param 102, Store Setting # */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "ST %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "ST %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 103, Recall Setting # */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "RC %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "RC %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 104, Recall Setting # */ - {GPIB_BO, GPIBCMD, IB_Q_HIGH, UDF, "CL \n", NULL, 0, 32, - NULL, 0, 0, NULL, &clear} + {&DSET_BO, GPIBCMD, IB_Q_HIGH, "CL \n", NULL, 0, 32, + NULL, 0, 0, NULL, &clear, -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. + * + ******************************************************************************/ +struct devGpibParmBlock devSupParms = { + &Dg535Debug, /* debugging flag pointer */ + 0, /* set if the device responds 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 */ + 4, /* magic SRQ param number (-1 if none) */ + "devXxDg535Gpib", /* 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 */ +}; + +/****************************************************************************** + * + * This is invoked by the linkTask when an SRQ is detected from a device + * operated by this module. + * + * It calls the work routine associated with the type of record expecting + * the SRQ response. + * + * No semaphore locks are needed around the references to anything in the + * hwpvt structure, because it is static unless modified by the linkTask and + * the linkTask is what will execute this function. + * + * THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF... + * - the MAGIC_SRQ_PARM command is a GPIBREADW command. + * - the device generates unsolicited SRQs while processing GPIBREADW commands. + * + * In general, this function will have to be heavily modified for each device + * type that SRQs are to be supported. This is because the serial poll byte + * format varies from device to device. + * + ******************************************************************************/ + +/* NOT USED FOR DG535 ... NO SRQHANDLER FUNCTION POINTER DEFINED */ + +#define DG535_CMDERR 97 +#define DG535_EXEERR 98 +#define DG535_INTERR 99 + +#define DG535_PON 65 /* power just turned on */ +#define DG535_OPC 66 /* operation just completed */ +#define DG535_USER 67 /* user requested SRQ */ + +static int srqHandler(phwpvt, srqStatus) +struct hwpvt *phwpvt; +int srqStatus; /* The poll response from the device */ +{ + int status = IDLE; /* assume device will be idle when finished */ + + if (Dg535Debug || ibSrqDebug) + logMsg("srqHandler(0x%08.8X, 0x%02.2X): called\n", phwpvt, srqStatus); + + switch (srqStatus & 0xef) { + case DG535_OPC: + + /* Invoke the command-type specific SRQ handler */ + if (phwpvt->srqCallback != NULL) + status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); + else + logMsg("Unsolicited operation complete from DG535 device support!\n"); + break; +/* BUG - I have to clear out the error status by doing an err? read operation */ + + case DG535_USER: + + /* user requested srq event is specific to the Dg535 */ + logMsg("Dg535 User requested srq event link %d, device %d\n", phwpvt->link, phwpvt->device); + break; +/* BUG - I have to clear out the error status by doing an err? read operation */ + + case DG535_PON: + + logMsg("Power cycled on DG535\n"); + break; +/* BUG - I have to clear out the error status by doing an err? read operation */ + + default: + + + if (phwpvt->unsolicitedDpvt != NULL) + { + if(Dg535Debug || ibSrqDebug) + logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n", + phwpvt->link, phwpvt->device, srqStatus); + + ((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.finishProc = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process; + ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri; + callbackRequest(phwpvt->unsolicitedDpvt); + } + else + { + logMsg("Unsolicited SRQ ignored from link %d, device %d, status = 0x%02.2X\n", + phwpvt->link, phwpvt->device, srqStatus); + } + } + return(status); +} + +/****************************************************************************** + * + * 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(parm) +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() +{ + return(devGpibLib_report(&DSET_AI)); +} + + +/**************************************************************************** + * + * + * Custom convert routines for DG535 + * + * + ***************************************************************************/ -#define GPIBMSGLENGTH 32 /* used by the delay routines only */ /****************************************************************************** * * Unique message interpretaion for reading Channel Delays : - * The command to read the delay setting returns a string with two arguments. - * This routine extracts both arguments and assigns them appropriately. Also, + * The command to read the delay setting returns a string with two arguments, + * (eg 1, 4.300000000000) + * This routine extracts both arguments and assigns them appropriately. If the + * parameter corresponds to a "READ DELAY INTO STRING RECORD", * a string is generated with the format CHAN + xxx.xxxxxxxxxxxx and stored - * in the .DESC field of the ai record. (ex: T + .000000500000) If either - * parameter has changed, a db_post_event is issued for the .DESC field (ai - * record only). - * - ******************************************************************************/ + * in the val field of the SI record. (ex: T + .000000500000) + *****************************************************************************/ static int rdDelay(pdpvt) struct gpibDpvt *pdpvt; @@ -845,12 +836,12 @@ struct gpibDpvt *pdpvt; int status; double delay; unsigned long chan; - unsigned short monitor_mask = 0; struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); struct mbbiRecord *pmbbi= (struct mbbiRecord *)(pdpvt->precord); + struct stringinRecord *psi= (struct stringinRecord *)(pdpvt->precord); - if(dg535Debug) + if(Dg535Debug) logMsg("rdDelay : returned msg :%s\n",pdpvt->msg); /* Change the "," in returned string to a " " to separate fields */ @@ -859,32 +850,39 @@ struct gpibDpvt *pdpvt; /* scan response string for chan reference & delay value */ status = sscanf(pdpvt->msg, "%ld%lf", &chan, &delay); - if(dg535Debug) + if(Dg535Debug) logMsg("rdDelay :sscanf status = %d\n",status); switch (pdpvt->parm) { + case 4: /* A Delay monitor, must be an si record */ + case 20: /* B Delay monitor, must be an si record */ + case 46: /* C Delay monitor, must be an si record */ + case 62: /* D Delay monitor, must be an si record */ + if (status == 2) /* make sure both parameters were assigned */ + { + /* create a string in the value field*/ + strcpy(psi->val, pchanName[chan]); + strcat(pai->val, &((pdpvt->msg)[3])); + } + else + { + if (psi->nsev < VALID_ALARM) + { + psi->nsev = VALID_ALARM; + psi->nsta = READ_ALARM; + } + } + break; + case 3: /* A Delay monitor, must be an ai record */ case 19: /* B Delay monitor, must be an ai record */ case 45: /* C Delay monitor, must be an ai record */ case 61: /* D Delay monitor, must be an ai record */ if (status == 2) /* make sure both parameters were assigned */ { - /* check if delay or reference channel has changed */ - if ((pai->val != delay) || (pai->desc[0] != pchanName[chan][0])) - { - monitor_mask = DBE_VALUE; - } /* assign new delay to value field*/ pai->val = delay; - strcpy(pai->desc, pchanName[chan]); - strcat(pai->desc, &((pdpvt->msg)[3])); - if(dg535Debug) - logMsg("rdDelay : %s",pai->desc); - if (monitor_mask) - { - db_post_events(pai, pai->desc, monitor_mask); - } } else { @@ -922,51 +920,40 @@ struct gpibDpvt *pdpvt; * Unique message generation for writing channel Delays : * The command to set the channel delay requires two parameters: The channel * # to reference from and the time delay. Since changing either of these - * parameters requires the command to be sent, the current state of other - * parameter must be determined. This is done by reading the delay (which + * parameters requires the entire command to be sent, the current state of + * other parameter must be determined. This is done by reading the delay (which * returns both parameters), changing one of the paramaters, and sending * the command back. * - * WARNING!!!!! - * This function modifies the gpibCmds table!!! This is not a very nice - * thing to do! It is OK to do if only one dg535 is out there. But it will NOT - * work if there are more because modifying the gpibCmds table removes - * the re-entrant properties of this routine!!!! This should be - * re-designed to use a local temporary storage area. - * - ******************************************************************************/ + *************************************************************************/ static int setDelay(pdpvt) struct gpibDpvt *pdpvt; { int status; char curChan; - char tempMsg[GPIBMSGLENGTH]; + char tempMsg[32]; struct aoRecord *pao= (struct aoRecord *)(pdpvt->precord); struct mbboRecord *pmbbo= (struct mbboRecord *)(pdpvt->precord); - if(dg535Debug) + if(Dg535Debug) logMsg("setDelay : returned msg :%s\n",pdpvt->msg); - /* adjust the gpibCmd to do a GPIBREAD of the current - * delay setting first. - */ - - gpibCmds[pdpvt->parm].type = GPIBREAD; - - /* go read the current delay setting */ - if(xxGpibWork(pdpvt, gpibCmds[pdpvt->parm].type) == ERROR) - { /* abort operation if read failed */ - gpibCmds[pdpvt->parm].type = GPIBWRITE; /* set back to write */ - return(ERROR); /* return, signalling an error */ + /* go read the current delay & channel reference setting */ + /* this is done by specifying a GPIBREAD even though the gpibCmd is + defined as a GPIBWRITE. The cmd string in the gpibCmd is initialized + to make this work */ + + if(xxGpibWork(pdpvt, GPIBREAD) == ERROR) + { /* abort operation if read failed */ + return(ERROR); /* return, signalling an error */ } /* Due to a fluke in the DG535, read again to insure accurate data */ - if(xxGpibWork(pdpvt, gpibCmds[pdpvt->parm].type) == ERROR) /* go read the current delay setting */ - { /* abort operation if read failed */ - gpibCmds[pdpvt->parm].type = GPIBWRITE; /* set back to write */ + if(xxGpibWork(pdpvt, GPIBREAD) == ERROR) + { /* abort operation if read failed */ return(ERROR); /* return, signalling an error */ } @@ -989,1417 +976,11 @@ struct gpibDpvt *pdpvt; case 47: case 63: strcpy(tempMsg, &((pdpvt->msg)[3])); /* save current delay setting */ - /* generate new channel reference */ + /* generate new channel reference */ sprintf(pdpvt->msg, gpibCmds[pdpvt->parm].format, (unsigned int)pmbbo->rval); strcat(pdpvt->msg, tempMsg); /* append current delay setting */ break; } - gpibCmds[pdpvt->parm].type = GPIBWRITE; /* set cmnd back to write */ - return(OK); /* aoGpibWork or mbboGpibWork will call xxGpibWork */ } -/************************************************************************** - * - * This should be the end of device specific modifications. - * - **************************************************************************/ - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - ******************************************************************************/ -static long -report() -{ - struct hwpvt *phwpvt; - - printf("DG535 device support loaded:\n"); - - phwpvt = hwpvtHead; - - while (phwpvt != NULL) - { - if (phwpvt->linkType == GPIB_IO) - printf(" NI-link %d, node %d, timeouts %ld\n", phwpvt->link, phwpvt->device, phwpvt->tmoCount); - else if (phwpvt->linkType == BBGPIB_IO) - printf(" BB-link %d, bug %d, node %d, timeouts %ld\n", phwpvt->link, phwpvt->bug, phwpvt->device, phwpvt->tmoCount); - - phwpvt = phwpvt->next; - } - return(0); -} - - -/****************************************************************************** - * - * 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_dev_sup() -{ - - static char firstTime = 1; - - if (!firstTime) - { - return(OK); - } - firstTime = 0; - logMsg("dg535 Device Support Initializing ...\n"); - - return(OK); -} - -/****************************************************************************** - * - * Initialization routines. - * - ******************************************************************************/ -/****************************************************************************** - * - * ai record init - * - ******************************************************************************/ - -static long -init_rec_ai(pai, process) -struct aiRecord *pai; -void (*process)(); -{ - long result; - - /* Do common initialization */ - if (result = init_rec_xx((caddr_t) pai, &pai->inp, GPIB_AI)) - { - return(result); - } - /* Do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pai->dpvt)->head.workStart = aiGpibWork; - - return(0); -} - -/****************************************************************************** - * - * ao record init - * - ******************************************************************************/ - -static long -init_rec_ao(pao, process) -struct aoRecord *pao; -void (*process)(); -{ - long result; - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pao, &pao->out, GPIB_AO)) - { - return(result); - } - /* do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pao->dpvt)->head.workStart = aoGpibWork; - - return(0); -} - -/****************************************************************************** - * - * bi record init - * - ******************************************************************************/ - -static long -init_rec_bi(pbi, process) -struct biRecord *pbi; -void (*process)(); -{ - long result; - - /* Do common initialization */ - if (result = init_rec_xx((caddr_t) pbi, &pbi->inp, GPIB_BI)) - { - return(result); - } - /* Do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pbi->dpvt)->head.workStart = biGpibWork; - - /* See if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist != NULL) - { - if (pbi->znam[0] == '\0') - { - strcpy(pbi->znam, gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist->item[0]); - } - if (pbi->onam[0] == '\0') - { - strcpy(pbi->onam, gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist->item[1]); - } - } - return(0); -} - -/****************************************************************************** - * - * bo record init - * - ******************************************************************************/ - -static long -init_rec_bo(pbo, process) -struct boRecord *pbo; -void (*process)(); -{ - long result; - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pbo, &pbo->out, GPIB_BO)) - { - return(result); - } - /* do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pbo->dpvt)->head.workStart = boGpibWork; - - /* see if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist != NULL) - { - if (pbo->znam[0] == '\0') - { - strcpy(pbo->znam, gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist->item[0]); - } - if (pbo->onam[0] == '\0') - { - strcpy(pbo->onam, gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist->item[1]); - } - } - return(0); -} - -/****************************************************************************** - * - * mbbi record init - * - ******************************************************************************/ - -static long -init_rec_mbbi(pmbbi, process) -struct mbbiRecord *pmbbi; -void (*process)(); -{ - long result; - char message[100]; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - int name_ct; /* for filling in the name strings */ - char *name_ptr; /* index into name list array */ - unsigned long *val_ptr; /* indev into the value list array */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t)pmbbi, &pmbbi->inp, GPIB_MBBI)) - { - return(result); - } - - dpvt = (struct gpibDpvt *)pmbbi->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = mbbiGpibWork; - - /* see if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[dpvt->parm].namelist != NULL) - { - if (gpibCmds[dpvt->parm].namelist->value == NULL) - { - sprintf(message, "devDg535Gpib: MBBI value list wrong for param #%d\n", dpvt->parm); - logMsg(message); - return(ERROR); - } - pmbbi->nobt = gpibCmds[dpvt->parm].namelist->nobt; - name_ct = 0; /* current name string element */ - name_ptr = pmbbi->zrst; /* first name string element */ - val_ptr = &(pmbbi->zrvl); /* first value element */ - while (name_ct < gpibCmds[dpvt->parm].namelist->count) - { - if (name_ptr[0] == '\0') - { - strcpy(name_ptr, gpibCmds[dpvt->parm].namelist->item[name_ct]); - *val_ptr = gpibCmds[dpvt->parm].namelist->value[name_ct]; - } - name_ct++; - name_ptr += sizeof(pmbbi->zrst); - val_ptr++; - } - } - return(0); -} - -/****************************************************************************** - * - * mbbo record init - * - ******************************************************************************/ - -static long -init_rec_mbbo(pmbbo, process) -struct mbboRecord *pmbbo; -void (*process)(); -{ - long result; - char message[100]; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - int name_ct; /* for filling in the name strings */ - char *name_ptr; /* index into name list array */ - unsigned long *val_ptr; /* indev into the value list array */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t)pmbbo, &pmbbo->out, GPIB_MBBO)) - { - return(result); - } - - dpvt = (struct gpibDpvt *)pmbbo->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = mbboGpibWork; - - /* see if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[dpvt->parm].namelist != NULL) - { - if (gpibCmds[dpvt->parm].namelist->value == NULL) - { - sprintf(message, "devDg535Gpib: MBBO value list wrong for param #%d\ -n", dpvt->parm); - logMsg(message); - return(ERROR); - } - - pmbbo->nobt = gpibCmds[dpvt->parm].namelist->nobt; - name_ct = 0; /* current name string element */ - name_ptr = pmbbo->zrst; /* first name string element */ - val_ptr = &(pmbbo->zrvl); /* first value element */ - while (name_ct < gpibCmds[dpvt->parm].namelist->count) - { - if (name_ptr[0] == '\0') - { - strcpy(name_ptr, gpibCmds[dpvt->parm].namelist->item[name_ct]); - *val_ptr = gpibCmds[dpvt->parm].namelist->value[name_ct]; - } - name_ct++; - name_ptr += sizeof(pmbbo->zrst); - val_ptr++; - } - } - return(2); -} - -/****************************************************************************** - * - * stringin record init - * - ******************************************************************************/ - -static long -init_rec_stringin(pstringin, process) -struct stringinRecord *pstringin; -void (*process)(); -{ - long result; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pstringin, &pstringin->inp, GPIB_SI)) - { - return(result); - } - dpvt = (struct gpibDpvt *)pstringin->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = stringinGpibWork; - - return(0); -} - -/****************************************************************************** - * - * stringout record init - * - ******************************************************************************/ - -static long -init_rec_stringout(pstringout, process) -struct stringoutRecord *pstringout; -void (*process)(); -{ - long result; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pstringout, &pstringout->out, GPIB_SO)) - { - return(result); - } - - dpvt = (struct gpibDpvt *)pstringout->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = stringoutGpibWork; - - return(0); -} - -/****************************************************************************** - * - * This init routine is common to all record types - * - ******************************************************************************/ -static long -init_rec_xx(prec, plink, rec_typ) -struct dbCommon *prec; -struct link *plink; -int rec_typ; -{ - struct gpibDpvt *pdpvt; - struct dbCommon *pdbCommon = (struct dbCommon *)prec; - char message[100]; - struct gpibCmd *pCmd; - char foundIt; - int bbnode; - - /* allocate space for the private structure */ - pdpvt = (struct gpibDpvt *) malloc(sizeof(struct gpibDpvt)); - prec->dpvt = (void *) pdpvt; - - pdpvt->precord = prec; - pdpvt->parm = -1; /* In case the sscanf fails */ - pdpvt->linkType = plink->type; - - switch (plink->type) { - case GPIB_IO: /* Is a straight Network Instruments link */ - pdpvt->head.link = plink->value.gpibio.link; /* NI link number */ - pdpvt->head.device = plink->value.gpibio.addr; /* gpib dev address */ - sscanf(plink->value.gpibio.parm, "%hd", &(pdpvt->parm)); - pdpvt->head.bitBusDpvt = NULL; /* no bitbus data needed */ - bbnode = -1; - break; - - case BBGPIB_IO: /* Is a bitbus -> gpib link */ - pdpvt->head.device = plink->value.bbgpibio.gpibaddr; /* dev address */ - sscanf(plink->value.bbgpibio.parm, "%hd", &(pdpvt->parm)); - pdpvt->head.bitBusDpvt = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - pdpvt->head.bitBusDpvt->txMsg = (struct bitBusMsg *) malloc(sizeof(struct bitBusMsg)); - pdpvt->head.bitBusDpvt->rxMsg = (struct bitBusMsg *) malloc(sizeof(struct bitBusMsg)); - pdpvt->head.bitBusDpvt->txMsg->node = plink->value.bbgpibio.bbaddr; /* bug node address */ - bbnode = plink->value.bbgpibio.bbaddr; - pdpvt->head.bitBusDpvt->link = plink->value.bbgpibio.link; /* bug link number */ - pdpvt->head.link = plink->value.bbgpibio.link; - pdpvt->head.bitBusDpvt->rxMaxLen = sizeof(struct bitBusMsg); - break; - - default: - strcpy(message, pdbCommon->name); - strcat(message,": init_record : GPIB link type is invalid"); - errMessage(S_db_badField, message); - return(S_db_badField); - break; - } - /* Try to find the hardware private structure */ - foundIt = 0; - pdpvt->phwpvt = hwpvtHead; - while ((pdpvt->phwpvt != NULL) && !foundIt) - { - if (pdpvt->phwpvt->linkType == plink->type && - pdpvt->phwpvt->link == pdpvt->head.link && - pdpvt->phwpvt->device == pdpvt->head.device) - if (plink->type == BBGPIB_IO) - { - if (pdpvt->phwpvt->bug == pdpvt->head.bitBusDpvt->txMsg->node) - foundIt = 1; - } - else - foundIt = 1; - else - pdpvt->phwpvt = pdpvt->phwpvt->next; /* check the next one */ - } - if (!foundIt) - { /* I couldn't find it. Allocate a new one */ - pdpvt->phwpvt = (struct hwpvt *) malloc(sizeof (struct hwpvt)); - pdpvt->phwpvt->next = hwpvtHead; /* put at the top of the list */ - hwpvtHead = pdpvt->phwpvt; - - pdpvt->phwpvt->linkType = plink->type; - pdpvt->phwpvt->link = pdpvt->head.link; - pdpvt->phwpvt->device = pdpvt->head.device; - - if (pdpvt->phwpvt->linkType == BBGPIB_IO) - pdpvt->phwpvt->bug = pdpvt->head.bitBusDpvt->txMsg->node; - - pdpvt->phwpvt->tmoVal = 0; - pdpvt->phwpvt->tmoCount = 0; - pdpvt->phwpvt->srqCallback = NULL; - pdpvt->phwpvt->parm = (caddr_t)NULL; - } - - /* Check for valid GPIB address */ - if ((pdpvt->head.device < 0) || (pdpvt->head.device >= IBAPERLINK)) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record : GPIB address out of range"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - /* Check for valid param entry */ - if ((pdpvt->parm < 0) || (pdpvt->parm > NUMPARAMS)) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record : Parameter # out of range"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - /* make sure that the record type matches the GPIB port type (jrw) */ - if (gpibCmds[pdpvt->parm].rec_typ != rec_typ ) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record: record type invalid for spec'd param #"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - pCmd = &gpibCmds[pdpvt->parm]; - if(pCmd->msgLen > 0) - pdpvt->msg = (char *)(malloc(pCmd->msgLen)); - if(pCmd->rspLen > 0) - pdpvt->rsp = (char *)(malloc(pCmd->rspLen)); - -#ifdef _SRQSUPPORT_ -/* - * Ok to re-register a handler for the same device, just don't do it after - * init time is over! - */ - (*(drvGpib.registerSrqCallback))(pdpvt->linkType, pdpvt->head.link, - bbnode, pdpvt->head.device, srqHandler, pdpvt->phwpvt); -#endif - - /* fill in the required stuff for the callcack task (jrw) */ - pdpvt->process = processCallback; - pdpvt->processPri = priorityLow; - - return(0); -} - -/****************************************************************************** - * - * These are the functions that are called to actually communicate with - * the GPIB device. - * - ******************************************************************************/ -static long -read_ai(pai) -struct aiRecord *pai; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pai->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - if (pai->pact) - { - if (dg535Debug) - logMsg("read_ai with PACT = 1\n"); - return(2); /* work is all done, return '2' to indicate val */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dpvt field on ring buffer */ - if (dg535Debug) - logMsg("read_ai with PACT = 0\n"); - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pai,MAJOR_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -write_ao(pao) -struct aoRecord *pao; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pao->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pao->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pao,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -read_bi(pbi) -struct biRecord *pbi; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pbi->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pbi->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pbi,READ_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - - -static long -write_bo(pbo) -struct boRecord *pbo; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pbo->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pbo->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pbo,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -read_mbbi(pmbbi) -struct mbbiRecord *pmbbi; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pmbbi->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pmbbi->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - - -static long -write_mbbo(pmbbo) -struct mbboRecord *pmbbo; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pmbbo->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pmbbo->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -read_stringin(pstringin) -struct stringinRecord *pstringin; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pstringin->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - if (pstringin->pact) - { - if (dg535Debug) - logMsg("read_stringin with PACT = 1\n"); - return(2); /* work is all done, return '2' to indicate val */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if (dg535Debug) - logMsg("read_stringin with PACT = 0\n"); - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pstringin,MAJOR_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -write_stringout(pstringout) -struct stringoutRecord *pstringout; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pstringout->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pstringout->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pstringout,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -/****************************************************************************** - * - * Routines that do the actual GPIB work. They are called by the linkTask. - * - ******************************************************************************/ - -static int -aiGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct aiRecord *pai= ((struct aiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if(dg535Debug) - logMsg("aiGpibWork: starting ...\n"); - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - setPvSevr(pai,READ_ALARM,VALID_ALARM); - - if(dg535Debug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - } - else - { - if (pCmd->type != GPIBREADW) - aiGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = aiGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); /* indicate device is now idle */ -} - -static int -aiGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("aiGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; - - aiGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -aiGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - double value; - struct aiRecord *pai = ((struct aiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - if(dg535Debug) - logMsg("aiGpibWork: calling convert ...\n"); - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - if(dg535Debug) - logMsg("aiGpibWork: returned from convert ...\n"); - } - else /* interpret msg with predefined format and write into .val */ - { - /* scan response string, return value will be 1 if successful */ - if(sscanf(pdpvt->msg,pCmd->format,&value)) - { - pai->val = value; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pai,READ_ALARM,VALID_ALARM); - } - } - if(dg535Debug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - - return(0); -} - -static int -aoGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - struct aoRecord *pao= ((struct aoRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - sprintf(pdpvt->msg, pCmd->format, pao->val); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pao,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static int -biGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - setPvSevr(pbi,READ_ALARM,VALID_ALARM); - - if(dg535Debug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - } - else /* interpret response that came back */ - { - if (pCmd->type != GPIBREADW) - biGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = biGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); -} - -static int -biGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("biGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ - - biGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -biGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - unsigned long value; - struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* interpret msg with predefined format and write into .rval */ - { - /* scan response string, return value will be 1 if successful */ - if(sscanf(pdpvt->msg,pCmd->format, &value)) - { - pbi->rval = value; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pbi,READ_ALARM,VALID_ALARM); - } - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ - - return(0); -} - - -static int -boGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - int strStat = OK; - struct boRecord *pbo= ((struct boRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - sprintf(pdpvt->msg, pCmd->format, (unsigned int)pbo->val); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pbo,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); -} - -static int -mbbiGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read string response into msg[] */ - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM); - - if(dg535Debug) - logMsg("mbbiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - } - else - { - if (pCmd->type != GPIBREADW) - mbbiGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = mbbiGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); -} - -static int -mbbiGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("mbbiGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ - - mbbiGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -mbbiGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - unsigned long value; - struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* interpret msg with predefined format and write into .rval */ - { - /* scan response string, return value will be 1 if successful */ - if(sscanf(pdpvt->msg, pCmd->format, &value)) - { - pmbbi->rval = value; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); - } - } - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - - return(0); -} - -static int -mbboGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - int strStat = OK; - struct mbboRecord *pmbbo= ((struct mbboRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - sprintf(pdpvt->msg, pCmd->format, (unsigned int)pmbbo->rval); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static int -stringinGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct stringinRecord *pstringin=((struct stringinRecord*)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if(dg535Debug) - logMsg("stringinGpibWork: starting ...\n"); - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - if(dg535Debug) - logMsg("stringinGpibWork: error in xxGpibWork ...\n"); - setPvSevr(pstringin,READ_ALARM,VALID_ALARM); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ - } - else - { - if (pCmd->type != GPIBREADW) - stringinGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = stringinGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); -} - -static int -stringinGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("stringinGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ - - stringinGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -stringinGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct stringinRecord *pstringin=((struct stringinRecord*)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - if(dg535Debug) - logMsg("stringinGpibWork: calling convert ...\n"); - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - if(dg535Debug) - logMsg("stringinGpibWork: returned from convert ...\n"); - } - else /* interpret msg with predefined format and write into .val */ - { - /* scan response string, return value will be 1 if successful */ - strncpy(pstringin->val,pdpvt->msg,39); - pstringin->val[40] = '\0'; - } - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ - - return(0); -} - -static int -stringoutGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - struct stringoutRecord *pstringout= ((struct stringoutRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1, pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - strncpy(pdpvt->msg, pstringout->val, 40); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pstringout,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static int -xxGpibWork(pdpvt, cmdType) -struct gpibDpvt *pdpvt; -int cmdType; -{ - int status; /* for GPIBREAD, contains ERROR or # of bytes read */ - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - short ibnode = pdpvt->head.device; - short bbnode; /* In case is a bitbus->gpib type link */ - - /* If is a BBGPIB_IO link, the bug address is needed */ - if (pdpvt->linkType == BBGPIB_IO) - bbnode = pdpvt->head.bitBusDpvt->txMsg->node; - - /* - * check to see if this node has timed out within last 10 sec - */ - if(tickGet() < (pdpvt->phwpvt->tmoVal +TIME_WINDOW) ) - { - if (dg535Debug) - logMsg("dg535-xxGpibWork(): timeout flush\n"); - return(ERROR); - } - switch (cmdType) - { - case GPIBWRITE: /* write the message to the GPIB listen adrs */ - if(dg535Debug) - logMsg("xxGpibWork : processing GPIBWRITE\n"); - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pdpvt->msg, strlen(pdpvt->msg)); - - /* - * use for devices which respond to write commands - */ -#ifdef RESPONDS_2_WRITES - if (status == ERROR) - { - break; - } - status = (*(drvGpib.readIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pdpvt->rsp, pCmd->rspLen); -#endif - break; - - case GPIBREAD: /* write the command string */ - if(dg535Debug) - logMsg("xxGpibWork : processing GPIBREAD\n"); - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pCmd->cmd, strlen(pCmd->cmd)); - if (status == ERROR) - { - break; - } - /* This falls thru to the raw read code below! */ - - case GPIBRAWREAD: /* for SRQs, read the data w/o a sending a command */ - - /* read the instrument */ - status = (*(drvGpib.readIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pdpvt->msg, pCmd->msgLen); - if (status == ERROR) - { - break; - } - else if (status >( (pCmd->msgLen) - 1) ) /* check length of resp */ - { - logMsg("GPIB Response length equaled allocated space !!!\n"); - pdpvt->msg[(pCmd->msgLen)-1] = '\0'; /* place \0 at end */ - } - else - { - pdpvt->msg[status] = '\0'; /* terminate response with \0 */ - } - break; - - case GPIBREADW: /* for SRQs, write the command first */ - case GPIBCMD: /* write the cmd to the GPIB listen adrs */ - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pCmd->cmd, strlen(pCmd->cmd)); - break; - case GPIBCNTL: /* send cmd with atn line active */ - status = (*(drvGpib.writeIbCmd))(pdpvt->linkType, pdpvt->head.link, - bbnode, pCmd->cmd, strlen(pCmd->cmd)); - break; - } - if(dg535Debug) - logMsg("xxGpibWork : done, status = %d\n",status); - - /* if error occurrs then mark it with time */ - if(status == ERROR) - { - (pdpvt->phwpvt->tmoCount)++; /* count number of timeouts */ - pdpvt->phwpvt->tmoVal = tickGet(); /* set last timeout time */ - } - return(status); -} - -/****************************************************************************** - * - * This is invoked by the linkTask when an SRQ is detected from a device - * operated by this module. - * - * It calls the work routine associated with the type of record expecting - * the SRQ response. - * - * No semaphore locks are needed around the references to anything in the - * hwpvt structure, because it is static unless modified by the linkTask. - * - ******************************************************************************/ - -#ifdef _SRQSUPPORT_ - -static int srqHandler(phwpvt, srqStatus) -struct hwpvt *phwpvt; -int srqStatus; /* The poll response from the device */ -{ - if (dg535Debug || ibSrqDebug) - logMsg("srqHandler(0x%08.8X, 0x%02.2X): called\n", phwpvt, srqStatus); - - /* Invoke the command-type specific SRQ handler */ - if (phwpvt->srqCallback != NULL) - return((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); - - logMsg("Unsolicited SRQ rec'd from link %d, device %d, status = 0x%02.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - - return(IDLE); -} - -#endif /* _SRQSUPPORT_ */ - -/****************************************************************************** - * - * This function is called by the callback task. The callback task - * calls it after being given the 'go ahead' by callbackRequest() - * function calls made in the xxxWork routines defined above. - * - * The reason it is done this way is because the process() call may - * recursively call itself when records are chained and the callback - * task's stack is larger... just for this purpose. (jrw) - * - ******************************************************************************/ - -static void -processCallback(pDpvt) -struct gpibDpvt *pDpvt; -{ - if(dg535Debug) - logMsg("processCallback: calling process\n"); - - dbScanLock(pDpvt->precord); - (*(struct rset *)(pDpvt->precord->rset)).process(pDpvt->precord->pdba); - dbScanUnlock(pDpvt->precord); -} - -/****************************************************************************** - * - * This function is used to set alarm status information. - * - ******************************************************************************/ -static long -setPvSevr(pPv, status, severity) -struct dbCommon *pPv; -short severity; -short status; -{ - if (severity > pPv->nsev ) - { - pPv->nsta = status; - pPv->nsev = severity; - } -} diff --git a/src/vxWorks/devOpt/devXxDg535Gpib.c b/src/vxWorks/devOpt/devXxDg535Gpib.c index eb43dc513..455ab9f91 100644 --- a/src/vxWorks/devOpt/devXxDg535Gpib.c +++ b/src/vxWorks/devOpt/devXxDg535Gpib.c @@ -1,8 +1,8 @@ /* devXxDg535Gpib.c */ -/* share/src/devOpt $Id$ */ +/* share/src/devOpt $Id$ */ /* - * Author: Ned D. Arnold - * Date: 05-28-91 + * Author: John Winans + * Date: 11-19-91 * * Experimental Physics and Industrial Control System (EPICS) * @@ -33,22 +33,14 @@ * * Modification Log: * ----------------- - * .01 05-30-91 nda Initial Release - * .02 06-18-91 nda init_rec_mbbo must return(2) if no init value - * .03 07-02-91 nda renamed String/StringOut DSET's to Si/So - * .04 07-11-91 jrw added the callbackRequest to process() - * .05 07-15-91 jrw redesigned init processing... more generic - * .06 11-01-91 jrw major rework to fit into new GPIB driver - * .07 11-11-91 jrw added new version of SRQ support - * ... + * .01 05-30-91 jrw Initial Release + * .02 01-06-92 nda dg535 support under EPICS 3.3 */ - - -/* devDg535Gpib.c - Device Support Routines */ -/* includes support for the following device types : */ - + #define DSET_AI devAiDg535Gpib #define DSET_AO devAoDg535Gpib +#define DSET_LI devLiDg535Gpib +#define DSET_LO devLoDg535Gpib #define DSET_BI devBiDg535Gpib #define DSET_BO devBoDg535Gpib #define DSET_MBBO devMbbiDg535Gpib @@ -80,764 +72,763 @@ #include #include #include +#include +#include #include +#include -extern struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; - int (*qGpibReq)(); - int (*registerSrqCallback)(); - int (*writeIb)(); - int (*readIb)(); - int (*writeIbCmd)(); - int (*ioctl)(); -} drvGpib; - -long init_dev_sup(); -long init_rec_ai(); -long read_ai(); -long init_rec_ao(); -long write_ao(); -long init_rec_bi(); -long read_bi(); -long init_rec_bo(); -long write_bo(); -long init_rec_mbbi(); -long read_mbbi(); -long init_rec_mbbo(); -long write_mbbo(); -long init_rec_stringin(); -long read_stringin(); -long init_rec_stringout(); -long write_stringout(); -long init_rec_xx(); - -long report(); - -int aiGpibWork(), aiGpibSrq(), aiGpibFinish(); -int aoGpibWork(); -int biGpibWork(), biGpibSrq(), biGpibFinish(); -int boGpibWork(); -int mbbiGpibWork(), mbbiGpibSrq(), mbbiGpibFinish(); -int mbboGpibWork(); -int stringinGpibWork(), stringinGpibSrq(), stringinGpibFinish(); -int stringoutGpibWork(); -int xxGpibWork(); - -int srqHandler(); - -void processCallback(); -void callbackRequest(); +long init_dev_sup(), report(); +int srqHandler(); +int aiGpibSrq(), liGpibSrq(), biGpibSrq(), mbbiGpibSrq(), stringinGpibSrq(); +struct devGpibParmBlock devSupParms; /****************************************************************************** * * Define all the dset's. * * Note that the dset names are provided via the #define lines at the top of - * the file. + * this file. * - * Other than for the debugging flag, these DSETs are the only items that + * 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. + * ******************************************************************************/ -/* ai dset*/ -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} gDset; +gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, + devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, + (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; -gDset DSET_AI = { 6, report, init_dev_sup, init_rec_ai, NULL, read_ai, NULL }; -gDset DSET_AO = { 6, NULL, NULL, init_rec_ao, NULL, write_ao, NULL }; -gDset DSET_BI = { 5, NULL, NULL, init_rec_bi, NULL, read_bi }; -gDset DSET_BO = { 5, NULL, NULL, init_rec_bo, NULL, write_bo }; -gDset DSET_MBBI = { 5, NULL, NULL, init_rec_mbbi, NULL, read_mbbi }; -gDset DSET_MBBO = { 5, NULL, NULL, init_rec_mbbo, NULL, write_mbbo }; -gDset DSET_SI = { 5, NULL, NULL, init_rec_stringin, NULL, read_stringin }; -gDset DSET_SO = { 5, NULL, NULL, init_rec_stringout, NULL, write_stringout }; +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}}; -/****************************************************************************** - * - * This section defines any device-type specific data areas. - * - ******************************************************************************/ -/*#define RESPONDS_2_WRITES */ /* if GPIB machine responds to writes */ -#define _SRQSUPPORT_ /* for srq support */ - -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ - -int dg535Debug = 0; +int Dg535Debug = 0; /* debugging flags */ extern int ibSrqDebug; -static char UDF[10] = "Undefined"; -static char pOK[3] = "OK"; - -/* forward declarations of some custom convert routines */ - -int setDelay(); /* used to set delay */ -int rdDelay(); /* used to place string in .DESC field */ - -/****************************************************************************** +/* + * 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. * - * This structure holds device-related data on a per-device basis and is - * referenced by the gpibDpvt structures. They are built using a linked - * list entered from hwpvtHead. This linked list is only for this specific - * device type (other gpib devices may have their own lists.) - * - ******************************************************************************/ -struct hwpvt { - struct hwpvt *next; /* to next structure for same type device */ + * 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 20 /* 1/3 second on a watchdog time */ - int linkType; /* is a GPIB_IO, BBGPIB_IO... from link.h */ - int link; /* link number */ - int bug; /* used only on BBGPIB_IO links */ - int device; /* gpib device number */ - - unsigned long tmoVal; /* time last timeout occurred */ - unsigned long tmoCount; /* total number of timeouts since boot time */ - - /* No semaphore guards here because can inly be mod'd by the linkTask */ - int (*srqCallback)(); /* filled by cmds expecting SRQ callbacks */ - caddr_t parm; /* filled in by cmds expecting SRQ callbacks */ -}; -static struct hwpvt *hwpvtHead = NULL; /* pointer to first hwpvt in chain */ - -/****************************************************************************** - * - * This structure will be attached to each pv (via psub->dpvt) to store the - * appropriate head.workStart pointer, callback address to record support, - * gpib link #, device address, and command information. - * - ******************************************************************************/ - -struct gpibDpvt { - struct dpvtGpibHead head; /* fields used by the GPIB driver */ - - short parm; /* parameter index into gpib commands */ - char *rsp; /* for read/write message error Responses*/ - char *msg; /* for read/write messages */ - struct dbCommon *precord; /* record this dpvt is part of */ - void (*process)(); /* callback to perform forward db processing */ - int processPri; /* process callback's priority */ - long linkType; /* GPIB_IO, BBGPIB_IO... */ - struct hwpvt *phwpvt; /* pointer to per-device private area */ -}; - -/****************************************************************************** - * - * This is used to define the strings that are used for button labels. - * These strings are put into the record's znam & onam foelds if the - * record is a BI or BO type and into the zrst, onst... fields of an - * MBBI or MBBO record. - * - * Before these strings are placed into the record, the record is - * check to see if there is already a string defined (could be user-entered - * with DCT.) If there is already a string present, it will be preserved. - * - * There MUST ALWAYS be 2 and only 2 entries in the names.item list - * for BI and BO records if a name list is being specified for them here. - * The names.count field is ignored for BI and BO record types, but - * should be properly specified as 2 for future compatibility. - * - * NOTE: - * If a name string is filled in an an MBBI/MBBO record, it's corresponding - * value will be filled in as well. For this reason, there MUST be - * a value array and a valid nobt value for every MBBI/MBBO record that - * contains an item array! - * - ******************************************************************************/ - -struct names { - int count; /* CURRENTLY only used for MBBI and MBBO */ - char **item; - unsigned long *value; /* CURRENTLY only used for MBBI and MBBO */ - short nobt; /* CURRENTLY only used for MBBI and MBBO */ -}; +/* + * Strings used by the init routines to fill in the znam, onam, ... + * fields in BI, BO, MBBI, and MBBO record types. + */ static char *offOnList[] = { "Off", "On" }; -static struct names offOn = { 2, offOnList, NULL, 1 }; +static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; static char *disableEnableList[] = { "Disable", "Enable" }; -static struct names disableEnable = { 2, disableEnableList, NULL, 1 }; +static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; static char *resetList[] = { "Reset", "Reset" }; -static struct names reset = { 2, resetList, NULL, 1 }; +static struct devGpibNames reset = { 2, resetList, NULL, 1 }; static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct names lozHiz = {2, lozHizList, NULL, 1}; +static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; static char *invertNormList[] = { "INVERT", "NORM" }; -static struct names invertNorm = { 2, invertNormList, NULL, 1 }; +static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct names fallingRising = { 2, fallingRisingList, NULL, 1 }; +static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; static char *singleShotList[] = { "SINGLE", "SHOT" }; -static struct names singleShot = { 2, singleShotList, NULL, 1 }; +static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 }; static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct names clear = { 2, clearList, NULL, 1 }; +static struct devGpibNames clear = { 2, clearList, NULL, 1 }; static char *tABCDList[] = { "T", "A", "B", "C", "D" }; static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 }; -static struct names tABCD = { 5, tABCDList, tABCDVal, 3 }; +static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 }; static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" }; static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 }; -static struct names ttlNimEclVar = { 4, ttlNimEclVarList, +static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList, ttlNimEclVarVal, 2 }; static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL", "SINGLE SHOT", "BURST MODE", "STOP" }; static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 }; -static struct names intExtSsBm = { 4, intExtSsBmStopList, +static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList, intExtSsBmStopVal, 2 }; -static struct names intExtSsBmStop = { 5, intExtSsBmStopList, +static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList, intExtSsBmStopVal, 3 }; /* Channel Names, used to derive string representation of programmed delay */ char *pchanName[8] = {" ", "T + ", "A + ", "B + ", " ", "C + ", "D + ", " "}; -/****************************************************************************** - * - * The following #define statements enumerate the record types that - * are supported by this device support module. These are used by the init - * routines when they to type checking against the records that have - * been defined for use with this type of GPIB device. - * - ******************************************************************************/ - -#define GPIB_AO 1 -#define GPIB_AI 2 -#define GPIB_BO 3 -#define GPIB_BI 4 -#define GPIB_MBBO 5 -#define GPIB_MBBI 6 -#define GPIB_SI 7 -#define GPIB_SO 8 /****************************************************************************** * - * Enumeration of gpib command types supported by this device type. + * String arrays for EFAST operations. Note that the last entry must be + * NULL. + * + * On input operations, only as many bytes as are found in the string array + * elements are compared. If there are more bytes than that in the input + * message, they are ignored. The first matching string found (starting + * from the 0'th element) will be used as a match. + * + * NOTE: For the input operations, the strings are compared literally! This + * can cause problems if the instrument is returning things like \r and \n + * characters. You must take care when defining input strings so you include + * them as well. * ******************************************************************************/ -#define GPIBREAD 1 -#define GPIBWRITE 2 -#define GPIBCMD 3 -#define GPIBCNTL 4 -#define GPIBSOFT 5 -#define GPIBREADW 6 -#define GPIBRAWREAD 7 - -/****************************************************************************** - * - * The next structure defines the GPIB command and format statements to - * extract or send data to a GPIB Instrument. Each transaction type is - * described below : - * - * GPIBREAD : (1) The cmd string is sent to the instrument - * (2) Data is read from the inst into a buffer (gpibDpvt.msg) - * (3) The important data is extracted from the buffer using the - * format string. - * - * GPIBWRITE: (1) An ascii string is generated using the format string and - * contents of the gpibDpvt->dbAddr->precord->val - * (2) The ascii string is sent to the instrument - * - * GPIBCMD : (1) The cmd string is sent to the instrument - * - * GPIBCNTL : (1) The control string is sent to the instrument (ATN active) - * - * GPIBSOFT : (1) No GPIB activity involved - normally retrieves internal data - * - * GPIBREADW : (1) The cmd string is sent to the instrument - * (2) Wait for SRQ - * (3) Data is read from the inst into a buffer (gpibDpvt.msg) - * (4) The important data is extracted from the buffer using the - * format string. - * - * GPIBRAWREAD: Used internally with GPIBREADW. Not useful from cmd table. - * - * If a particular GPIB message does not fit one of these formats, a custom - * routine may be provided. Store a pointer to this routine in the - * gpibCmd.convert field to use it rather than the above approaches. - * - ******************************************************************************/ - -struct gpibCmd { - int rec_typ; /* enum - GPIB_AO GPIB_AI GPIB_BO... */ - int type; /* enum - GPIBREAD, GPIBWRITE, GPIBCMND */ - short pri; /* priority of gpib request--IB_Q_HIGH or IB_Q_LOW*/ - char *sta; /* status string */ - char *cmd; /* CONSTANT STRING to send to instrument */ - char *format; /* string used to generate or interpret msg*/ - short rspLen; /* room for response error message*/ - short msgLen; /* room for return data message length*/ - - int (*convert)(); /* custom routine for wierd conversions */ - int P1; /* parameter used in convert*/ - int P2; /* parameter user in convert*/ - char **P3; /* pointer to array containing pointers to - strings */ - struct names *namelist; /* pointer to button label strings */ -}; - +static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; + /****************************************************************************** * * Array of structures that define all GPIB messages * supported for this type of instrument. * ******************************************************************************/ - -#define FILL {0,0,IB_Q_LOW, UDF,NULL,NULL,0,0,NULL,0,0,NULL,NULL } -#define FILL10 FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL +#define dg535FILL {0,0,0,NULL,NULL,0,0,NULL,0,0,NULL,NULL,-1} + +/* forward declarations of some custom convert routines */ +int setDelay(); +int rdDelay(); static struct gpibCmd gpibCmds[] = { /* Param 0, (model) */ -FILL, +dg535FILL, /* Channel A Delay and Output */ /* Param 1, write A delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 2\n", "DT 2,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 2, currently undefined */ - FILL, + dg535FILL, /* Param 3, read A Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL }, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, - /* Param 4, not yet implemented */ - FILL, + /* Param 4, read A delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 5, set A delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 2\n", "DT 2,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 6, read A delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, &tABCD, -1}, /* Param 7, set A output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 2,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 8, read A output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 2\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 9, set A output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 2,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 2,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 10, read A output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 2\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 2\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 11, set A output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 2,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 2,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 12, read A output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 2\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 2\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 13, set A output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 2,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 14, read A output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 2\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 15, set A output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 2,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 16, read A output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 2\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel B Delay and Output */ /* Param 17, write B delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 3\n", "DT 3,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 18, currently undefined */ - FILL, + dg535FILL, /* Param 19, read B Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 3\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1}, - /* Param 20, not yet implemented */ - FILL, + /* Param 20, read B delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 21, set B delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 3\n", "DT 3,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 22, read B delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 3\n", NULL, 0, 32, - rdDelay, 0 ,0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, + rdDelay, 0 ,0, NULL, &tABCD, -1}, /* Param 23, set B output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 3,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 24, read B output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 3\n", "%lu", 0 ,32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 3\n", "%lu", 0 ,32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 25, set B output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 3,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 3,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 26, read B output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 3\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 3\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 27, set B output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 3,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 3,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 28, read B output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 3\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 3\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 29, set B output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 3,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 30, read B output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 3\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 3\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 31, set B output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 3,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 32, read B output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 3\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 3\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel AB Outputs */ /* Param 33, set AB output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 4,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 34, read AB output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 4\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 35, set AB output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 4,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 4,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 36, read AB output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 4\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 4\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 37, set AB output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 4,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 4,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 38, read AB output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 4\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 4\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 39, set AB output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 4,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 40, read AB output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 4\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 41, set AB output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 4,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 42, read AB output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 4\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel C Delay and Output */ /* Param 43, write C delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 5\n", "DT 5,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 44, currently undefined */ - FILL, + dg535FILL, /* Param 45, read C Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1}, - /* Param 46, not yet implemented */ - FILL, + /* Param 46, read C delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 47, set C delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 5\n", "DT 5,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 48, read C delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, &tABCD, -1}, /* Param 49, set C output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 5,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 50, read C output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 5\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 51, set C output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 5,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 5,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 52, read C output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 5\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 5\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 53, set C output offset */ - {GPIB_AI, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 5,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 5,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 54, read C output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 5\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 5\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 55, set C output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 5,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 56, read C utput Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 5\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 57, set C output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 5,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 58, read C output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 5\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel D Delay and Output */ /* Param 59, write D delay */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 6\n", "DT 6,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,?,%.12lf\n", 0, 32, + setDelay, 0, 0, NULL, NULL, -1}, /* Param 60, currently undefined */ - FILL, + dg535FILL, /* Param 61, read D Delay */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "DT 6\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1}, - /* Param 62, not yet implemented */ - FILL, + /* Param 62, read D delay reference channel and delay as string */ + {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, + rdDelay, 0, 0, NULL, NULL, -1 }, /* Param 63, set D delay reference channel */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, "DT 6\n", "DT 6,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,%u,", 0, 32, + setDelay, 0, 0, NULL, &tABCD, -1}, /* Param 64, read D delay reference */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "DT 6\n", NULL, 0, 32, - rdDelay, 0 ,0, NULL, &tABCD}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, + rdDelay, 0 ,0, NULL, &tABCD, -1}, /* Param 65, set D output mode */ - {GPIB_MBBI, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBWRITE, IB_Q_HIGH, NULL, "OM 6,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 66, read D output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 6\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 67, set D output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 6,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 6,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 68, read D output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 6\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 6\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 69, set D output offset */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 6,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 6,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 70, read D output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 6\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 6\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 71, set D output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 6,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 72, read D output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 6\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 73, set D output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 6,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 74, read D output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 6\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Channel CD Outputs */ /* Param 75, set CD output mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OM 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 7,%u\n", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 76, read CD output mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "OM 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 7\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &ttlNimEclVar, -1}, /* Param 77, set CD output amplitude */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OA 7,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 7,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 78, read CD output amplitude */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OA 7\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 7\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 79, set CD output offset */ - {GPIB_AI, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OO 7,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 7,%.1f\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 80, read CD output offset */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "OO 7\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 7\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 81, set CD output Termination */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 7,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 82, read CD output Termination */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 7\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 83, set CD output Polarity */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "OP 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 7,%u\n", 0, 32, + NULL, 0, 0, NULL, &invertNorm, -1}, /* Param 84, read CD output Polarity */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "OP 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 7\n", "%lu", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Trigger Settings */ /* Param 85, set Trig Mode */ - {GPIB_MBBO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TM %u\n", 0, 32, - NULL, 0, 0, NULL, &intExtSsBmStop}, + {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "TM %u\n", 0, 32, + NULL, 0, 0, NULL, &intExtSsBmStop, -1}, /* Param 86, read Trig Mode */ - {GPIB_MBBI, GPIBREAD, IB_Q_LOW, UDF, "TM \n", "%lu", 0, 32, - NULL, 0, 0, NULL, &intExtSsBm}, + {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "TM \n", "%lu", 0, 32, + NULL, 0, 0, NULL, &intExtSsBm, -1}, /* Param 87, set Trig Rate */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TR 0,%.3lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 0,%.3lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 88, read Trig Rate */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "TR 0\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 0\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 89, set Burst Rate */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TR 1,%.3lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 1,%.3lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 90, read Burst Rate */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "TR 1\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 1\n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 91, set Burst Count */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "BC %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BC %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 92, read Burst Count */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "BC \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "BC \n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 93, set Burst Period */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "BP %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BP %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 94, read Burst Period */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "BP \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "BP \n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 95, set Trig Input Z */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TZ 0,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 0,%u\n", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 96, read Trig Input Z */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TZ 0\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 0\n", "%lu", 0, 32, + NULL, 0, 0, NULL, &lozHiz, -1}, /* Param 97, set Trig Input slope */ - {GPIB_BO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TS %u\n", 0, 32, - NULL, 0, 0, NULL, &fallingRising}, + {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TS %u\n", 0, 32, + NULL, 0, 0, NULL, &fallingRising, -1}, /* Param 98, read Trig Input slope */ - {GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "TS \n", "%lu", 0, 32, - NULL, 0, 0, NULL, &fallingRising}, + {&DSET_BI, GPIBREAD, IB_Q_LOW, "TS \n", "%lu", 0, 32, + NULL, 0, 0, NULL, &fallingRising, -1}, /* Param 99, set Trig Input level */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "TL %.2lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TL %.2lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 100, read Trig Input Level */ - {GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "TL \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AI, GPIBREAD, IB_Q_LOW, "TL \n", "%lf", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 101, generate Single Trig */ - {GPIB_BO, GPIBCMD, IB_Q_HIGH, UDF, "SS \n", NULL, 0, 32, - NULL, 0, 0, NULL, &singleShot}, + {&DSET_BO, GPIBCMD, IB_Q_HIGH, "SS \n", NULL, 0, 32, + NULL, 0, 0, NULL, &singleShot, -1}, /* Param 102, Store Setting # */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "ST %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "ST %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 103, Recall Setting # */ - {GPIB_AO, GPIBWRITE, IB_Q_HIGH, UDF, NULL, "RC %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL}, + {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "RC %01.0lf\n", 0, 32, + NULL, 0, 0, NULL, NULL, -1}, /* Param 104, Recall Setting # */ - {GPIB_BO, GPIBCMD, IB_Q_HIGH, UDF, "CL \n", NULL, 0, 32, - NULL, 0, 0, NULL, &clear} + {&DSET_BO, GPIBCMD, IB_Q_HIGH, "CL \n", NULL, 0, 32, + NULL, 0, 0, NULL, &clear, -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. + * + ******************************************************************************/ +struct devGpibParmBlock devSupParms = { + &Dg535Debug, /* debugging flag pointer */ + 0, /* set if the device responds 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 */ + 4, /* magic SRQ param number (-1 if none) */ + "devXxDg535Gpib", /* 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 */ +}; + +/****************************************************************************** + * + * This is invoked by the linkTask when an SRQ is detected from a device + * operated by this module. + * + * It calls the work routine associated with the type of record expecting + * the SRQ response. + * + * No semaphore locks are needed around the references to anything in the + * hwpvt structure, because it is static unless modified by the linkTask and + * the linkTask is what will execute this function. + * + * THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF... + * - the MAGIC_SRQ_PARM command is a GPIBREADW command. + * - the device generates unsolicited SRQs while processing GPIBREADW commands. + * + * In general, this function will have to be heavily modified for each device + * type that SRQs are to be supported. This is because the serial poll byte + * format varies from device to device. + * + ******************************************************************************/ + +/* NOT USED FOR DG535 ... NO SRQHANDLER FUNCTION POINTER DEFINED */ + +#define DG535_CMDERR 97 +#define DG535_EXEERR 98 +#define DG535_INTERR 99 + +#define DG535_PON 65 /* power just turned on */ +#define DG535_OPC 66 /* operation just completed */ +#define DG535_USER 67 /* user requested SRQ */ + +static int srqHandler(phwpvt, srqStatus) +struct hwpvt *phwpvt; +int srqStatus; /* The poll response from the device */ +{ + int status = IDLE; /* assume device will be idle when finished */ + + if (Dg535Debug || ibSrqDebug) + logMsg("srqHandler(0x%08.8X, 0x%02.2X): called\n", phwpvt, srqStatus); + + switch (srqStatus & 0xef) { + case DG535_OPC: + + /* Invoke the command-type specific SRQ handler */ + if (phwpvt->srqCallback != NULL) + status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); + else + logMsg("Unsolicited operation complete from DG535 device support!\n"); + break; +/* BUG - I have to clear out the error status by doing an err? read operation */ + + case DG535_USER: + + /* user requested srq event is specific to the Dg535 */ + logMsg("Dg535 User requested srq event link %d, device %d\n", phwpvt->link, phwpvt->device); + break; +/* BUG - I have to clear out the error status by doing an err? read operation */ + + case DG535_PON: + + logMsg("Power cycled on DG535\n"); + break; +/* BUG - I have to clear out the error status by doing an err? read operation */ + + default: + + + if (phwpvt->unsolicitedDpvt != NULL) + { + if(Dg535Debug || ibSrqDebug) + logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n", + phwpvt->link, phwpvt->device, srqStatus); + + ((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.finishProc = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process; + ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri; + callbackRequest(phwpvt->unsolicitedDpvt); + } + else + { + logMsg("Unsolicited SRQ ignored from link %d, device %d, status = 0x%02.2X\n", + phwpvt->link, phwpvt->device, srqStatus); + } + } + return(status); +} + +/****************************************************************************** + * + * 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(parm) +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() +{ + return(devGpibLib_report(&DSET_AI)); +} + + +/**************************************************************************** + * + * + * Custom convert routines for DG535 + * + * + ***************************************************************************/ -#define GPIBMSGLENGTH 32 /* used by the delay routines only */ /****************************************************************************** * * Unique message interpretaion for reading Channel Delays : - * The command to read the delay setting returns a string with two arguments. - * This routine extracts both arguments and assigns them appropriately. Also, + * The command to read the delay setting returns a string with two arguments, + * (eg 1, 4.300000000000) + * This routine extracts both arguments and assigns them appropriately. If the + * parameter corresponds to a "READ DELAY INTO STRING RECORD", * a string is generated with the format CHAN + xxx.xxxxxxxxxxxx and stored - * in the .DESC field of the ai record. (ex: T + .000000500000) If either - * parameter has changed, a db_post_event is issued for the .DESC field (ai - * record only). - * - ******************************************************************************/ + * in the val field of the SI record. (ex: T + .000000500000) + *****************************************************************************/ static int rdDelay(pdpvt) struct gpibDpvt *pdpvt; @@ -845,12 +836,12 @@ struct gpibDpvt *pdpvt; int status; double delay; unsigned long chan; - unsigned short monitor_mask = 0; struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); struct mbbiRecord *pmbbi= (struct mbbiRecord *)(pdpvt->precord); + struct stringinRecord *psi= (struct stringinRecord *)(pdpvt->precord); - if(dg535Debug) + if(Dg535Debug) logMsg("rdDelay : returned msg :%s\n",pdpvt->msg); /* Change the "," in returned string to a " " to separate fields */ @@ -859,32 +850,39 @@ struct gpibDpvt *pdpvt; /* scan response string for chan reference & delay value */ status = sscanf(pdpvt->msg, "%ld%lf", &chan, &delay); - if(dg535Debug) + if(Dg535Debug) logMsg("rdDelay :sscanf status = %d\n",status); switch (pdpvt->parm) { + case 4: /* A Delay monitor, must be an si record */ + case 20: /* B Delay monitor, must be an si record */ + case 46: /* C Delay monitor, must be an si record */ + case 62: /* D Delay monitor, must be an si record */ + if (status == 2) /* make sure both parameters were assigned */ + { + /* create a string in the value field*/ + strcpy(psi->val, pchanName[chan]); + strcat(pai->val, &((pdpvt->msg)[3])); + } + else + { + if (psi->nsev < VALID_ALARM) + { + psi->nsev = VALID_ALARM; + psi->nsta = READ_ALARM; + } + } + break; + case 3: /* A Delay monitor, must be an ai record */ case 19: /* B Delay monitor, must be an ai record */ case 45: /* C Delay monitor, must be an ai record */ case 61: /* D Delay monitor, must be an ai record */ if (status == 2) /* make sure both parameters were assigned */ { - /* check if delay or reference channel has changed */ - if ((pai->val != delay) || (pai->desc[0] != pchanName[chan][0])) - { - monitor_mask = DBE_VALUE; - } /* assign new delay to value field*/ pai->val = delay; - strcpy(pai->desc, pchanName[chan]); - strcat(pai->desc, &((pdpvt->msg)[3])); - if(dg535Debug) - logMsg("rdDelay : %s",pai->desc); - if (monitor_mask) - { - db_post_events(pai, pai->desc, monitor_mask); - } } else { @@ -922,51 +920,40 @@ struct gpibDpvt *pdpvt; * Unique message generation for writing channel Delays : * The command to set the channel delay requires two parameters: The channel * # to reference from and the time delay. Since changing either of these - * parameters requires the command to be sent, the current state of other - * parameter must be determined. This is done by reading the delay (which + * parameters requires the entire command to be sent, the current state of + * other parameter must be determined. This is done by reading the delay (which * returns both parameters), changing one of the paramaters, and sending * the command back. * - * WARNING!!!!! - * This function modifies the gpibCmds table!!! This is not a very nice - * thing to do! It is OK to do if only one dg535 is out there. But it will NOT - * work if there are more because modifying the gpibCmds table removes - * the re-entrant properties of this routine!!!! This should be - * re-designed to use a local temporary storage area. - * - ******************************************************************************/ + *************************************************************************/ static int setDelay(pdpvt) struct gpibDpvt *pdpvt; { int status; char curChan; - char tempMsg[GPIBMSGLENGTH]; + char tempMsg[32]; struct aoRecord *pao= (struct aoRecord *)(pdpvt->precord); struct mbboRecord *pmbbo= (struct mbboRecord *)(pdpvt->precord); - if(dg535Debug) + if(Dg535Debug) logMsg("setDelay : returned msg :%s\n",pdpvt->msg); - /* adjust the gpibCmd to do a GPIBREAD of the current - * delay setting first. - */ - - gpibCmds[pdpvt->parm].type = GPIBREAD; - - /* go read the current delay setting */ - if(xxGpibWork(pdpvt, gpibCmds[pdpvt->parm].type) == ERROR) - { /* abort operation if read failed */ - gpibCmds[pdpvt->parm].type = GPIBWRITE; /* set back to write */ - return(ERROR); /* return, signalling an error */ + /* go read the current delay & channel reference setting */ + /* this is done by specifying a GPIBREAD even though the gpibCmd is + defined as a GPIBWRITE. The cmd string in the gpibCmd is initialized + to make this work */ + + if(xxGpibWork(pdpvt, GPIBREAD) == ERROR) + { /* abort operation if read failed */ + return(ERROR); /* return, signalling an error */ } /* Due to a fluke in the DG535, read again to insure accurate data */ - if(xxGpibWork(pdpvt, gpibCmds[pdpvt->parm].type) == ERROR) /* go read the current delay setting */ - { /* abort operation if read failed */ - gpibCmds[pdpvt->parm].type = GPIBWRITE; /* set back to write */ + if(xxGpibWork(pdpvt, GPIBREAD) == ERROR) + { /* abort operation if read failed */ return(ERROR); /* return, signalling an error */ } @@ -989,1417 +976,11 @@ struct gpibDpvt *pdpvt; case 47: case 63: strcpy(tempMsg, &((pdpvt->msg)[3])); /* save current delay setting */ - /* generate new channel reference */ + /* generate new channel reference */ sprintf(pdpvt->msg, gpibCmds[pdpvt->parm].format, (unsigned int)pmbbo->rval); strcat(pdpvt->msg, tempMsg); /* append current delay setting */ break; } - gpibCmds[pdpvt->parm].type = GPIBWRITE; /* set cmnd back to write */ - return(OK); /* aoGpibWork or mbboGpibWork will call xxGpibWork */ } -/************************************************************************** - * - * This should be the end of device specific modifications. - * - **************************************************************************/ - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - ******************************************************************************/ -static long -report() -{ - struct hwpvt *phwpvt; - - printf("DG535 device support loaded:\n"); - - phwpvt = hwpvtHead; - - while (phwpvt != NULL) - { - if (phwpvt->linkType == GPIB_IO) - printf(" NI-link %d, node %d, timeouts %ld\n", phwpvt->link, phwpvt->device, phwpvt->tmoCount); - else if (phwpvt->linkType == BBGPIB_IO) - printf(" BB-link %d, bug %d, node %d, timeouts %ld\n", phwpvt->link, phwpvt->bug, phwpvt->device, phwpvt->tmoCount); - - phwpvt = phwpvt->next; - } - return(0); -} - - -/****************************************************************************** - * - * 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_dev_sup() -{ - - static char firstTime = 1; - - if (!firstTime) - { - return(OK); - } - firstTime = 0; - logMsg("dg535 Device Support Initializing ...\n"); - - return(OK); -} - -/****************************************************************************** - * - * Initialization routines. - * - ******************************************************************************/ -/****************************************************************************** - * - * ai record init - * - ******************************************************************************/ - -static long -init_rec_ai(pai, process) -struct aiRecord *pai; -void (*process)(); -{ - long result; - - /* Do common initialization */ - if (result = init_rec_xx((caddr_t) pai, &pai->inp, GPIB_AI)) - { - return(result); - } - /* Do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pai->dpvt)->head.workStart = aiGpibWork; - - return(0); -} - -/****************************************************************************** - * - * ao record init - * - ******************************************************************************/ - -static long -init_rec_ao(pao, process) -struct aoRecord *pao; -void (*process)(); -{ - long result; - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pao, &pao->out, GPIB_AO)) - { - return(result); - } - /* do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pao->dpvt)->head.workStart = aoGpibWork; - - return(0); -} - -/****************************************************************************** - * - * bi record init - * - ******************************************************************************/ - -static long -init_rec_bi(pbi, process) -struct biRecord *pbi; -void (*process)(); -{ - long result; - - /* Do common initialization */ - if (result = init_rec_xx((caddr_t) pbi, &pbi->inp, GPIB_BI)) - { - return(result); - } - /* Do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pbi->dpvt)->head.workStart = biGpibWork; - - /* See if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist != NULL) - { - if (pbi->znam[0] == '\0') - { - strcpy(pbi->znam, gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist->item[0]); - } - if (pbi->onam[0] == '\0') - { - strcpy(pbi->onam, gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist->item[1]); - } - } - return(0); -} - -/****************************************************************************** - * - * bo record init - * - ******************************************************************************/ - -static long -init_rec_bo(pbo, process) -struct boRecord *pbo; -void (*process)(); -{ - long result; - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pbo, &pbo->out, GPIB_BO)) - { - return(result); - } - /* do initialization of other fields in the record that are unique - * to this record type */ - - ((struct gpibDpvt *)pbo->dpvt)->head.workStart = boGpibWork; - - /* see if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist != NULL) - { - if (pbo->znam[0] == '\0') - { - strcpy(pbo->znam, gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist->item[0]); - } - if (pbo->onam[0] == '\0') - { - strcpy(pbo->onam, gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist->item[1]); - } - } - return(0); -} - -/****************************************************************************** - * - * mbbi record init - * - ******************************************************************************/ - -static long -init_rec_mbbi(pmbbi, process) -struct mbbiRecord *pmbbi; -void (*process)(); -{ - long result; - char message[100]; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - int name_ct; /* for filling in the name strings */ - char *name_ptr; /* index into name list array */ - unsigned long *val_ptr; /* indev into the value list array */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t)pmbbi, &pmbbi->inp, GPIB_MBBI)) - { - return(result); - } - - dpvt = (struct gpibDpvt *)pmbbi->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = mbbiGpibWork; - - /* see if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[dpvt->parm].namelist != NULL) - { - if (gpibCmds[dpvt->parm].namelist->value == NULL) - { - sprintf(message, "devDg535Gpib: MBBI value list wrong for param #%d\n", dpvt->parm); - logMsg(message); - return(ERROR); - } - pmbbi->nobt = gpibCmds[dpvt->parm].namelist->nobt; - name_ct = 0; /* current name string element */ - name_ptr = pmbbi->zrst; /* first name string element */ - val_ptr = &(pmbbi->zrvl); /* first value element */ - while (name_ct < gpibCmds[dpvt->parm].namelist->count) - { - if (name_ptr[0] == '\0') - { - strcpy(name_ptr, gpibCmds[dpvt->parm].namelist->item[name_ct]); - *val_ptr = gpibCmds[dpvt->parm].namelist->value[name_ct]; - } - name_ct++; - name_ptr += sizeof(pmbbi->zrst); - val_ptr++; - } - } - return(0); -} - -/****************************************************************************** - * - * mbbo record init - * - ******************************************************************************/ - -static long -init_rec_mbbo(pmbbo, process) -struct mbboRecord *pmbbo; -void (*process)(); -{ - long result; - char message[100]; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - int name_ct; /* for filling in the name strings */ - char *name_ptr; /* index into name list array */ - unsigned long *val_ptr; /* indev into the value list array */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t)pmbbo, &pmbbo->out, GPIB_MBBO)) - { - return(result); - } - - dpvt = (struct gpibDpvt *)pmbbo->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = mbboGpibWork; - - /* see if there are names asociated with the record that should */ - /* be filled in */ - if (gpibCmds[dpvt->parm].namelist != NULL) - { - if (gpibCmds[dpvt->parm].namelist->value == NULL) - { - sprintf(message, "devDg535Gpib: MBBO value list wrong for param #%d\ -n", dpvt->parm); - logMsg(message); - return(ERROR); - } - - pmbbo->nobt = gpibCmds[dpvt->parm].namelist->nobt; - name_ct = 0; /* current name string element */ - name_ptr = pmbbo->zrst; /* first name string element */ - val_ptr = &(pmbbo->zrvl); /* first value element */ - while (name_ct < gpibCmds[dpvt->parm].namelist->count) - { - if (name_ptr[0] == '\0') - { - strcpy(name_ptr, gpibCmds[dpvt->parm].namelist->item[name_ct]); - *val_ptr = gpibCmds[dpvt->parm].namelist->value[name_ct]; - } - name_ct++; - name_ptr += sizeof(pmbbo->zrst); - val_ptr++; - } - } - return(2); -} - -/****************************************************************************** - * - * stringin record init - * - ******************************************************************************/ - -static long -init_rec_stringin(pstringin, process) -struct stringinRecord *pstringin; -void (*process)(); -{ - long result; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pstringin, &pstringin->inp, GPIB_SI)) - { - return(result); - } - dpvt = (struct gpibDpvt *)pstringin->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = stringinGpibWork; - - return(0); -} - -/****************************************************************************** - * - * stringout record init - * - ******************************************************************************/ - -static long -init_rec_stringout(pstringout, process) -struct stringoutRecord *pstringout; -void (*process)(); -{ - long result; - struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ - - /* do common initialization */ - if (result = init_rec_xx((caddr_t) pstringout, &pstringout->out, GPIB_SO)) - { - return(result); - } - - dpvt = (struct gpibDpvt *)pstringout->dpvt; /* init pointer to gpibDpvt */ - - /* do initialization of other fields in the record that are unique - * to this record type */ - - dpvt->head.workStart = stringoutGpibWork; - - return(0); -} - -/****************************************************************************** - * - * This init routine is common to all record types - * - ******************************************************************************/ -static long -init_rec_xx(prec, plink, rec_typ) -struct dbCommon *prec; -struct link *plink; -int rec_typ; -{ - struct gpibDpvt *pdpvt; - struct dbCommon *pdbCommon = (struct dbCommon *)prec; - char message[100]; - struct gpibCmd *pCmd; - char foundIt; - int bbnode; - - /* allocate space for the private structure */ - pdpvt = (struct gpibDpvt *) malloc(sizeof(struct gpibDpvt)); - prec->dpvt = (void *) pdpvt; - - pdpvt->precord = prec; - pdpvt->parm = -1; /* In case the sscanf fails */ - pdpvt->linkType = plink->type; - - switch (plink->type) { - case GPIB_IO: /* Is a straight Network Instruments link */ - pdpvt->head.link = plink->value.gpibio.link; /* NI link number */ - pdpvt->head.device = plink->value.gpibio.addr; /* gpib dev address */ - sscanf(plink->value.gpibio.parm, "%hd", &(pdpvt->parm)); - pdpvt->head.bitBusDpvt = NULL; /* no bitbus data needed */ - bbnode = -1; - break; - - case BBGPIB_IO: /* Is a bitbus -> gpib link */ - pdpvt->head.device = plink->value.bbgpibio.gpibaddr; /* dev address */ - sscanf(plink->value.bbgpibio.parm, "%hd", &(pdpvt->parm)); - pdpvt->head.bitBusDpvt = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - pdpvt->head.bitBusDpvt->txMsg = (struct bitBusMsg *) malloc(sizeof(struct bitBusMsg)); - pdpvt->head.bitBusDpvt->rxMsg = (struct bitBusMsg *) malloc(sizeof(struct bitBusMsg)); - pdpvt->head.bitBusDpvt->txMsg->node = plink->value.bbgpibio.bbaddr; /* bug node address */ - bbnode = plink->value.bbgpibio.bbaddr; - pdpvt->head.bitBusDpvt->link = plink->value.bbgpibio.link; /* bug link number */ - pdpvt->head.link = plink->value.bbgpibio.link; - pdpvt->head.bitBusDpvt->rxMaxLen = sizeof(struct bitBusMsg); - break; - - default: - strcpy(message, pdbCommon->name); - strcat(message,": init_record : GPIB link type is invalid"); - errMessage(S_db_badField, message); - return(S_db_badField); - break; - } - /* Try to find the hardware private structure */ - foundIt = 0; - pdpvt->phwpvt = hwpvtHead; - while ((pdpvt->phwpvt != NULL) && !foundIt) - { - if (pdpvt->phwpvt->linkType == plink->type && - pdpvt->phwpvt->link == pdpvt->head.link && - pdpvt->phwpvt->device == pdpvt->head.device) - if (plink->type == BBGPIB_IO) - { - if (pdpvt->phwpvt->bug == pdpvt->head.bitBusDpvt->txMsg->node) - foundIt = 1; - } - else - foundIt = 1; - else - pdpvt->phwpvt = pdpvt->phwpvt->next; /* check the next one */ - } - if (!foundIt) - { /* I couldn't find it. Allocate a new one */ - pdpvt->phwpvt = (struct hwpvt *) malloc(sizeof (struct hwpvt)); - pdpvt->phwpvt->next = hwpvtHead; /* put at the top of the list */ - hwpvtHead = pdpvt->phwpvt; - - pdpvt->phwpvt->linkType = plink->type; - pdpvt->phwpvt->link = pdpvt->head.link; - pdpvt->phwpvt->device = pdpvt->head.device; - - if (pdpvt->phwpvt->linkType == BBGPIB_IO) - pdpvt->phwpvt->bug = pdpvt->head.bitBusDpvt->txMsg->node; - - pdpvt->phwpvt->tmoVal = 0; - pdpvt->phwpvt->tmoCount = 0; - pdpvt->phwpvt->srqCallback = NULL; - pdpvt->phwpvt->parm = (caddr_t)NULL; - } - - /* Check for valid GPIB address */ - if ((pdpvt->head.device < 0) || (pdpvt->head.device >= IBAPERLINK)) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record : GPIB address out of range"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - /* Check for valid param entry */ - if ((pdpvt->parm < 0) || (pdpvt->parm > NUMPARAMS)) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record : Parameter # out of range"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - /* make sure that the record type matches the GPIB port type (jrw) */ - if (gpibCmds[pdpvt->parm].rec_typ != rec_typ ) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record: record type invalid for spec'd param #"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - pCmd = &gpibCmds[pdpvt->parm]; - if(pCmd->msgLen > 0) - pdpvt->msg = (char *)(malloc(pCmd->msgLen)); - if(pCmd->rspLen > 0) - pdpvt->rsp = (char *)(malloc(pCmd->rspLen)); - -#ifdef _SRQSUPPORT_ -/* - * Ok to re-register a handler for the same device, just don't do it after - * init time is over! - */ - (*(drvGpib.registerSrqCallback))(pdpvt->linkType, pdpvt->head.link, - bbnode, pdpvt->head.device, srqHandler, pdpvt->phwpvt); -#endif - - /* fill in the required stuff for the callcack task (jrw) */ - pdpvt->process = processCallback; - pdpvt->processPri = priorityLow; - - return(0); -} - -/****************************************************************************** - * - * These are the functions that are called to actually communicate with - * the GPIB device. - * - ******************************************************************************/ -static long -read_ai(pai) -struct aiRecord *pai; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pai->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - if (pai->pact) - { - if (dg535Debug) - logMsg("read_ai with PACT = 1\n"); - return(2); /* work is all done, return '2' to indicate val */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dpvt field on ring buffer */ - if (dg535Debug) - logMsg("read_ai with PACT = 0\n"); - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pai,MAJOR_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -write_ao(pao) -struct aoRecord *pao; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pao->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pao->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pao,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -read_bi(pbi) -struct biRecord *pbi; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pbi->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pbi->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pbi,READ_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - - -static long -write_bo(pbo) -struct boRecord *pbo; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pbo->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pbo->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pbo,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -read_mbbi(pmbbi) -struct mbbiRecord *pmbbi; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pmbbi->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pmbbi->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - - -static long -write_mbbo(pmbbo) -struct mbboRecord *pmbbo; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pmbbo->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pmbbo->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -read_stringin(pstringin) -struct stringinRecord *pstringin; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pstringin->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - if (pstringin->pact) - { - if (dg535Debug) - logMsg("read_stringin with PACT = 1\n"); - return(2); /* work is all done, return '2' to indicate val */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if (dg535Debug) - logMsg("read_stringin with PACT = 0\n"); - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pstringin,MAJOR_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -static long -write_stringout(pstringout) -struct stringoutRecord *pstringout; -{ - struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pstringout->dpvt); - struct gpibCmd *pCmd; - - pCmd = &gpibCmds[pdpvt->parm]; - - if (pstringout->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pstringout,WRITE_ALARM,VALID_ALARM); - return(0); - } - return(1); - } -} - -/****************************************************************************** - * - * Routines that do the actual GPIB work. They are called by the linkTask. - * - ******************************************************************************/ - -static int -aiGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct aiRecord *pai= ((struct aiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if(dg535Debug) - logMsg("aiGpibWork: starting ...\n"); - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - setPvSevr(pai,READ_ALARM,VALID_ALARM); - - if(dg535Debug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - } - else - { - if (pCmd->type != GPIBREADW) - aiGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = aiGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); /* indicate device is now idle */ -} - -static int -aiGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("aiGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; - - aiGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -aiGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - double value; - struct aiRecord *pai = ((struct aiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - if(dg535Debug) - logMsg("aiGpibWork: calling convert ...\n"); - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - if(dg535Debug) - logMsg("aiGpibWork: returned from convert ...\n"); - } - else /* interpret msg with predefined format and write into .val */ - { - /* scan response string, return value will be 1 if successful */ - if(sscanf(pdpvt->msg,pCmd->format,&value)) - { - pai->val = value; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pai,READ_ALARM,VALID_ALARM); - } - } - if(dg535Debug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - - return(0); -} - -static int -aoGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - struct aoRecord *pao= ((struct aoRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - sprintf(pdpvt->msg, pCmd->format, pao->val); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pao,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static int -biGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - setPvSevr(pbi,READ_ALARM,VALID_ALARM); - - if(dg535Debug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - } - else /* interpret response that came back */ - { - if (pCmd->type != GPIBREADW) - biGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = biGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); -} - -static int -biGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("biGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ - - biGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -biGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - unsigned long value; - struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* interpret msg with predefined format and write into .rval */ - { - /* scan response string, return value will be 1 if successful */ - if(sscanf(pdpvt->msg,pCmd->format, &value)) - { - pbi->rval = value; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pbi,READ_ALARM,VALID_ALARM); - } - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ - - return(0); -} - - -static int -boGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - int strStat = OK; - struct boRecord *pbo= ((struct boRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - sprintf(pdpvt->msg, pCmd->format, (unsigned int)pbo->val); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pbo,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); -} - -static int -mbbiGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read string response into msg[] */ - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM); - - if(dg535Debug) - logMsg("mbbiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - } - else - { - if (pCmd->type != GPIBREADW) - mbbiGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = mbbiGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); -} - -static int -mbbiGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("mbbiGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ - - mbbiGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -mbbiGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - unsigned long value; - struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* interpret msg with predefined format and write into .rval */ - { - /* scan response string, return value will be 1 if successful */ - if(sscanf(pdpvt->msg, pCmd->format, &value)) - { - pmbbi->rval = value; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); - } - } - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); - - return(0); -} - -static int -mbboGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - int strStat = OK; - struct mbboRecord *pmbbo= ((struct mbboRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - sprintf(pdpvt->msg, pCmd->format, (unsigned int)pmbbo->rval); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static int -stringinGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct stringinRecord *pstringin=((struct stringinRecord*)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if(dg535Debug) - logMsg("stringinGpibWork: starting ...\n"); - - if (xxGpibWork(pdpvt, pCmd->type) == ERROR) - { - if(dg535Debug) - logMsg("stringinGpibWork: error in xxGpibWork ...\n"); - setPvSevr(pstringin,READ_ALARM,VALID_ALARM); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ - } - else - { - if (pCmd->type != GPIBREADW) - stringinGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ - else - { - pdpvt->phwpvt->srqCallback = stringinGpibSrq; /* mark the handler */ - pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ - return(BUSY); /* indicate device still in use */ - } - } - return(IDLE); -} - -static int -stringinGpibSrq(pdpvt, srqStatus) -struct gpibDpvt *pdpvt; -int srqStatus; -{ - if (dg535Debug || ibSrqDebug) - logMsg("stringinGpibSrq(0x%08.8X, 0x%02.2X): processing srq\n", pdpvt, srqStatus); - - /* do actual SRQ processing in here */ - - pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ - pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ - - stringinGpibFinish(pdpvt); /* and finish the processing */ - return(IDLE); /* indicate device now idle */ -} - -static int -stringinGpibFinish(pdpvt) -struct gpibDpvt *pdpvt; -{ - struct stringinRecord *pstringin=((struct stringinRecord*)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - if (pCmd->convert != NULL) - { - if(dg535Debug) - logMsg("stringinGpibWork: calling convert ...\n"); - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - if(dg535Debug) - logMsg("stringinGpibWork: returned from convert ...\n"); - } - else /* interpret msg with predefined format and write into .val */ - { - /* scan response string, return value will be 1 if successful */ - strncpy(pstringin->val,pdpvt->msg,39); - pstringin->val[40] = '\0'; - } - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ - - return(0); -} - -static int -stringoutGpibWork(pdpvt) -struct gpibDpvt *pdpvt; -{ - int cnvrtStat = OK; - struct stringoutRecord *pstringout= ((struct stringoutRecord *)(pdpvt->precord)); - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - - /* generate command string to be sent */ - - /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1, pCmd->P2, pCmd->P3); - } - else /* generate msg using predefined format and current val */ - { - strncpy(pdpvt->msg, pstringout->val, 40); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt, pCmd->type) == ERROR)) - { - setPvSevr(pstringout,WRITE_ALARM,VALID_ALARM); - } - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static int -xxGpibWork(pdpvt, cmdType) -struct gpibDpvt *pdpvt; -int cmdType; -{ - int status; /* for GPIBREAD, contains ERROR or # of bytes read */ - struct gpibCmd *pCmd = &gpibCmds[pdpvt->parm]; - short ibnode = pdpvt->head.device; - short bbnode; /* In case is a bitbus->gpib type link */ - - /* If is a BBGPIB_IO link, the bug address is needed */ - if (pdpvt->linkType == BBGPIB_IO) - bbnode = pdpvt->head.bitBusDpvt->txMsg->node; - - /* - * check to see if this node has timed out within last 10 sec - */ - if(tickGet() < (pdpvt->phwpvt->tmoVal +TIME_WINDOW) ) - { - if (dg535Debug) - logMsg("dg535-xxGpibWork(): timeout flush\n"); - return(ERROR); - } - switch (cmdType) - { - case GPIBWRITE: /* write the message to the GPIB listen adrs */ - if(dg535Debug) - logMsg("xxGpibWork : processing GPIBWRITE\n"); - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pdpvt->msg, strlen(pdpvt->msg)); - - /* - * use for devices which respond to write commands - */ -#ifdef RESPONDS_2_WRITES - if (status == ERROR) - { - break; - } - status = (*(drvGpib.readIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pdpvt->rsp, pCmd->rspLen); -#endif - break; - - case GPIBREAD: /* write the command string */ - if(dg535Debug) - logMsg("xxGpibWork : processing GPIBREAD\n"); - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pCmd->cmd, strlen(pCmd->cmd)); - if (status == ERROR) - { - break; - } - /* This falls thru to the raw read code below! */ - - case GPIBRAWREAD: /* for SRQs, read the data w/o a sending a command */ - - /* read the instrument */ - status = (*(drvGpib.readIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pdpvt->msg, pCmd->msgLen); - if (status == ERROR) - { - break; - } - else if (status >( (pCmd->msgLen) - 1) ) /* check length of resp */ - { - logMsg("GPIB Response length equaled allocated space !!!\n"); - pdpvt->msg[(pCmd->msgLen)-1] = '\0'; /* place \0 at end */ - } - else - { - pdpvt->msg[status] = '\0'; /* terminate response with \0 */ - } - break; - - case GPIBREADW: /* for SRQs, write the command first */ - case GPIBCMD: /* write the cmd to the GPIB listen adrs */ - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, - bbnode, ibnode, pCmd->cmd, strlen(pCmd->cmd)); - break; - case GPIBCNTL: /* send cmd with atn line active */ - status = (*(drvGpib.writeIbCmd))(pdpvt->linkType, pdpvt->head.link, - bbnode, pCmd->cmd, strlen(pCmd->cmd)); - break; - } - if(dg535Debug) - logMsg("xxGpibWork : done, status = %d\n",status); - - /* if error occurrs then mark it with time */ - if(status == ERROR) - { - (pdpvt->phwpvt->tmoCount)++; /* count number of timeouts */ - pdpvt->phwpvt->tmoVal = tickGet(); /* set last timeout time */ - } - return(status); -} - -/****************************************************************************** - * - * This is invoked by the linkTask when an SRQ is detected from a device - * operated by this module. - * - * It calls the work routine associated with the type of record expecting - * the SRQ response. - * - * No semaphore locks are needed around the references to anything in the - * hwpvt structure, because it is static unless modified by the linkTask. - * - ******************************************************************************/ - -#ifdef _SRQSUPPORT_ - -static int srqHandler(phwpvt, srqStatus) -struct hwpvt *phwpvt; -int srqStatus; /* The poll response from the device */ -{ - if (dg535Debug || ibSrqDebug) - logMsg("srqHandler(0x%08.8X, 0x%02.2X): called\n", phwpvt, srqStatus); - - /* Invoke the command-type specific SRQ handler */ - if (phwpvt->srqCallback != NULL) - return((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); - - logMsg("Unsolicited SRQ rec'd from link %d, device %d, status = 0x%02.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - - return(IDLE); -} - -#endif /* _SRQSUPPORT_ */ - -/****************************************************************************** - * - * This function is called by the callback task. The callback task - * calls it after being given the 'go ahead' by callbackRequest() - * function calls made in the xxxWork routines defined above. - * - * The reason it is done this way is because the process() call may - * recursively call itself when records are chained and the callback - * task's stack is larger... just for this purpose. (jrw) - * - ******************************************************************************/ - -static void -processCallback(pDpvt) -struct gpibDpvt *pDpvt; -{ - if(dg535Debug) - logMsg("processCallback: calling process\n"); - - dbScanLock(pDpvt->precord); - (*(struct rset *)(pDpvt->precord->rset)).process(pDpvt->precord->pdba); - dbScanUnlock(pDpvt->precord); -} - -/****************************************************************************** - * - * This function is used to set alarm status information. - * - ******************************************************************************/ -static long -setPvSevr(pPv, status, severity) -struct dbCommon *pPv; -short severity; -short status; -{ - if (severity > pPv->nsev ) - { - pPv->nsta = status; - pPv->nsev = severity; - } -}