Files
sicspsi/psi.c
koennecke 59d292cb79 - Added bridge functions to histmemsec to make it look more like histmem
- Modifed many modules using histmem to work also with histmemsec
- Extended tasker with task names and task groups
- There is a new taskobj which allows to list tasks and to interact with them.
- Task now supports running Tcl functions as tasks
- There is a new experimental sctcomtask module which allows to define communication
  tasks against a scriptcontext. This is a new feature which should facilitate
  writing sequential scripts using asynchronous communication.
- A fix to make spss7 work when there are no switches
- ORION support for single X. TRICS measures crystals hanging down, ORION
  standing up
2012-12-20 11:32:34 +00:00

550 lines
18 KiB
C

/*------------------------------------------------------------------------
P S I
This is the site specific interface to SICS for PSI. This file implements
the interface defined in ../site.h
copyright: see file COPYRIGHT
Mark Koennecke, June 2003 - May 2007
Modules initialized with an installation sics command are added to
AddPsiCommands with SCMD.
Modules initialized with a startup C command are added to SiteInit with
INIT.
There is no need to add include statements or prototype declarations for
above items.
However, for drivers added, we still need to declare the prototypes or
include the header file.
Markus Zolliker, Jan 2010
-----------------------------------------------------------------------*/
#include <tcl.h>
#include "sics.h"
#include "site.h"
#include <motor.h>
#include <site.h>
#include "ecbdriv.h"
#include "ecbcounter.h"
#include "sinqhmdriv.i"
#include "tdchm.h"
#include "tecsdriv.h"
#include "itc4.h"
#include "bruker.h"
#include "ltc11.h"
#include "A1931.h"
#include "eurodriv.h"
#include "el755driv.h"
#include <evdriver.i>
#include "serial.h"
#include "sinq.h"
#include "sinqhttp.h"
/*--------------------------------------------------------------------------*/
void SiteInit(void)
{
#define INIT(F) { void F(void); F(); }
/* insert here initialization routines ... */
INIT(IlmStartup);
INIT(IpsStartup);
INIT(ItcStartup);
INIT(IghStartup);
INIT(Euro2kStartup);
INIT(StrObjStartup);
INIT(ArrayObjStartup);
INIT(Lsc370Startup);
INIT(LinaStartup);
INIT(HaakeStartup);
INIT(AmiStartup);
/*
* SICS specific Asynchronous I/O protocols
*/
INIT(AddJulChoProtocoll);
INIT(AddHttpProtocoll);
INIT(AddHttpOptProtocoll);
INIT(AddPMACProtocoll);
INIT(AddPfeifferProtocoll);
INIT(AddTermProtocoll);
INIT(AddPhytronProtocoll);
INIT(AddSLSEchoProtocoll);
INIT(AddCharByCharProtocoll);
INIT(AddBinProtocol);
INIT(AddSeaClientProtocol);
INIT(AddDumProtocol);
INIT(AddJVLProtocoll);
}
static pSite sitePSI = NULL;
/*
* from tclClock.c
*/
int Tcl_ClockObjCmd (ClientData client, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
/*----------------------------------------------------------------------*/
static void AddPsiCommands(SicsInterp * pInter)
{
/* declare and add permanent command */
#define PCMD(NAME, FUN) { \
int FUN(SConnection * pCon, SicsInterp * pSics, void *pData, \
int argc, char *argv[]); \
AddCommandWithFlag(pInter, NAME, FUN, NULL, NULL, 0); \
}
/* declare and add startup command */
#define SCMD(NAME, FUN) { \
int FUN(SConnection * pCon, SicsInterp * pSics, void *pData, \
int argc, char *argv[]); \
AddCommandWithFlag(pInter, NAME, FUN, NULL, NULL, 1); \
}
/* alphabetic order */
SCMD("InstallFocusMerge", InstallFocusMerge);
SCMD("MakeAmorSet", AmorSetFactory);
SCMD("MakeAmorStatus", AmorStatusFactory);
SCMD("MakeECB", MakeECB);
SCMD("MakeFocusAverager", MakeFA);
SCMD("MakeJulCho", JulChoFactory);
SCMD("MakeLMD200", MakeLMD200);
SCMD("MakePIMotor", PIMotorFactory);
SCMD("MakePoldiReiss", MakePoldiReiss);
SCMD("MakePSDFrame", MakeFrameFunc);
SCMD("MakeRitaFix", MakeRitaFix);
SCMD("MakeRitaWin", MakeRitaWin);
PCMD("MakeRuenBuffer", InitBufferSys);
SCMD("MakeSansliRebin", MakeSansliRebin);
SCMD("MakeSANSWave", MakeSANSWave);
SCMD("MakeSinq", SinqFactory);
SCMD("MakeSinqRedirect", SinqRedirectFactory);
SCMD("MakeSPS", SPSFactory);
SCMD("MakeSPSS7", MakeSPSS7);
PCMD("MakeSWHPMotor", MakeSWHPMotor);
SCMD("MakeSWMotor", MakeSWMotor);
SCMD("MakeTableDrive", TableDriveFactory);
SCMD("MakeTAS", TASFactory);
SCMD("MakeTRICSSupport", MakeTricsSupport);
SCMD("PolterInstall", PolterInstall);
SCMD("SerialInit", SerialInit);
SCMD("MakeEiger", InitEiger);
PCMD("cnvrt", CnvrtAction);
/*
* Tcl 8.5 has implemented the clock command in tcl rather then C.
* This includes the same command, backported from Tcl 8.4
*/
Tcl_CreateObjCommand(InterpGetTcl(pServ->pSics), "clock", Tcl_ClockObjCmd, NULL, NULL);
/*
SCMD("MakeDifrac",MakeDifrac);
*/
}
/*---------------------------------------------------------------------*/
MotorDriver *CreateEL734(SConnection * pCon, int argc, char *argv[]);
MotorDriver *CreateEL734DC(SConnection * pCon, int argc, char *argv[]);
MotorDriver *CreateEL734HP(SConnection * pCon, int argc, char *argv[]);
MotorDriver *CreateEL734HPT(SConnection * pCon, int argc, char *argv[]);
MotorDriver *MakePiPiezo(Tcl_Interp * pTcl, char *pArray);
/*-------------------------------------------------------------------*/
static pMotor CreatePsiMotor(SConnection * pCon, int argc, char *argv[])
{
MotorDriver *pDriver = NULL;
pMotor pNew = NULL;
Tcl_Interp *pTcl = NULL;
char pBueffel[132];
if (strcmp(argv[1], "pipiezo") == 0) {
pTcl = InterpGetTcl(pServ->pSics);
pDriver = (MotorDriver *) MakePiPiezo(pTcl, argv[2]);
if (!pDriver) {
SCWrite(pCon, pTcl->result, eError);
return NULL;
}
/* create the motor */
pNew = MotorInit("PIPIEZO", argv[0], pDriver);
if (!pNew) {
snprintf(pBueffel,131, "Failure to create motor %s", argv[0]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
} else if (strcmp(argv[1], "el734") == 0) {
pDriver = (MotorDriver *) CreateEL734(pCon, argc - 2, &argv[2]);
if (!pDriver) {
return NULL;
}
/* create the motor */
pNew = MotorInit("EL734", argv[0], pDriver);
if (!pNew) {
snprintf(pBueffel,131, "Failure to create motor %s", argv[1]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
} else if (strcmp(argv[1], "el734hp") == 0) {
pDriver = (MotorDriver *) CreateEL734HP(pCon, argc - 2, &argv[2]);
if (!pDriver) {
return NULL;
}
/* create the motor */
pNew = MotorInit("EL734HP", argv[0], pDriver);
if (!pNew) {
snprintf(pBueffel,131, "Failure to create motor %s", argv[1]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
} else if (strcmp(argv[1], "el734hpt") == 0) {
pDriver = (MotorDriver *) CreateEL734HPT(pCon, argc - 2, &argv[2]);
if (!pDriver) {
return NULL;
}
/* create the motor */
pNew = MotorInit("EL734HPT", argv[0], pDriver);
if (!pNew) {
snprintf(pBueffel,131, "Failure to create motor %s", argv[1]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
} else if (strcmp(argv[1], "el734dc") == 0) {
pDriver = (MotorDriver *) CreateEL734DC(pCon, argc - 2, &argv[2]);
if (!pDriver) {
return NULL;
}
/* create the motor */
pNew = MotorInit("EL734DC", argv[0], pDriver);
if (!pNew) {
snprintf(pBueffel,131, "Failure to create motor %s", argv[1]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
} else if (strcmp(argv[1], "ecb") == 0) {
pDriver = (MotorDriver *) CreateECBMotor(pCon, argc - 2, &argv[2]);
if (!pDriver) {
return NULL;
}
/* create the motor */
pNew = MotorInit("ECB", argv[0], pDriver);
if (!pNew) {
snprintf(pBueffel,131, "Failure to create motor %s", argv[0]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
}
return pNew;
}
/*-------------------------------------------------------------------*/
extern pCounterDriver CreateEL737Counter(SConnection * pCon, char *name,
int argc, char *argv[]);
extern pCounterDriver MakeEL737HP(SConnection * pCon, char *name,
int argc, char *argv[]);
extern pCounterDriver MakeEL737HPV2(SConnection * pCon, char *name,
int argc, char *argv[]);
pCounterDriver MakeEL737hpsps(SConnection * pCon, char *name,
int argc, char *argv[]);
/*-------------------------------------------------------------------*/
static pCounterDriver CreatePsiCounterDriver(SConnection * pCon,
int argc, char *argv[])
{
pCounterDriver pNew = NULL;
/*
our caller has already checked for enough arguments
*/
if (strcmp(argv[2], "el737") == 0) {
pNew = CreateEL737Counter(pCon, argv[1], argc - 3, &argv[3]);
} else if (strcmp(argv[2], "el737hp") == 0) {
pNew = MakeEL737HP(pCon, argv[1], argc - 3, &argv[3]);
} else if (strcmp(argv[2], "el737hpsps") == 0) {
pNew = MakeEL737hpsps(pCon, argv[1], argc - 3, &argv[3]);
} else if (strcmp(argv[2], "el737hpv2") == 0) {
pNew = MakeEL737HPV2(pCon, argv[1], argc - 3, &argv[3]);
} else if (strcmp(argv[2], "ecb") == 0) {
if (argc < 4) {
SCWrite(pCon,
"ERROR: insufficient no of arguments to create ECB counter",
eError);
return NULL;
}
pNew = MakeECBCounter(argv[3]);
}
return pNew;
}
/*-------------------------------------------------------------------*/
extern pHistDriver MakeDelcamHM(pStringDict options); /* in delcam.c */
/*--------------------------------------------------------------------*/
static HistDriver *CreatePsiHistMem(char *name, pStringDict pOptions)
{
HistDriver *pNew = NULL;
if (strcmp(name, "sinqhm") == 0) {
pNew = CreateSINQDriver(pOptions);
} else if (strcmp(name, "tdc") == 0) {
pNew = MakeTDCHM(pOptions);
} else if (strcmp(name, "sinqhttp") == 0) {
pNew = CreateSinqHttpDriver(pOptions);
} else if (strcmp(name, "delcam") == 0) {
pNew = MakeDelcamHM(pOptions);
}
return pNew;
}
/*-------------------------------------------------------------------*/
extern pVelSelDriv VSCreateDornierSINQ(char *name, Tcl_Interp * pTcl);
extern pVelSelDriv VSCreateDornier2003(char *name, Tcl_Interp * pTcl);
/*-------------------------------------------------------------------*/
static pVelSelDriv CreatePsiVelSelDriv(char *name, char *array,
Tcl_Interp * pTcl)
{
pVelSelDriv pNew = NULL;
if (strcmp(name, "dornier") == 0) {
pNew = VSCreateDornierSINQ(array, pTcl);
} else if (strcmp(name, "dornier2003") == 0) {
pNew = VSCreateDornier2003(array, pTcl);
}
return pNew;
}
/*------------------------------------------------------------------*/
extern pCodri MakeCookerDriver(char *pHost, int iPort, int iChannel);
/*-------------------------------------------------------------------*/
static pCodri CreatePsiController(SConnection * pCon, int argc,
char *argv[])
{
pCodri pNew = NULL;
Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics);
int iPort, iChannel, iRet, iSingle = 0;
char pBueffel[512];
if (strcmp(argv[0], "sanscook") == 0) {
if (argc < 4) {
SCWrite(pCon,
"ERROR: Insufficient number of arguments to install SANS Cooker driver",
eError);
return NULL;
}
iRet = Tcl_GetInt(pTcl, argv[2], &iPort);
if (iRet != TCL_OK) {
snprintf(pBueffel, 511, "ERROR: expected integer as port number, got %s",
argv[2]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
iRet = Tcl_GetInt(pTcl, argv[3], &iChannel);
if (iRet != TCL_OK) {
sprintf(pBueffel,
"ERROR: expected integer as channel number, got %s",
argv[3]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
pNew = MakeCookerDriver(argv[1], iPort, iChannel);
}
return pNew;
}
/*-----------------------------------------------------------------
ConfigureController is a helper function which configures parameters
for certain controller types
--------------------------------------------------------------------*/
static void ConfigureController(char *name, pEVControl pNew,
SConnection * pCon)
{
EVCSetPar(pNew, "upperlimit", 300.0, pCon);
EVCSetPar(pNew, "lowerlimit", 1.0, pCon);
if (strcmp(name, "tecs") == 0) {
TecsCustomize(pCon, pNew);
} else if (strcmp(name, "euro") == 0) {
EVCSetPar(pNew, "upperlimit", 750.0, pCon);
EVCSetPar(pNew, "lowerlimit", 15.0, pCon);
} else if (strcmp(name, "el755") == 0) {
EVCSetPar(pNew, "upperlimit", 10., pCon);
EVCSetPar(pNew, "lowerlimit", -10., pCon);
} else if (strcmp(name, "bruker") == 0) {
EVCSetPar(pNew, "upperlimit", 45., pCon);
EVCSetPar(pNew, "lowerlimit", 0., pCon);
} else if (strcmp(name, "ltc11") == 0) {
EVCSetPar(pNew, "upperlimit", 500., pCon);
EVCSetPar(pNew, "lowerlimit", 1.5, pCon);
}
}
/*-------------------------------------------------------------------*/
extern pEVDriver CreateSLSDriv(int argc, char *argv[]);
extern pEVDriver CreateSLSVMEDriv(int argc, char *argv[]);
/*------------------------------------------------------------------*/
static pEVControl InstallPsiEnvironmentController(SicsInterp * pSics,
SConnection * pCon,
int argc, char *argv[])
{
pEVControl pNew = NULL;
pEVDriver pDriv = NULL;
int status = 1, checkError = 0, commandInstalled = 0;
char pBueffel[512], pError[132];
/*
flag usage:
checkError becomes 1 when a driver has been recognized and an error
must be issued if something failed.
commandInstalled becomes 1 when the command has already been installed
for the device. If 0 the default command will be installed later on
*/
if (strcmp(argv[3], "tecs") == 0) {
checkError = 1;
pDriv = CreateTecsDriver(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
if (pNew) {
AddCommand(pSics, argv[2], TecsWrapper, DeleteEVController, pNew);
commandInstalled = 1;
}
}
} else if (strcmp(argv[3], "itc4") == 0) {
checkError = 1;
pDriv = CreateITC4Driver(argc - 4, &argv[4]);
if (pDriv) {
pNew = CreateEVController(pDriv, argv[2], &status);
if (pNew != NULL) {
AddCommand(pSics, argv[2], ITC4Wrapper, DeleteEVController, pNew);
commandInstalled = 1;
}
}
} else if (strcmp(argv[3], "bruker") == 0) {
checkError = 1;
pDriv = CreateBrukerDriver(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
if (pNew != NULL) {
AddCommand(pSics, argv[2], BrukerAction, DeleteEVController, pNew);
commandInstalled = 1;
}
}
} else if (strcmp(argv[2], "ltc11") == 0) {
checkError = 1;
pDriv = CreateLTC11Driver(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
if (pNew != NULL) {
AddCommand(pSics, argv[2], LTC11Action, DeleteEVController, pNew);
commandInstalled = 1;
}
}
} else if (strcmp(argv[3], "a1931") == 0) {
checkError = 1;
pDriv = CreateA1931Driver(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
if (pNew != NULL) {
AddCommand(pSics, argv[2], A1931Action, DeleteEVController, pNew);
commandInstalled = 1;
}
}
} else if (strcmp(argv[3], "euro") == 0) {
checkError = 1;
pDriv = CreateEURODriv(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
}
} else if (strcmp(argv[3], "psi-dsp") == 0) {
checkError = 1;
pDriv = CreateSLSDriv(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
}
} else if (strcmp(argv[3], "vme-dsp") == 0) {
checkError = 1;
pDriv = CreateSLSVMEDriv(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
}
} else if (strcmp(argv[3], "el755") == 0) {
checkError = 1;
pDriv = CreateEL755Driv(argc - 4, &argv[4]);
if (pDriv != NULL) {
pNew = CreateEVController(pDriv, argv[2], &status);
}
} else {
snprintf(pBueffel,511, "ERROR: %s not recognized as a valid driver type",
argv[3]);
SCWrite(pCon, pBueffel, eError);
return NULL;
}
/* if we recognized the driver, check for installation errors */
if (checkError == 1) {
if (pDriv == NULL) {
SCWrite(pCon, "ERROR: failed to create driver", eError);
return NULL;
}
if (status != 1) {
SCWrite(pCon, "ERROR: failed to initialize device", eError);
pDriv->GetError(pDriv, &status, pError, 131);
snprintf(pBueffel, 511,"HW reported: %s", pError);
SCWrite(pCon, pBueffel, eError);
}
if (pNew == NULL) {
SCWrite(pCon, "ERROR: failed to create environment device object",
eError);
DeleteEVDriver(pDriv);
return NULL;
}
if (commandInstalled == 0) {
AddCommand(pSics, argv[2], EVControlWrapper, DeleteEVController,
pNew);
}
ConfigureController(argv[3], pNew, pCon);
}
return pNew;
}
/*-----------------------------------------------------------------*/
static int ConfigurePsiScan(pScanData self, char *option)
{
return 0;
}
/*--------------------------------------------------------------------*/
static void KillPsi(void *site)
{
free(site);
sitePSI = NULL;
}
/*---------------------------------------------------------------------
The scheme here goes along the lines of the singleton design pattern
---------------------------------------------------------------------*/
pSite getSite(void)
{
if (sitePSI == NULL) {
sitePSI = (pSite) malloc(sizeof(Site));
/*
we cannot go on if we do not even have enough memory to allocate
the site data structure
*/
assert(sitePSI);
/*
initializing function pointers
*/
sitePSI->AddSiteCommands = AddPsiCommands;
sitePSI->RemoveSiteCommands = NULL;
sitePSI->CreateMotor = CreatePsiMotor;
sitePSI->CreateCounterDriver = CreatePsiCounterDriver;
sitePSI->CreateHistogramMemoryDriver = CreatePsiHistMem;
sitePSI->CreateVelocitySelector = CreatePsiVelSelDriv;
sitePSI->CreateControllerDriver = CreatePsiController;
sitePSI->InstallEnvironmentController =
InstallPsiEnvironmentController;
sitePSI->ConfigureScan = ConfigurePsiScan;
sitePSI->KillSite = KillPsi;
}
return sitePSI;
}