/*
 * MH2000 device support 
 */

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

/******************************************************************************
 *
 * The following define statements are used to declare the names to be used
 * for the dset tables.   
 *
 * A DSET_AI entry must be declared here and referenced in an application
 * database description file even if the device provides no AI records.
 *
 ******************************************************************************/
#define DSET_AI     devAiMH2000
#define DSET_AO     devAoMH2000
#define DSET_BI     devBiMH2000
#define DSET_BO     devBoMH2000
#define DSET_EV     devEvMH2000
#define DSET_LI     devLiMH2000
#define DSET_LO     devLoMH2000
#define DSET_MBBI   devMbbiMH2000
#define DSET_MBBID  devMbbidMH2000
#define DSET_MBBO   devMbboMH2000
#define DSET_MBBOD  devMbbodMH2000
#define DSET_SI     devSiMH2000
#define DSET_SO     devSoMH2000
#define DSET_WF     devWfMH2000

#define MH2000_ADend     1    /* end of A/D conversion */
#define MH2000_Gerr      2    /* grammer error */
#define MH2000_ICerr     4    /* IC card error */
#define MH2000_Unope     8    /* operation unavailable */
#define MH2000_Chartend  16   /* chart end */
#define MH2000_busy      32   /* scan busy */
#define MH2000_int       64   /* interrupt */
#define MH2000_init      128  /* initializeing */


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

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

static float get_onetemp(char wa1[]);
static int rd_temp(char wav[], float temp[]);
static int rd_wf_temp(struct gpibDpvt *pdpvt,  int p1, int p2, char **p3);





/*static int rd_efast_data(struct gpibDpvt *pdpvt,  int p1, int p2, char **p3);
 */

/******************************************************************************
 * Strings used by the init routines to fill in the znam,onam,...
 * fields in BI and BO record types.
 ******************************************************************************/

/******************************************************************************
 * Structures used by the init routines to fill in the onst,twst,... and the
 * onvl,twvl,... fields in MBBI and MBBO record types.
 *
 * Note that the intExtSsBm and intExtSsBmStop structures use the same
 * intExtSsBmStopList and intExtSsBmStopVal lists but have a different number
 * of elements in them that they use... The intExtSsBm structure only represents
 * 4 elements,while the intExtSsBmStop structure represents 5.
 ******************************************************************************/


/******************************************************************************
 * String arrays for EFAST operations. The last entry must be 0.
 *
 * On input operations,only as many bytes as are found in the string array
 * elements are compared.  Additional bytes are ignored.
 * The first matching string  will be used as a match.
 *
 * For the input operations,the strings are compared literally!  This
 * can cause problems if the instrument is returning things like \r and \n
 * characters.  When defining input strings so you include them as well.
 ******************************************************************************/



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

    /* CMMAND 0 read 1-10 data */
  {&DSET_WF, GPIBREAD, IB_Q_LOW, "11,01,\r\n",NULL, 0, 4096, rd_wf_temp, 0, 0, NULL, NULL, NULL },
  /* Command 1 read 11-20 data */
  {&DSET_WF, GPIBREAD, IB_Q_LOW, "11,02,\r\n",NULL, 0, 4096, rd_wf_temp, 0, 0, NULL, NULL, NULL },
  /* Command 2 read 21-30 data */
  {&DSET_WF, GPIBREAD, IB_Q_LOW, "11,03,\r\n",NULL, 0, 4096, rd_wf_temp, 0, 0, NULL, NULL, NULL },



};




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

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

/******************************************************************************
 *
 * c code
 *
 *****************************************************************************/
static float get_onetemp(char wa1[])
{

#define E_TEMP  -100.0
int s;

 

  s = (wa1[4]-'0');
  if (s != 0) {
    /* printf("error on conversion =%x\n",s); */
     return E_TEMP;
     }
else return atof(wa1+5);
} /*STATIC int rd_temp(char wav[], float temp[], int s[])*/ static int rd_temp(char wav[], float temp[]) { int i; char wa1[30]; #define NAK 0x15 if (wav[0]!=NAK) { strtok(wav,","); strtok(NULL,","); for (i=0; i<10; i++)
{ strcpy(wa1,strtok(NULL,",")); /* printf("%d = %s\n",i, wa1); */
temp[i] = get_onetemp(wa1);
}
return 0; } else { /* s[0] = atoi(wav+1);*/ return 1; } } static int rd_wf_temp(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) { struct waveformRecord *pwf = (struct waveformRecord *) (pdpvt->precord);
char*craw, *ccc;
float*temparray;
float temp[511],*ptemp;
ints[511],ok_flag;
unsigned longnumElem;
temparray = (float *) pwf->bptr; craw = pdpvt->msg; /* printf("input org: %s",&craw); */ craw = strtok(craw,"\n\r"); /* printf("input data: %s\n",craw); */ if (craw == NULL) /* fairly unlikely ... */ { /* devGpibLib_setPvSevr(pwf, READ_ALARM, INVALID_ALARM); */ printf("null data in MH2000\n"); return(-1); } /* strtok(NULL," "); printf("check %s\n",craw);*/ ok_flag = rd_temp(craw,temp); if (ok_flag != 0) { /* devGpibLib_setPvSevr(pwf,READ_ALARM, INVALID_ALARM); */ printf("Not OK MH2000\n"); return(-1); } numElem = 10; if (numElem > pwf->nelm) numElem = pwf->nelm; pwf->nord = numElem;
ptemp=temp;
while (numElem--) { /* printf( "\n%d-th data: %f",numElem, *ptemp); */ *temparray++ = (float) *ptemp++; } /* printf( "\nread_wf end normally\n"); */ return(0); }