/*------------------------------------------------------------------------ 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 -----------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include "buffer.h" #include "dmc.h" #include "nxsans.h" #include "nextrics.h" #include "sps.h" #include "pimotor.h" #include "sanswave.h" #include "faverage.h" #include "fowrite.h" #include "amor2t.h" #include "nxamor.h" #include "amorstat.h" #include "tas.h" #include "swmotor.h" #include "polterwrite.h" #include "ecb.h" #include "frame.h" #include "ecbdriv.h" #include "ecbcounter.h" #include #include "sinqhmdriv.i" #include "tdchm.h" #include "tecsdriv.h" #include "itc4.h" #include "bruker.h" #include "ltc11.h" #include "A1931.h" #include "dilludriv.h" #include "eurodriv.h" #include "el755driv.h" #include #include "amorscan.h" #include "serial.h" #include "fomerge.h" #include "remob.h" #include "tricssupport.h" #include "sinq.h" #include "tabledrive.h" #include "amorset.h" #include "sinqhttp.h" #include "poldizug.h" /* from tcpdornier.c */ extern int VelSelTcpFactory(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); /* * from julcho.c */ extern int JulChoFactory(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); /* from ritastorage.c */ extern int MakeRitaFix(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); /* from sanslirebin.c */ extern int MakeSansliRebin(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); /* from lmd200.c */ extern int MakeLMD200(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); /* from julchoprot.c */ extern void AddJulChoProtocoll(); /* from sinqhttpprot.c */ extern void AddHttpProtocoll(); /* from pmacprot.c */ extern void AddPMACProtocoll(); /*--------------------------------------------------------------------------*/ 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 */ AddJulChoProtocoll(); AddHttpProtocoll(); AddPMACProtocoll(); } static pSite sitePSI = NULL; /*----------------------------------------------------------------------*/ static void AddPsiCommands(SicsInterp * pInter) { AddCommand(pInter, "MakeRuenBuffer", InitBufferSys, NULL, NULL); AddCommand(pInter, "InitDMC", InitDmc, NULL, NULL); AddCommand(pInter, "InitSANS", InitSANS, NULL, NULL); AddCommand(pInter, "MakeTRICSNEXUS", NexTricsFactory, NULL, NULL); AddCommand(pInter, "MakeTRICSSupport", MakeTricsSupport, NULL, NULL); AddCommand(pInter, "MakeSPS", SPSFactory, NULL, NULL); AddCommand(pInter, "MakePIMotor", PIMotorFactory, NULL, NULL); AddCommand(pInter, "MakeSANSWave", MakeSANSWave, NULL, NULL); AddCommand(pInter, "MakeFocusAverager", MakeFA, NULL, NULL); AddCommand(pInter, "FocusInstall", FoInstall, NULL, NULL); AddCommand(pInter, "MakeAmor2T", Amor2TFactory, NULL, NULL); AddCommand(pInter, "MakeStoreAmor", AmorStoreMake, NULL, NULL); AddCommand(pInter, "MakeAmorStatus", AmorStatusFactory, NULL, NULL); AddCommand(pInter, "MakeTAS", TASFactory, NULL, NULL); AddCommand(pInter, "MakeSWMotor", MakeSWMotor, NULL, NULL); AddCommand(pInter, "MakeSWHPMotor", MakeSWHPMotor, NULL, NULL); AddCommand(pInter, "PolterInstall", PolterInstall, NULL, NULL); AddCommand(pInter, "MakeECB", MakeECB, NULL, NULL); AddCommand(pInter, "MakePSDFrame", MakeFrameFunc, NULL, NULL); AddCommand(pInter, "SerialInit", SerialInit, NULL, NULL); AddCommand(pInter, "InstallFocusMerge", InstallFocusMerge, NULL, NULL); AddCommand(pInter, "Remob", RemobCreate, NULL, NULL); AddCommand(pInter, "MakeSinq", SinqFactory, NULL, NULL); AddCommand(pInter, "MakeTableDrive", TableDriveFactory, NULL, NULL); AddCommand(pInter, "MakeAmorSet", AmorSetFactory, NULL, NULL); AddCommand(pInter, "MakeTCPSelector", VelSelTcpFactory, NULL, NULL); AddCommand(pInter, "MakeJulCho", JulChoFactory, NULL, NULL); AddCommand(pInter, "MakeRitaFix", MakeRitaFix, NULL, NULL); AddCommand(pInter, "MakePoldiReiss", MakePoldiReiss, NULL, NULL); AddCommand(pInter, "MakeSansliRebin", MakeSansliRebin, NULL, NULL); AddCommand(pInter, "MakeLMD200", MakeLMD200, NULL, NULL); /* AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL); */ } /*---------------------------------------------------------------------*/ static void RemovePsiCommands(SicsInterp * pSics) { RemoveCommand(pSics, "InitDMC"); RemoveCommand(pSics, "InitSANS"); RemoveCommand(pSics, "MakeTRICSNEXUS"); RemoveCommand(pSics, "MakeTRICSSupport"); RemoveCommand(pSics, "MakeSPS"); RemoveCommand(pSics, "MakePIMotor"); RemoveCommand(pSics, "MakeSANSWave"); RemoveCommand(pSics, "MakeFocusAverager"); RemoveCommand(pSics, "FocusInstall"); RemoveCommand(pSics, "InstallFocusMerge"); RemoveCommand(pSics, "MakeAmor2T"); RemoveCommand(pSics, "MakeStoreAmor"); RemoveCommand(pSics, "MakeAmorStatus"); RemoveCommand(pSics, "MakeTCPSelector"); RemoveCommand(pSics, "MakeJulCho"); RemoveCommand(pSics, "MakeRitaFix"); RemoveCommand(pSics, "MakePoldiReiss"); RemoveCommand(pSics, "MakeSansliRebin"); RemoveCommand(pSics, "MakeLMD200"); /* RemoveCommand(pSics,"MakeDifrac"); */ RemoveCommand(pSics, "MakeTAS"); RemoveCommand(pSics, "MakeSWMotor"); RemoveCommand(pSics, "PolterInstall"); RemoveCommand(pSics, "MakeECB"); RemoveCommand(pSics, "MakePSDFrame"); RemoveCommand(pSics, "SerialInit"); RemoveCommand(pSics, "MakeSinq"); RemoveCommand(pSics, "MakeTableDrive"); RemoveCommand(pSics, "MakeAmorSet"); } /*---------------------------------------------------------------------*/ 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) { sprintf(pBueffel, "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) { sprintf(pBueffel, "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) { sprintf(pBueffel, "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) { sprintf(pBueffel, "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) { sprintf(pBueffel, "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) { sprintf(pBueffel, "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 MakeDoChoDriver(char *pHost, int iPort, int iChannel, int iSingle); extern pCodri MakeCookerDriver(char *pHost, int iPort, int iChannel); extern pCodri MakeTcpDoChoDriver(char *tclArray, SConnection * pCon); /*-------------------------------------------------------------------*/ 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], "docho") == 0) { if (argc < 4) { SCWrite(pCon, "ERROR: Insufficient number of arguments to install Dornier Chopper driver", eError); return NULL; } iRet = Tcl_GetInt(pTcl, argv[2], &iPort); if (iRet != TCL_OK) { sprintf(pBueffel, "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; } if (argc > 4) { iRet = Tcl_GetInt(pTcl, argv[4], &iSingle); if (iRet != TCL_OK) { sprintf(pBueffel, "ERROR: expected integer as single flag, got %s", argv[4]); SCWrite(pCon, pBueffel, eError); return NULL; } } pNew = MakeDoChoDriver(argv[1], iPort, iChannel, iSingle); } else if (strcmp(argv[0], "tcpdocho") == 0) { if (argc < 2) { SCWrite(pCon, "ERROR: insufficient number of argumets for creating TcpDoCho", eError); return NULL; } return MakeTcpDoChoDriver(argv[1], pCon); } else 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) { sprintf(pBueffel, "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], "dillu") == 0) { checkError = 1; pDriv = CreateDILLUDriv(argc - 4, &argv[4]); if (pDriv != NULL) { pNew = CreateEVController(pDriv, argv[2], &status); } } 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 { sprintf(pBueffel, "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); sprintf(pBueffel, "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) { if (strcmp(option, "amor") == 0) { ConfigureAmor(self); return 1; } 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 = RemovePsiCommands; 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; }