forked from optics/eib700
990 lines
26 KiB
C
990 lines
26 KiB
C
/* R. Follath,
|
|
|
|
EPICS-Interface to cEommunicate with EIB741
|
|
This is an interpolation electronics from Heidenhain to read and interpolate Incremental and Endat- encoders
|
|
|
|
25.9.2024 started with project
|
|
|
|
*/
|
|
// export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/afs/psi.ch/user/f/follath_r/progs/EIB700/lib64
|
|
|
|
|
|
#ifndef _DEFAULT_SOURCE
|
|
#define _DEFAULT_SOURCE /* sonst kommt eine WARNING */
|
|
#endif
|
|
|
|
#include <dbDefs.h>
|
|
#include <dbAccess.h>
|
|
#include <recSup.h>
|
|
#include <devSup.h>
|
|
#include <drvSup.h>
|
|
#include <menuConvert.h>
|
|
#include <aiRecord.h>
|
|
#include <aoRecord.h>
|
|
#include <calcoutRecord.h>
|
|
#include <longinRecord.h>
|
|
#include <longoutRecord.h>
|
|
#include <stringinRecord.h>
|
|
#include <stringoutRecord.h>
|
|
#include <mbboRecord.h>
|
|
#include <mbbiRecord.h>
|
|
#include <waveformRecord.h>
|
|
#include <errlog.h>
|
|
#include <dbScan.h>
|
|
#include <recGbl.h>
|
|
|
|
// #include <stddef.h>
|
|
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <math.h>
|
|
#include <float.h> // DBL_MIN
|
|
#include <errno.h>
|
|
#include <iocsh.h>
|
|
#include <unistd.h>
|
|
#include <sys/termios.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/signal.h>
|
|
|
|
#include <epicsMath.h>
|
|
#include <epicsMessageQueue.h>
|
|
#include <epicsEvent.h>
|
|
#include <epicsThread.h>
|
|
#include <epicsExport.h>
|
|
#include <epicsExit.h>
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
|
// #include "epicsExit.h"
|
|
#include "epicsThread.h"
|
|
#include "iocsh.h"
|
|
|
|
|
|
#include "Error.h"
|
|
#include "AuxFuncs.h"
|
|
#include "eib7.h"
|
|
#include "myEIB.h"
|
|
#include "Events.h"
|
|
|
|
// #include <asDbLib.h>
|
|
|
|
|
|
/*****************************************************************************/
|
|
enum commands /* Fuer die Kommunikation mit den Modulen */
|
|
{
|
|
UNB = 0,
|
|
CON = 1,
|
|
CH = 2,
|
|
READ = 3,
|
|
INCS = 30,
|
|
GPAL = 41,
|
|
SPAL = 42,
|
|
GPAD = 43,
|
|
SPAD = 44,
|
|
CHNAME = 49,
|
|
DOHOME = 50,
|
|
HCFNAME = 51,
|
|
RON_HBN = 52,
|
|
EIBH = 70,
|
|
EIBIP = 71,
|
|
GLE0 = 81,
|
|
GLE1 = 82,
|
|
GLE2 = 83,
|
|
CLE = 84,
|
|
MONERROR = 90,
|
|
AKTION = 99
|
|
};
|
|
typedef enum commands CMD;
|
|
|
|
typedef struct
|
|
{
|
|
unsigned short init;
|
|
CMD cmd;
|
|
// CALLBACK *pCallBack;
|
|
union
|
|
{
|
|
long parL;
|
|
double parD;
|
|
char buffer[120];
|
|
}com;
|
|
} MYDATA;
|
|
|
|
//CALLBACK *pCallBack;
|
|
|
|
int EpicsInfo = 0;
|
|
|
|
|
|
|
|
|
|
static long EIBai_parse (struct aiRecord *pai);
|
|
static long EIBai_read (struct aiRecord *pai);
|
|
static long EIBai_Linconv(struct aiRecord *pai, int after);
|
|
|
|
static long EIBwf_parse (struct waveformRecord *pwf);
|
|
static long EIBwf_read (struct waveformRecord *pwf);
|
|
|
|
static long EIBli_parse (struct longinRecord *pli);
|
|
static long EIBli_read (struct longinRecord *pli);
|
|
|
|
static long EIBso_parse (struct stringoutRecord *pso);
|
|
static long EIBso_write (struct stringoutRecord *pso);
|
|
|
|
static long EIBsi_read (struct stringinRecord *psi);
|
|
static long EIBsi_parse (struct stringinRecord *psi);
|
|
|
|
static long EIBlo_parse (struct longoutRecord *plo);
|
|
static long EIBlo_write (struct longoutRecord *plo);
|
|
|
|
static long EIBmbbo_parse (struct mbboRecord *pmbbo);
|
|
static long EIBmbbo_write (struct mbboRecord *pmbbo);
|
|
|
|
struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN write_mbbo;
|
|
DEVSUPFUN special_linconv;
|
|
}
|
|
EIBmbbo =
|
|
{
|
|
6,
|
|
NULL,
|
|
NULL,
|
|
EIBmbbo_parse,
|
|
NULL,
|
|
EIBmbbo_write,
|
|
NULL
|
|
};
|
|
epicsExportAddress(dset, EIBmbbo);
|
|
|
|
|
|
static struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN write_longout;
|
|
}
|
|
EIBlo =
|
|
{
|
|
5,
|
|
NULL,
|
|
NULL,
|
|
EIBlo_parse,
|
|
NULL,
|
|
EIBlo_write
|
|
};
|
|
epicsExportAddress(dset,EIBlo );
|
|
|
|
struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN read_stringin;
|
|
}
|
|
EIBsi =
|
|
{
|
|
5,
|
|
NULL,
|
|
NULL,
|
|
EIBsi_parse,
|
|
NULL,
|
|
EIBsi_read
|
|
};
|
|
epicsExportAddress(dset, EIBsi);
|
|
|
|
struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN read_stringin;
|
|
}
|
|
EIBso =
|
|
{
|
|
5,
|
|
NULL,
|
|
NULL,
|
|
EIBso_parse,
|
|
NULL,
|
|
EIBso_write
|
|
};
|
|
epicsExportAddress(dset, EIBso);
|
|
|
|
|
|
struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN read_longin;
|
|
}
|
|
/* umfasst MonoGetLongPar */
|
|
EIBli =
|
|
{
|
|
5,
|
|
NULL,
|
|
NULL,
|
|
EIBli_parse,
|
|
NULL,
|
|
EIBli_read
|
|
};
|
|
epicsExportAddress(dset, EIBli);
|
|
|
|
|
|
|
|
/********************* Liest einen Double *********************/
|
|
struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN read_ai;
|
|
DEVSUPFUN special_linconv;
|
|
}
|
|
EIBai =
|
|
{
|
|
6,
|
|
NULL,
|
|
NULL,
|
|
EIBai_parse,
|
|
NULL,
|
|
EIBai_read,
|
|
EIBai_Linconv
|
|
};
|
|
epicsExportAddress(dset,EIBai );
|
|
|
|
/************************* Waveform Record ******************/
|
|
struct
|
|
{
|
|
long number;
|
|
DEVSUPFUN report;
|
|
DEVSUPFUN init;
|
|
DEVSUPFUN init_record;
|
|
DEVSUPFUN get_ioint_info;
|
|
DEVSUPFUN read_ai;
|
|
DEVSUPFUN special_linconv;
|
|
}
|
|
EIBwaveform =
|
|
{
|
|
6,
|
|
NULL,
|
|
NULL,
|
|
EIBwf_parse,
|
|
NULL,
|
|
EIBwf_read,
|
|
NULL
|
|
};
|
|
epicsExportAddress(dset, EIBwaveform);
|
|
|
|
/*******************************************************************************/
|
|
static long EIBmbbo_parse(struct mbboRecord *pmbbo)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
name = pmbbo->out.value.instio.string;
|
|
data = (MYDATA *) calloc(1, sizeof(MYDATA));
|
|
data->cmd = UNB;
|
|
data->init = pmbbo->pini;
|
|
pmbbo->dpvt = (void *) data;
|
|
|
|
|
|
printf("EIB_mbbo_parse: <%s> ini = %i\n",name, pmbbo->pini);
|
|
|
|
if (pmbbo->out.type != INST_IO)
|
|
{
|
|
printf("EIB_mbbo_parse: <%s> Wrong ouput type\n",name);
|
|
return(S_db_badField);
|
|
}
|
|
|
|
/*------------------------ Kommandos zuweisen --------------------------------*/
|
|
|
|
if (!strcmp(name,"UNB" )) data->cmd = UNB;
|
|
else data->cmd = SPAL;
|
|
|
|
|
|
|
|
/*--------------- Beschriftung der Auswahlmenues setzen --------------------*/
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case UNB : sprintf(pmbbo->zrst, " Out");
|
|
sprintf(pmbbo->onst, "eins ");
|
|
break;
|
|
|
|
default: break;
|
|
}; /* switch */
|
|
|
|
return(MON_NO_ERROR);
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* setzt das Menue auf den aktuellen Eintrag. */
|
|
/* Geht nur wenn es zu Beginn in MonoSetMbbo_write aufgerufen wird */
|
|
/* !!!!!!!! Im ini-Feld des entsprechenden Records muss eine 1 stehen !!!!!!! */
|
|
static long EIBmbbo_init(MYDATA *data, char *name )
|
|
{
|
|
long res=0;
|
|
|
|
printf("EIB_mbbo_init : name <%s>\n",name);
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case UNB : break; // falsch, aktuelles Gitter wird mit GIB bestimmt
|
|
case SPAL : EIB_GpaL(name, &res) ; break; // falsch, aktuelles Gitter wird mit GIB bestimmt
|
|
default : printf("EIB_mbbo_init name not handled <%s>\n",name);
|
|
};
|
|
|
|
|
|
return(res);
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
static long EIBmbbo_write(struct mbboRecord *pmbbo)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
name = pmbbo->out.value.instio.string;
|
|
data = (MYDATA *)(pmbbo->dpvt);
|
|
|
|
printf("EIB_mbbo_write: <%s> Status = %i, val = %i\n",name, pmbbo->stat, pmbbo->val);
|
|
|
|
|
|
if (data->init)
|
|
{
|
|
pmbbo->val = EIBmbbo_init(data, name );
|
|
data->init = 0;
|
|
pmbbo->udf = FALSE;
|
|
return (MON_NO_ERROR);
|
|
}
|
|
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case SPAL : if (EpicsInfo) printf("EIB_mbbo_write: SPAL (%i), val = %i\n", SPAL, pmbbo->val);
|
|
EIB_SpaL(name, pmbbo->val);
|
|
break;
|
|
default : break;
|
|
}
|
|
|
|
return (MON_NO_ERROR);
|
|
}
|
|
|
|
/*************** Schreibt einen Long Parameter *******************************/
|
|
static long EIBlo_parse(struct longoutRecord *plo)
|
|
{
|
|
|
|
char *name;
|
|
MYDATA *data; /* my private datas */
|
|
|
|
|
|
data = (MYDATA *) calloc(1, sizeof(MYDATA));
|
|
name = plo->out.value.instio.string;
|
|
data->init= plo->pini;
|
|
plo->dpvt = (void *) data;
|
|
|
|
printf("EIB_lo_parse : process <%s> PINI= %i,\n",name,plo->pini);
|
|
|
|
if (!strcmp(name,"Trigger" )) data->cmd = UNB;
|
|
if (!strcmp(name,"AKTION" )) data->cmd = AKTION;
|
|
else if (!strcmp(name,"DebugLevel")) data->cmd = UNB;
|
|
|
|
else if (!contain(name,"CH_","_DOHOME" ,&data->com.parL))
|
|
{
|
|
if ( EIB_ValidEncoder(data->com.parL) )
|
|
{
|
|
printf("GPAL: <%s>, num = %li not available\n",name,data->com.parL);
|
|
return(MON_ERROR);
|
|
}
|
|
data->cmd = DOHOME;
|
|
}
|
|
else
|
|
data->cmd = SPAL;
|
|
|
|
/*--------------------- 6.8.2024 initialisieren ------------------------*/
|
|
/* PINI = 1 : den Wert aus der database oder autoSR nehmen */
|
|
/* PINI = 0 : den Wert aus der Steuerung (z.B.: MONO.CFG) nehmen */
|
|
/*
|
|
if (data->cmd == SPAL)
|
|
{
|
|
if (plo->pini)
|
|
{
|
|
printf("AthosSetLong_parse PINI= %i: <%s> set to %i \n",plo->pini,InstioString,plo->val);
|
|
MonoSpaL(InstioString,plo->val);
|
|
plo->pini = 0;
|
|
data->init = 0;
|
|
}
|
|
else
|
|
{
|
|
MonoGpaL(InstioString,&(plo->val));
|
|
printf("AthosSetLong_parse PINI= %i: <%s> use default value %i\n",plo->pini, InstioString, plo->val);
|
|
}
|
|
}
|
|
|
|
*/
|
|
return(MON_NO_ERROR);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
static long EIBlo_write(struct longoutRecord *plo)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
name = plo->out.value.instio.string;
|
|
data = (MYDATA *)(plo->dpvt);
|
|
|
|
if (EpicsInfo) printf("EIBlo_write: process <%s>, cmd=%i\n",name,data->cmd);
|
|
|
|
/* 6.8.2024
|
|
if (data->init)
|
|
{
|
|
data->init = 0;
|
|
plo->udf = FALSE;
|
|
printf("AthosSetLong_write:<%s> Set to %i\n", name,plo->val);
|
|
return (MON_NO_ERROR);
|
|
}
|
|
*/
|
|
switch (data->cmd)
|
|
{
|
|
|
|
case DOHOME : EIB_StartReference(data->com.parL);
|
|
break;
|
|
|
|
case AKTION : switch (plo->val)
|
|
{
|
|
case 99 : exit(0); break;
|
|
case 999 : monintGenerator(MONINT_EVNT_UPDATE); break;
|
|
case 50 : printf("EIBlo_write(AKTION): Write Amplitude-data to file with basename %s\n",RON_Hey_Basename);
|
|
EIB_WriteAllPointsToFile(RON_Hey_Basename);
|
|
break;
|
|
case 51 : printf("EIBlo_write(AKTION): Read corrections from file with basename %s\n",RON_Hey_Basename);
|
|
EIB_ReadAllPointsFromFile(RON_Hey_Basename);
|
|
break;
|
|
default: break;
|
|
};
|
|
break;
|
|
case SPAL : EIB_SpaL(name, plo->val); break;
|
|
default : printf("EIBlo_write: Unknown command %i\n",data->cmd); break;
|
|
};
|
|
|
|
plo->proc = 0;
|
|
plo->udf = FALSE;
|
|
|
|
return (MON_NO_ERROR);
|
|
|
|
}
|
|
|
|
/*******************************************************************************/
|
|
/* Holt einen String vom Mono */
|
|
static long EIBsi_parse(struct stringinRecord *psi)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
name = psi->inp.value.instio.string;
|
|
|
|
data = (MYDATA *) calloc(1, sizeof(MYDATA));
|
|
psi->dpvt = (void *) data;
|
|
|
|
printf("EIB_si_parse : process <%s>, pini = %i\n",name, psi->pini );
|
|
|
|
if (!strcmp(name,"errortext0")) data->cmd = GLE0; // letzter Fehler Nur zur Initialisierung */
|
|
else if (!strcmp(name,"errortext1")) data->cmd = GLE1;
|
|
else if (!strcmp(name,"errortext2")) data->cmd = GLE2;
|
|
else if (!strcmp(name,"HOSTNAME" )) data->cmd = EIBH;
|
|
else if (!strcmp(name,"IP")) data->cmd = EIBIP;
|
|
else if (!strcmp(name,"RON_HBN")) data->cmd = RON_HBN;
|
|
else if (!contain(name,"CH_","_NAME" ,&data->com.parL))
|
|
{
|
|
if ( data->com.parL > NCHANNELS)
|
|
{
|
|
printf("EIB_si_parse : Maximal number of CHANNELS = %i\n",NCHANNELS);
|
|
printf(" Try to initialize number %li exit.\n", data->com.parL );
|
|
exit(1);
|
|
}
|
|
data->cmd = CHNAME;
|
|
}
|
|
else if (!contain(name,"CH_","_HCFNAME" ,&data->com.parL))
|
|
{
|
|
if ( data->com.parL > NCHANNELS)
|
|
{
|
|
printf("EIB_si_parse : Maximal number of CHANNELS = %i\n",NCHANNELS);
|
|
printf(" Try to initialize number %li exit.\n", data->com.parL );
|
|
exit(1);
|
|
}
|
|
data->cmd = HCFNAME; // Heydemann-Correction File Name
|
|
}
|
|
else data->cmd = UNB;
|
|
|
|
return(MON_NO_ERROR);
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Retrieve strings out of c-code, e.g. RON_Hey_Basename */
|
|
static long EIBsi_read(struct stringinRecord *psi)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
char *text;
|
|
|
|
data = (MYDATA *)(psi->dpvt) ;
|
|
name = psi->inp.value.instio.string;
|
|
|
|
if (EpicsInfo) printf("EIBsi_read name <%s> \n",name );
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case GLE0 : text= Fehler[gle0].Msg;
|
|
strncpy(psi->val,text,39); // Maximum 40 characters, see Record Reference Manual
|
|
return(MON_NO_ERROR);
|
|
case GLE1 : text= Fehler[gle1].Msg;
|
|
strncpy(psi->val,text,39 ); // Maximum 40 characters, see Record Reference Manual
|
|
return(MON_NO_ERROR);
|
|
case GLE2 : text= Fehler[gle2].Msg;
|
|
strncpy(psi->val,text,39); // Maximum 40 characters, see Record Reference Manual
|
|
return(MON_NO_ERROR);
|
|
|
|
case EIBH : memcpy(psi->val,eib.hostname,40);
|
|
return(MON_NO_ERROR);
|
|
break;
|
|
|
|
case EIBIP : memcpy(psi->val, eib.sip ,40 );
|
|
return(MON_NO_ERROR);
|
|
break;
|
|
case CHNAME : strncpy(psi->val,eib.enc[data->com.parL].Name,39); // Maximum 40 characters, see Record Reference Manual
|
|
break;
|
|
|
|
case HCFNAME: strncpy(psi->val,eib.enc[data->com.parL].HeyFileName ,39); // Maximum 40 characters, see Record Reference Manual
|
|
break;
|
|
|
|
case RON_HBN: snprintf(psi->val, sizeof(psi->val), "%s",RON_Hey_Basename );
|
|
break;
|
|
|
|
default : strncpy(psi->val,"ERROR\0",6);
|
|
break;
|
|
}
|
|
|
|
if (EpicsInfo) printf("EIBsi_read line %i: name = %s, psi->val=<%s> \n",__LINE__,name,psi->val );
|
|
|
|
return (MON_NO_ERROR);
|
|
}
|
|
|
|
/*******************************************************************************/
|
|
/* Setzt einen String im Mono */
|
|
static long EIBso_parse(struct stringoutRecord *pso)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
name = pso->out.value.instio.string;
|
|
data = (MYDATA *) calloc(1, sizeof(MYDATA));
|
|
pso->dpvt = (void *) data;
|
|
|
|
if (EpicsInfo) printf(" EIBso_parse: process <%s>, pini=%i\n",name, pso->pini);
|
|
|
|
if (!strcmp(name,"MONERROR")) data->cmd = MONERROR;
|
|
else if (!strcmp(name,"EIB_HOSTNANME"))data->cmd = EIBH;
|
|
else if (!strcmp(name,"EIB_IP")) data->cmd = EIBIP;
|
|
else if (!strcmp(name,"RON_HBN")) data->cmd = RON_HBN;
|
|
else
|
|
{
|
|
printf("EIBso_parse: unknown Channel <%s>.\n",name);
|
|
}
|
|
|
|
|
|
pso->proc = 0;
|
|
pso->udf = FALSE;
|
|
|
|
return (MON_NO_ERROR);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Set Strings in c-code, e.g. RON_Hey_Basename */
|
|
static long EIBso_write(struct stringoutRecord *pso)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
data = (MYDATA *)(pso->dpvt);
|
|
name = pso->out.value.instio.string;
|
|
|
|
|
|
if (EpicsInfo) printf("EIBso_write: process <%s>, cmd=%i\n",name, data->cmd);
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case MONERROR : MonError(pso->val); break;
|
|
case EIBH : MonError(pso->val); break;
|
|
case EIBIP : MonError(pso->val); break;
|
|
case RON_HBN : printf("EIBso_write: Basename for Recoreded Encoder Values %s\n",pso->val);
|
|
snprintf(RON_Hey_Basename, sizeof(RON_Hey_Basename), "%s", pso->val);
|
|
monintGenerator(MONINT_EVNT_UPDATE);
|
|
break;
|
|
default : printf("EIBso_write: Unknown command %i\n",data->cmd); break;
|
|
};
|
|
|
|
|
|
pso->proc = 0;
|
|
pso->udf = FALSE;
|
|
|
|
return (MON_NO_ERROR);
|
|
}
|
|
|
|
|
|
/*******************************************************************************/
|
|
/* liest einen long Parameter aus dem Mono */
|
|
static long EIBli_parse(struct longinRecord *pli)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
long val;
|
|
|
|
name = pli->inp.value.instio.string;
|
|
data = (MYDATA *) calloc(1, sizeof(MYDATA));
|
|
pli->dpvt = (void *) data;
|
|
data->com.parL=0;
|
|
|
|
// if (EpicsInfo)
|
|
printf("EIB_li_parse : process <%s>, pini=%i\n",name, pli->pini);
|
|
|
|
|
|
if (pli->inp.type != INST_IO)
|
|
{
|
|
printf("EIB_li_parse line %i: Wrong input type\n",__LINE__);
|
|
return(S_db_badField);
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------ i n i t i a l i z e ------------*/
|
|
|
|
if (!strcmp(name,"CONNECTED")) data->cmd = CON ; /* Clear Errors */
|
|
else if (!strcmp(name,"CONNECT")) data->cmd = GPAL ;
|
|
else if (!EIB_GpaL(name,&val)) data->cmd = GPAL ;
|
|
else data->cmd = UNB;
|
|
|
|
|
|
|
|
/* ------------------------ PINI == 1 ?? ------------------*/
|
|
|
|
if (pli->pini==1)
|
|
{
|
|
printf("EIB_li_parse : init <%s> with %i\n",name, pli->val);
|
|
if ( data->cmd == CON) pli->val = eib.connected;
|
|
if (!strcmp(name,"CH_0_HOMED")) pli->val = eib.enc[0].HOMED;
|
|
if (!strcmp(name,"CH_1_HOMED")) pli->val = eib.enc[1].HOMED;
|
|
if (!strcmp(name,"CH_2_HOMED")) pli->val = eib.enc[2].HOMED;
|
|
if (!strcmp(name,"CH_3_HOMED")) pli->val = eib.enc[3].HOMED;
|
|
}
|
|
|
|
return(MON_NO_ERROR);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
static long EIBli_read(struct longinRecord *pli)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
long val;
|
|
|
|
data = (MYDATA *)(pli->dpvt);
|
|
name = pli->inp.value.instio.string;
|
|
|
|
if (EpicsInfo) printf("EIB_li_read : line %i: name <%s>\n",__LINE__,name);
|
|
|
|
/* ------------------------ r e a d ------------------------*/
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case CON : pli->val = eib.connected;
|
|
if (EpicsInfo) printf("EIB_li_read : eib.connected= %i\n",eib.connected );
|
|
break;
|
|
case GPAL : EIB_GpaL(name,&val);
|
|
pli->val = val;
|
|
break;
|
|
default : printf("EIB_li_read: Unknown Command %i NAME=%s\n",data->cmd,name); break;
|
|
};
|
|
|
|
if (EpicsInfo) printf("EIB_li_read : value = %i\n",pli->val);
|
|
|
|
|
|
/* ------------------------ PINI == 1 ?? ------------------*/
|
|
|
|
|
|
if (pli->pini==1)
|
|
{
|
|
printf("EIB_li_read : init <%s> with %i\n",name, pli->val);
|
|
if ( data->cmd == CON) pli->val = eib.connected; /* Clear Errors */
|
|
if (!strcmp(name,"CH_0_HOMED")) pli->val = eib.enc[0].HOMED;
|
|
pli->pini=0;
|
|
}
|
|
|
|
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
static long EIBwf_parse(struct waveformRecord *pwf)
|
|
{
|
|
char *name;
|
|
long num;
|
|
|
|
name = pwf->inp.value.instio.string;
|
|
|
|
pwf->dpvt= NULL;
|
|
|
|
printf("EIB_wf_parse : process <%s>, pini = %i\n",name, pwf->pini);
|
|
|
|
if (!contain(name,"CH_","_ADC00",&num))
|
|
{
|
|
if ( EIB_ValidEncoder(num) )
|
|
{
|
|
printf("EIB_wf_parse : <%s>, num = %li not available\n",name,num);
|
|
return(MON_ERROR);
|
|
}
|
|
pwf->bptr =(void *) (eib.enc[num].adc00);
|
|
pwf->nord = NUMPOINTS; /* number of data points to be store, e.g. for Heydemann-correction */
|
|
pwf->nelm = NUMPOINTS;
|
|
return(MON_NO_ERROR); // 8.10.2024 stempor�r auskommentiert
|
|
}
|
|
else if (!contain(name,"CH_","_ADC90",&num))
|
|
{
|
|
if ( EIB_ValidEncoder(num) )
|
|
{
|
|
printf("EIB_wf_parse : <%s>, num = %li not available\n",name,num);
|
|
return(MON_ERROR);
|
|
}
|
|
pwf->bptr =(void *) (eib.enc[num].adc90);
|
|
pwf->nord = NUMPOINTS; /* number of data points to be store, e.g. for Heydemann-correction */
|
|
pwf->nelm = NUMPOINTS;
|
|
return(MON_NO_ERROR);
|
|
}
|
|
if (!contain(name,"CH_","_CORRECTION",&num))
|
|
{
|
|
if ( EIB_ValidEncoder(num) )
|
|
{
|
|
printf("EIB_wf_parse : <%s>, num = %li not available\n",name,num);
|
|
return(MON_ERROR);
|
|
}
|
|
pwf->bptr =(void *) (eib.enc[num].Correction);
|
|
pwf->nord = NUMHEY; /* number of data points to be store, e.g. for Heydemann-correction */
|
|
pwf->nelm = NUMHEY;
|
|
return(MON_NO_ERROR);
|
|
}
|
|
|
|
|
|
return(MON_NO_ERROR);
|
|
|
|
} /* init record*/
|
|
/*-------------------------------------------------------------------------------------------*/
|
|
static long EIBwf_read(struct waveformRecord *pwf)
|
|
{
|
|
//short *bptr;
|
|
char *name;
|
|
int i;
|
|
long num;
|
|
|
|
name = pwf->inp.value.instio.string;
|
|
|
|
if (EpicsInfo>1) printf("EIB_wf_read: process <%s>\n",name);
|
|
|
|
if (!contain(name,"CH_","_ADC00",&num))
|
|
{
|
|
if (EpicsInfo)
|
|
{
|
|
printf("EIB_wf_read: pwf->nord = %i\n",pwf->nord);
|
|
for (i=0;i<10;i++) printf(" %i: pos %f\n",i, ((double *) pwf->bptr)[i] );
|
|
}
|
|
pwf->nord = NUMPOINTS ;
|
|
pwf->nelm = NUMPOINTS ;
|
|
return(0);
|
|
}
|
|
else if (!contain(name,"CH_","_ADC90",&num))
|
|
{
|
|
if (EpicsInfo)
|
|
{
|
|
printf("EIB_wf_read: pwf->nord = %i\n",pwf->nord);
|
|
for (i=0;i<10;i++) printf(" %i: pos %f\n",i, ((double *) pwf->bptr)[i] );
|
|
}
|
|
pwf->nord = NUMPOINTS ;
|
|
pwf->nelm = NUMPOINTS ;
|
|
return(0);
|
|
}
|
|
|
|
pwf->udf = FALSE;
|
|
|
|
return(MON_NO_ERROR);
|
|
|
|
} /* read_wf */
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
/* gibt den Wert einer internen Variablen an */
|
|
static long EIBai_parse(struct aiRecord *pai)
|
|
{
|
|
char *name;
|
|
MYDATA *data;
|
|
|
|
|
|
name = pai->inp.value.instio.string;
|
|
data = (MYDATA *) calloc(1, sizeof(MYDATA)); /* new */
|
|
pai->dpvt = (void *) data;
|
|
|
|
if (EpicsInfo) printf("EIB_ai_parse: process <%s>, pini = %i\n",name, pai->pini);
|
|
|
|
if (pai->inp.type != INST_IO)
|
|
{
|
|
printf("EIB_ai_parse: <%s> Wrong input type\n",name);
|
|
return(S_db_badField);
|
|
}
|
|
|
|
if (!strcmp(name, "UNB")) data->cmd = UNB; /* only to keep the syntax */
|
|
else if (!strcmp(name, "READ")) data->cmd = READ; /* Readback Photonenergy */
|
|
else if (!contain(name,"CH_","_VALUE" ,&data->com.parL))
|
|
{
|
|
if ( data->com.parL > NCHANNELS)
|
|
{
|
|
printf("EIB_ai_parse : Maximal number of CHANNELS = %i\n",NCHANNELS);
|
|
printf(" Try to initialize number %li exit.\n", data->com.parL );
|
|
exit(1);
|
|
}
|
|
data->cmd = CH;
|
|
}
|
|
else if (!strcmp(name,"INCS")) data->cmd = INCS; /* Readback Photonenergy */
|
|
else data->cmd = GPAD;
|
|
|
|
return(MON_NO_ERROR);
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* gibt den Wert einer internen Variablen an EPICS weiter */
|
|
static long EIBai_read(struct aiRecord *pai)
|
|
{
|
|
MYDATA *data;
|
|
char *name;
|
|
int ch;
|
|
int err;
|
|
double value;
|
|
|
|
data = (MYDATA *)(pai->dpvt);
|
|
name = pai->inp.value.instio.string;
|
|
|
|
if (EpicsInfo) printf("EIB_ai_read: %i, name = %s\n",data->cmd,name);
|
|
|
|
pai->udf = FALSE; /* Keine Ahnung was das hier macht */
|
|
pai->proc = 0;
|
|
|
|
switch (data->cmd)
|
|
{
|
|
case UNB : pai->val = 0; break; /* Werte wieder nach EPICS geben */
|
|
case READ :
|
|
case CH : ch = data->com.parL;
|
|
err=EIB_Read(ch,&value);
|
|
|
|
// if (err) pai->udf=1; else pai->udf=0;
|
|
|
|
if (EpicsInfo) printf("\nEIB_ai_read:err = %i, val= %f udf=%i\n",err,value, pai->udf);
|
|
pai->val = value;
|
|
break;
|
|
|
|
case GPAD : EIB_GpaD(name,&(pai->val));
|
|
break;
|
|
|
|
default : printf("EIBai_read: Unknown command %i, name=%s",data->cmd,name); break;
|
|
};
|
|
|
|
pai->rval= pai->val; /* rval ist anscheinend nur ganzzahl ?*/
|
|
|
|
return(2);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
static long EIBai_Linconv(struct aiRecord *pai, int after)
|
|
{
|
|
// MYDATA *data;
|
|
char *name;
|
|
|
|
//data = (MYDATA *)(pai->dpvt);
|
|
name = pai->inp.value.instio.string;
|
|
|
|
printf("EIB_ai_Linconv: Called from %s\n",name);
|
|
pai->val = pai->rval;
|
|
if (pai->linr ==2) pai->val = ((pai->rval + pai->roff) * pai->aslo + pai->aoff) * pai->eslo + pai->eoff;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
|
|
epicsExportAddress(int, EpicsInfo); /* in Athos.dbd: variable(EpicsInfo), auf shell dann: var lastError */
|
|
|
|
static const iocshArg RF_Arg0 = {"Filename", iocshArgString}; /* iocshArgInt, iocshArgDouble, iocshArgString, ... */
|
|
static const iocshArg *RF_Args[] = {&RF_Arg0};
|
|
static const iocshFuncDef ME_FuncDef = {"Menu" , 0, RF_Args }; /* Name unter iocshell, Anzahl Argumente, Argumente */
|
|
static const iocshFuncDef SE_FuncDef = {"ShowErrors", 0, RF_Args }; /* Name unter iocshell, Anzahl Argumente, Argumente */
|
|
|
|
|
|
static void ME_CallFunc (const iocshArgBuf *args) { EIB_Menu(); }
|
|
static void SE_CallFunc (const iocshArgBuf *args) { ShowErrors(); }
|
|
|
|
static void Register_Function (void)
|
|
{
|
|
iocshRegister(&SE_FuncDef, SE_CallFunc);
|
|
iocshRegister(&ME_FuncDef, ME_CallFunc);
|
|
EIB_Start();
|
|
}
|
|
|
|
epicsExportRegistrar(Register_Function);
|
|
|
|
|
|
// 129.129.179.151
|
|
/***********************************************************************************************/
|
|
/***********************************************************************************************/
|
|
/***********************************************************************************************/
|
|
int main(int argc,char *argv[])
|
|
{
|
|
if(argc>=2) {
|
|
iocsh(argv[1]);
|
|
epicsThreadSleep(.2);
|
|
}
|
|
printf("\n\nHello World\n\n");
|
|
|
|
// poll();
|
|
|
|
printf("%s: main EpicsInfo =%i\n\n" ,__FILE__, EpicsInfo);
|
|
printf(" Available functions : %s\n",ME_FuncDef.name);
|
|
|
|
monintGenerator(MONINT_EVNT_ERROR); /* Fehlermeldungen anzeigen */
|
|
|
|
iocsh(NULL);
|
|
epicsExit(0);
|
|
return(0);
|
|
}
|