/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
*     National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
*     Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution. 
\*************************************************************************/

/*
 * Modification Log:
 * -----------------
 * .01  05-30-91        jrw     Initial Release
 * .02  01-14-02        nda     modified init_dev_sup() per 3.13 req'ts
 * .03  05-11-04        wen     example of R3.13 to R3.14/ASYN conversion
 */

#define DSET_AI         devAiK196Gpib
#define DSET_BO         devBoK196Gpib
#define DSET_MBBO       devMbboK196Gpib

#include <devCommonGpib.h>
#include <devGpib.h>

/*
 * Use the TIME_WINDOW defn to indicate how long commands should be ignored
 * for a given device after it times out.  The ignored commands will be
 * returned as errors to device support.
 *
 * Use the TIMEOUT to define how long you wish to wait for an I/O operation
 * to complete once started.
 */
#define TIME_WINDOW     10.0
#define TIMEOUT         1.0

/******************************************************************************
 *
 * 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.
 *
 ******************************************************************************/

static char     *(set196function[]) = {"F0X",  /* DC Volts */
                                       "F1X",  /* AC Volts */
                                       "F2X",  /* Ohms */
                                       "F3X",  /* DC Current */
                                       "F4X",  /* AC Current Function */
                                       "F5X",  /* ACV db */
                                       "F6X",  /* ACA db */
                                       "F7X",  /* Offset Compensated ohms */
                                        NULL};

static char     *(set196range[]) = {"R0X",  /* Auto Scale */
                                    "R1X",  /* 300 (mV) (uA) 300 (ohm) */
                                    "R2X",  /* 3 (V) (mA)      3 (Kohm) */
                                    "R3X",  /* 30 (DCV) (ACmV) (DCmA) (ACmA) 30 (Kohm) */
                                    "R4X",  /* 300 (V) (mA)  300 (Kohm) */
                                    "R5X",  /* 300 (V) 3 (A)   3 (Mohm) */
                                    "R6X",  /* 300 (V) 3 (A)  30 (Mohm) */
                                    "R7X",  /* 300 (V) 3 (A) 300 (Mohm) */
                                    NULL};

static char     *(set196rate[]) = {"S0X",  /* 3 1/2 Digits */
                                   "S1X",  /* 4 1/2 Digits */
                                   "S2X",  /* 5 1/2 Digits */
                                   "S3X",  /* 6 1/2 Digits */
                                   NULL};

/******************************************************************************
 *
 * Array of structures that define all GPIB messages
 * supported for this type of instrument.
 *
 ******************************************************************************/

static struct gpibCmd gpibCmds[] = 
{
  /* Param 0, (model)   */
  FILL,

  /* Param 1 initialization string */
  {&DSET_BO, GPIBCMD, IB_Q_HIGH, "L0XR3X", NULL, 0, 32,
                   NULL, 0, 0, NULL, NULL, NULL},

  /* Param 2 read current or voltage value */
  /* "%*4c%lf" = ignore first 4 characters, use double precision floating point format */
  {&DSET_AI, GPIBREAD, IB_Q_HIGH, "U7", "%*4c%lf", 0, 32,
                   NULL, 0, 0, NULL, NULL, NULL},

  /* Param 3 set function */
  {&DSET_MBBO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 0,
                   NULL, 0, 0, set196function, NULL, NULL},

  /* Param 4 set range */
  {&DSET_MBBO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 0,
                   NULL, 0, 0, set196range, NULL, NULL},
 
  /* Param 5 set resolution */
  {&DSET_MBBO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 0,
                   NULL, 0, 0, set196rate, NULL, NULL},
};

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