472 lines
15 KiB
C
472 lines
15 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 "sinqhmdriv.i"
|
|
#include "tdchm.h"
|
|
#include "itc4.h"
|
|
#include "bruker.h"
|
|
#include "ltc11.h"
|
|
#include "eurodriv.h"
|
|
#include "el755driv.h"
|
|
#include <evdriver.i>
|
|
#include "serial.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(LinaStartup);
|
|
INIT(HaakeStartup);
|
|
INIT(MongoLogInit);
|
|
|
|
/*
|
|
* SICS specific Asynchronous I/O protocols
|
|
*/
|
|
INIT(AddAstriumnetProtocoll);
|
|
INIT(AddJulChoProtocoll);
|
|
INIT(AddHttpProtocoll);
|
|
INIT(AddHttpOptProtocoll);
|
|
INIT(AddPfeifferProtocoll);
|
|
INIT(AddTermProtocoll);
|
|
INIT(AddPhytronProtocoll);
|
|
INIT(AddSLSEchoProtocoll);
|
|
INIT(AddSeaClientProtocol);
|
|
INIT(AddDumProtocol);
|
|
INIT(AddJVLProtocoll);
|
|
INIT(AddSputterProtocoll);
|
|
INIT(AddZwickrollProtocoll);
|
|
|
|
}
|
|
|
|
|
|
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("MakeLMD200", MakeLMD200);
|
|
SCMD("MakePIMotor", PIMotorFactory);
|
|
SCMD("MakePoldiFold", MakePoldiFold);
|
|
SCMD("MakePSDFrame", MakeFrameFunc);
|
|
SCMD("MakeRitaFix", MakeRitaFix);
|
|
SCMD("MakeRitaWin", MakeRitaWin);
|
|
PCMD("MakeRuenBuffer", InitBufferSys);
|
|
SCMD("MakeSansliRebin", MakeSansliRebin);
|
|
SCMD("MakeSANSWave", MakeSANSWave);
|
|
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);
|
|
SCMD("MakeEigerMono", InitEigerMono);
|
|
PCMD("cnvrt", CnvrtAction);
|
|
/* SCMD("MakeEpicsAdapter", MakeEpicsAdapter); */
|
|
PCMD("zebraswap", ZebraSwap);
|
|
/*
|
|
* 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 *CreateEL734HP(SConnection * pCon, int argc, char *argv[]);
|
|
MotorDriver *CreateEL734HPT(SConnection * pCon, int argc, char *argv[]);
|
|
MotorDriver *CreateEL734Air(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], "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], "el734air") == 0) {
|
|
pDriver = (MotorDriver *) CreateEL734Air(pCon, argc - 2, &argv[2]);
|
|
if (!pDriver) {
|
|
return NULL;
|
|
}
|
|
/* create the motor */
|
|
pNew = MotorInit("EL734air", 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;
|
|
}
|
|
}
|
|
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[]);
|
|
|
|
pCounterDriver MakeEPICSCounter(char *rootname);
|
|
/*-------------------------------------------------------------------*/
|
|
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], "epics") == 0) {
|
|
if (argc < 4) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient no of arguments to create epics counter",
|
|
eError);
|
|
return NULL;
|
|
}
|
|
pNew = MakeEPICSCounter(argv[3]);
|
|
*/
|
|
}
|
|
return pNew;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
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);
|
|
}
|
|
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, "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 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], "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], "euro") == 0) {
|
|
checkError = 1;
|
|
pDriv = CreateEURODriv(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 = NULL;
|
|
sitePSI->CreateControllerDriver = CreatePsiController;
|
|
sitePSI->InstallEnvironmentController =
|
|
InstallPsiEnvironmentController;
|
|
sitePSI->ConfigureScan = ConfigurePsiScan;
|
|
sitePSI->KillSite = KillPsi;
|
|
}
|
|
return sitePSI;
|
|
}
|